* objc/objc-act.c (build_constructor): Cast initializer values
[official-gcc.git] / gcc / objc / objc-act.c
blobbf770e9cb8958277d9e6f7a6457c262779e95f7c
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
34 the translator.
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
42 #include "config.h"
43 #include "system.h"
44 #include "tree.h"
45 #include "rtl.h"
46 #include "expr.h"
47 #include "c-tree.h"
48 #include "c-lex.h"
49 #include "c-common.h"
50 #include "flags.h"
51 #include "objc-act.h"
52 #include "input.h"
53 #include "except.h"
54 #include "function.h"
55 #include "output.h"
56 #include "toplev.h"
57 #include "ggc.h"
58 #include "cpplib.h"
59 #include "debug.h"
60 #include "target.h"
61 #include "varray.h"
63 /* This is the default way of generating a method name. */
64 /* I am not sure it is really correct.
65 Perhaps there's a danger that it will make name conflicts
66 if method names contain underscores. -- rms. */
67 #ifndef OBJC_GEN_METHOD_LABEL
68 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
69 do { \
70 char *temp; \
71 sprintf ((BUF), "_%s_%s_%s_%s", \
72 ((IS_INST) ? "i" : "c"), \
73 (CLASS_NAME), \
74 ((CAT_NAME)? (CAT_NAME) : ""), \
75 (SEL_NAME)); \
76 for (temp = (BUF); *temp; temp++) \
77 if (*temp == ':') *temp = '_'; \
78 } while (0)
79 #endif
81 /* These need specifying. */
82 #ifndef OBJC_FORWARDING_STACK_OFFSET
83 #define OBJC_FORWARDING_STACK_OFFSET 0
84 #endif
86 #ifndef OBJC_FORWARDING_MIN_OFFSET
87 #define OBJC_FORWARDING_MIN_OFFSET 0
88 #endif
90 /* Define the special tree codes that we use. */
92 /* Table indexed by tree code giving a string containing a character
93 classifying the tree code. */
95 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
97 static const char objc_tree_code_type[] = {
98 'x',
99 #include "objc-tree.def"
101 #undef DEFTREECODE
103 /* Table indexed by tree code giving number of expression
104 operands beyond the fixed part of the node structure.
105 Not used for types or decls. */
107 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
109 static const int objc_tree_code_length[] = {
111 #include "objc-tree.def"
113 #undef DEFTREECODE
115 /* Names of tree components.
116 Used for printing out the tree and error messages. */
117 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
119 static const char * const objc_tree_code_name[] = {
120 "@@dummy",
121 #include "objc-tree.def"
123 #undef DEFTREECODE
125 /* Set up for use of obstacks. */
127 #include "obstack.h"
129 #define obstack_chunk_alloc xmalloc
130 #define obstack_chunk_free free
132 /* This obstack is used to accumulate the encoding of a data type. */
133 static struct obstack util_obstack;
134 /* This points to the beginning of obstack contents,
135 so we can free the whole contents. */
136 char *util_firstobj;
138 /* for encode_method_def */
139 #include "rtl.h"
141 /* The version identifies which language generation and runtime
142 the module (file) was compiled for, and is recorded in the
143 module descriptor. */
145 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
146 #define PROTOCOL_VERSION 2
148 /* (Decide if these can ever be validly changed.) */
149 #define OBJC_ENCODE_INLINE_DEFS 0
150 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
152 /*** Private Interface (procedures) ***/
154 /* Used by compile_file. */
156 static void init_objc PARAMS ((void));
157 static void finish_objc PARAMS ((void));
159 /* Code generation. */
161 static void synth_module_prologue PARAMS ((void));
162 static tree build_constructor PARAMS ((tree, tree));
163 static rtx build_module_descriptor PARAMS ((void));
164 static tree init_module_descriptor PARAMS ((tree));
165 static tree build_objc_method_call PARAMS ((int, tree, tree,
166 tree, tree, tree));
167 static void generate_strings PARAMS ((void));
168 static tree get_proto_encoding PARAMS ((tree));
169 static void build_selector_translation_table PARAMS ((void));
170 static tree build_ivar_chain PARAMS ((tree, int));
172 static tree objc_add_static_instance PARAMS ((tree, tree));
174 static tree build_ivar_template PARAMS ((void));
175 static tree build_method_template PARAMS ((void));
176 static tree build_private_template PARAMS ((tree));
177 static void build_class_template PARAMS ((void));
178 static void build_selector_template PARAMS ((void));
179 static void build_category_template PARAMS ((void));
180 static tree build_super_template PARAMS ((void));
181 static tree build_category_initializer PARAMS ((tree, tree, tree,
182 tree, tree, tree));
183 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
184 tree, tree));
186 static void synth_forward_declarations PARAMS ((void));
187 static void generate_ivar_lists PARAMS ((void));
188 static void generate_dispatch_tables PARAMS ((void));
189 static void generate_shared_structures PARAMS ((void));
190 static tree generate_protocol_list PARAMS ((tree));
191 static void generate_forward_declaration_to_string_table PARAMS ((void));
192 static void build_protocol_reference PARAMS ((tree));
194 static tree build_keyword_selector PARAMS ((tree));
195 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
197 static void generate_static_references PARAMS ((void));
198 static int check_methods_accessible PARAMS ((tree, tree,
199 int));
200 static void encode_aggregate_within PARAMS ((tree, int, int,
201 int, int));
202 static const char *objc_demangle PARAMS ((const char *));
203 static const char *objc_printable_name PARAMS ((tree, int));
204 static void objc_expand_function_end PARAMS ((void));
206 /* Hash tables to manage the global pool of method prototypes. */
208 hash *nst_method_hash_list = 0;
209 hash *cls_method_hash_list = 0;
211 static size_t hash_func PARAMS ((tree));
212 static void hash_init PARAMS ((void));
213 static void hash_enter PARAMS ((hash *, tree));
214 static hash hash_lookup PARAMS ((hash *, tree));
215 static void hash_add_attr PARAMS ((hash, tree));
216 static tree lookup_method PARAMS ((tree, tree));
217 static tree lookup_instance_method_static PARAMS ((tree, tree));
218 static tree lookup_class_method_static PARAMS ((tree, tree));
219 static tree add_class PARAMS ((tree));
220 static void add_category PARAMS ((tree, tree));
222 enum string_section
224 class_names, /* class, category, protocol, module names */
225 meth_var_names, /* method and variable names */
226 meth_var_types /* method and variable type descriptors */
229 static tree add_objc_string PARAMS ((tree,
230 enum string_section));
231 static tree get_objc_string_decl PARAMS ((tree,
232 enum string_section));
233 static tree build_objc_string_decl PARAMS ((enum string_section));
234 static tree build_selector_reference_decl PARAMS ((void));
236 /* Protocol additions. */
238 static tree add_protocol PARAMS ((tree));
239 static tree lookup_protocol PARAMS ((tree));
240 static void check_protocol_recursively PARAMS ((tree, tree));
241 static tree lookup_and_install_protocols PARAMS ((tree));
243 /* Type encoding. */
245 static void encode_type_qualifiers PARAMS ((tree));
246 static void encode_pointer PARAMS ((tree, int, int));
247 static void encode_array PARAMS ((tree, int, int));
248 static void encode_aggregate PARAMS ((tree, int, int));
249 static void encode_bitfield PARAMS ((int));
250 static void encode_type PARAMS ((tree, int, int));
251 static void encode_field_decl PARAMS ((tree, int, int));
253 static void really_start_method PARAMS ((tree, tree));
254 static int comp_method_with_proto PARAMS ((tree, tree));
255 static int comp_proto_with_proto PARAMS ((tree, tree));
256 static tree get_arg_type_list PARAMS ((tree, int, int));
257 static tree expr_last PARAMS ((tree));
259 /* Utilities for debugging and error diagnostics. */
261 static void warn_with_method PARAMS ((const char *, int, tree));
262 static void error_with_ivar PARAMS ((const char *, tree, tree));
263 static char *gen_method_decl PARAMS ((tree, char *));
264 static char *gen_declaration PARAMS ((tree, char *));
265 static void gen_declaration_1 PARAMS ((tree, char *));
266 static char *gen_declarator PARAMS ((tree, char *,
267 const char *));
268 static int is_complex_decl PARAMS ((tree));
269 static void adorn_decl PARAMS ((tree, char *));
270 static void dump_interface PARAMS ((FILE *, tree));
272 /* Everything else. */
274 static void add_objc_tree_codes PARAMS ((void));
275 static tree define_decl PARAMS ((tree, tree));
276 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
277 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
278 static tree create_builtin_decl PARAMS ((enum tree_code,
279 tree, const char *));
280 static void setup_string_decl PARAMS ((void));
281 static tree my_build_string PARAMS ((int, const char *));
282 static void build_objc_symtab_template PARAMS ((void));
283 static tree init_def_list PARAMS ((tree));
284 static tree init_objc_symtab PARAMS ((tree));
285 static void forward_declare_categories PARAMS ((void));
286 static void generate_objc_symtab_decl PARAMS ((void));
287 static tree build_selector PARAMS ((tree));
288 static tree build_typed_selector_reference PARAMS ((tree, tree));
289 static tree build_selector_reference PARAMS ((tree));
290 static tree build_class_reference_decl PARAMS ((void));
291 static void add_class_reference PARAMS ((tree));
292 static tree objc_copy_list PARAMS ((tree, tree *));
293 static tree build_protocol_template PARAMS ((void));
294 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
295 static tree build_method_prototype_list_template PARAMS ((tree, int));
296 static tree build_method_prototype_template PARAMS ((void));
297 static int forwarding_offset PARAMS ((tree));
298 static tree encode_method_prototype PARAMS ((tree, tree));
299 static tree generate_descriptor_table PARAMS ((tree, const char *,
300 int, tree, tree));
301 static void generate_method_descriptors PARAMS ((tree));
302 static tree build_tmp_function_decl PARAMS ((void));
303 static void hack_method_prototype PARAMS ((tree, tree));
304 static void generate_protocol_references PARAMS ((tree));
305 static void generate_protocols PARAMS ((void));
306 static void check_ivars PARAMS ((tree, tree));
307 static tree build_ivar_list_template PARAMS ((tree, int));
308 static tree build_method_list_template PARAMS ((tree, int));
309 static tree build_ivar_list_initializer PARAMS ((tree, tree));
310 static tree generate_ivars_list PARAMS ((tree, const char *,
311 int, tree));
312 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
313 static tree generate_dispatch_table PARAMS ((tree, const char *,
314 int, tree));
315 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
316 tree, int, tree, tree,
317 tree));
318 static void generate_category PARAMS ((tree));
319 static int is_objc_type_qualifier PARAMS ((tree));
320 static tree adjust_type_for_id_default PARAMS ((tree));
321 static tree check_duplicates PARAMS ((hash));
322 static tree receiver_is_class_object PARAMS ((tree));
323 static int check_methods PARAMS ((tree, tree, int));
324 static int conforms_to_protocol PARAMS ((tree, tree));
325 static void check_protocol PARAMS ((tree, const char *,
326 const char *));
327 static void check_protocols PARAMS ((tree, const char *,
328 const char *));
329 static tree encode_method_def PARAMS ((tree));
330 static void gen_declspecs PARAMS ((tree, char *, int));
331 static void generate_classref_translation_entry PARAMS ((tree));
332 static void handle_class_ref PARAMS ((tree));
333 static void generate_struct_by_value_array PARAMS ((void))
334 ATTRIBUTE_NORETURN;
335 static void objc_act_parse_init PARAMS ((void));
336 static void ggc_mark_imp_list PARAMS ((void *));
337 static void ggc_mark_hash_table PARAMS ((void *));
339 /*** Private Interface (data) ***/
341 /* Reserved tag definitions. */
343 #define TYPE_ID "id"
344 #define TAG_OBJECT "objc_object"
345 #define TAG_CLASS "objc_class"
346 #define TAG_SUPER "objc_super"
347 #define TAG_SELECTOR "objc_selector"
349 #define UTAG_CLASS "_objc_class"
350 #define UTAG_IVAR "_objc_ivar"
351 #define UTAG_IVAR_LIST "_objc_ivar_list"
352 #define UTAG_METHOD "_objc_method"
353 #define UTAG_METHOD_LIST "_objc_method_list"
354 #define UTAG_CATEGORY "_objc_category"
355 #define UTAG_MODULE "_objc_module"
356 #define UTAG_STATICS "_objc_statics"
357 #define UTAG_SYMTAB "_objc_symtab"
358 #define UTAG_SUPER "_objc_super"
359 #define UTAG_SELECTOR "_objc_selector"
361 #define UTAG_PROTOCOL "_objc_protocol"
362 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
363 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
364 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
366 #ifdef NEXT_OBJC_RUNTIME
367 #define STRING_OBJECT_CLASS_NAME "NSConstantString"
368 #else
369 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
370 #endif
371 /* Note that the string object global name is only needed for the
372 NeXT runtime. */
373 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
375 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
377 static const char *constant_string_class_name = NULL;
379 static const char *TAG_GETCLASS;
380 static const char *TAG_GETMETACLASS;
381 static const char *TAG_MSGSEND;
382 static const char *TAG_MSGSENDSUPER;
383 static const char *TAG_EXECCLASS;
385 /* The OCTI_... enumeration itself in in objc/objc-act.h. */
386 tree objc_global_trees[OCTI_MAX];
388 int objc_receiver_context;
390 static void handle_impent PARAMS ((struct imp_entry *));
392 struct imp_entry *imp_list = 0;
393 int imp_count = 0; /* `@implementation' */
394 int cat_count = 0; /* `@category' */
396 static int method_slot = 0; /* Used by start_method_def, */
398 #define BUFSIZE 1024
400 static char *errbuf; /* Buffer for error diagnostics */
402 /* Data imported from tree.c. */
404 extern enum debug_info_type write_symbols;
406 /* Data imported from toplev.c. */
408 extern const char *dump_base_name;
410 /* Generate code for GNU or NeXT runtime environment. */
412 #ifdef NEXT_OBJC_RUNTIME
413 int flag_next_runtime = 1;
414 #else
415 int flag_next_runtime = 0;
416 #endif
418 int flag_typed_selectors;
420 /* Open and close the file for outputting class declarations, if requested. */
422 int flag_gen_declaration = 0;
424 FILE *gen_declaration_file;
426 /* Warn if multiple methods are seen for the same selector, but with
427 different argument types. */
429 int warn_selector = 0;
431 /* Warn if methods required by a protocol are not implemented in the
432 class adopting it. When turned off, methods inherited to that
433 class are also considered implemented */
435 int flag_warn_protocol = 1;
437 /* Tells "encode_pointer/encode_aggregate" whether we are generating
438 type descriptors for instance variables (as opposed to methods).
439 Type descriptors for instance variables contain more information
440 than methods (for static typing and embedded structures). This
441 was added to support features being planned for dbkit2. */
443 static int generating_instance_variables = 0;
445 /* Tells the compiler that this is a special run. Do not perform
446 any compiling, instead we are to test some platform dependent
447 features and output a C header file with appropriate definitions. */
449 static int print_struct_values = 0;
451 static varray_type deferred_fns;
453 /* Some platforms pass small structures through registers versus through
454 an invisible pointer. Determine at what size structure is the
455 transition point between the two possibilities. */
457 static void
458 generate_struct_by_value_array ()
460 tree type;
461 tree field_decl, field_decl_chain;
462 int i, j;
463 int aggregate_in_mem[32];
464 int found = 0;
466 /* Presumably no platform passes 32 byte structures in a register. */
467 for (i = 1; i < 32; i++)
469 char buffer[5];
471 /* Create an unnamed struct that has `i' character components */
472 type = start_struct (RECORD_TYPE, NULL_TREE);
474 strcpy (buffer, "c1");
475 field_decl = create_builtin_decl (FIELD_DECL,
476 char_type_node,
477 buffer);
478 field_decl_chain = field_decl;
480 for (j = 1; j < i; j++)
482 sprintf (buffer, "c%d", j + 1);
483 field_decl = create_builtin_decl (FIELD_DECL,
484 char_type_node,
485 buffer);
486 chainon (field_decl_chain, field_decl);
488 finish_struct (type, field_decl_chain, NULL_TREE);
490 aggregate_in_mem[i] = aggregate_value_p (type);
491 if (!aggregate_in_mem[i])
492 found = 1;
495 /* We found some structures that are returned in registers instead of memory
496 so output the necessary data. */
497 if (found)
499 for (i = 31; i >= 0; i--)
500 if (!aggregate_in_mem[i])
501 break;
502 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
504 /* The first member of the structure is always 0 because we don't handle
505 structures with 0 members */
506 printf ("static int struct_forward_array[] = {\n 0");
508 for (j = 1; j <= i; j++)
509 printf (", %d", aggregate_in_mem[j]);
510 printf ("\n};\n");
513 exit (0);
516 const char *
517 objc_init (filename)
518 const char *filename;
520 filename = c_objc_common_init (filename);
521 add_objc_tree_codes ();
523 decl_printable_name = objc_printable_name;
525 /* Force the line number back to 0; check_newline will have
526 raised it to 1, which will make the builtin functions appear
527 not to be built in. */
528 lineno = 0;
530 /* If gen_declaration desired, open the output file. */
531 if (flag_gen_declaration)
533 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
534 gen_declaration_file = fopen (dumpname, "w");
535 if (gen_declaration_file == 0)
536 fatal_io_error ("can't open %s", dumpname);
537 free (dumpname);
540 if (flag_next_runtime)
542 TAG_GETCLASS = "objc_getClass";
543 TAG_GETMETACLASS = "objc_getMetaClass";
544 TAG_MSGSEND = "objc_msgSend";
545 TAG_MSGSENDSUPER = "objc_msgSendSuper";
546 TAG_EXECCLASS = "__objc_execClass";
548 else
550 TAG_GETCLASS = "objc_get_class";
551 TAG_GETMETACLASS = "objc_get_meta_class";
552 TAG_MSGSEND = "objc_msg_lookup";
553 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
554 TAG_EXECCLASS = "__objc_exec_class";
555 flag_typed_selectors = 1;
558 objc_ellipsis_node = make_node (ERROR_MARK);
560 init_objc ();
562 if (print_struct_values)
563 generate_struct_by_value_array ();
565 objc_act_parse_init ();
567 VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
568 ggc_add_tree_varray_root (&deferred_fns, 1);
570 return filename;
573 /* Register a function tree, so that its optimization and conversion
574 to RTL is only done at the end of the compilation. */
577 defer_fn (fn)
578 tree fn;
580 VARRAY_PUSH_TREE (deferred_fns, fn);
582 return 1;
585 void
586 finish_file ()
588 size_t i;
590 for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
591 /* Don't output the same function twice. We may run into such
592 situations when an extern inline function is later given a
593 non-extern-inline definition. */
594 if (! TREE_ASM_WRITTEN (VARRAY_TREE (deferred_fns, i)))
595 c_expand_deferred_function (VARRAY_TREE (deferred_fns, i));
596 VARRAY_FREE (deferred_fns);
598 finish_objc (); /* Objective-C finalization */
600 if (gen_declaration_file)
601 fclose (gen_declaration_file);
605 objc_decode_option (argc, argv)
606 int argc;
607 char **argv;
609 const char *p = argv[0];
611 if (!strcmp (p, "-gen-decls"))
612 flag_gen_declaration = 1;
613 else if (!strcmp (p, "-Wselector"))
614 warn_selector = 1;
615 else if (!strcmp (p, "-Wno-selector"))
616 warn_selector = 0;
617 else if (!strcmp (p, "-Wprotocol"))
618 flag_warn_protocol = 1;
619 else if (!strcmp (p, "-Wno-protocol"))
620 flag_warn_protocol = 0;
621 else if (!strcmp (p, "-fgnu-runtime"))
622 flag_next_runtime = 0;
623 else if (!strcmp (p, "-fno-next-runtime"))
624 flag_next_runtime = 0;
625 else if (!strcmp (p, "-fno-gnu-runtime"))
626 flag_next_runtime = 1;
627 else if (!strcmp (p, "-fnext-runtime"))
628 flag_next_runtime = 1;
629 else if (!strcmp (p, "-print-objc-runtime-info"))
630 print_struct_values = 1;
631 #define CSTSTRCLASS "-fconstant-string-class="
632 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
633 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
634 error ("no class name specified as argument to -fconstant-string-class");
635 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
637 #undef CSTSTRCLASS
638 else
639 return c_decode_option (argc, argv);
641 return 1;
645 static tree
646 define_decl (declarator, declspecs)
647 tree declarator;
648 tree declspecs;
650 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
651 finish_decl (decl, NULL_TREE, NULL_TREE);
652 return decl;
655 /* Return 1 if LHS and RHS are compatible types for assignment or
656 various other operations. Return 0 if they are incompatible, and
657 return -1 if we choose to not decide. When the operation is
658 REFLEXIVE, check for compatibility in either direction.
660 For statically typed objects, an assignment of the form `a' = `b'
661 is permitted if:
663 `a' is of type "id",
664 `a' and `b' are the same class type, or
665 `a' and `b' are of class types A and B such that B is a descendant of A. */
668 maybe_objc_comptypes (lhs, rhs, reflexive)
669 tree lhs, rhs;
670 int reflexive;
672 return objc_comptypes (lhs, rhs, reflexive);
675 static tree
676 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
677 tree rproto_list;
678 tree sel_name;
679 int class_meth;
681 tree rproto, p;
682 tree fnd = 0;
684 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
686 p = TREE_VALUE (rproto);
688 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
690 if ((fnd = lookup_method (class_meth
691 ? PROTOCOL_CLS_METHODS (p)
692 : PROTOCOL_NST_METHODS (p), sel_name)))
694 else if (PROTOCOL_LIST (p))
695 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
696 sel_name, class_meth);
698 else
700 ; /* An identifier...if we could not find a protocol. */
703 if (fnd)
704 return fnd;
707 return 0;
710 static tree
711 lookup_protocol_in_reflist (rproto_list, lproto)
712 tree rproto_list;
713 tree lproto;
715 tree rproto, p;
717 /* Make sure the protocol is supported by the object on the rhs. */
718 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
720 tree fnd = 0;
721 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
723 p = TREE_VALUE (rproto);
725 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
727 if (lproto == p)
728 fnd = lproto;
730 else if (PROTOCOL_LIST (p))
731 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
734 if (fnd)
735 return fnd;
738 else
740 ; /* An identifier...if we could not find a protocol. */
743 return 0;
746 /* Return 1 if LHS and RHS are compatible types for assignment
747 or various other operations. Return 0 if they are incompatible,
748 and return -1 if we choose to not decide. When the operation
749 is REFLEXIVE, check for compatibility in either direction. */
752 objc_comptypes (lhs, rhs, reflexive)
753 tree lhs;
754 tree rhs;
755 int reflexive;
757 /* New clause for protocols. */
759 if (TREE_CODE (lhs) == POINTER_TYPE
760 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
761 && TREE_CODE (rhs) == POINTER_TYPE
762 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
764 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
765 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
767 if (lhs_is_proto)
769 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
770 tree rproto, rproto_list;
771 tree p;
773 if (rhs_is_proto)
775 rproto_list = TYPE_PROTOCOL_LIST (rhs);
777 /* Make sure the protocol is supported by the object
778 on the rhs. */
779 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
781 p = TREE_VALUE (lproto);
782 rproto = lookup_protocol_in_reflist (rproto_list, p);
784 if (!rproto)
785 warning ("object does not conform to the `%s' protocol",
786 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
789 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
791 tree rname = TYPE_NAME (TREE_TYPE (rhs));
792 tree rinter;
794 /* Make sure the protocol is supported by the object
795 on the rhs. */
796 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
798 p = TREE_VALUE (lproto);
799 rproto = 0;
800 rinter = lookup_interface (rname);
802 while (rinter && !rproto)
804 tree cat;
806 rproto_list = CLASS_PROTOCOL_LIST (rinter);
807 /* If the underlying ObjC class does not have
808 protocols attached to it, perhaps there are
809 "one-off" protocols attached to the rhs?
810 E.g., 'id<MyProt> foo;'. */
811 if (!rproto_list)
812 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
813 rproto = lookup_protocol_in_reflist (rproto_list, p);
815 /* Check for protocols adopted by categories. */
816 cat = CLASS_CATEGORY_LIST (rinter);
817 while (cat && !rproto)
819 rproto_list = CLASS_PROTOCOL_LIST (cat);
820 rproto = lookup_protocol_in_reflist (rproto_list, p);
822 cat = CLASS_CATEGORY_LIST (cat);
825 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
828 if (!rproto)
829 warning ("class `%s' does not implement the `%s' protocol",
830 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
831 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
835 /* May change...based on whether there was any mismatch */
836 return 1;
838 else if (rhs_is_proto)
839 /* Lhs is not a protocol...warn if it is statically typed */
840 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
842 else
843 /* Defer to comptypes. */
844 return -1;
847 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
848 ; /* Fall thru. This is the case we have been handling all along */
849 else
850 /* Defer to comptypes. */
851 return -1;
853 /* `id' = `<class> *', `<class> *' = `id' */
855 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
856 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
857 return 1;
859 /* `id' = `Class', `Class' = `id' */
861 else if ((TYPE_NAME (lhs) == objc_object_id
862 && TYPE_NAME (rhs) == objc_class_id)
863 || (TYPE_NAME (lhs) == objc_class_id
864 && TYPE_NAME (rhs) == objc_object_id))
865 return 1;
867 /* `<class> *' = `<class> *' */
869 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
871 tree lname = TYPE_NAME (lhs);
872 tree rname = TYPE_NAME (rhs);
873 tree inter;
875 if (lname == rname)
876 return 1;
878 /* If the left hand side is a super class of the right hand side,
879 allow it. */
880 for (inter = lookup_interface (rname); inter;
881 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
882 if (lname == CLASS_SUPER_NAME (inter))
883 return 1;
885 /* Allow the reverse when reflexive. */
886 if (reflexive)
887 for (inter = lookup_interface (lname); inter;
888 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
889 if (rname == CLASS_SUPER_NAME (inter))
890 return 1;
892 return 0;
894 else
895 /* Defer to comptypes. */
896 return -1;
899 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
901 void
902 objc_check_decl (decl)
903 tree decl;
905 tree type = TREE_TYPE (decl);
907 if (TREE_CODE (type) == RECORD_TYPE
908 && TREE_STATIC_TEMPLATE (type)
909 && type != constant_string_type)
910 error_with_decl (decl, "`%s' cannot be statically allocated");
913 void
914 maybe_objc_check_decl (decl)
915 tree decl;
917 objc_check_decl (decl);
920 /* Implement static typing. At this point, we know we have an interface. */
922 tree
923 get_static_reference (interface, protocols)
924 tree interface;
925 tree protocols;
927 tree type = xref_tag (RECORD_TYPE, interface);
929 if (protocols)
931 tree t, m = TYPE_MAIN_VARIANT (type);
933 t = copy_node (type);
934 TYPE_BINFO (t) = make_tree_vec (2);
936 /* Add this type to the chain of variants of TYPE. */
937 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
938 TYPE_NEXT_VARIANT (m) = t;
940 /* Look up protocols and install in lang specific list. Note
941 that the protocol list can have a different lifetime than T! */
942 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
944 /* This forces a new pointer type to be created later
945 (in build_pointer_type)...so that the new template
946 we just created will actually be used...what a hack! */
947 if (TYPE_POINTER_TO (t))
948 TYPE_POINTER_TO (t) = NULL_TREE;
950 type = t;
953 return type;
956 tree
957 get_object_reference (protocols)
958 tree protocols;
960 tree type_decl = lookup_name (objc_id_id);
961 tree type;
963 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
965 type = TREE_TYPE (type_decl);
966 if (TYPE_MAIN_VARIANT (type) != id_type)
967 warning ("unexpected type for `id' (%s)",
968 gen_declaration (type, errbuf));
970 else
972 error ("undefined type `id', please import <objc/objc.h>");
973 return error_mark_node;
976 /* This clause creates a new pointer type that is qualified with
977 the protocol specification...this info is used later to do more
978 elaborate type checking. */
980 if (protocols)
982 tree t, m = TYPE_MAIN_VARIANT (type);
984 t = copy_node (type);
985 TYPE_BINFO (t) = make_tree_vec (2);
987 /* Add this type to the chain of variants of TYPE. */
988 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
989 TYPE_NEXT_VARIANT (m) = t;
991 /* Look up protocols...and install in lang specific list */
992 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
994 /* This forces a new pointer type to be created later
995 (in build_pointer_type)...so that the new template
996 we just created will actually be used...what a hack! */
997 if (TYPE_POINTER_TO (t))
998 TYPE_POINTER_TO (t) = NULL_TREE;
1000 type = t;
1002 return type;
1005 /* Check for circular dependencies in protocols. The arguments are
1006 PROTO, the protocol to check, and LIST, a list of protocol it
1007 conforms to. */
1009 static void
1010 check_protocol_recursively (proto, list)
1011 tree proto;
1012 tree list;
1014 tree p;
1016 for (p = list; p; p = TREE_CHAIN (p))
1018 tree pp = TREE_VALUE (p);
1020 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1021 pp = lookup_protocol (pp);
1023 if (pp == proto)
1024 fatal_error ("protocol `%s' has circular dependency",
1025 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1026 if (pp)
1027 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1031 static tree
1032 lookup_and_install_protocols (protocols)
1033 tree protocols;
1035 tree proto;
1036 tree prev = NULL;
1037 tree return_value = protocols;
1039 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1041 tree ident = TREE_VALUE (proto);
1042 tree p = lookup_protocol (ident);
1044 if (!p)
1046 error ("cannot find protocol declaration for `%s'",
1047 IDENTIFIER_POINTER (ident));
1048 if (prev)
1049 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1050 else
1051 return_value = TREE_CHAIN (proto);
1053 else
1055 /* Replace identifier with actual protocol node. */
1056 TREE_VALUE (proto) = p;
1057 prev = proto;
1061 return return_value;
1064 /* Create and push a decl for a built-in external variable or field NAME.
1065 CODE says which.
1066 TYPE is its data type. */
1068 static tree
1069 create_builtin_decl (code, type, name)
1070 enum tree_code code;
1071 tree type;
1072 const char *name;
1074 tree decl = build_decl (code, get_identifier (name), type);
1076 if (code == VAR_DECL)
1078 TREE_STATIC (decl) = 1;
1079 make_decl_rtl (decl, 0);
1080 pushdecl (decl);
1083 DECL_ARTIFICIAL (decl) = 1;
1084 return decl;
1087 /* Find the decl for the constant string class. */
1089 static void
1090 setup_string_decl ()
1092 if (!string_class_decl)
1094 if (!constant_string_global_id)
1095 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1096 string_class_decl = lookup_name (constant_string_global_id);
1100 /* Purpose: "play" parser, creating/installing representations
1101 of the declarations that are required by Objective-C.
1103 Model:
1105 type_spec--------->sc_spec
1106 (tree_list) (tree_list)
1109 identifier_node identifier_node */
1111 static void
1112 synth_module_prologue ()
1114 tree temp_type;
1115 tree super_p;
1117 /* Defined in `objc.h' */
1118 objc_object_id = get_identifier (TAG_OBJECT);
1120 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1122 id_type = build_pointer_type (objc_object_reference);
1124 objc_id_id = get_identifier (TYPE_ID);
1125 objc_class_id = get_identifier (TAG_CLASS);
1127 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1128 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1129 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1131 /* Declare type of selector-objects that represent an operation name. */
1133 /* `struct objc_selector *' */
1134 selector_type
1135 = build_pointer_type (xref_tag (RECORD_TYPE,
1136 get_identifier (TAG_SELECTOR)));
1138 /* Forward declare type, or else the prototype for msgSendSuper will
1139 complain. */
1141 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1142 get_identifier (TAG_SUPER)));
1145 /* id objc_msgSend (id, SEL, ...); */
1147 temp_type
1148 = build_function_type (id_type,
1149 tree_cons (NULL_TREE, id_type,
1150 tree_cons (NULL_TREE, selector_type,
1151 NULL_TREE)));
1153 if (! flag_next_runtime)
1155 umsg_decl = build_decl (FUNCTION_DECL,
1156 get_identifier (TAG_MSGSEND), temp_type);
1157 DECL_EXTERNAL (umsg_decl) = 1;
1158 TREE_PUBLIC (umsg_decl) = 1;
1159 DECL_INLINE (umsg_decl) = 1;
1160 DECL_ARTIFICIAL (umsg_decl) = 1;
1162 if (flag_traditional && TAG_MSGSEND[0] != '_')
1163 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1165 make_decl_rtl (umsg_decl, NULL);
1166 pushdecl (umsg_decl);
1168 else
1169 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1171 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1173 temp_type
1174 = build_function_type (id_type,
1175 tree_cons (NULL_TREE, super_p,
1176 tree_cons (NULL_TREE, selector_type,
1177 NULL_TREE)));
1179 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1180 temp_type, 0, NOT_BUILT_IN, 0);
1182 /* id objc_getClass (const char *); */
1184 temp_type = build_function_type (id_type,
1185 tree_cons (NULL_TREE,
1186 const_string_type_node,
1187 tree_cons (NULL_TREE, void_type_node,
1188 NULL_TREE)));
1190 objc_get_class_decl
1191 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1193 /* id objc_getMetaClass (const char *); */
1195 objc_get_meta_class_decl
1196 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1198 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1200 if (! flag_next_runtime)
1202 if (flag_typed_selectors)
1204 /* Suppress outputting debug symbols, because
1205 dbxout_init hasn'r been called yet. */
1206 enum debug_info_type save_write_symbols = write_symbols;
1207 struct gcc_debug_hooks *save_hooks = debug_hooks;
1208 write_symbols = NO_DEBUG;
1209 debug_hooks = &do_nothing_debug_hooks;
1211 build_selector_template ();
1212 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1214 write_symbols = save_write_symbols;
1215 debug_hooks = save_hooks;
1217 else
1218 temp_type = build_array_type (selector_type, NULL_TREE);
1220 layout_type (temp_type);
1221 UOBJC_SELECTOR_TABLE_decl
1222 = create_builtin_decl (VAR_DECL, temp_type,
1223 "_OBJC_SELECTOR_TABLE");
1225 /* Avoid warning when not sending messages. */
1226 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1229 generate_forward_declaration_to_string_table ();
1231 /* Forward declare constant_string_id and constant_string_type. */
1232 if (!constant_string_class_name)
1233 constant_string_class_name = STRING_OBJECT_CLASS_NAME;
1235 constant_string_id = get_identifier (constant_string_class_name);
1236 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1239 /* Custom build_string which sets TREE_TYPE! */
1241 static tree
1242 my_build_string (len, str)
1243 int len;
1244 const char *str;
1246 int wide_flag = 0;
1247 tree a_string = build_string (len, str);
1249 /* Some code from combine_strings, which is local to c-parse.y. */
1250 if (TREE_TYPE (a_string) == int_array_type_node)
1251 wide_flag = 1;
1253 TREE_TYPE (a_string)
1254 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1255 build_index_type (build_int_2 (len - 1, 0)));
1257 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1258 TREE_STATIC (a_string) = 1;
1260 return a_string;
1263 /* Given a chain of STRING_CST's, build a static instance of
1264 NXConstantString which points at the concatenation of those strings.
1265 We place the string object in the __string_objects section of the
1266 __OBJC segment. The Objective-C runtime will initialize the isa
1267 pointers of the string objects to point at the NXConstantString
1268 class object. */
1270 tree
1271 build_objc_string_object (strings)
1272 tree strings;
1274 tree string, initlist, constructor;
1275 int length;
1277 if (lookup_interface (constant_string_id) == NULL_TREE)
1279 error ("cannot find interface declaration for `%s'",
1280 IDENTIFIER_POINTER (constant_string_id));
1281 return error_mark_node;
1284 add_class_reference (constant_string_id);
1286 string = combine_strings (strings);
1287 TREE_SET_CODE (string, STRING_CST);
1288 length = TREE_STRING_LENGTH (string) - 1;
1290 /* & ((NXConstantString) {0, string, length}) */
1292 if (flag_next_runtime)
1294 /* For the NeXT runtime, we can generate a literal reference
1295 to the string class, don't need to run a constructor. */
1296 setup_string_decl ();
1297 if (string_class_decl == NULL_TREE)
1299 error ("cannot find reference tag for class `%s'",
1300 IDENTIFIER_POINTER (constant_string_id));
1301 return error_mark_node;
1303 initlist = build_tree_list
1304 (NULL_TREE,
1305 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1307 else
1309 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1312 initlist
1313 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1314 initlist);
1315 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1316 constructor = build_constructor (constant_string_type, nreverse (initlist));
1318 if (!flag_next_runtime)
1320 constructor
1321 = objc_add_static_instance (constructor, constant_string_type);
1324 return (build_unary_op (ADDR_EXPR, constructor, 1));
1327 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1329 static tree
1330 objc_add_static_instance (constructor, class_decl)
1331 tree constructor, class_decl;
1333 static int num_static_inst;
1334 tree *chain, decl;
1335 char buf[256];
1337 /* Find the list of static instances for the CLASS_DECL. Create one if
1338 not found. */
1339 for (chain = &objc_static_instances;
1340 *chain && TREE_VALUE (*chain) != class_decl;
1341 chain = &TREE_CHAIN (*chain));
1342 if (!*chain)
1344 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1345 add_objc_string (TYPE_NAME (class_decl), class_names);
1348 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1349 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1350 DECL_COMMON (decl) = 1;
1351 TREE_STATIC (decl) = 1;
1352 DECL_ARTIFICIAL (decl) = 1;
1353 DECL_INITIAL (decl) = constructor;
1355 /* We may be writing something else just now.
1356 Postpone till end of input. */
1357 DECL_DEFER_OUTPUT (decl) = 1;
1358 pushdecl_top_level (decl);
1359 rest_of_decl_compilation (decl, 0, 1, 0);
1361 /* Add the DECL to the head of this CLASS' list. */
1362 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1364 return decl;
1367 /* Build a static constant CONSTRUCTOR
1368 with type TYPE and elements ELTS. */
1370 static tree
1371 build_constructor (type, elts)
1372 tree type, elts;
1374 tree constructor, f, e;
1376 /* ??? Most of the places that we build constructors, we don't fill in
1377 the type of integers properly. Convert them all en masse. */
1378 if (TREE_CODE (type) == ARRAY_TYPE)
1380 f = TREE_TYPE (type);
1381 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1382 for (e = elts; e ; e = TREE_CHAIN (e))
1383 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1385 else
1387 f = TYPE_FIELDS (type);
1388 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1389 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1390 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1391 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1394 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1395 TREE_CONSTANT (constructor) = 1;
1396 TREE_STATIC (constructor) = 1;
1397 TREE_READONLY (constructor) = 1;
1399 return constructor;
1402 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1404 /* Predefine the following data type:
1406 struct _objc_symtab
1408 long sel_ref_cnt;
1409 SEL *refs;
1410 short cls_def_cnt;
1411 short cat_def_cnt;
1412 void *defs[cls_def_cnt + cat_def_cnt];
1413 }; */
1415 static void
1416 build_objc_symtab_template ()
1418 tree field_decl, field_decl_chain, index;
1420 objc_symtab_template
1421 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1423 /* long sel_ref_cnt; */
1425 field_decl = create_builtin_decl (FIELD_DECL,
1426 long_integer_type_node,
1427 "sel_ref_cnt");
1428 field_decl_chain = field_decl;
1430 /* SEL *refs; */
1432 field_decl = create_builtin_decl (FIELD_DECL,
1433 build_pointer_type (selector_type),
1434 "refs");
1435 chainon (field_decl_chain, field_decl);
1437 /* short cls_def_cnt; */
1439 field_decl = create_builtin_decl (FIELD_DECL,
1440 short_integer_type_node,
1441 "cls_def_cnt");
1442 chainon (field_decl_chain, field_decl);
1444 /* short cat_def_cnt; */
1446 field_decl = create_builtin_decl (FIELD_DECL,
1447 short_integer_type_node,
1448 "cat_def_cnt");
1449 chainon (field_decl_chain, field_decl);
1451 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1453 if (!flag_next_runtime)
1454 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1455 else
1456 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1457 imp_count == 0 && cat_count == 0
1458 ? -1 : 0));
1459 field_decl = create_builtin_decl (FIELD_DECL,
1460 build_array_type (ptr_type_node, index),
1461 "defs");
1462 chainon (field_decl_chain, field_decl);
1464 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1467 /* Create the initial value for the `defs' field of _objc_symtab.
1468 This is a CONSTRUCTOR. */
1470 static tree
1471 init_def_list (type)
1472 tree type;
1474 tree expr, initlist = NULL_TREE;
1475 struct imp_entry *impent;
1477 if (imp_count)
1478 for (impent = imp_list; impent; impent = impent->next)
1480 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1482 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1483 initlist = tree_cons (NULL_TREE, expr, initlist);
1487 if (cat_count)
1488 for (impent = imp_list; impent; impent = impent->next)
1490 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1492 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1493 initlist = tree_cons (NULL_TREE, expr, initlist);
1497 if (!flag_next_runtime)
1499 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1500 tree expr;
1502 if (static_instances_decl)
1503 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1504 else
1505 expr = build_int_2 (0, 0);
1507 initlist = tree_cons (NULL_TREE, expr, initlist);
1510 return build_constructor (type, nreverse (initlist));
1513 /* Construct the initial value for all of _objc_symtab. */
1515 static tree
1516 init_objc_symtab (type)
1517 tree type;
1519 tree initlist;
1521 /* sel_ref_cnt = { ..., 5, ... } */
1523 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1525 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1527 if (flag_next_runtime || ! sel_ref_chain)
1528 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1529 else
1530 initlist = tree_cons (NULL_TREE,
1531 build_unary_op (ADDR_EXPR,
1532 UOBJC_SELECTOR_TABLE_decl, 1),
1533 initlist);
1535 /* cls_def_cnt = { ..., 5, ... } */
1537 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1539 /* cat_def_cnt = { ..., 5, ... } */
1541 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1543 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1545 if (imp_count || cat_count || static_instances_decl)
1548 tree field = TYPE_FIELDS (type);
1549 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1551 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1552 initlist);
1555 return build_constructor (type, nreverse (initlist));
1558 /* Push forward-declarations of all the categories
1559 so that init_def_list can use them in a CONSTRUCTOR. */
1561 static void
1562 forward_declare_categories ()
1564 struct imp_entry *impent;
1565 tree sav = objc_implementation_context;
1567 for (impent = imp_list; impent; impent = impent->next)
1569 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1571 /* Set an invisible arg to synth_id_with_class_suffix. */
1572 objc_implementation_context = impent->imp_context;
1573 impent->class_decl
1574 = create_builtin_decl (VAR_DECL, objc_category_template,
1575 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1578 objc_implementation_context = sav;
1581 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1582 and initialized appropriately. */
1584 static void
1585 generate_objc_symtab_decl ()
1587 tree sc_spec;
1589 if (!objc_category_template)
1590 build_category_template ();
1592 /* forward declare categories */
1593 if (cat_count)
1594 forward_declare_categories ();
1596 if (!objc_symtab_template)
1597 build_objc_symtab_template ();
1599 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1601 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1602 tree_cons (NULL_TREE,
1603 objc_symtab_template, sc_spec),
1605 NULL_TREE);
1607 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1608 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1609 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1610 finish_decl (UOBJC_SYMBOLS_decl,
1611 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1612 NULL_TREE);
1615 static tree
1616 init_module_descriptor (type)
1617 tree type;
1619 tree initlist, expr;
1621 /* version = { 1, ... } */
1623 expr = build_int_2 (OBJC_VERSION, 0);
1624 initlist = build_tree_list (NULL_TREE, expr);
1626 /* size = { ..., sizeof (struct objc_module), ... } */
1628 expr = size_in_bytes (objc_module_template);
1629 initlist = tree_cons (NULL_TREE, expr, initlist);
1631 /* name = { ..., "foo.m", ... } */
1633 expr = add_objc_string (get_identifier (input_filename), class_names);
1634 initlist = tree_cons (NULL_TREE, expr, initlist);
1636 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1638 if (UOBJC_SYMBOLS_decl)
1639 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1640 else
1641 expr = build_int_2 (0, 0);
1642 initlist = tree_cons (NULL_TREE, expr, initlist);
1644 return build_constructor (type, nreverse (initlist));
1647 /* Write out the data structures to describe Objective C classes defined.
1648 If appropriate, compile and output a setup function to initialize them.
1649 Return a symbol_ref to the function to call to initialize the Objective C
1650 data structures for this file (and perhaps for other files also).
1652 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1654 static rtx
1655 build_module_descriptor ()
1657 tree decl_specs, field_decl, field_decl_chain;
1659 objc_module_template
1660 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1662 /* Long version; */
1664 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1665 field_decl = get_identifier ("version");
1666 field_decl
1667 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1668 field_decl_chain = field_decl;
1670 /* long size; */
1672 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1673 field_decl = get_identifier ("size");
1674 field_decl
1675 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1676 chainon (field_decl_chain, field_decl);
1678 /* char *name; */
1680 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1681 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1682 field_decl
1683 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1684 chainon (field_decl_chain, field_decl);
1686 /* struct objc_symtab *symtab; */
1688 decl_specs = get_identifier (UTAG_SYMTAB);
1689 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1690 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1691 field_decl
1692 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1693 chainon (field_decl_chain, field_decl);
1695 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1697 /* Create an instance of "objc_module". */
1699 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1700 build_tree_list (NULL_TREE,
1701 ridpointers[(int) RID_STATIC]));
1703 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1704 decl_specs, 1, NULL_TREE);
1706 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1707 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1708 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1710 finish_decl (UOBJC_MODULES_decl,
1711 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1712 NULL_TREE);
1714 /* Mark the decl to avoid "defined but not used" warning. */
1715 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1717 /* Generate a constructor call for the module descriptor.
1718 This code was generated by reading the grammar rules
1719 of c-parse.in; Therefore, it may not be the most efficient
1720 way of generating the requisite code. */
1722 if (flag_next_runtime)
1723 return NULL_RTX;
1726 tree parms, execclass_decl, decelerator, void_list_node_1;
1727 tree init_function_name, init_function_decl;
1729 /* Declare void __objc_execClass (void *); */
1731 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1732 execclass_decl = build_decl (FUNCTION_DECL,
1733 get_identifier (TAG_EXECCLASS),
1734 build_function_type (void_type_node,
1735 tree_cons (NULL_TREE, ptr_type_node,
1736 void_list_node_1)));
1737 DECL_EXTERNAL (execclass_decl) = 1;
1738 DECL_ARTIFICIAL (execclass_decl) = 1;
1739 TREE_PUBLIC (execclass_decl) = 1;
1740 pushdecl (execclass_decl);
1741 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1742 assemble_external (execclass_decl);
1744 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1746 init_function_name = get_file_function_name ('I');
1747 start_function (void_list_node_1,
1748 build_nt (CALL_EXPR, init_function_name,
1749 tree_cons (NULL_TREE, NULL_TREE,
1750 void_list_node_1),
1751 NULL_TREE),
1752 NULL_TREE);
1753 store_parm_decls ();
1755 init_function_decl = current_function_decl;
1756 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1757 TREE_USED (init_function_decl) = 1;
1758 current_function_cannot_inline
1759 = "static constructors and destructors cannot be inlined";
1761 parms
1762 = build_tree_list (NULL_TREE,
1763 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1764 decelerator = build_function_call (execclass_decl, parms);
1766 c_expand_expr_stmt (decelerator);
1768 finish_function (0);
1770 return XEXP (DECL_RTL (init_function_decl), 0);
1774 /* extern const char _OBJC_STRINGS[]; */
1776 static void
1777 generate_forward_declaration_to_string_table ()
1779 tree sc_spec, decl_specs, expr_decl;
1781 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1782 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1784 expr_decl
1785 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1787 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1790 /* Return the DECL of the string IDENT in the SECTION. */
1792 static tree
1793 get_objc_string_decl (ident, section)
1794 tree ident;
1795 enum string_section section;
1797 tree chain;
1799 if (section == class_names)
1800 chain = class_names_chain;
1801 else if (section == meth_var_names)
1802 chain = meth_var_names_chain;
1803 else if (section == meth_var_types)
1804 chain = meth_var_types_chain;
1805 else
1806 abort ();
1808 for (; chain != 0; chain = TREE_VALUE (chain))
1809 if (TREE_VALUE (chain) == ident)
1810 return (TREE_PURPOSE (chain));
1812 abort ();
1813 return NULL_TREE;
1816 /* Output references to all statically allocated objects. Return the DECL
1817 for the array built. */
1819 static void
1820 generate_static_references ()
1822 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1823 tree class_name, class, decl, initlist;
1824 tree cl_chain, in_chain, type;
1825 int num_inst, num_class;
1826 char buf[256];
1828 if (flag_next_runtime)
1829 abort ();
1831 for (cl_chain = objc_static_instances, num_class = 0;
1832 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1834 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1835 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1837 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1838 ident = get_identifier (buf);
1840 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1841 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1842 build_tree_list (NULL_TREE,
1843 ridpointers[(int) RID_STATIC]));
1844 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1845 DECL_CONTEXT (decl) = 0;
1846 DECL_ARTIFICIAL (decl) = 1;
1848 /* Output {class_name, ...}. */
1849 class = TREE_VALUE (cl_chain);
1850 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1851 initlist = build_tree_list (NULL_TREE,
1852 build_unary_op (ADDR_EXPR, class_name, 1));
1854 /* Output {..., instance, ...}. */
1855 for (in_chain = TREE_PURPOSE (cl_chain);
1856 in_chain; in_chain = TREE_CHAIN (in_chain))
1858 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1859 initlist = tree_cons (NULL_TREE, expr, initlist);
1862 /* Output {..., NULL}. */
1863 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1865 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1866 finish_decl (decl, expr, NULL_TREE);
1867 TREE_USED (decl) = 1;
1869 type = build_array_type (build_pointer_type (void_type_node), 0);
1870 decl = build_decl (VAR_DECL, ident, type);
1871 TREE_USED (decl) = 1;
1872 TREE_STATIC (decl) = 1;
1873 decls
1874 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1877 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1878 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1879 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1880 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1881 build_tree_list (NULL_TREE,
1882 ridpointers[(int) RID_STATIC]));
1883 static_instances_decl
1884 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1885 TREE_USED (static_instances_decl) = 1;
1886 DECL_CONTEXT (static_instances_decl) = 0;
1887 DECL_ARTIFICIAL (static_instances_decl) = 1;
1888 expr = build_constructor (TREE_TYPE (static_instances_decl),
1889 nreverse (decls));
1890 finish_decl (static_instances_decl, expr, NULL_TREE);
1893 /* Output all strings. */
1895 static void
1896 generate_strings ()
1898 tree sc_spec, decl_specs, expr_decl;
1899 tree chain, string_expr;
1900 tree string, decl;
1902 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1904 string = TREE_VALUE (chain);
1905 decl = TREE_PURPOSE (chain);
1906 sc_spec
1907 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1908 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1909 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1910 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1911 DECL_CONTEXT (decl) = NULL_TREE;
1912 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1913 IDENTIFIER_POINTER (string));
1914 finish_decl (decl, string_expr, NULL_TREE);
1917 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1919 string = TREE_VALUE (chain);
1920 decl = TREE_PURPOSE (chain);
1921 sc_spec
1922 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1923 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1924 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1925 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1926 DECL_CONTEXT (decl) = NULL_TREE;
1927 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1928 IDENTIFIER_POINTER (string));
1929 finish_decl (decl, string_expr, NULL_TREE);
1932 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1934 string = TREE_VALUE (chain);
1935 decl = TREE_PURPOSE (chain);
1936 sc_spec
1937 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1938 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1939 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1940 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1941 DECL_CONTEXT (decl) = NULL_TREE;
1942 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1943 IDENTIFIER_POINTER (string));
1944 finish_decl (decl, string_expr, NULL_TREE);
1948 static tree
1949 build_selector_reference_decl ()
1951 tree decl, ident;
1952 char buf[256];
1953 static int idx = 0;
1955 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1957 ident = get_identifier (buf);
1959 decl = build_decl (VAR_DECL, ident, selector_type);
1960 DECL_EXTERNAL (decl) = 1;
1961 TREE_PUBLIC (decl) = 1;
1962 TREE_USED (decl) = 1;
1963 TREE_READONLY (decl) = 1;
1964 DECL_ARTIFICIAL (decl) = 1;
1965 DECL_CONTEXT (decl) = 0;
1967 make_decl_rtl (decl, 0);
1968 pushdecl_top_level (decl);
1970 return decl;
1973 /* Just a handy wrapper for add_objc_string. */
1975 static tree
1976 build_selector (ident)
1977 tree ident;
1979 tree expr = add_objc_string (ident, meth_var_names);
1980 if (flag_typed_selectors)
1981 return expr;
1982 else
1983 return build_c_cast (selector_type, expr); /* cast! */
1986 static void
1987 build_selector_translation_table ()
1989 tree sc_spec, decl_specs;
1990 tree chain, initlist = NULL_TREE;
1991 int offset = 0;
1992 tree decl = NULL_TREE, var_decl, name;
1994 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1996 tree expr;
1998 expr = build_selector (TREE_VALUE (chain));
2000 if (flag_next_runtime)
2002 name = DECL_NAME (TREE_PURPOSE (chain));
2004 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2006 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2007 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2009 var_decl = name;
2011 /* The `decl' that is returned from start_decl is the one that we
2012 forward declared in `build_selector_reference' */
2013 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2016 /* add one for the '\0' character */
2017 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2019 if (flag_next_runtime)
2020 finish_decl (decl, expr, NULL_TREE);
2021 else
2023 if (flag_typed_selectors)
2025 tree eltlist = NULL_TREE;
2026 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2027 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2028 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2029 expr = build_constructor (objc_selector_template,
2030 nreverse (eltlist));
2032 initlist = tree_cons (NULL_TREE, expr, initlist);
2037 if (! flag_next_runtime)
2039 /* Cause the variable and its initial value to be actually output. */
2040 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2041 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2042 /* NULL terminate the list and fix the decl for output. */
2043 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2044 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2045 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2046 nreverse (initlist));
2047 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2048 current_function_decl = NULL_TREE;
2052 static tree
2053 get_proto_encoding (proto)
2054 tree proto;
2056 tree encoding;
2057 if (proto)
2059 tree tmp_decl;
2061 if (! METHOD_ENCODING (proto))
2063 tmp_decl = build_tmp_function_decl ();
2064 hack_method_prototype (proto, tmp_decl);
2065 encoding = encode_method_prototype (proto, tmp_decl);
2066 METHOD_ENCODING (proto) = encoding;
2068 else
2069 encoding = METHOD_ENCODING (proto);
2071 return add_objc_string (encoding, meth_var_types);
2073 else
2074 return build_int_2 (0, 0);
2077 /* sel_ref_chain is a list whose "value" fields will be instances of
2078 identifier_node that represent the selector. */
2080 static tree
2081 build_typed_selector_reference (ident, proto)
2082 tree ident, proto;
2084 tree *chain = &sel_ref_chain;
2085 tree expr;
2086 int index = 0;
2088 while (*chain)
2090 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2091 goto return_at_index;
2093 index++;
2094 chain = &TREE_CHAIN (*chain);
2097 *chain = tree_cons (proto, ident, NULL_TREE);
2099 return_at_index:
2100 expr = build_unary_op (ADDR_EXPR,
2101 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2102 build_int_2 (index, 0)),
2104 return build_c_cast (selector_type, expr);
2107 static tree
2108 build_selector_reference (ident)
2109 tree ident;
2111 tree *chain = &sel_ref_chain;
2112 tree expr;
2113 int index = 0;
2115 while (*chain)
2117 if (TREE_VALUE (*chain) == ident)
2118 return (flag_next_runtime
2119 ? TREE_PURPOSE (*chain)
2120 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2121 build_int_2 (index, 0)));
2123 index++;
2124 chain = &TREE_CHAIN (*chain);
2127 expr = build_selector_reference_decl ();
2129 *chain = tree_cons (expr, ident, NULL_TREE);
2131 return (flag_next_runtime
2132 ? expr
2133 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2134 build_int_2 (index, 0)));
2137 static tree
2138 build_class_reference_decl ()
2140 tree decl, ident;
2141 char buf[256];
2142 static int idx = 0;
2144 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2146 ident = get_identifier (buf);
2148 decl = build_decl (VAR_DECL, ident, objc_class_type);
2149 DECL_EXTERNAL (decl) = 1;
2150 TREE_PUBLIC (decl) = 1;
2151 TREE_USED (decl) = 1;
2152 TREE_READONLY (decl) = 1;
2153 DECL_CONTEXT (decl) = 0;
2154 DECL_ARTIFICIAL (decl) = 1;
2156 make_decl_rtl (decl, 0);
2157 pushdecl_top_level (decl);
2159 return decl;
2162 /* Create a class reference, but don't create a variable to reference
2163 it. */
2165 static void
2166 add_class_reference (ident)
2167 tree ident;
2169 tree chain;
2171 if ((chain = cls_ref_chain))
2173 tree tail;
2176 if (ident == TREE_VALUE (chain))
2177 return;
2179 tail = chain;
2180 chain = TREE_CHAIN (chain);
2182 while (chain);
2184 /* Append to the end of the list */
2185 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2187 else
2188 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2191 /* Get a class reference, creating it if necessary. Also create the
2192 reference variable. */
2194 tree
2195 get_class_reference (ident)
2196 tree ident;
2198 if (flag_next_runtime)
2200 tree *chain;
2201 tree decl;
2203 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2204 if (TREE_VALUE (*chain) == ident)
2206 if (! TREE_PURPOSE (*chain))
2207 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2209 return TREE_PURPOSE (*chain);
2212 decl = build_class_reference_decl ();
2213 *chain = tree_cons (decl, ident, NULL_TREE);
2214 return decl;
2216 else
2218 tree params;
2220 add_class_reference (ident);
2222 params = build_tree_list (NULL_TREE,
2223 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2224 IDENTIFIER_POINTER (ident)));
2226 assemble_external (objc_get_class_decl);
2227 return build_function_call (objc_get_class_decl, params);
2231 /* For each string section we have a chain which maps identifier nodes
2232 to decls for the strings. */
2234 static tree
2235 add_objc_string (ident, section)
2236 tree ident;
2237 enum string_section section;
2239 tree *chain, decl;
2241 if (section == class_names)
2242 chain = &class_names_chain;
2243 else if (section == meth_var_names)
2244 chain = &meth_var_names_chain;
2245 else if (section == meth_var_types)
2246 chain = &meth_var_types_chain;
2247 else
2248 abort ();
2250 while (*chain)
2252 if (TREE_VALUE (*chain) == ident)
2253 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2255 chain = &TREE_CHAIN (*chain);
2258 decl = build_objc_string_decl (section);
2260 *chain = tree_cons (decl, ident, NULL_TREE);
2262 return build_unary_op (ADDR_EXPR, decl, 1);
2265 static tree
2266 build_objc_string_decl (section)
2267 enum string_section section;
2269 tree decl, ident;
2270 char buf[256];
2271 static int class_names_idx = 0;
2272 static int meth_var_names_idx = 0;
2273 static int meth_var_types_idx = 0;
2275 if (section == class_names)
2276 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2277 else if (section == meth_var_names)
2278 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2279 else if (section == meth_var_types)
2280 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2282 ident = get_identifier (buf);
2284 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2285 DECL_EXTERNAL (decl) = 1;
2286 TREE_PUBLIC (decl) = 1;
2287 TREE_USED (decl) = 1;
2288 TREE_READONLY (decl) = 1;
2289 TREE_CONSTANT (decl) = 1;
2290 DECL_CONTEXT (decl) = 0;
2291 DECL_ARTIFICIAL (decl) = 1;
2293 make_decl_rtl (decl, 0);
2294 pushdecl_top_level (decl);
2296 return decl;
2300 void
2301 objc_declare_alias (alias_ident, class_ident)
2302 tree alias_ident;
2303 tree class_ident;
2305 if (is_class_name (class_ident) != class_ident)
2306 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2307 else if (is_class_name (alias_ident))
2308 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2309 else
2310 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2313 void
2314 objc_declare_class (ident_list)
2315 tree ident_list;
2317 tree list;
2319 for (list = ident_list; list; list = TREE_CHAIN (list))
2321 tree ident = TREE_VALUE (list);
2322 tree decl;
2324 if ((decl = lookup_name (ident)))
2326 error ("`%s' redeclared as different kind of symbol",
2327 IDENTIFIER_POINTER (ident));
2328 error_with_decl (decl, "previous declaration of `%s'");
2331 if (! is_class_name (ident))
2333 tree record = xref_tag (RECORD_TYPE, ident);
2334 TREE_STATIC_TEMPLATE (record) = 1;
2335 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2340 tree
2341 is_class_name (ident)
2342 tree ident;
2344 tree chain;
2346 if (lookup_interface (ident))
2347 return ident;
2349 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2351 if (ident == TREE_VALUE (chain))
2352 return ident;
2355 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2357 if (ident == TREE_VALUE (chain))
2358 return TREE_PURPOSE (chain);
2361 return 0;
2364 tree
2365 lookup_interface (ident)
2366 tree ident;
2368 tree chain;
2370 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2372 if (ident == CLASS_NAME (chain))
2373 return chain;
2375 return NULL_TREE;
2378 static tree
2379 objc_copy_list (list, head)
2380 tree list;
2381 tree *head;
2383 tree newlist = NULL_TREE, tail = NULL_TREE;
2385 while (list)
2387 tail = copy_node (list);
2389 /* The following statement fixes a bug when inheriting instance
2390 variables that are declared to be bitfields. finish_struct
2391 expects to find the width of the bitfield in DECL_INITIAL. */
2392 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2393 DECL_INITIAL (tail) = DECL_SIZE (tail);
2395 newlist = chainon (newlist, tail);
2396 list = TREE_CHAIN (list);
2399 *head = newlist;
2400 return tail;
2403 /* Used by: build_private_template, get_class_ivars, and
2404 continue_class. COPY is 1 when called from @defs. In this case
2405 copy all fields. Otherwise don't copy leaf ivars since we rely on
2406 them being side-effected exactly once by finish_struct. */
2408 static tree
2409 build_ivar_chain (interface, copy)
2410 tree interface;
2411 int copy;
2413 tree my_name, super_name, ivar_chain;
2415 my_name = CLASS_NAME (interface);
2416 super_name = CLASS_SUPER_NAME (interface);
2418 /* Possibly copy leaf ivars. */
2419 if (copy)
2420 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2421 else
2422 ivar_chain = CLASS_IVARS (interface);
2424 while (super_name)
2426 tree op1;
2427 tree super_interface = lookup_interface (super_name);
2429 if (!super_interface)
2431 /* fatal did not work with 2 args...should fix */
2432 error ("cannot find interface declaration for `%s', superclass of `%s'",
2433 IDENTIFIER_POINTER (super_name),
2434 IDENTIFIER_POINTER (my_name));
2435 exit (FATAL_EXIT_CODE);
2438 if (super_interface == interface)
2439 fatal_error ("circular inheritance in interface declaration for `%s'",
2440 IDENTIFIER_POINTER (super_name));
2442 interface = super_interface;
2443 my_name = CLASS_NAME (interface);
2444 super_name = CLASS_SUPER_NAME (interface);
2446 op1 = CLASS_IVARS (interface);
2447 if (op1)
2449 tree head, tail = objc_copy_list (op1, &head);
2451 /* Prepend super class ivars...make a copy of the list, we
2452 do not want to alter the original. */
2453 TREE_CHAIN (tail) = ivar_chain;
2454 ivar_chain = head;
2457 return ivar_chain;
2460 /* struct <classname> {
2461 struct objc_class *isa;
2463 }; */
2465 static tree
2466 build_private_template (class)
2467 tree class;
2469 tree ivar_context;
2471 if (CLASS_STATIC_TEMPLATE (class))
2473 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2474 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2476 else
2478 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2480 ivar_context = build_ivar_chain (class, 0);
2482 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2484 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2486 /* mark this record as class template - for class type checking */
2487 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2490 instance_type
2491 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2492 uprivate_record),
2493 build1 (INDIRECT_REF, NULL_TREE,
2494 NULL_TREE)));
2496 return ivar_context;
2499 /* Begin code generation for protocols... */
2501 /* struct objc_protocol {
2502 char *protocol_name;
2503 struct objc_protocol **protocol_list;
2504 struct objc_method_desc *instance_methods;
2505 struct objc_method_desc *class_methods;
2506 }; */
2508 static tree
2509 build_protocol_template ()
2511 tree decl_specs, field_decl, field_decl_chain;
2512 tree template;
2514 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2516 /* struct objc_class *isa; */
2518 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2519 get_identifier (UTAG_CLASS)));
2520 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2521 field_decl
2522 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2523 field_decl_chain = field_decl;
2525 /* char *protocol_name; */
2527 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2528 field_decl
2529 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2530 field_decl
2531 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2532 chainon (field_decl_chain, field_decl);
2534 /* struct objc_protocol **protocol_list; */
2536 decl_specs = build_tree_list (NULL_TREE, template);
2537 field_decl
2538 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2539 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2540 field_decl
2541 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2542 chainon (field_decl_chain, field_decl);
2544 /* struct objc_method_list *instance_methods; */
2546 decl_specs
2547 = build_tree_list (NULL_TREE,
2548 xref_tag (RECORD_TYPE,
2549 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2550 field_decl
2551 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2552 field_decl
2553 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2554 chainon (field_decl_chain, field_decl);
2556 /* struct objc_method_list *class_methods; */
2558 decl_specs
2559 = build_tree_list (NULL_TREE,
2560 xref_tag (RECORD_TYPE,
2561 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2562 field_decl
2563 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2564 field_decl
2565 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2566 chainon (field_decl_chain, field_decl);
2568 return finish_struct (template, field_decl_chain, NULL_TREE);
2571 static tree
2572 build_descriptor_table_initializer (type, entries)
2573 tree type;
2574 tree entries;
2576 tree initlist = NULL_TREE;
2580 tree eltlist = NULL_TREE;
2582 eltlist
2583 = tree_cons (NULL_TREE,
2584 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2585 eltlist
2586 = tree_cons (NULL_TREE,
2587 add_objc_string (METHOD_ENCODING (entries),
2588 meth_var_types),
2589 eltlist);
2591 initlist
2592 = tree_cons (NULL_TREE,
2593 build_constructor (type, nreverse (eltlist)), initlist);
2595 entries = TREE_CHAIN (entries);
2597 while (entries);
2599 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2602 /* struct objc_method_prototype_list {
2603 int count;
2604 struct objc_method_prototype {
2605 SEL name;
2606 char *types;
2607 } list[1];
2608 }; */
2610 static tree
2611 build_method_prototype_list_template (list_type, size)
2612 tree list_type;
2613 int size;
2615 tree objc_ivar_list_record;
2616 tree decl_specs, field_decl, field_decl_chain;
2618 /* Generate an unnamed struct definition. */
2620 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2622 /* int method_count; */
2624 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2625 field_decl = get_identifier ("method_count");
2627 field_decl
2628 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2629 field_decl_chain = field_decl;
2631 /* struct objc_method method_list[]; */
2633 decl_specs = build_tree_list (NULL_TREE, list_type);
2634 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2635 build_int_2 (size, 0));
2637 field_decl
2638 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2639 chainon (field_decl_chain, field_decl);
2641 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2643 return objc_ivar_list_record;
2646 static tree
2647 build_method_prototype_template ()
2649 tree proto_record;
2650 tree decl_specs, field_decl, field_decl_chain;
2652 proto_record
2653 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2655 /* struct objc_selector *_cmd; */
2656 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2657 get_identifier (TAG_SELECTOR)), NULL_TREE);
2658 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2660 field_decl
2661 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2662 field_decl_chain = field_decl;
2664 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2665 field_decl
2666 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2667 field_decl
2668 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2669 chainon (field_decl_chain, field_decl);
2671 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2673 return proto_record;
2676 /* True if last call to forwarding_offset yielded a register offset. */
2677 static int offset_is_register;
2679 static int
2680 forwarding_offset (parm)
2681 tree parm;
2683 int offset_in_bytes;
2685 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2687 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2689 /* ??? Here we assume that the parm address is indexed
2690 off the frame pointer or arg pointer.
2691 If that is not true, we produce meaningless results,
2692 but do not crash. */
2693 if (GET_CODE (addr) == PLUS
2694 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2695 offset_in_bytes = INTVAL (XEXP (addr, 1));
2696 else
2697 offset_in_bytes = 0;
2699 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2700 offset_is_register = 0;
2702 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2704 int regno = REGNO (DECL_INCOMING_RTL (parm));
2705 offset_in_bytes = apply_args_register_offset (regno);
2706 offset_is_register = 1;
2708 else
2709 return 0;
2711 /* This is the case where the parm is passed as an int or double
2712 and it is converted to a char, short or float and stored back
2713 in the parmlist. In this case, describe the parm
2714 with the variable's declared type, and adjust the address
2715 if the least significant bytes (which we are using) are not
2716 the first ones. */
2717 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2718 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2719 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2721 return offset_in_bytes;
2724 static tree
2725 encode_method_prototype (method_decl, func_decl)
2726 tree method_decl;
2727 tree func_decl;
2729 tree parms;
2730 int stack_size, i;
2731 tree user_args;
2732 HOST_WIDE_INT max_parm_end = 0;
2733 char buf[40];
2734 tree result;
2736 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2737 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2739 /* C type. */
2740 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2741 obstack_object_size (&util_obstack),
2742 OBJC_ENCODE_INLINE_DEFS);
2744 /* Stack size. */
2745 for (parms = DECL_ARGUMENTS (func_decl); parms;
2746 parms = TREE_CHAIN (parms))
2748 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2749 + int_size_in_bytes (TREE_TYPE (parms)));
2751 if (!offset_is_register && max_parm_end < parm_end)
2752 max_parm_end = parm_end;
2755 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2757 sprintf (buf, "%d", stack_size);
2758 obstack_grow (&util_obstack, buf, strlen (buf));
2760 user_args = METHOD_SEL_ARGS (method_decl);
2762 /* Argument types. */
2763 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2764 parms = TREE_CHAIN (parms), i++)
2766 /* Process argument qualifiers for user supplied arguments. */
2767 if (i > 1)
2769 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2770 user_args = TREE_CHAIN (user_args);
2773 /* Type. */
2774 encode_type (TREE_TYPE (parms),
2775 obstack_object_size (&util_obstack),
2776 OBJC_ENCODE_INLINE_DEFS);
2778 /* Compute offset. */
2779 sprintf (buf, "%d", forwarding_offset (parms));
2781 /* Indicate register. */
2782 if (offset_is_register)
2783 obstack_1grow (&util_obstack, '+');
2785 obstack_grow (&util_obstack, buf, strlen (buf));
2788 obstack_1grow (&util_obstack, '\0');
2789 result = get_identifier (obstack_finish (&util_obstack));
2790 obstack_free (&util_obstack, util_firstobj);
2791 return result;
2794 static tree
2795 generate_descriptor_table (type, name, size, list, proto)
2796 tree type;
2797 const char *name;
2798 int size;
2799 tree list;
2800 tree proto;
2802 tree sc_spec, decl_specs, decl, initlist;
2804 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2805 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2807 decl = start_decl (synth_id_with_class_suffix (name, proto),
2808 decl_specs, 1, NULL_TREE);
2809 DECL_CONTEXT (decl) = NULL_TREE;
2811 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2812 initlist = tree_cons (NULL_TREE, list, initlist);
2814 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2815 NULL_TREE);
2817 return decl;
2820 static void
2821 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2822 tree protocol;
2824 tree initlist, chain, method_list_template;
2825 tree cast, variable_length_type;
2826 int size;
2828 if (!objc_method_prototype_template)
2830 objc_method_prototype_template = build_method_prototype_template ();
2833 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2834 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2835 NULL_TREE);
2836 variable_length_type = groktypename (cast);
2838 chain = PROTOCOL_CLS_METHODS (protocol);
2839 if (chain)
2841 size = list_length (chain);
2843 method_list_template
2844 = build_method_prototype_list_template (objc_method_prototype_template,
2845 size);
2847 initlist
2848 = build_descriptor_table_initializer (objc_method_prototype_template,
2849 chain);
2851 UOBJC_CLASS_METHODS_decl
2852 = generate_descriptor_table (method_list_template,
2853 "_OBJC_PROTOCOL_CLASS_METHODS",
2854 size, initlist, protocol);
2855 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2857 else
2858 UOBJC_CLASS_METHODS_decl = 0;
2860 chain = PROTOCOL_NST_METHODS (protocol);
2861 if (chain)
2863 size = list_length (chain);
2865 method_list_template
2866 = build_method_prototype_list_template (objc_method_prototype_template,
2867 size);
2868 initlist
2869 = build_descriptor_table_initializer (objc_method_prototype_template,
2870 chain);
2872 UOBJC_INSTANCE_METHODS_decl
2873 = generate_descriptor_table (method_list_template,
2874 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2875 size, initlist, protocol);
2876 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2878 else
2879 UOBJC_INSTANCE_METHODS_decl = 0;
2882 /* Generate a temporary FUNCTION_DECL node to be used in
2883 hack_method_prototype below. */
2885 static tree
2886 build_tmp_function_decl ()
2888 tree decl_specs, expr_decl, parms;
2889 static int xxx = 0;
2890 char buffer[80];
2892 /* struct objc_object *objc_xxx (id, SEL, ...); */
2893 pushlevel (0);
2894 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2895 push_parm_decl (build_tree_list
2896 (build_tree_list (decl_specs,
2897 build1 (INDIRECT_REF, NULL_TREE,
2898 NULL_TREE)),
2899 NULL_TREE));
2901 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2902 get_identifier (TAG_SELECTOR)));
2903 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2905 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2906 NULL_TREE));
2907 parms = get_parm_info (0);
2908 poplevel (0, 0, 0);
2910 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2911 sprintf (buffer, "__objc_tmp_%x", xxx++);
2912 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2913 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2915 return define_decl (expr_decl, decl_specs);
2918 /* Generate the prototypes for protocol methods. This is used to
2919 generate method encodings for these.
2921 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2922 a decl node to be used. This is also where the return value is
2923 given. */
2925 static void
2926 hack_method_prototype (nst_methods, tmp_decl)
2927 tree nst_methods;
2928 tree tmp_decl;
2930 tree parms;
2931 tree parm;
2933 /* Hack to avoid problem with static typing of self arg. */
2934 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2935 start_method_def (nst_methods);
2936 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2938 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2939 parms = get_parm_info (0); /* we have a `, ...' */
2940 else
2941 parms = get_parm_info (1); /* place a `void_at_end' */
2943 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2945 /* Usually called from store_parm_decls -> init_function_start. */
2947 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2948 current_function_decl = tmp_decl;
2951 /* Code taken from start_function. */
2952 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2953 /* Promote the value to int before returning it. */
2954 if (TREE_CODE (restype) == INTEGER_TYPE
2955 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2956 restype = integer_type_node;
2957 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2960 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2961 DECL_CONTEXT (parm) = tmp_decl;
2963 init_function_start (tmp_decl, "objc-act", 0);
2965 /* Typically called from expand_function_start for function definitions. */
2966 assign_parms (tmp_decl);
2968 /* install return type */
2969 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2973 static void
2974 generate_protocol_references (plist)
2975 tree plist;
2977 tree lproto;
2979 /* Forward declare protocols referenced. */
2980 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2982 tree proto = TREE_VALUE (lproto);
2984 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2985 && PROTOCOL_NAME (proto))
2987 if (! PROTOCOL_FORWARD_DECL (proto))
2988 build_protocol_reference (proto);
2990 if (PROTOCOL_LIST (proto))
2991 generate_protocol_references (PROTOCOL_LIST (proto));
2996 static void
2997 generate_protocols ()
2999 tree p, tmp_decl, encoding;
3000 tree sc_spec, decl_specs, decl;
3001 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3002 tree cast_type2;
3004 tmp_decl = build_tmp_function_decl ();
3006 if (! objc_protocol_template)
3007 objc_protocol_template = build_protocol_template ();
3009 /* If a protocol was directly referenced, pull in indirect references. */
3010 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3011 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3012 generate_protocol_references (PROTOCOL_LIST (p));
3014 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3016 tree nst_methods = PROTOCOL_NST_METHODS (p);
3017 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3019 /* If protocol wasn't referenced, don't generate any code. */
3020 if (! PROTOCOL_FORWARD_DECL (p))
3021 continue;
3023 /* Make sure we link in the Protocol class. */
3024 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3026 while (nst_methods)
3028 if (! METHOD_ENCODING (nst_methods))
3030 hack_method_prototype (nst_methods, tmp_decl);
3031 encoding = encode_method_prototype (nst_methods, tmp_decl);
3032 METHOD_ENCODING (nst_methods) = encoding;
3034 nst_methods = TREE_CHAIN (nst_methods);
3037 while (cls_methods)
3039 if (! METHOD_ENCODING (cls_methods))
3041 hack_method_prototype (cls_methods, tmp_decl);
3042 encoding = encode_method_prototype (cls_methods, tmp_decl);
3043 METHOD_ENCODING (cls_methods) = encoding;
3046 cls_methods = TREE_CHAIN (cls_methods);
3048 generate_method_descriptors (p);
3050 if (PROTOCOL_LIST (p))
3051 refs_decl = generate_protocol_list (p);
3052 else
3053 refs_decl = 0;
3055 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3057 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3058 NULL_TREE);
3059 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3061 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3062 decl_specs, 1, NULL_TREE);
3064 DECL_CONTEXT (decl) = NULL_TREE;
3066 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3068 if (refs_decl)
3070 cast_type2
3071 = groktypename
3072 (build_tree_list (build_tree_list (NULL_TREE,
3073 objc_protocol_template),
3074 build1 (INDIRECT_REF, NULL_TREE,
3075 build1 (INDIRECT_REF, NULL_TREE,
3076 NULL_TREE))));
3078 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3079 TREE_TYPE (refs_expr) = cast_type2;
3081 else
3082 refs_expr = build_int_2 (0, 0);
3084 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3085 by generate_method_descriptors, which is called above. */
3086 initlist = build_protocol_initializer (TREE_TYPE (decl),
3087 protocol_name_expr, refs_expr,
3088 UOBJC_INSTANCE_METHODS_decl,
3089 UOBJC_CLASS_METHODS_decl);
3090 finish_decl (decl, initlist, NULL_TREE);
3092 /* Mark the decl as used to avoid "defined but not used" warning. */
3093 TREE_USED (decl) = 1;
3097 static tree
3098 build_protocol_initializer (type, protocol_name, protocol_list,
3099 instance_methods, class_methods)
3100 tree type;
3101 tree protocol_name;
3102 tree protocol_list;
3103 tree instance_methods;
3104 tree class_methods;
3106 tree initlist = NULL_TREE, expr;
3107 tree cast_type;
3109 cast_type = groktypename
3110 (build_tree_list
3111 (build_tree_list (NULL_TREE,
3112 xref_tag (RECORD_TYPE,
3113 get_identifier (UTAG_CLASS))),
3114 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3116 /* Filling the "isa" in with one allows the runtime system to
3117 detect that the version change...should remove before final release. */
3119 expr = build_int_2 (PROTOCOL_VERSION, 0);
3120 TREE_TYPE (expr) = cast_type;
3121 initlist = tree_cons (NULL_TREE, expr, initlist);
3122 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3123 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3125 if (!instance_methods)
3126 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3127 else
3129 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3130 initlist = tree_cons (NULL_TREE, expr, initlist);
3133 if (!class_methods)
3134 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3135 else
3137 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3138 initlist = tree_cons (NULL_TREE, expr, initlist);
3141 return build_constructor (type, nreverse (initlist));
3144 /* struct objc_category {
3145 char *category_name;
3146 char *class_name;
3147 struct objc_method_list *instance_methods;
3148 struct objc_method_list *class_methods;
3149 struct objc_protocol_list *protocols;
3150 }; */
3152 static void
3153 build_category_template ()
3155 tree decl_specs, field_decl, field_decl_chain;
3157 objc_category_template = start_struct (RECORD_TYPE,
3158 get_identifier (UTAG_CATEGORY));
3159 /* char *category_name; */
3161 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3162 field_decl
3163 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3164 field_decl
3165 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3166 field_decl_chain = field_decl;
3168 /* char *class_name; */
3170 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3171 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3172 field_decl
3173 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3174 chainon (field_decl_chain, field_decl);
3176 /* struct objc_method_list *instance_methods; */
3178 decl_specs = build_tree_list (NULL_TREE,
3179 xref_tag (RECORD_TYPE,
3180 get_identifier (UTAG_METHOD_LIST)));
3181 field_decl
3182 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3183 field_decl
3184 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3185 chainon (field_decl_chain, field_decl);
3187 /* struct objc_method_list *class_methods; */
3189 decl_specs = build_tree_list (NULL_TREE,
3190 xref_tag (RECORD_TYPE,
3191 get_identifier (UTAG_METHOD_LIST)));
3192 field_decl
3193 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3194 field_decl
3195 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3196 chainon (field_decl_chain, field_decl);
3198 /* struct objc_protocol **protocol_list; */
3200 decl_specs = build_tree_list (NULL_TREE,
3201 xref_tag (RECORD_TYPE,
3202 get_identifier (UTAG_PROTOCOL)));
3203 field_decl
3204 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3205 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3206 field_decl
3207 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3208 chainon (field_decl_chain, field_decl);
3210 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3213 /* struct objc_selector {
3214 void *sel_id;
3215 char *sel_type;
3216 }; */
3218 static void
3219 build_selector_template ()
3222 tree decl_specs, field_decl, field_decl_chain;
3224 objc_selector_template
3225 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3227 /* void *sel_id; */
3229 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3230 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3231 field_decl
3232 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3233 field_decl_chain = field_decl;
3235 /* char *sel_type; */
3237 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3238 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3239 field_decl
3240 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3241 chainon (field_decl_chain, field_decl);
3243 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3246 /* struct objc_class {
3247 struct objc_class *isa;
3248 struct objc_class *super_class;
3249 char *name;
3250 long version;
3251 long info;
3252 long instance_size;
3253 struct objc_ivar_list *ivars;
3254 struct objc_method_list *methods;
3255 if (flag_next_runtime)
3256 struct objc_cache *cache;
3257 else {
3258 struct sarray *dtable;
3259 struct objc_class *subclass_list;
3260 struct objc_class *sibling_class;
3262 struct objc_protocol_list *protocols;
3263 void *gc_object_type;
3264 }; */
3266 static void
3267 build_class_template ()
3269 tree decl_specs, field_decl, field_decl_chain;
3271 objc_class_template
3272 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3274 /* struct objc_class *isa; */
3276 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3277 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3278 field_decl
3279 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3280 field_decl_chain = field_decl;
3282 /* struct objc_class *super_class; */
3284 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3285 field_decl
3286 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3287 field_decl
3288 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3289 chainon (field_decl_chain, field_decl);
3291 /* char *name; */
3293 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3294 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3295 field_decl
3296 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3297 chainon (field_decl_chain, field_decl);
3299 /* long version; */
3301 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3302 field_decl = get_identifier ("version");
3303 field_decl
3304 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3305 chainon (field_decl_chain, field_decl);
3307 /* long info; */
3309 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3310 field_decl = get_identifier ("info");
3311 field_decl
3312 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3313 chainon (field_decl_chain, field_decl);
3315 /* long instance_size; */
3317 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3318 field_decl = get_identifier ("instance_size");
3319 field_decl
3320 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3321 chainon (field_decl_chain, field_decl);
3323 /* struct objc_ivar_list *ivars; */
3325 decl_specs = build_tree_list (NULL_TREE,
3326 xref_tag (RECORD_TYPE,
3327 get_identifier (UTAG_IVAR_LIST)));
3328 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3329 field_decl
3330 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3331 chainon (field_decl_chain, field_decl);
3333 /* struct objc_method_list *methods; */
3335 decl_specs = build_tree_list (NULL_TREE,
3336 xref_tag (RECORD_TYPE,
3337 get_identifier (UTAG_METHOD_LIST)));
3338 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3339 field_decl
3340 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3341 chainon (field_decl_chain, field_decl);
3343 if (flag_next_runtime)
3345 /* struct objc_cache *cache; */
3347 decl_specs = build_tree_list (NULL_TREE,
3348 xref_tag (RECORD_TYPE,
3349 get_identifier ("objc_cache")));
3350 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3351 field_decl = grokfield (input_filename, lineno, field_decl,
3352 decl_specs, NULL_TREE);
3353 chainon (field_decl_chain, field_decl);
3355 else
3357 /* struct sarray *dtable; */
3359 decl_specs = build_tree_list (NULL_TREE,
3360 xref_tag (RECORD_TYPE,
3361 get_identifier ("sarray")));
3362 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3363 field_decl = grokfield (input_filename, lineno, field_decl,
3364 decl_specs, NULL_TREE);
3365 chainon (field_decl_chain, field_decl);
3367 /* struct objc_class *subclass_list; */
3369 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3370 field_decl
3371 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3372 field_decl = grokfield (input_filename, lineno, field_decl,
3373 decl_specs, NULL_TREE);
3374 chainon (field_decl_chain, field_decl);
3376 /* struct objc_class *sibling_class; */
3378 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3379 field_decl
3380 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3381 field_decl = grokfield (input_filename, lineno, field_decl,
3382 decl_specs, NULL_TREE);
3383 chainon (field_decl_chain, field_decl);
3386 /* struct objc_protocol **protocol_list; */
3388 decl_specs = build_tree_list (NULL_TREE,
3389 xref_tag (RECORD_TYPE,
3390 get_identifier (UTAG_PROTOCOL)));
3391 field_decl
3392 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3393 field_decl
3394 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3395 field_decl = grokfield (input_filename, lineno, field_decl,
3396 decl_specs, NULL_TREE);
3397 chainon (field_decl_chain, field_decl);
3399 /* void *sel_id; */
3401 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3402 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3403 field_decl
3404 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3405 chainon (field_decl_chain, field_decl);
3407 /* void *gc_object_type; */
3409 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3410 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3411 field_decl
3412 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3413 chainon (field_decl_chain, field_decl);
3415 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3418 /* Generate appropriate forward declarations for an implementation. */
3420 static void
3421 synth_forward_declarations ()
3423 tree sc_spec, decl_specs, an_id;
3425 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3427 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3429 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3430 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3431 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3432 TREE_USED (UOBJC_CLASS_decl) = 1;
3433 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3435 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3437 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3438 objc_implementation_context);
3440 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3441 TREE_USED (UOBJC_METACLASS_decl) = 1;
3442 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3444 /* Pre-build the following entities - for speed/convenience. */
3446 an_id = get_identifier ("super_class");
3447 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3448 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3451 static void
3452 error_with_ivar (message, decl, rawdecl)
3453 const char *message;
3454 tree decl;
3455 tree rawdecl;
3457 count_error (0);
3459 report_error_function (DECL_SOURCE_FILE (decl));
3461 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3462 DECL_SOURCE_LINE (decl),
3463 "%s `%s'",
3464 message, gen_declaration (rawdecl, errbuf));
3468 #define USERTYPE(t) \
3469 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3470 || TREE_CODE (t) == ENUMERAL_TYPE)
3472 static void
3473 check_ivars (inter, imp)
3474 tree inter;
3475 tree imp;
3477 tree intdecls = CLASS_IVARS (inter);
3478 tree impdecls = CLASS_IVARS (imp);
3479 tree rawintdecls = CLASS_RAW_IVARS (inter);
3480 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3482 while (1)
3484 tree t1, t2;
3486 if (intdecls == 0 && impdecls == 0)
3487 break;
3488 if (intdecls == 0 || impdecls == 0)
3490 error ("inconsistent instance variable specification");
3491 break;
3494 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3496 if (!comptypes (t1, t2))
3498 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3500 error_with_ivar ("conflicting instance variable type",
3501 impdecls, rawimpdecls);
3502 error_with_ivar ("previous declaration of",
3503 intdecls, rawintdecls);
3505 else /* both the type and the name don't match */
3507 error ("inconsistent instance variable specification");
3508 break;
3512 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3514 error_with_ivar ("conflicting instance variable name",
3515 impdecls, rawimpdecls);
3516 error_with_ivar ("previous declaration of",
3517 intdecls, rawintdecls);
3520 intdecls = TREE_CHAIN (intdecls);
3521 impdecls = TREE_CHAIN (impdecls);
3522 rawintdecls = TREE_CHAIN (rawintdecls);
3523 rawimpdecls = TREE_CHAIN (rawimpdecls);
3527 /* Set super_type to the data type node for struct objc_super *,
3528 first defining struct objc_super itself.
3529 This needs to be done just once per compilation. */
3531 static tree
3532 build_super_template ()
3534 tree record, decl_specs, field_decl, field_decl_chain;
3536 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3538 /* struct objc_object *self; */
3540 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3541 field_decl = get_identifier ("self");
3542 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3543 field_decl = grokfield (input_filename, lineno,
3544 field_decl, decl_specs, NULL_TREE);
3545 field_decl_chain = field_decl;
3547 /* struct objc_class *class; */
3549 decl_specs = get_identifier (UTAG_CLASS);
3550 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3551 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3553 field_decl = grokfield (input_filename, lineno,
3554 field_decl, decl_specs, NULL_TREE);
3555 chainon (field_decl_chain, field_decl);
3557 finish_struct (record, field_decl_chain, NULL_TREE);
3559 /* `struct objc_super *' */
3560 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3561 record),
3562 build1 (INDIRECT_REF,
3563 NULL_TREE, NULL_TREE)));
3564 return record;
3567 /* struct objc_ivar {
3568 char *ivar_name;
3569 char *ivar_type;
3570 int ivar_offset;
3571 }; */
3573 static tree
3574 build_ivar_template ()
3576 tree objc_ivar_id, objc_ivar_record;
3577 tree decl_specs, field_decl, field_decl_chain;
3579 objc_ivar_id = get_identifier (UTAG_IVAR);
3580 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3582 /* char *ivar_name; */
3584 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3585 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3587 field_decl = grokfield (input_filename, lineno, field_decl,
3588 decl_specs, NULL_TREE);
3589 field_decl_chain = field_decl;
3591 /* char *ivar_type; */
3593 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3594 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3596 field_decl = grokfield (input_filename, lineno, field_decl,
3597 decl_specs, NULL_TREE);
3598 chainon (field_decl_chain, field_decl);
3600 /* int ivar_offset; */
3602 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3603 field_decl = get_identifier ("ivar_offset");
3605 field_decl = grokfield (input_filename, lineno, field_decl,
3606 decl_specs, NULL_TREE);
3607 chainon (field_decl_chain, field_decl);
3609 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3611 return objc_ivar_record;
3614 /* struct {
3615 int ivar_count;
3616 struct objc_ivar ivar_list[ivar_count];
3617 }; */
3619 static tree
3620 build_ivar_list_template (list_type, size)
3621 tree list_type;
3622 int size;
3624 tree objc_ivar_list_record;
3625 tree decl_specs, field_decl, field_decl_chain;
3627 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3629 /* int ivar_count; */
3631 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3632 field_decl = get_identifier ("ivar_count");
3634 field_decl = grokfield (input_filename, lineno, field_decl,
3635 decl_specs, NULL_TREE);
3636 field_decl_chain = field_decl;
3638 /* struct objc_ivar ivar_list[]; */
3640 decl_specs = build_tree_list (NULL_TREE, list_type);
3641 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3642 build_int_2 (size, 0));
3644 field_decl = grokfield (input_filename, lineno,
3645 field_decl, decl_specs, NULL_TREE);
3646 chainon (field_decl_chain, field_decl);
3648 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3650 return objc_ivar_list_record;
3653 /* struct {
3654 int method_next;
3655 int method_count;
3656 struct objc_method method_list[method_count];
3657 }; */
3659 static tree
3660 build_method_list_template (list_type, size)
3661 tree list_type;
3662 int size;
3664 tree objc_ivar_list_record;
3665 tree decl_specs, field_decl, field_decl_chain;
3667 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3669 /* int method_next; */
3671 decl_specs
3672 = build_tree_list
3673 (NULL_TREE,
3674 xref_tag (RECORD_TYPE,
3675 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3676 field_decl
3677 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3678 field_decl = grokfield (input_filename, lineno, field_decl,
3679 decl_specs, NULL_TREE);
3680 field_decl_chain = field_decl;
3682 /* int method_count; */
3684 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3685 field_decl = get_identifier ("method_count");
3687 field_decl = grokfield (input_filename, lineno,
3688 field_decl, decl_specs, NULL_TREE);
3689 chainon (field_decl_chain, field_decl);
3691 /* struct objc_method method_list[]; */
3693 decl_specs = build_tree_list (NULL_TREE, list_type);
3694 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3695 build_int_2 (size, 0));
3697 field_decl = grokfield (input_filename, lineno,
3698 field_decl, decl_specs, NULL_TREE);
3699 chainon (field_decl_chain, field_decl);
3701 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3703 return objc_ivar_list_record;
3706 static tree
3707 build_ivar_list_initializer (type, field_decl)
3708 tree type;
3709 tree field_decl;
3711 tree initlist = NULL_TREE;
3715 tree ivar = NULL_TREE;
3717 /* Set name. */
3718 if (DECL_NAME (field_decl))
3719 ivar = tree_cons (NULL_TREE,
3720 add_objc_string (DECL_NAME (field_decl),
3721 meth_var_names),
3722 ivar);
3723 else
3724 /* Unnamed bit-field ivar (yuck). */
3725 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3727 /* Set type. */
3728 encode_field_decl (field_decl,
3729 obstack_object_size (&util_obstack),
3730 OBJC_ENCODE_DONT_INLINE_DEFS);
3732 /* Null terminate string. */
3733 obstack_1grow (&util_obstack, 0);
3734 ivar
3735 = tree_cons
3736 (NULL_TREE,
3737 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3738 meth_var_types),
3739 ivar);
3740 obstack_free (&util_obstack, util_firstobj);
3742 /* Set offset. */
3743 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3744 initlist = tree_cons (NULL_TREE,
3745 build_constructor (type, nreverse (ivar)),
3746 initlist);
3748 field_decl = TREE_CHAIN (field_decl);
3750 while (field_decl);
3752 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3755 static tree
3756 generate_ivars_list (type, name, size, list)
3757 tree type;
3758 const char *name;
3759 int size;
3760 tree list;
3762 tree sc_spec, decl_specs, decl, initlist;
3764 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3765 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3767 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3768 decl_specs, 1, NULL_TREE);
3770 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3771 initlist = tree_cons (NULL_TREE, list, initlist);
3773 finish_decl (decl,
3774 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3775 NULL_TREE);
3777 return decl;
3780 static void
3781 generate_ivar_lists ()
3783 tree initlist, ivar_list_template, chain;
3784 tree cast, variable_length_type;
3785 int size;
3787 generating_instance_variables = 1;
3789 if (!objc_ivar_template)
3790 objc_ivar_template = build_ivar_template ();
3792 cast
3793 = build_tree_list
3794 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3795 get_identifier (UTAG_IVAR_LIST))),
3796 NULL_TREE);
3797 variable_length_type = groktypename (cast);
3799 /* Only generate class variables for the root of the inheritance
3800 hierarchy since these will be the same for every class. */
3802 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3803 && (chain = TYPE_FIELDS (objc_class_template)))
3805 size = list_length (chain);
3807 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3808 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3810 UOBJC_CLASS_VARIABLES_decl
3811 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3812 size, initlist);
3813 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3815 else
3816 UOBJC_CLASS_VARIABLES_decl = 0;
3818 chain = CLASS_IVARS (implementation_template);
3819 if (chain)
3821 size = list_length (chain);
3822 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3823 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3825 UOBJC_INSTANCE_VARIABLES_decl
3826 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3827 size, initlist);
3828 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3830 else
3831 UOBJC_INSTANCE_VARIABLES_decl = 0;
3833 generating_instance_variables = 0;
3836 static tree
3837 build_dispatch_table_initializer (type, entries)
3838 tree type;
3839 tree entries;
3841 tree initlist = NULL_TREE;
3845 tree elemlist = NULL_TREE;
3847 elemlist = tree_cons (NULL_TREE,
3848 build_selector (METHOD_SEL_NAME (entries)),
3849 NULL_TREE);
3851 elemlist = tree_cons (NULL_TREE,
3852 add_objc_string (METHOD_ENCODING (entries),
3853 meth_var_types),
3854 elemlist);
3856 elemlist = tree_cons (NULL_TREE,
3857 build_unary_op (ADDR_EXPR,
3858 METHOD_DEFINITION (entries), 1),
3859 elemlist);
3861 initlist = tree_cons (NULL_TREE,
3862 build_constructor (type, nreverse (elemlist)),
3863 initlist);
3865 entries = TREE_CHAIN (entries);
3867 while (entries);
3869 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3872 /* To accomplish method prototyping without generating all kinds of
3873 inane warnings, the definition of the dispatch table entries were
3874 changed from:
3876 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3878 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3880 static tree
3881 build_method_template ()
3883 tree _SLT_record;
3884 tree decl_specs, field_decl, field_decl_chain;
3886 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3888 /* struct objc_selector *_cmd; */
3889 decl_specs = tree_cons (NULL_TREE,
3890 xref_tag (RECORD_TYPE,
3891 get_identifier (TAG_SELECTOR)),
3892 NULL_TREE);
3893 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3895 field_decl = grokfield (input_filename, lineno, field_decl,
3896 decl_specs, NULL_TREE);
3897 field_decl_chain = field_decl;
3899 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3900 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3901 get_identifier ("method_types"));
3902 field_decl = grokfield (input_filename, lineno, field_decl,
3903 decl_specs, NULL_TREE);
3904 chainon (field_decl_chain, field_decl);
3906 /* void *_imp; */
3908 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3909 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3910 field_decl = grokfield (input_filename, lineno, field_decl,
3911 decl_specs, NULL_TREE);
3912 chainon (field_decl_chain, field_decl);
3914 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3916 return _SLT_record;
3920 static tree
3921 generate_dispatch_table (type, name, size, list)
3922 tree type;
3923 const char *name;
3924 int size;
3925 tree list;
3927 tree sc_spec, decl_specs, decl, initlist;
3929 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3930 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3932 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3933 decl_specs, 1, NULL_TREE);
3935 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3936 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3937 initlist = tree_cons (NULL_TREE, list, initlist);
3939 finish_decl (decl,
3940 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3941 NULL_TREE);
3943 return decl;
3946 static void
3947 generate_dispatch_tables ()
3949 tree initlist, chain, method_list_template;
3950 tree cast, variable_length_type;
3951 int size;
3953 if (!objc_method_template)
3954 objc_method_template = build_method_template ();
3956 cast
3957 = build_tree_list
3958 (build_tree_list (NULL_TREE,
3959 xref_tag (RECORD_TYPE,
3960 get_identifier (UTAG_METHOD_LIST))),
3961 NULL_TREE);
3963 variable_length_type = groktypename (cast);
3965 chain = CLASS_CLS_METHODS (objc_implementation_context);
3966 if (chain)
3968 size = list_length (chain);
3970 method_list_template
3971 = build_method_list_template (objc_method_template, size);
3972 initlist
3973 = build_dispatch_table_initializer (objc_method_template, chain);
3975 UOBJC_CLASS_METHODS_decl
3976 = generate_dispatch_table (method_list_template,
3977 ((TREE_CODE (objc_implementation_context)
3978 == CLASS_IMPLEMENTATION_TYPE)
3979 ? "_OBJC_CLASS_METHODS"
3980 : "_OBJC_CATEGORY_CLASS_METHODS"),
3981 size, initlist);
3982 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3984 else
3985 UOBJC_CLASS_METHODS_decl = 0;
3987 chain = CLASS_NST_METHODS (objc_implementation_context);
3988 if (chain)
3990 size = list_length (chain);
3992 method_list_template
3993 = build_method_list_template (objc_method_template, size);
3994 initlist
3995 = build_dispatch_table_initializer (objc_method_template, chain);
3997 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3998 UOBJC_INSTANCE_METHODS_decl
3999 = generate_dispatch_table (method_list_template,
4000 "_OBJC_INSTANCE_METHODS",
4001 size, initlist);
4002 else
4003 /* We have a category. */
4004 UOBJC_INSTANCE_METHODS_decl
4005 = generate_dispatch_table (method_list_template,
4006 "_OBJC_CATEGORY_INSTANCE_METHODS",
4007 size, initlist);
4008 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4010 else
4011 UOBJC_INSTANCE_METHODS_decl = 0;
4014 static tree
4015 generate_protocol_list (i_or_p)
4016 tree i_or_p;
4018 tree initlist, decl_specs, sc_spec;
4019 tree refs_decl, expr_decl, lproto, e, plist;
4020 tree cast_type;
4021 int size = 0;
4023 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4024 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4025 plist = CLASS_PROTOCOL_LIST (i_or_p);
4026 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4027 plist = PROTOCOL_LIST (i_or_p);
4028 else
4029 abort ();
4031 cast_type = groktypename
4032 (build_tree_list
4033 (build_tree_list (NULL_TREE,
4034 xref_tag (RECORD_TYPE,
4035 get_identifier (UTAG_PROTOCOL))),
4036 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4038 /* Compute size. */
4039 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4040 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4041 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4042 size++;
4044 /* Build initializer. */
4045 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4047 e = build_int_2 (size, 0);
4048 TREE_TYPE (e) = cast_type;
4049 initlist = tree_cons (NULL_TREE, e, initlist);
4051 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4053 tree pval = TREE_VALUE (lproto);
4055 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4056 && PROTOCOL_FORWARD_DECL (pval))
4058 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4059 initlist = tree_cons (NULL_TREE, e, initlist);
4063 /* static struct objc_protocol *refs[n]; */
4065 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4066 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4067 get_identifier (UTAG_PROTOCOL)),
4068 sc_spec);
4070 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4071 expr_decl = build_nt (ARRAY_REF,
4072 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4073 i_or_p),
4074 build_int_2 (size + 2, 0));
4075 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4076 expr_decl = build_nt (ARRAY_REF,
4077 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4078 i_or_p),
4079 build_int_2 (size + 2, 0));
4080 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4081 expr_decl
4082 = build_nt (ARRAY_REF,
4083 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4084 i_or_p),
4085 build_int_2 (size + 2, 0));
4086 else
4087 abort ();
4089 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4091 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4092 DECL_CONTEXT (refs_decl) = NULL_TREE;
4094 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4095 nreverse (initlist)),
4096 NULL_TREE);
4098 return refs_decl;
4101 static tree
4102 build_category_initializer (type, cat_name, class_name,
4103 instance_methods, class_methods, protocol_list)
4104 tree type;
4105 tree cat_name;
4106 tree class_name;
4107 tree instance_methods;
4108 tree class_methods;
4109 tree protocol_list;
4111 tree initlist = NULL_TREE, expr;
4113 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4114 initlist = tree_cons (NULL_TREE, class_name, initlist);
4116 if (!instance_methods)
4117 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4118 else
4120 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4121 initlist = tree_cons (NULL_TREE, expr, initlist);
4123 if (!class_methods)
4124 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4125 else
4127 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4128 initlist = tree_cons (NULL_TREE, expr, initlist);
4131 /* protocol_list = */
4132 if (!protocol_list)
4133 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4134 else
4136 tree cast_type2 = groktypename
4137 (build_tree_list
4138 (build_tree_list (NULL_TREE,
4139 xref_tag (RECORD_TYPE,
4140 get_identifier (UTAG_PROTOCOL))),
4141 build1 (INDIRECT_REF, NULL_TREE,
4142 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4144 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4145 TREE_TYPE (expr) = cast_type2;
4146 initlist = tree_cons (NULL_TREE, expr, initlist);
4149 return build_constructor (type, nreverse (initlist));
4152 /* struct objc_class {
4153 struct objc_class *isa;
4154 struct objc_class *super_class;
4155 char *name;
4156 long version;
4157 long info;
4158 long instance_size;
4159 struct objc_ivar_list *ivars;
4160 struct objc_method_list *methods;
4161 if (flag_next_runtime)
4162 struct objc_cache *cache;
4163 else {
4164 struct sarray *dtable;
4165 struct objc_class *subclass_list;
4166 struct objc_class *sibling_class;
4168 struct objc_protocol_list *protocols;
4169 void *gc_object_type;
4170 }; */
4172 static tree
4173 build_shared_structure_initializer (type, isa, super, name, size, status,
4174 dispatch_table, ivar_list, protocol_list)
4175 tree type;
4176 tree isa;
4177 tree super;
4178 tree name;
4179 tree size;
4180 int status;
4181 tree dispatch_table;
4182 tree ivar_list;
4183 tree protocol_list;
4185 tree initlist = NULL_TREE, expr;
4187 /* isa = */
4188 initlist = tree_cons (NULL_TREE, isa, initlist);
4190 /* super_class = */
4191 initlist = tree_cons (NULL_TREE, super, initlist);
4193 /* name = */
4194 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4196 /* version = */
4197 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4199 /* info = */
4200 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4202 /* instance_size = */
4203 initlist = tree_cons (NULL_TREE, size, initlist);
4205 /* objc_ivar_list = */
4206 if (!ivar_list)
4207 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4208 else
4210 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4211 initlist = tree_cons (NULL_TREE, expr, initlist);
4214 /* objc_method_list = */
4215 if (!dispatch_table)
4216 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4217 else
4219 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4220 initlist = tree_cons (NULL_TREE, expr, initlist);
4223 if (flag_next_runtime)
4224 /* method_cache = */
4225 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4226 else
4228 /* dtable = */
4229 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4231 /* subclass_list = */
4232 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4234 /* sibling_class = */
4235 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4238 /* protocol_list = */
4239 if (! protocol_list)
4240 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4241 else
4243 tree cast_type2
4244 = groktypename
4245 (build_tree_list
4246 (build_tree_list (NULL_TREE,
4247 xref_tag (RECORD_TYPE,
4248 get_identifier (UTAG_PROTOCOL))),
4249 build1 (INDIRECT_REF, NULL_TREE,
4250 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4252 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4253 TREE_TYPE (expr) = cast_type2;
4254 initlist = tree_cons (NULL_TREE, expr, initlist);
4257 /* gc_object_type = NULL */
4258 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4260 return build_constructor (type, nreverse (initlist));
4263 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4265 static void
4266 generate_category (cat)
4267 tree cat;
4269 tree sc_spec, decl_specs, decl;
4270 tree initlist, cat_name_expr, class_name_expr;
4271 tree protocol_decl, category;
4273 add_class_reference (CLASS_NAME (cat));
4274 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4276 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4278 category = CLASS_CATEGORY_LIST (implementation_template);
4280 /* find the category interface from the class it is associated with */
4281 while (category)
4283 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4284 break;
4285 category = CLASS_CATEGORY_LIST (category);
4288 if (category && CLASS_PROTOCOL_LIST (category))
4290 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4291 protocol_decl = generate_protocol_list (category);
4293 else
4294 protocol_decl = 0;
4296 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4297 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4299 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4300 objc_implementation_context),
4301 decl_specs, 1, NULL_TREE);
4303 initlist = build_category_initializer (TREE_TYPE (decl),
4304 cat_name_expr, class_name_expr,
4305 UOBJC_INSTANCE_METHODS_decl,
4306 UOBJC_CLASS_METHODS_decl,
4307 protocol_decl);
4309 TREE_USED (decl) = 1;
4310 finish_decl (decl, initlist, NULL_TREE);
4313 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4314 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4316 static void
4317 generate_shared_structures ()
4319 tree sc_spec, decl_specs, decl;
4320 tree name_expr, super_expr, root_expr;
4321 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4322 tree cast_type, initlist, protocol_decl;
4324 my_super_id = CLASS_SUPER_NAME (implementation_template);
4325 if (my_super_id)
4327 add_class_reference (my_super_id);
4329 /* Compute "my_root_id" - this is required for code generation.
4330 the "isa" for all meta class structures points to the root of
4331 the inheritance hierarchy (e.g. "__Object")... */
4332 my_root_id = my_super_id;
4335 tree my_root_int = lookup_interface (my_root_id);
4337 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4338 my_root_id = CLASS_SUPER_NAME (my_root_int);
4339 else
4340 break;
4342 while (1);
4344 else
4345 /* No super class. */
4346 my_root_id = CLASS_NAME (implementation_template);
4348 cast_type
4349 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4350 objc_class_template),
4351 build1 (INDIRECT_REF,
4352 NULL_TREE, NULL_TREE)));
4354 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4355 class_names);
4357 /* Install class `isa' and `super' pointers at runtime. */
4358 if (my_super_id)
4360 super_expr = add_objc_string (my_super_id, class_names);
4361 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4363 else
4364 super_expr = build_int_2 (0, 0);
4366 root_expr = add_objc_string (my_root_id, class_names);
4367 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4369 if (CLASS_PROTOCOL_LIST (implementation_template))
4371 generate_protocol_references
4372 (CLASS_PROTOCOL_LIST (implementation_template));
4373 protocol_decl = generate_protocol_list (implementation_template);
4375 else
4376 protocol_decl = 0;
4378 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4380 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4381 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4383 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4384 NULL_TREE);
4386 initlist
4387 = build_shared_structure_initializer
4388 (TREE_TYPE (decl),
4389 root_expr, super_expr, name_expr,
4390 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4391 2 /*CLS_META*/,
4392 UOBJC_CLASS_METHODS_decl,
4393 UOBJC_CLASS_VARIABLES_decl,
4394 protocol_decl);
4396 finish_decl (decl, initlist, NULL_TREE);
4398 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4400 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4401 NULL_TREE);
4403 initlist
4404 = build_shared_structure_initializer
4405 (TREE_TYPE (decl),
4406 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4407 super_expr, name_expr,
4408 convert (integer_type_node,
4409 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4410 (implementation_template))),
4411 1 /*CLS_FACTORY*/,
4412 UOBJC_INSTANCE_METHODS_decl,
4413 UOBJC_INSTANCE_VARIABLES_decl,
4414 protocol_decl);
4416 finish_decl (decl, initlist, NULL_TREE);
4419 static tree
4420 synth_id_with_class_suffix (preamble, ctxt)
4421 const char *preamble;
4422 tree ctxt;
4424 char *string;
4425 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4426 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4428 const char *const class_name
4429 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4430 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4431 sprintf (string, "%s_%s", preamble,
4432 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4434 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4435 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4437 /* We have a category. */
4438 const char *const class_name
4439 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4440 const char *const class_super_name
4441 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4442 string = (char *) alloca (strlen (preamble)
4443 + strlen (class_name)
4444 + strlen (class_super_name)
4445 + 3);
4446 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4448 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4450 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4451 string
4452 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4453 sprintf (string, "%s_%s", preamble, protocol_name);
4455 else
4456 abort ();
4458 return get_identifier (string);
4461 static int
4462 is_objc_type_qualifier (node)
4463 tree node;
4465 return (TREE_CODE (node) == IDENTIFIER_NODE
4466 && (node == ridpointers [(int) RID_CONST]
4467 || node == ridpointers [(int) RID_VOLATILE]
4468 || node == ridpointers [(int) RID_IN]
4469 || node == ridpointers [(int) RID_OUT]
4470 || node == ridpointers [(int) RID_INOUT]
4471 || node == ridpointers [(int) RID_BYCOPY]
4472 || node == ridpointers [(int) RID_BYREF]
4473 || node == ridpointers [(int) RID_ONEWAY]));
4476 /* If type is empty or only type qualifiers are present, add default
4477 type of id (otherwise grokdeclarator will default to int). */
4479 static tree
4480 adjust_type_for_id_default (type)
4481 tree type;
4483 tree declspecs, chain;
4485 if (!type)
4486 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4487 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4489 declspecs = TREE_PURPOSE (type);
4491 /* Determine if a typespec is present. */
4492 for (chain = declspecs;
4493 chain;
4494 chain = TREE_CHAIN (chain))
4496 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4497 return type;
4500 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4501 declspecs),
4502 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4505 /* Usage:
4506 keyworddecl:
4507 selector ':' '(' typename ')' identifier
4509 Purpose:
4510 Transform an Objective-C keyword argument into
4511 the C equivalent parameter declarator.
4513 In: key_name, an "identifier_node" (optional).
4514 arg_type, a "tree_list" (optional).
4515 arg_name, an "identifier_node".
4517 Note: It would be really nice to strongly type the preceding
4518 arguments in the function prototype; however, then I
4519 could not use the "accessor" macros defined in "tree.h".
4521 Out: an instance of "keyword_decl". */
4523 tree
4524 build_keyword_decl (key_name, arg_type, arg_name)
4525 tree key_name;
4526 tree arg_type;
4527 tree arg_name;
4529 tree keyword_decl;
4531 /* If no type is specified, default to "id". */
4532 arg_type = adjust_type_for_id_default (arg_type);
4534 keyword_decl = make_node (KEYWORD_DECL);
4536 TREE_TYPE (keyword_decl) = arg_type;
4537 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4538 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4540 return keyword_decl;
4543 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4545 static tree
4546 build_keyword_selector (selector)
4547 tree selector;
4549 int len = 0;
4550 tree key_chain, key_name;
4551 char *buf;
4553 /* Scan the selector to see how much space we'll need. */
4554 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4556 if (TREE_CODE (selector) == KEYWORD_DECL)
4557 key_name = KEYWORD_KEY_NAME (key_chain);
4558 else if (TREE_CODE (selector) == TREE_LIST)
4559 key_name = TREE_PURPOSE (key_chain);
4560 else
4561 abort ();
4563 if (key_name)
4564 len += IDENTIFIER_LENGTH (key_name) + 1;
4565 else
4566 /* Just a ':' arg. */
4567 len++;
4570 buf = (char *) alloca (len + 1);
4571 /* Start the buffer out as an empty string. */
4572 buf[0] = '\0';
4574 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4576 if (TREE_CODE (selector) == KEYWORD_DECL)
4577 key_name = KEYWORD_KEY_NAME (key_chain);
4578 else if (TREE_CODE (selector) == TREE_LIST)
4579 key_name = TREE_PURPOSE (key_chain);
4580 else
4581 abort ();
4583 if (key_name)
4584 strcat (buf, IDENTIFIER_POINTER (key_name));
4585 strcat (buf, ":");
4588 return get_identifier (buf);
4591 /* Used for declarations and definitions. */
4593 tree
4594 build_method_decl (code, ret_type, selector, add_args)
4595 enum tree_code code;
4596 tree ret_type;
4597 tree selector;
4598 tree add_args;
4600 tree method_decl;
4602 /* If no type is specified, default to "id". */
4603 ret_type = adjust_type_for_id_default (ret_type);
4605 method_decl = make_node (code);
4606 TREE_TYPE (method_decl) = ret_type;
4608 /* If we have a keyword selector, create an identifier_node that
4609 represents the full selector name (`:' included)... */
4610 if (TREE_CODE (selector) == KEYWORD_DECL)
4612 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4613 METHOD_SEL_ARGS (method_decl) = selector;
4614 METHOD_ADD_ARGS (method_decl) = add_args;
4616 else
4618 METHOD_SEL_NAME (method_decl) = selector;
4619 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4620 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4623 return method_decl;
4626 #define METHOD_DEF 0
4627 #define METHOD_REF 1
4629 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4630 an argument list for method METH. CONTEXT is either METHOD_DEF or
4631 METHOD_REF, saying whether we are trying to define a method or call
4632 one. SUPERFLAG says this is for a send to super; this makes a
4633 difference for the NeXT calling sequence in which the lookup and
4634 the method call are done together. */
4636 static tree
4637 get_arg_type_list (meth, context, superflag)
4638 tree meth;
4639 int context;
4640 int superflag;
4642 tree arglist, akey;
4644 /* Receiver type. */
4645 if (flag_next_runtime && superflag)
4646 arglist = build_tree_list (NULL_TREE, super_type);
4647 else if (context == METHOD_DEF)
4648 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4649 else
4650 arglist = build_tree_list (NULL_TREE, id_type);
4652 /* Selector type - will eventually change to `int'. */
4653 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4655 /* Build a list of argument types. */
4656 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4658 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4659 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4662 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4663 /* We have a `, ...' immediately following the selector,
4664 finalize the arglist...simulate get_parm_info (0). */
4666 else if (METHOD_ADD_ARGS (meth))
4668 /* we have a variable length selector */
4669 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4670 chainon (arglist, add_arg_list);
4672 else
4673 /* finalize the arglist...simulate get_parm_info (1) */
4674 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4676 return arglist;
4679 static tree
4680 check_duplicates (hsh)
4681 hash hsh;
4683 tree meth = NULL_TREE;
4685 if (hsh)
4687 meth = hsh->key;
4689 if (hsh->list)
4691 /* We have two methods with the same name and different types. */
4692 attr loop;
4693 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4695 warning ("multiple declarations for method `%s'",
4696 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4698 warn_with_method ("using", type, meth);
4699 for (loop = hsh->list; loop; loop = loop->next)
4700 warn_with_method ("also found", type, loop->value);
4703 return meth;
4706 /* If RECEIVER is a class reference, return the identifier node for
4707 the referenced class. RECEIVER is created by get_class_reference,
4708 so we check the exact form created depending on which runtimes are
4709 used. */
4711 static tree
4712 receiver_is_class_object (receiver)
4713 tree receiver;
4715 tree chain, exp, arg;
4717 /* The receiver is 'self' in the context of a class method. */
4718 if (objc_method_context
4719 && receiver == self_decl
4720 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4722 return CLASS_NAME (objc_implementation_context);
4725 if (flag_next_runtime)
4727 /* The receiver is a variable created by
4728 build_class_reference_decl. */
4729 if (TREE_CODE (receiver) == VAR_DECL
4730 && TREE_TYPE (receiver) == objc_class_type)
4731 /* Look up the identifier. */
4732 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4733 if (TREE_PURPOSE (chain) == receiver)
4734 return TREE_VALUE (chain);
4736 else
4738 /* The receiver is a function call that returns an id. Check if
4739 it is a call to objc_getClass, if so, pick up the class name. */
4740 if (TREE_CODE (receiver) == CALL_EXPR
4741 && (exp = TREE_OPERAND (receiver, 0))
4742 && TREE_CODE (exp) == ADDR_EXPR
4743 && (exp = TREE_OPERAND (exp, 0))
4744 && TREE_CODE (exp) == FUNCTION_DECL
4745 && exp == objc_get_class_decl
4746 /* We have a call to objc_getClass! */
4747 && (arg = TREE_OPERAND (receiver, 1))
4748 && TREE_CODE (arg) == TREE_LIST
4749 && (arg = TREE_VALUE (arg)))
4751 STRIP_NOPS (arg);
4752 if (TREE_CODE (arg) == ADDR_EXPR
4753 && (arg = TREE_OPERAND (arg, 0))
4754 && TREE_CODE (arg) == STRING_CST)
4755 /* Finally, we have the class name. */
4756 return get_identifier (TREE_STRING_POINTER (arg));
4759 return 0;
4762 /* If we are currently building a message expr, this holds
4763 the identifier of the selector of the message. This is
4764 used when printing warnings about argument mismatches. */
4766 static tree building_objc_message_expr = 0;
4768 tree
4769 maybe_building_objc_message_expr ()
4771 return building_objc_message_expr;
4774 /* Construct an expression for sending a message.
4775 MESS has the object to send to in TREE_PURPOSE
4776 and the argument list (including selector) in TREE_VALUE.
4778 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4779 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4781 tree
4782 build_message_expr (mess)
4783 tree mess;
4785 tree receiver = TREE_PURPOSE (mess);
4786 tree sel_name;
4787 tree args = TREE_VALUE (mess);
4788 tree method_params = NULL_TREE;
4790 if (TREE_CODE (receiver) == ERROR_MARK)
4791 return error_mark_node;
4793 /* Obtain the full selector name. */
4794 if (TREE_CODE (args) == IDENTIFIER_NODE)
4795 /* A unary selector. */
4796 sel_name = args;
4797 else if (TREE_CODE (args) == TREE_LIST)
4798 sel_name = build_keyword_selector (args);
4799 else
4800 abort ();
4802 /* Build the parameter list to give to the method. */
4803 if (TREE_CODE (args) == TREE_LIST)
4805 tree chain = args, prev = NULL_TREE;
4807 /* We have a keyword selector--check for comma expressions. */
4808 while (chain)
4810 tree element = TREE_VALUE (chain);
4812 /* We have a comma expression, must collapse... */
4813 if (TREE_CODE (element) == TREE_LIST)
4815 if (prev)
4816 TREE_CHAIN (prev) = element;
4817 else
4818 args = element;
4820 prev = chain;
4821 chain = TREE_CHAIN (chain);
4823 method_params = args;
4826 return finish_message_expr (receiver, sel_name, method_params);
4829 /* The 'finish_message_expr' routine is called from within
4830 'build_message_expr' for non-template functions. In the case of
4831 C++ template functions, it is called from 'build_expr_from_tree'
4832 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4834 tree
4835 finish_message_expr (receiver, sel_name, method_params)
4836 tree receiver, sel_name, method_params;
4838 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4839 tree selector, self_object, retval;
4840 int statically_typed = 0, statically_allocated = 0;
4842 /* Determine receiver type. */
4843 tree rtype = TREE_TYPE (receiver);
4844 int super = IS_SUPER (rtype);
4846 if (! super)
4848 if (TREE_STATIC_TEMPLATE (rtype))
4849 statically_allocated = 1;
4850 else if (TREE_CODE (rtype) == POINTER_TYPE
4851 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4852 statically_typed = 1;
4853 else if ((flag_next_runtime
4854 || (IS_ID (rtype)
4855 && (class_ident = receiver_is_class_object (receiver)))))
4857 else if (! IS_ID (rtype)
4858 /* Allow any type that matches objc_class_type. */
4859 && ! comptypes (rtype, objc_class_type))
4861 warning ("invalid receiver type `%s'",
4862 gen_declaration (rtype, errbuf));
4864 if (statically_allocated)
4865 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4867 /* Don't evaluate the receiver twice. */
4868 receiver = save_expr (receiver);
4869 self_object = receiver;
4871 else
4872 /* If sending to `super', use current self as the object. */
4873 self_object = self_decl;
4875 /* Determine operation return type. */
4877 if (super)
4879 tree iface;
4881 if (CLASS_SUPER_NAME (implementation_template))
4883 iface
4884 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4886 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4887 method_prototype = lookup_instance_method_static (iface, sel_name);
4888 else
4889 method_prototype = lookup_class_method_static (iface, sel_name);
4891 if (iface && !method_prototype)
4892 warning ("`%s' does not respond to `%s'",
4893 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4894 IDENTIFIER_POINTER (sel_name));
4896 else
4898 error ("no super class declared in interface for `%s'",
4899 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4900 return error_mark_node;
4904 else if (statically_allocated)
4906 tree ctype = TREE_TYPE (rtype);
4907 tree iface = lookup_interface (TYPE_NAME (rtype));
4909 if (iface)
4910 method_prototype = lookup_instance_method_static (iface, sel_name);
4912 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4913 method_prototype
4914 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4915 sel_name, 0);
4917 if (!method_prototype)
4918 warning ("`%s' does not respond to `%s'",
4919 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4920 IDENTIFIER_POINTER (sel_name));
4922 else if (statically_typed)
4924 tree ctype = TREE_TYPE (rtype);
4926 /* `self' is now statically_typed. All methods should be visible
4927 within the context of the implementation. */
4928 if (objc_implementation_context
4929 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4931 method_prototype
4932 = lookup_instance_method_static (implementation_template,
4933 sel_name);
4935 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4936 method_prototype
4937 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4938 sel_name, 0);
4940 if (! method_prototype
4941 && implementation_template != objc_implementation_context)
4942 /* The method is not published in the interface. Check
4943 locally. */
4944 method_prototype
4945 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4946 sel_name);
4948 else
4950 tree iface;
4952 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4953 method_prototype = lookup_instance_method_static (iface, sel_name);
4955 if (! method_prototype)
4957 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4958 if (protocol_list)
4959 method_prototype
4960 = lookup_method_in_protocol_list (protocol_list,
4961 sel_name, 0);
4965 if (!method_prototype)
4966 warning ("`%s' does not respond to `%s'",
4967 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4968 IDENTIFIER_POINTER (sel_name));
4970 else if (class_ident)
4972 if (objc_implementation_context
4973 && CLASS_NAME (objc_implementation_context) == class_ident)
4975 method_prototype
4976 = lookup_class_method_static (implementation_template, sel_name);
4978 if (!method_prototype
4979 && implementation_template != objc_implementation_context)
4980 /* The method is not published in the interface. Check
4981 locally. */
4982 method_prototype
4983 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4984 sel_name);
4986 else
4988 tree iface;
4990 if ((iface = lookup_interface (class_ident)))
4991 method_prototype = lookup_class_method_static (iface, sel_name);
4994 if (!method_prototype)
4996 warning ("cannot find class (factory) method");
4997 warning ("return type for `%s' defaults to id",
4998 IDENTIFIER_POINTER (sel_name));
5001 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5003 /* An anonymous object that has been qualified with a protocol. */
5005 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5007 method_prototype = lookup_method_in_protocol_list (protocol_list,
5008 sel_name, 0);
5010 if (!method_prototype)
5012 hash hsh;
5014 warning ("method `%s' not implemented by protocol",
5015 IDENTIFIER_POINTER (sel_name));
5017 /* Try and find the method signature in the global pools. */
5019 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5020 hsh = hash_lookup (cls_method_hash_list, sel_name);
5022 if (!(method_prototype = check_duplicates (hsh)))
5023 warning ("return type defaults to id");
5026 else
5028 hash hsh;
5030 /* We think we have an instance...loophole: extern id Object; */
5031 hsh = hash_lookup (nst_method_hash_list, sel_name);
5033 if (!hsh)
5034 /* For various loopholes */
5035 hsh = hash_lookup (cls_method_hash_list, sel_name);
5037 method_prototype = check_duplicates (hsh);
5038 if (!method_prototype)
5040 warning ("cannot find method");
5041 warning ("return type for `%s' defaults to id",
5042 IDENTIFIER_POINTER (sel_name));
5046 /* Save the selector name for printing error messages. */
5047 building_objc_message_expr = sel_name;
5049 /* Build the parameters list for looking up the method.
5050 These are the object itself and the selector. */
5052 if (flag_typed_selectors)
5053 selector = build_typed_selector_reference (sel_name, method_prototype);
5054 else
5055 selector = build_selector_reference (sel_name);
5057 retval = build_objc_method_call (super, method_prototype,
5058 receiver, self_object,
5059 selector, method_params);
5061 building_objc_message_expr = 0;
5063 return retval;
5066 /* Build a tree expression to send OBJECT the operation SELECTOR,
5067 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5068 assuming the method has prototype METHOD_PROTOTYPE.
5069 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5070 Use METHOD_PARAMS as list of args to pass to the method.
5071 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5073 static tree
5074 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5075 selector, method_params)
5076 int super_flag;
5077 tree method_prototype, lookup_object, object, selector, method_params;
5079 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5080 tree rcv_p = (super_flag
5081 ? build_pointer_type (xref_tag (RECORD_TYPE,
5082 get_identifier (TAG_SUPER)))
5083 : id_type);
5085 if (flag_next_runtime)
5087 if (! method_prototype)
5089 method_params = tree_cons (NULL_TREE, lookup_object,
5090 tree_cons (NULL_TREE, selector,
5091 method_params));
5092 assemble_external (sender);
5093 return build_function_call (sender, method_params);
5095 else
5097 /* This is a real kludge, but it is used only for the Next.
5098 Clobber the data type of SENDER temporarily to accept
5099 all the arguments for this operation, and to return
5100 whatever this operation returns. */
5101 tree arglist = NULL_TREE, retval, savarg, savret;
5102 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5104 /* Save the proper contents of SENDER's data type. */
5105 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5106 savret = TREE_TYPE (TREE_TYPE (sender));
5108 /* Install this method's argument types. */
5109 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5110 super_flag);
5111 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5113 /* Install this method's return type. */
5114 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5116 /* Call SENDER with all the parameters. This will do type
5117 checking using the arg types for this method. */
5118 method_params = tree_cons (NULL_TREE, lookup_object,
5119 tree_cons (NULL_TREE, selector,
5120 method_params));
5121 assemble_external (sender);
5122 retval = build_function_call (sender, method_params);
5124 /* Restore SENDER's return/argument types. */
5125 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5126 TREE_TYPE (TREE_TYPE (sender)) = savret;
5127 return retval;
5130 else
5132 /* This is the portable way.
5133 First call the lookup function to get a pointer to the method,
5134 then cast the pointer, then call it with the method arguments. */
5135 tree method;
5137 /* Avoid trouble since we may evaluate each of these twice. */
5138 object = save_expr (object);
5139 selector = save_expr (selector);
5141 lookup_object = build_c_cast (rcv_p, lookup_object);
5143 assemble_external (sender);
5144 method
5145 = build_function_call (sender,
5146 tree_cons (NULL_TREE, lookup_object,
5147 tree_cons (NULL_TREE, selector,
5148 NULL_TREE)));
5150 /* If we have a method prototype, construct the data type this
5151 method needs, and cast what we got from SENDER into a pointer
5152 to that type. */
5153 if (method_prototype)
5155 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5156 super_flag);
5157 tree valtype = groktypename (TREE_TYPE (method_prototype));
5158 tree fake_function_type = build_function_type (valtype, arglist);
5159 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5161 else
5162 TREE_TYPE (method)
5163 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5165 /* Pass the object to the method. */
5166 assemble_external (method);
5167 return build_function_call (method,
5168 tree_cons (NULL_TREE, object,
5169 tree_cons (NULL_TREE, selector,
5170 method_params)));
5174 static void
5175 build_protocol_reference (p)
5176 tree p;
5178 tree decl, ident, ptype;
5180 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5182 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5183 ptype
5184 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5185 objc_protocol_template),
5186 NULL_TREE));
5188 if (IDENTIFIER_GLOBAL_VALUE (ident))
5189 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5190 else
5192 decl = build_decl (VAR_DECL, ident, ptype);
5193 DECL_EXTERNAL (decl) = 1;
5194 TREE_PUBLIC (decl) = 1;
5195 TREE_USED (decl) = 1;
5196 DECL_ARTIFICIAL (decl) = 1;
5198 make_decl_rtl (decl, 0);
5199 pushdecl_top_level (decl);
5202 PROTOCOL_FORWARD_DECL (p) = decl;
5205 tree
5206 build_protocol_expr (protoname)
5207 tree protoname;
5209 tree expr;
5210 tree p = lookup_protocol (protoname);
5212 if (!p)
5214 error ("cannot find protocol declaration for `%s'",
5215 IDENTIFIER_POINTER (protoname));
5216 return error_mark_node;
5219 if (!PROTOCOL_FORWARD_DECL (p))
5220 build_protocol_reference (p);
5222 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5224 TREE_TYPE (expr) = protocol_type;
5226 return expr;
5229 tree
5230 build_selector_expr (selnamelist)
5231 tree selnamelist;
5233 tree selname;
5235 /* Obtain the full selector name. */
5236 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5237 /* A unary selector. */
5238 selname = selnamelist;
5239 else if (TREE_CODE (selnamelist) == TREE_LIST)
5240 selname = build_keyword_selector (selnamelist);
5241 else
5242 abort ();
5244 if (flag_typed_selectors)
5245 return build_typed_selector_reference (selname, 0);
5246 else
5247 return build_selector_reference (selname);
5250 tree
5251 build_encode_expr (type)
5252 tree type;
5254 tree result;
5255 const char *string;
5257 encode_type (type, obstack_object_size (&util_obstack),
5258 OBJC_ENCODE_INLINE_DEFS);
5259 obstack_1grow (&util_obstack, 0); /* null terminate string */
5260 string = obstack_finish (&util_obstack);
5262 /* Synthesize a string that represents the encoded struct/union. */
5263 result = my_build_string (strlen (string) + 1, string);
5264 obstack_free (&util_obstack, util_firstobj);
5265 return result;
5268 tree
5269 build_ivar_reference (id)
5270 tree id;
5272 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5274 /* Historically, a class method that produced objects (factory
5275 method) would assign `self' to the instance that it
5276 allocated. This would effectively turn the class method into
5277 an instance method. Following this assignment, the instance
5278 variables could be accessed. That practice, while safe,
5279 violates the simple rule that a class method should not refer
5280 to an instance variable. It's better to catch the cases
5281 where this is done unknowingly than to support the above
5282 paradigm. */
5283 warning ("instance variable `%s' accessed in class method",
5284 IDENTIFIER_POINTER (id));
5285 TREE_TYPE (self_decl) = instance_type; /* cast */
5288 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5291 /* Compute a hash value for a given method SEL_NAME. */
5293 static size_t
5294 hash_func (sel_name)
5295 tree sel_name;
5297 const unsigned char *s
5298 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5299 size_t h = 0;
5301 while (*s)
5302 h = h * 67 + *s++ - 113;
5303 return h;
5306 static void
5307 hash_init ()
5309 nst_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5310 cls_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5313 /* WARNING!!!! hash_enter is called with a method, and will peek
5314 inside to find its selector! But hash_lookup is given a selector
5315 directly, and looks for the selector that's inside the found
5316 entry's key (method) for comparison. */
5318 static void
5319 hash_enter (hashlist, method)
5320 hash *hashlist;
5321 tree method;
5323 static hash hash_alloc_list = 0;
5324 static int hash_alloc_index = 0;
5325 hash obj;
5326 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5328 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5330 hash_alloc_index = 0;
5331 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5332 * HASH_ALLOC_LIST_SIZE);
5334 obj = &hash_alloc_list[hash_alloc_index++];
5335 obj->list = 0;
5336 obj->next = hashlist[slot];
5337 obj->key = method;
5339 hashlist[slot] = obj; /* append to front */
5342 static hash
5343 hash_lookup (hashlist, sel_name)
5344 hash *hashlist;
5345 tree sel_name;
5347 hash target;
5349 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5351 while (target)
5353 if (sel_name == METHOD_SEL_NAME (target->key))
5354 return target;
5356 target = target->next;
5358 return 0;
5361 static void
5362 hash_add_attr (entry, value)
5363 hash entry;
5364 tree value;
5366 static attr attr_alloc_list = 0;
5367 static int attr_alloc_index = 0;
5368 attr obj;
5370 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5372 attr_alloc_index = 0;
5373 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5374 * ATTR_ALLOC_LIST_SIZE);
5376 obj = &attr_alloc_list[attr_alloc_index++];
5377 obj->next = entry->list;
5378 obj->value = value;
5380 entry->list = obj; /* append to front */
5383 static tree
5384 lookup_method (mchain, method)
5385 tree mchain;
5386 tree method;
5388 tree key;
5390 if (TREE_CODE (method) == IDENTIFIER_NODE)
5391 key = method;
5392 else
5393 key = METHOD_SEL_NAME (method);
5395 while (mchain)
5397 if (METHOD_SEL_NAME (mchain) == key)
5398 return mchain;
5399 mchain = TREE_CHAIN (mchain);
5401 return NULL_TREE;
5404 static tree
5405 lookup_instance_method_static (interface, ident)
5406 tree interface;
5407 tree ident;
5409 tree inter = interface;
5410 tree chain = CLASS_NST_METHODS (inter);
5411 tree meth = NULL_TREE;
5415 if ((meth = lookup_method (chain, ident)))
5416 return meth;
5418 if (CLASS_CATEGORY_LIST (inter))
5420 tree category = CLASS_CATEGORY_LIST (inter);
5421 chain = CLASS_NST_METHODS (category);
5425 if ((meth = lookup_method (chain, ident)))
5426 return meth;
5428 /* Check for instance methods in protocols in categories. */
5429 if (CLASS_PROTOCOL_LIST (category))
5431 if ((meth = (lookup_method_in_protocol_list
5432 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5433 return meth;
5436 if ((category = CLASS_CATEGORY_LIST (category)))
5437 chain = CLASS_NST_METHODS (category);
5439 while (category);
5442 if (CLASS_PROTOCOL_LIST (inter))
5444 if ((meth = (lookup_method_in_protocol_list
5445 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5446 return meth;
5449 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5450 chain = CLASS_NST_METHODS (inter);
5452 while (inter);
5454 return meth;
5457 static tree
5458 lookup_class_method_static (interface, ident)
5459 tree interface;
5460 tree ident;
5462 tree inter = interface;
5463 tree chain = CLASS_CLS_METHODS (inter);
5464 tree meth = NULL_TREE;
5465 tree root_inter = NULL_TREE;
5469 if ((meth = lookup_method (chain, ident)))
5470 return meth;
5472 if (CLASS_CATEGORY_LIST (inter))
5474 tree category = CLASS_CATEGORY_LIST (inter);
5475 chain = CLASS_CLS_METHODS (category);
5479 if ((meth = lookup_method (chain, ident)))
5480 return meth;
5482 /* Check for class methods in protocols in categories. */
5483 if (CLASS_PROTOCOL_LIST (category))
5485 if ((meth = (lookup_method_in_protocol_list
5486 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5487 return meth;
5490 if ((category = CLASS_CATEGORY_LIST (category)))
5491 chain = CLASS_CLS_METHODS (category);
5493 while (category);
5496 /* Check for class methods in protocols. */
5497 if (CLASS_PROTOCOL_LIST (inter))
5499 if ((meth = (lookup_method_in_protocol_list
5500 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5501 return meth;
5504 root_inter = inter;
5505 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5506 chain = CLASS_CLS_METHODS (inter);
5508 while (inter);
5510 /* If no class (factory) method was found, check if an _instance_
5511 method of the same name exists in the root class. This is what
5512 the Objective-C runtime will do. */
5513 return lookup_instance_method_static (root_inter, ident);
5516 tree
5517 add_class_method (class, method)
5518 tree class;
5519 tree method;
5521 tree mth;
5522 hash hsh;
5524 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5526 /* put method on list in reverse order */
5527 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5528 CLASS_CLS_METHODS (class) = method;
5530 else
5532 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5533 error ("duplicate definition of class method `%s'",
5534 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5535 else
5537 /* Check types; if different, complain. */
5538 if (!comp_proto_with_proto (method, mth))
5539 error ("duplicate declaration of class method `%s'",
5540 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5544 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5546 /* Install on a global chain. */
5547 hash_enter (cls_method_hash_list, method);
5549 else
5551 /* Check types; if different, add to a list. */
5552 if (!comp_proto_with_proto (method, hsh->key))
5553 hash_add_attr (hsh, method);
5555 return method;
5558 tree
5559 add_instance_method (class, method)
5560 tree class;
5561 tree method;
5563 tree mth;
5564 hash hsh;
5566 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5568 /* Put method on list in reverse order. */
5569 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5570 CLASS_NST_METHODS (class) = method;
5572 else
5574 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5575 error ("duplicate definition of instance method `%s'",
5576 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5577 else
5579 /* Check types; if different, complain. */
5580 if (!comp_proto_with_proto (method, mth))
5581 error ("duplicate declaration of instance method `%s'",
5582 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5586 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5588 /* Install on a global chain. */
5589 hash_enter (nst_method_hash_list, method);
5591 else
5593 /* Check types; if different, add to a list. */
5594 if (!comp_proto_with_proto (method, hsh->key))
5595 hash_add_attr (hsh, method);
5597 return method;
5600 static tree
5601 add_class (class)
5602 tree class;
5604 /* Put interfaces on list in reverse order. */
5605 TREE_CHAIN (class) = interface_chain;
5606 interface_chain = class;
5607 return interface_chain;
5610 static void
5611 add_category (class, category)
5612 tree class;
5613 tree category;
5615 /* Put categories on list in reverse order. */
5616 tree cat = CLASS_CATEGORY_LIST (class);
5618 while (cat)
5620 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5621 warning ("duplicate interface declaration for category `%s(%s)'",
5622 IDENTIFIER_POINTER (CLASS_NAME (class)),
5623 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5624 cat = CLASS_CATEGORY_LIST (cat);
5627 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5628 CLASS_CATEGORY_LIST (class) = category;
5631 /* Called after parsing each instance variable declaration. Necessary to
5632 preserve typedefs and implement public/private...
5634 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5636 tree
5637 add_instance_variable (class, public, declarator, declspecs, width)
5638 tree class;
5639 int public;
5640 tree declarator;
5641 tree declspecs;
5642 tree width;
5644 tree field_decl, raw_decl;
5646 raw_decl = build_tree_list (declspecs, declarator);
5648 if (CLASS_RAW_IVARS (class))
5649 chainon (CLASS_RAW_IVARS (class), raw_decl);
5650 else
5651 CLASS_RAW_IVARS (class) = raw_decl;
5653 field_decl = grokfield (input_filename, lineno,
5654 declarator, declspecs, width);
5656 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5657 switch (public)
5659 case 0:
5660 TREE_PUBLIC (field_decl) = 0;
5661 TREE_PRIVATE (field_decl) = 0;
5662 TREE_PROTECTED (field_decl) = 1;
5663 break;
5665 case 1:
5666 TREE_PUBLIC (field_decl) = 1;
5667 TREE_PRIVATE (field_decl) = 0;
5668 TREE_PROTECTED (field_decl) = 0;
5669 break;
5671 case 2:
5672 TREE_PUBLIC (field_decl) = 0;
5673 TREE_PRIVATE (field_decl) = 1;
5674 TREE_PROTECTED (field_decl) = 0;
5675 break;
5679 if (CLASS_IVARS (class))
5680 chainon (CLASS_IVARS (class), field_decl);
5681 else
5682 CLASS_IVARS (class) = field_decl;
5684 return class;
5687 tree
5688 is_ivar (decl_chain, ident)
5689 tree decl_chain;
5690 tree ident;
5692 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5693 if (DECL_NAME (decl_chain) == ident)
5694 return decl_chain;
5695 return NULL_TREE;
5698 /* True if the ivar is private and we are not in its implementation. */
5701 is_private (decl)
5702 tree decl;
5704 if (TREE_PRIVATE (decl)
5705 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5707 error ("instance variable `%s' is declared private",
5708 IDENTIFIER_POINTER (DECL_NAME (decl)));
5709 return 1;
5711 else
5712 return 0;
5715 /* We have an instance variable reference;, check to see if it is public. */
5718 is_public (expr, identifier)
5719 tree expr;
5720 tree identifier;
5722 tree basetype = TREE_TYPE (expr);
5723 enum tree_code code = TREE_CODE (basetype);
5724 tree decl;
5726 if (code == RECORD_TYPE)
5728 if (TREE_STATIC_TEMPLATE (basetype))
5730 if (!lookup_interface (TYPE_NAME (basetype)))
5732 error ("cannot find interface declaration for `%s'",
5733 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5734 return 0;
5737 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5739 if (TREE_PUBLIC (decl))
5740 return 1;
5742 /* Important difference between the Stepstone translator:
5743 all instance variables should be public within the context
5744 of the implementation. */
5745 if (objc_implementation_context
5746 && (((TREE_CODE (objc_implementation_context)
5747 == CLASS_IMPLEMENTATION_TYPE)
5748 || (TREE_CODE (objc_implementation_context)
5749 == CATEGORY_IMPLEMENTATION_TYPE))
5750 && (CLASS_NAME (objc_implementation_context)
5751 == TYPE_NAME (basetype))))
5752 return ! is_private (decl);
5754 error ("instance variable `%s' is declared %s",
5755 IDENTIFIER_POINTER (identifier),
5756 TREE_PRIVATE (decl) ? "private" : "protected");
5757 return 0;
5761 else if (objc_implementation_context && (basetype == objc_object_reference))
5763 TREE_TYPE (expr) = uprivate_record;
5764 warning ("static access to object of type `id'");
5768 return 1;
5771 /* Implement @defs (<classname>) within struct bodies. */
5773 tree
5774 get_class_ivars (interface)
5775 tree interface;
5777 /* Make sure we copy the leaf ivars in case @defs is used in a local
5778 context. Otherwise finish_struct will overwrite the layout info
5779 using temporary storage. */
5780 return build_ivar_chain (interface, 1);
5783 /* Make sure all entries in CHAIN are also in LIST. */
5785 static int
5786 check_methods (chain, list, mtype)
5787 tree chain;
5788 tree list;
5789 int mtype;
5791 int first = 1;
5793 while (chain)
5795 if (!lookup_method (list, chain))
5797 if (first)
5799 if (TREE_CODE (objc_implementation_context)
5800 == CLASS_IMPLEMENTATION_TYPE)
5801 warning ("incomplete implementation of class `%s'",
5802 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5803 else if (TREE_CODE (objc_implementation_context)
5804 == CATEGORY_IMPLEMENTATION_TYPE)
5805 warning ("incomplete implementation of category `%s'",
5806 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5807 first = 0;
5810 warning ("method definition for `%c%s' not found",
5811 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5814 chain = TREE_CHAIN (chain);
5817 return first;
5820 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5822 static int
5823 conforms_to_protocol (class, protocol)
5824 tree class;
5825 tree protocol;
5827 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5829 tree p = CLASS_PROTOCOL_LIST (class);
5830 while (p && TREE_VALUE (p) != protocol)
5831 p = TREE_CHAIN (p);
5833 if (!p)
5835 tree super = (CLASS_SUPER_NAME (class)
5836 ? lookup_interface (CLASS_SUPER_NAME (class))
5837 : NULL_TREE);
5838 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5839 if (!tmp)
5840 return 0;
5844 return 1;
5847 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5848 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5850 static int
5851 check_methods_accessible (chain, context, mtype)
5852 tree chain;
5853 tree context;
5854 int mtype;
5856 int first = 1;
5857 tree list;
5858 tree base_context = context;
5860 while (chain)
5862 context = base_context;
5863 while (context)
5865 if (mtype == '+')
5866 list = CLASS_CLS_METHODS (context);
5867 else
5868 list = CLASS_NST_METHODS (context);
5870 if (lookup_method (list, chain))
5871 break;
5873 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5874 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5875 context = (CLASS_SUPER_NAME (context)
5876 ? lookup_interface (CLASS_SUPER_NAME (context))
5877 : NULL_TREE);
5879 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5880 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5881 context = (CLASS_NAME (context)
5882 ? lookup_interface (CLASS_NAME (context))
5883 : NULL_TREE);
5884 else
5885 abort ();
5888 if (context == NULL_TREE)
5890 if (first)
5892 if (TREE_CODE (objc_implementation_context)
5893 == CLASS_IMPLEMENTATION_TYPE)
5894 warning ("incomplete implementation of class `%s'",
5895 IDENTIFIER_POINTER
5896 (CLASS_NAME (objc_implementation_context)));
5897 else if (TREE_CODE (objc_implementation_context)
5898 == CATEGORY_IMPLEMENTATION_TYPE)
5899 warning ("incomplete implementation of category `%s'",
5900 IDENTIFIER_POINTER
5901 (CLASS_SUPER_NAME (objc_implementation_context)));
5902 first = 0;
5904 warning ("method definition for `%c%s' not found",
5905 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5908 chain = TREE_CHAIN (chain); /* next method... */
5910 return first;
5913 /* Check whether the current interface (accessible via
5914 'objc_implementation_context') actually implements protocol P, along
5915 with any protocols that P inherits. */
5917 static void
5918 check_protocol (p, type, name)
5919 tree p;
5920 const char *type;
5921 const char *name;
5923 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5925 int f1, f2;
5927 /* Ensure that all protocols have bodies! */
5928 if (flag_warn_protocol)
5930 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5931 CLASS_CLS_METHODS (objc_implementation_context),
5932 '+');
5933 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5934 CLASS_NST_METHODS (objc_implementation_context),
5935 '-');
5937 else
5939 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5940 objc_implementation_context,
5941 '+');
5942 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5943 objc_implementation_context,
5944 '-');
5947 if (!f1 || !f2)
5948 warning ("%s `%s' does not fully implement the `%s' protocol",
5949 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5952 /* Check protocols recursively. */
5953 if (PROTOCOL_LIST (p))
5955 tree subs = PROTOCOL_LIST (p);
5956 tree super_class =
5957 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5958 while (subs)
5960 tree sub = TREE_VALUE (subs);
5962 /* If the superclass does not conform to the protocols
5963 inherited by P, then we must! */
5964 if (!super_class || !conforms_to_protocol (super_class, sub))
5965 check_protocol (sub, type, name);
5966 subs = TREE_CHAIN (subs);
5971 /* Check whether the current interface (accessible via
5972 'objc_implementation_context') actually implements the protocols listed
5973 in PROTO_LIST. */
5975 static void
5976 check_protocols (proto_list, type, name)
5977 tree proto_list;
5978 const char *type;
5979 const char *name;
5981 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5983 tree p = TREE_VALUE (proto_list);
5985 check_protocol (p, type, name);
5989 /* Make sure that the class CLASS_NAME is defined
5990 CODE says which kind of thing CLASS_NAME ought to be.
5991 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5992 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5994 tree
5995 start_class (code, class_name, super_name, protocol_list)
5996 enum tree_code code;
5997 tree class_name;
5998 tree super_name;
5999 tree protocol_list;
6001 tree class, decl;
6003 if (objc_implementation_context)
6005 warning ("`@end' missing in implementation context");
6006 finish_class (objc_implementation_context);
6007 objc_ivar_chain = NULL_TREE;
6008 objc_implementation_context = NULL_TREE;
6011 class = make_node (code);
6012 TYPE_BINFO (class) = make_tree_vec (5);
6014 CLASS_NAME (class) = class_name;
6015 CLASS_SUPER_NAME (class) = super_name;
6016 CLASS_CLS_METHODS (class) = NULL_TREE;
6018 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6020 error ("`%s' redeclared as different kind of symbol",
6021 IDENTIFIER_POINTER (class_name));
6022 error_with_decl (decl, "previous declaration of `%s'");
6025 if (code == CLASS_IMPLEMENTATION_TYPE)
6028 tree chain;
6030 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6031 if (TREE_VALUE (chain) == class_name)
6033 error ("reimplementation of class `%s'",
6034 IDENTIFIER_POINTER (class_name));
6035 return error_mark_node;
6037 implemented_classes = tree_cons (NULL_TREE, class_name,
6038 implemented_classes);
6041 /* Pre-build the following entities - for speed/convenience. */
6042 if (!self_id)
6043 self_id = get_identifier ("self");
6044 if (!ucmd_id)
6045 ucmd_id = get_identifier ("_cmd");
6046 if (!unused_list)
6047 unused_list
6048 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6049 if (!objc_super_template)
6050 objc_super_template = build_super_template ();
6052 /* Reset for multiple classes per file. */
6053 method_slot = 0;
6055 objc_implementation_context = class;
6057 /* Lookup the interface for this implementation. */
6059 if (!(implementation_template = lookup_interface (class_name)))
6061 warning ("cannot find interface declaration for `%s'",
6062 IDENTIFIER_POINTER (class_name));
6063 add_class (implementation_template = objc_implementation_context);
6066 /* If a super class has been specified in the implementation,
6067 insure it conforms to the one specified in the interface. */
6069 if (super_name
6070 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6072 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6073 const char *const name =
6074 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6075 error ("conflicting super class name `%s'",
6076 IDENTIFIER_POINTER (super_name));
6077 error ("previous declaration of `%s'", name);
6080 else if (! super_name)
6082 CLASS_SUPER_NAME (objc_implementation_context)
6083 = CLASS_SUPER_NAME (implementation_template);
6087 else if (code == CLASS_INTERFACE_TYPE)
6089 if (lookup_interface (class_name))
6090 warning ("duplicate interface declaration for class `%s'",
6091 IDENTIFIER_POINTER (class_name));
6092 else
6093 add_class (class);
6095 if (protocol_list)
6096 CLASS_PROTOCOL_LIST (class)
6097 = lookup_and_install_protocols (protocol_list);
6100 else if (code == CATEGORY_INTERFACE_TYPE)
6102 tree class_category_is_assoc_with;
6104 /* For a category, class_name is really the name of the class that
6105 the following set of methods will be associated with. We must
6106 find the interface so that can derive the objects template. */
6108 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6110 error ("cannot find interface declaration for `%s'",
6111 IDENTIFIER_POINTER (class_name));
6112 exit (FATAL_EXIT_CODE);
6114 else
6115 add_category (class_category_is_assoc_with, class);
6117 if (protocol_list)
6118 CLASS_PROTOCOL_LIST (class)
6119 = lookup_and_install_protocols (protocol_list);
6122 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6124 /* Pre-build the following entities for speed/convenience. */
6125 if (!self_id)
6126 self_id = get_identifier ("self");
6127 if (!ucmd_id)
6128 ucmd_id = get_identifier ("_cmd");
6129 if (!unused_list)
6130 unused_list
6131 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6132 if (!objc_super_template)
6133 objc_super_template = build_super_template ();
6135 /* Reset for multiple classes per file. */
6136 method_slot = 0;
6138 objc_implementation_context = class;
6140 /* For a category, class_name is really the name of the class that
6141 the following set of methods will be associated with. We must
6142 find the interface so that can derive the objects template. */
6144 if (!(implementation_template = lookup_interface (class_name)))
6146 error ("cannot find interface declaration for `%s'",
6147 IDENTIFIER_POINTER (class_name));
6148 exit (FATAL_EXIT_CODE);
6151 return class;
6154 tree
6155 continue_class (class)
6156 tree class;
6158 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6159 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6161 struct imp_entry *imp_entry;
6162 tree ivar_context;
6164 /* Check consistency of the instance variables. */
6166 if (CLASS_IVARS (class))
6167 check_ivars (implementation_template, class);
6169 /* code generation */
6171 ivar_context = build_private_template (implementation_template);
6173 if (!objc_class_template)
6174 build_class_template ();
6176 imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry));
6178 imp_entry->next = imp_list;
6179 imp_entry->imp_context = class;
6180 imp_entry->imp_template = implementation_template;
6182 synth_forward_declarations ();
6183 imp_entry->class_decl = UOBJC_CLASS_decl;
6184 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6186 /* Append to front and increment count. */
6187 imp_list = imp_entry;
6188 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6189 imp_count++;
6190 else
6191 cat_count++;
6193 return ivar_context;
6196 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6198 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6200 if (!TYPE_FIELDS (record))
6202 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6203 CLASS_STATIC_TEMPLATE (class) = record;
6205 /* Mark this record as a class template for static typing. */
6206 TREE_STATIC_TEMPLATE (record) = 1;
6209 return NULL_TREE;
6212 else
6213 return error_mark_node;
6216 /* This is called once we see the "@end" in an interface/implementation. */
6218 void
6219 finish_class (class)
6220 tree class;
6222 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6224 /* All code generation is done in finish_objc. */
6226 if (implementation_template != objc_implementation_context)
6228 /* Ensure that all method listed in the interface contain bodies. */
6229 check_methods (CLASS_CLS_METHODS (implementation_template),
6230 CLASS_CLS_METHODS (objc_implementation_context), '+');
6231 check_methods (CLASS_NST_METHODS (implementation_template),
6232 CLASS_NST_METHODS (objc_implementation_context), '-');
6234 if (CLASS_PROTOCOL_LIST (implementation_template))
6235 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6236 "class",
6237 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6241 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6243 tree category = CLASS_CATEGORY_LIST (implementation_template);
6245 /* Find the category interface from the class it is associated with. */
6246 while (category)
6248 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6249 break;
6250 category = CLASS_CATEGORY_LIST (category);
6253 if (category)
6255 /* Ensure all method listed in the interface contain bodies. */
6256 check_methods (CLASS_CLS_METHODS (category),
6257 CLASS_CLS_METHODS (objc_implementation_context), '+');
6258 check_methods (CLASS_NST_METHODS (category),
6259 CLASS_NST_METHODS (objc_implementation_context), '-');
6261 if (CLASS_PROTOCOL_LIST (category))
6262 check_protocols (CLASS_PROTOCOL_LIST (category),
6263 "category",
6264 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6268 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6270 tree decl_specs;
6271 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6272 char *string = (char *) alloca (strlen (class_name) + 3);
6274 /* extern struct objc_object *_<my_name>; */
6276 sprintf (string, "_%s", class_name);
6278 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6279 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6280 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6281 decl_specs);
6285 static tree
6286 add_protocol (protocol)
6287 tree protocol;
6289 /* Put protocol on list in reverse order. */
6290 TREE_CHAIN (protocol) = protocol_chain;
6291 protocol_chain = protocol;
6292 return protocol_chain;
6295 static tree
6296 lookup_protocol (ident)
6297 tree ident;
6299 tree chain;
6301 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6303 if (ident == PROTOCOL_NAME (chain))
6304 return chain;
6307 return NULL_TREE;
6310 /* This function forward declares the protocols named by NAMES. If
6311 they are already declared or defined, the function has no effect. */
6313 void
6314 objc_declare_protocols (names)
6315 tree names;
6317 tree list;
6319 for (list = names; list; list = TREE_CHAIN (list))
6321 tree name = TREE_VALUE (list);
6323 if (lookup_protocol (name) == NULL_TREE)
6325 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6327 TYPE_BINFO (protocol) = make_tree_vec (2);
6328 PROTOCOL_NAME (protocol) = name;
6329 PROTOCOL_LIST (protocol) = NULL_TREE;
6330 add_protocol (protocol);
6331 PROTOCOL_DEFINED (protocol) = 0;
6332 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6337 tree
6338 start_protocol (code, name, list)
6339 enum tree_code code;
6340 tree name;
6341 tree list;
6343 tree protocol;
6345 /* This is as good a place as any. Need to invoke
6346 push_tag_toplevel. */
6347 if (!objc_protocol_template)
6348 objc_protocol_template = build_protocol_template ();
6350 protocol = lookup_protocol (name);
6352 if (!protocol)
6354 protocol = make_node (code);
6355 TYPE_BINFO (protocol) = make_tree_vec (2);
6357 PROTOCOL_NAME (protocol) = name;
6358 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6359 add_protocol (protocol);
6360 PROTOCOL_DEFINED (protocol) = 1;
6361 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6363 check_protocol_recursively (protocol, list);
6365 else if (! PROTOCOL_DEFINED (protocol))
6367 PROTOCOL_DEFINED (protocol) = 1;
6368 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6370 check_protocol_recursively (protocol, list);
6372 else
6374 warning ("duplicate declaration for protocol `%s'",
6375 IDENTIFIER_POINTER (name));
6377 return protocol;
6380 void
6381 finish_protocol (protocol)
6382 tree protocol ATTRIBUTE_UNUSED;
6387 /* "Encode" a data type into a string, which grows in util_obstack.
6388 ??? What is the FORMAT? Someone please document this! */
6390 static void
6391 encode_type_qualifiers (declspecs)
6392 tree declspecs;
6394 tree spec;
6396 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6398 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6399 obstack_1grow (&util_obstack, 'r');
6400 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6401 obstack_1grow (&util_obstack, 'n');
6402 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6403 obstack_1grow (&util_obstack, 'N');
6404 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6405 obstack_1grow (&util_obstack, 'o');
6406 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6407 obstack_1grow (&util_obstack, 'O');
6408 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6409 obstack_1grow (&util_obstack, 'R');
6410 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6411 obstack_1grow (&util_obstack, 'V');
6415 /* Encode a pointer type. */
6417 static void
6418 encode_pointer (type, curtype, format)
6419 tree type;
6420 int curtype;
6421 int format;
6423 tree pointer_to = TREE_TYPE (type);
6425 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6427 if (TYPE_NAME (pointer_to)
6428 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6430 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6432 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6434 obstack_1grow (&util_obstack, '@');
6435 return;
6437 else if (TREE_STATIC_TEMPLATE (pointer_to))
6439 if (generating_instance_variables)
6441 obstack_1grow (&util_obstack, '@');
6442 obstack_1grow (&util_obstack, '"');
6443 obstack_grow (&util_obstack, name, strlen (name));
6444 obstack_1grow (&util_obstack, '"');
6445 return;
6447 else
6449 obstack_1grow (&util_obstack, '@');
6450 return;
6453 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6455 obstack_1grow (&util_obstack, '#');
6456 return;
6458 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6460 obstack_1grow (&util_obstack, ':');
6461 return;
6465 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6466 && TYPE_MODE (pointer_to) == QImode)
6468 obstack_1grow (&util_obstack, '*');
6469 return;
6472 /* We have a type that does not get special treatment. */
6474 /* NeXT extension */
6475 obstack_1grow (&util_obstack, '^');
6476 encode_type (pointer_to, curtype, format);
6479 static void
6480 encode_array (type, curtype, format)
6481 tree type;
6482 int curtype;
6483 int format;
6485 tree an_int_cst = TYPE_SIZE (type);
6486 tree array_of = TREE_TYPE (type);
6487 char buffer[40];
6489 /* An incomplete array is treated like a pointer. */
6490 if (an_int_cst == NULL)
6492 encode_pointer (type, curtype, format);
6493 return;
6496 sprintf (buffer, "[%ld",
6497 (long) (TREE_INT_CST_LOW (an_int_cst)
6498 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6500 obstack_grow (&util_obstack, buffer, strlen (buffer));
6501 encode_type (array_of, curtype, format);
6502 obstack_1grow (&util_obstack, ']');
6503 return;
6506 static void
6507 encode_aggregate_within (type, curtype, format, left, right)
6508 tree type;
6509 int curtype;
6510 int format;
6511 int left;
6512 int right;
6514 /* The RECORD_TYPE may in fact be a typedef! For purposes
6515 of encoding, we need the real underlying enchilada. */
6516 if (TYPE_MAIN_VARIANT (type))
6517 type = TYPE_MAIN_VARIANT (type);
6519 if (obstack_object_size (&util_obstack) > 0
6520 && *(obstack_next_free (&util_obstack) - 1) == '^')
6522 tree name = TYPE_NAME (type);
6524 /* we have a reference; this is a NeXT extension. */
6526 if (obstack_object_size (&util_obstack) - curtype == 1
6527 && format == OBJC_ENCODE_INLINE_DEFS)
6529 /* Output format of struct for first level only. */
6530 tree fields = TYPE_FIELDS (type);
6532 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6534 obstack_1grow (&util_obstack, left);
6535 obstack_grow (&util_obstack,
6536 IDENTIFIER_POINTER (name),
6537 strlen (IDENTIFIER_POINTER (name)));
6538 obstack_1grow (&util_obstack, '=');
6540 else
6542 obstack_1grow (&util_obstack, left);
6543 obstack_grow (&util_obstack, "?=", 2);
6546 for ( ; fields; fields = TREE_CHAIN (fields))
6547 encode_field_decl (fields, curtype, format);
6549 obstack_1grow (&util_obstack, right);
6552 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6554 obstack_1grow (&util_obstack, left);
6555 obstack_grow (&util_obstack,
6556 IDENTIFIER_POINTER (name),
6557 strlen (IDENTIFIER_POINTER (name)));
6558 obstack_1grow (&util_obstack, right);
6561 else
6563 /* We have an untagged structure or a typedef. */
6564 obstack_1grow (&util_obstack, left);
6565 obstack_1grow (&util_obstack, '?');
6566 obstack_1grow (&util_obstack, right);
6570 else
6572 tree name = TYPE_NAME (type);
6573 tree fields = TYPE_FIELDS (type);
6575 if (format == OBJC_ENCODE_INLINE_DEFS
6576 || generating_instance_variables)
6578 obstack_1grow (&util_obstack, left);
6579 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6580 obstack_grow (&util_obstack,
6581 IDENTIFIER_POINTER (name),
6582 strlen (IDENTIFIER_POINTER (name)));
6583 else
6584 obstack_1grow (&util_obstack, '?');
6586 obstack_1grow (&util_obstack, '=');
6588 for (; fields; fields = TREE_CHAIN (fields))
6590 if (generating_instance_variables)
6592 tree fname = DECL_NAME (fields);
6594 obstack_1grow (&util_obstack, '"');
6595 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6597 obstack_grow (&util_obstack,
6598 IDENTIFIER_POINTER (fname),
6599 strlen (IDENTIFIER_POINTER (fname)));
6602 obstack_1grow (&util_obstack, '"');
6605 encode_field_decl (fields, curtype, format);
6608 obstack_1grow (&util_obstack, right);
6611 else
6613 obstack_1grow (&util_obstack, left);
6614 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6615 obstack_grow (&util_obstack,
6616 IDENTIFIER_POINTER (name),
6617 strlen (IDENTIFIER_POINTER (name)));
6618 else
6619 /* We have an untagged structure or a typedef. */
6620 obstack_1grow (&util_obstack, '?');
6622 obstack_1grow (&util_obstack, right);
6627 static void
6628 encode_aggregate (type, curtype, format)
6629 tree type;
6630 int curtype;
6631 int format;
6633 enum tree_code code = TREE_CODE (type);
6635 switch (code)
6637 case RECORD_TYPE:
6639 encode_aggregate_within(type, curtype, format, '{', '}');
6640 break;
6642 case UNION_TYPE:
6644 encode_aggregate_within(type, curtype, format, '(', ')');
6645 break;
6648 case ENUMERAL_TYPE:
6649 obstack_1grow (&util_obstack, 'i');
6650 break;
6652 default:
6653 break;
6657 /* Support bitfields. The current version of Objective-C does not support
6658 them. The string will consist of one or more "b:n"'s where n is an
6659 integer describing the width of the bitfield. Currently, classes in
6660 the kit implement a method "-(char *)describeBitfieldStruct:" that
6661 simulates this. If they do not implement this method, the archiver
6662 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6663 according to the GNU compiler. After looking at the "kit", it appears
6664 that all classes currently rely on this default behavior, rather than
6665 hand generating this string (which is tedious). */
6667 static void
6668 encode_bitfield (width)
6669 int width;
6671 char buffer[40];
6672 sprintf (buffer, "b%d", width);
6673 obstack_grow (&util_obstack, buffer, strlen (buffer));
6676 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6678 static void
6679 encode_type (type, curtype, format)
6680 tree type;
6681 int curtype;
6682 int format;
6684 enum tree_code code = TREE_CODE (type);
6686 if (code == INTEGER_TYPE)
6688 if (integer_zerop (TYPE_MIN_VALUE (type)))
6690 /* Unsigned integer types. */
6692 if (TYPE_MODE (type) == QImode)
6693 obstack_1grow (&util_obstack, 'C');
6694 else if (TYPE_MODE (type) == HImode)
6695 obstack_1grow (&util_obstack, 'S');
6696 else if (TYPE_MODE (type) == SImode)
6698 if (type == long_unsigned_type_node)
6699 obstack_1grow (&util_obstack, 'L');
6700 else
6701 obstack_1grow (&util_obstack, 'I');
6703 else if (TYPE_MODE (type) == DImode)
6704 obstack_1grow (&util_obstack, 'Q');
6707 else
6708 /* Signed 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_integer_type_node)
6717 obstack_1grow (&util_obstack, 'l');
6718 else
6719 obstack_1grow (&util_obstack, 'i');
6722 else if (TYPE_MODE (type) == DImode)
6723 obstack_1grow (&util_obstack, 'q');
6727 else if (code == REAL_TYPE)
6729 /* Floating point types. */
6731 if (TYPE_MODE (type) == SFmode)
6732 obstack_1grow (&util_obstack, 'f');
6733 else if (TYPE_MODE (type) == DFmode
6734 || TYPE_MODE (type) == TFmode)
6735 obstack_1grow (&util_obstack, 'd');
6738 else if (code == VOID_TYPE)
6739 obstack_1grow (&util_obstack, 'v');
6741 else if (code == ARRAY_TYPE)
6742 encode_array (type, curtype, format);
6744 else if (code == POINTER_TYPE)
6745 encode_pointer (type, curtype, format);
6747 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6748 encode_aggregate (type, curtype, format);
6750 else if (code == FUNCTION_TYPE) /* '?' */
6751 obstack_1grow (&util_obstack, '?');
6754 static void
6755 encode_complete_bitfield (int position, tree type, int size)
6757 enum tree_code code = TREE_CODE (type);
6758 char buffer[40];
6759 char charType = '?';
6761 if (code == INTEGER_TYPE)
6763 if (integer_zerop (TYPE_MIN_VALUE (type)))
6765 /* Unsigned integer types. */
6767 if (TYPE_MODE (type) == QImode)
6768 charType = 'C';
6769 else if (TYPE_MODE (type) == HImode)
6770 charType = 'S';
6771 else if (TYPE_MODE (type) == SImode)
6773 if (type == long_unsigned_type_node)
6774 charType = 'L';
6775 else
6776 charType = 'I';
6778 else if (TYPE_MODE (type) == DImode)
6779 charType = 'Q';
6782 else
6783 /* Signed integer types. */
6785 if (TYPE_MODE (type) == QImode)
6786 charType = 'c';
6787 else if (TYPE_MODE (type) == HImode)
6788 charType = 's';
6789 else if (TYPE_MODE (type) == SImode)
6791 if (type == long_integer_type_node)
6792 charType = 'l';
6793 else
6794 charType = 'i';
6797 else if (TYPE_MODE (type) == DImode)
6798 charType = 'q';
6802 else
6803 abort ();
6805 sprintf (buffer, "b%d%c%d", position, charType, size);
6806 obstack_grow (&util_obstack, buffer, strlen (buffer));
6809 static void
6810 encode_field_decl (field_decl, curtype, format)
6811 tree field_decl;
6812 int curtype;
6813 int format;
6815 tree type;
6817 type = TREE_TYPE (field_decl);
6819 /* If this field is obviously a bitfield, or is a bitfield that has been
6820 clobbered to look like a ordinary integer mode, go ahead and generate
6821 the bitfield typing information. */
6822 if (flag_next_runtime)
6824 if (DECL_BIT_FIELD (field_decl))
6825 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6826 else
6827 encode_type (TREE_TYPE (field_decl), curtype, format);
6829 else
6831 if (DECL_BIT_FIELD (field_decl))
6832 encode_complete_bitfield (int_bit_position (field_decl),
6833 DECL_BIT_FIELD_TYPE (field_decl),
6834 tree_low_cst (DECL_SIZE (field_decl), 1));
6835 else
6836 encode_type (TREE_TYPE (field_decl), curtype, format);
6840 static tree
6841 expr_last (complex_expr)
6842 tree complex_expr;
6844 tree next;
6846 if (complex_expr)
6847 while ((next = TREE_OPERAND (complex_expr, 0)))
6848 complex_expr = next;
6850 return complex_expr;
6853 /* Transform a method definition into a function definition as follows:
6854 - synthesize the first two arguments, "self" and "_cmd". */
6856 void
6857 start_method_def (method)
6858 tree method;
6860 tree decl_specs;
6862 /* Required to implement _msgSuper. */
6863 objc_method_context = method;
6864 UOBJC_SUPER_decl = NULL_TREE;
6866 /* Must be called BEFORE start_function. */
6867 pushlevel (0);
6869 /* Generate prototype declarations for arguments..."new-style". */
6871 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6872 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6873 else
6874 /* Really a `struct objc_class *'. However, we allow people to
6875 assign to self, which changes its type midstream. */
6876 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6878 push_parm_decl (build_tree_list
6879 (build_tree_list (decl_specs,
6880 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6881 unused_list));
6883 decl_specs = build_tree_list (NULL_TREE,
6884 xref_tag (RECORD_TYPE,
6885 get_identifier (TAG_SELECTOR)));
6886 push_parm_decl (build_tree_list
6887 (build_tree_list (decl_specs,
6888 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6889 unused_list));
6891 /* Generate argument declarations if a keyword_decl. */
6892 if (METHOD_SEL_ARGS (method))
6894 tree arglist = METHOD_SEL_ARGS (method);
6897 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6898 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6900 if (arg_decl)
6902 tree last_expr = expr_last (arg_decl);
6904 /* Unite the abstract decl with its name. */
6905 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6906 push_parm_decl (build_tree_list
6907 (build_tree_list (arg_spec, arg_decl),
6908 NULL_TREE));
6910 /* Unhook: restore the abstract declarator. */
6911 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6914 else
6915 push_parm_decl (build_tree_list
6916 (build_tree_list (arg_spec,
6917 KEYWORD_ARG_NAME (arglist)),
6918 NULL_TREE));
6920 arglist = TREE_CHAIN (arglist);
6922 while (arglist);
6925 if (METHOD_ADD_ARGS (method) != NULL_TREE
6926 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6928 /* We have a variable length selector - in "prototype" format. */
6929 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6930 while (akey)
6932 /* This must be done prior to calling pushdecl. pushdecl is
6933 going to change our chain on us. */
6934 tree nextkey = TREE_CHAIN (akey);
6935 pushdecl (akey);
6936 akey = nextkey;
6941 static void
6942 warn_with_method (message, mtype, method)
6943 const char *message;
6944 int mtype;
6945 tree method;
6947 if (count_error (1) == 0)
6948 return;
6950 report_error_function (DECL_SOURCE_FILE (method));
6952 /* Add a readable method name to the warning. */
6953 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6954 DECL_SOURCE_LINE (method),
6955 "%s `%c%s'",
6956 message, mtype,
6957 gen_method_decl (method, errbuf));
6960 /* Return 1 if METHOD is consistent with PROTO. */
6962 static int
6963 comp_method_with_proto (method, proto)
6964 tree method, proto;
6966 /* Create a function template node at most once. */
6967 if (!function1_template)
6968 function1_template = make_node (FUNCTION_TYPE);
6970 /* Install argument types - normally set by build_function_type. */
6971 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6973 /* install return type */
6974 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6976 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6979 /* Return 1 if PROTO1 is consistent with PROTO2. */
6981 static int
6982 comp_proto_with_proto (proto0, proto1)
6983 tree proto0, proto1;
6985 /* Create a couple of function_template nodes at most once. */
6986 if (!function1_template)
6987 function1_template = make_node (FUNCTION_TYPE);
6988 if (!function2_template)
6989 function2_template = make_node (FUNCTION_TYPE);
6991 /* Install argument types; normally set by build_function_type. */
6992 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6993 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6995 /* Install return type. */
6996 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6997 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6999 return comptypes (function1_template, function2_template);
7002 /* - Generate an identifier for the function. the format is "_n_cls",
7003 where 1 <= n <= nMethods, and cls is the name the implementation we
7004 are processing.
7005 - Install the return type from the method declaration.
7006 - If we have a prototype, check for type consistency. */
7008 static void
7009 really_start_method (method, parmlist)
7010 tree method, parmlist;
7012 tree sc_spec, ret_spec, ret_decl, decl_specs;
7013 tree method_decl, method_id;
7014 const char *sel_name, *class_name, *cat_name;
7015 char *buf;
7017 /* Synth the storage class & assemble the return type. */
7018 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7019 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7020 decl_specs = chainon (sc_spec, ret_spec);
7022 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7023 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7024 cat_name = ((TREE_CODE (objc_implementation_context)
7025 == CLASS_IMPLEMENTATION_TYPE)
7026 ? NULL
7027 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7028 method_slot++;
7030 /* Make sure this is big enough for any plausible method label. */
7031 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7032 + (cat_name ? strlen (cat_name) : 0));
7034 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7035 class_name, cat_name, sel_name, method_slot);
7037 method_id = get_identifier (buf);
7039 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7041 /* Check the declarator portion of the return type for the method. */
7042 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7044 /* Unite the complex decl (specified in the abstract decl) with the
7045 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7046 tree save_expr = expr_last (ret_decl);
7048 TREE_OPERAND (save_expr, 0) = method_decl;
7049 method_decl = ret_decl;
7051 /* Fool the parser into thinking it is starting a function. */
7052 start_function (decl_specs, method_decl, NULL_TREE);
7054 /* Unhook: this has the effect of restoring the abstract declarator. */
7055 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7058 else
7060 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7062 /* Fool the parser into thinking it is starting a function. */
7063 start_function (decl_specs, method_decl, NULL_TREE);
7065 /* Unhook: this has the effect of restoring the abstract declarator. */
7066 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7069 METHOD_DEFINITION (method) = current_function_decl;
7071 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7073 if (implementation_template != objc_implementation_context)
7075 tree proto;
7077 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7078 proto = lookup_instance_method_static (implementation_template,
7079 METHOD_SEL_NAME (method));
7080 else
7081 proto = lookup_class_method_static (implementation_template,
7082 METHOD_SEL_NAME (method));
7084 if (proto && ! comp_method_with_proto (method, proto))
7086 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7088 warn_with_method ("conflicting types for", type, method);
7089 warn_with_method ("previous declaration of", type, proto);
7094 /* The following routine is always called...this "architecture" is to
7095 accommodate "old-style" variable length selectors.
7097 - a:a b:b // prototype ; id c; id d; // old-style. */
7099 void
7100 continue_method_def ()
7102 tree parmlist;
7104 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7105 /* We have a `, ...' immediately following the selector. */
7106 parmlist = get_parm_info (0);
7107 else
7108 parmlist = get_parm_info (1); /* place a `void_at_end' */
7110 /* Set self_decl from the first argument...this global is used by
7111 build_ivar_reference calling build_indirect_ref. */
7112 self_decl = TREE_PURPOSE (parmlist);
7114 poplevel (0, 0, 0);
7115 really_start_method (objc_method_context, parmlist);
7116 store_parm_decls ();
7119 /* Called by the parser, from the `pushlevel' production. */
7121 void
7122 add_objc_decls ()
7124 if (!UOBJC_SUPER_decl)
7126 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7127 build_tree_list (NULL_TREE,
7128 objc_super_template),
7129 0, NULL_TREE);
7131 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7133 /* This prevents `unused variable' warnings when compiling with -Wall. */
7134 TREE_USED (UOBJC_SUPER_decl) = 1;
7135 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7139 /* _n_Method (id self, SEL sel, ...)
7141 struct objc_super _S;
7142 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7143 } */
7145 tree
7146 get_super_receiver ()
7148 if (objc_method_context)
7150 tree super_expr, super_expr_list;
7152 /* Set receiver to self. */
7153 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7154 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7155 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7157 /* Set class to begin searching. */
7158 super_expr = build_component_ref (UOBJC_SUPER_decl,
7159 get_identifier ("class"));
7161 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7163 /* [_cls, __cls]Super are "pre-built" in
7164 synth_forward_declarations. */
7166 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7167 ((TREE_CODE (objc_method_context)
7168 == INSTANCE_METHOD_DECL)
7169 ? ucls_super_ref
7170 : uucls_super_ref));
7173 else
7174 /* We have a category. */
7176 tree super_name = CLASS_SUPER_NAME (implementation_template);
7177 tree super_class;
7179 /* Barf if super used in a category of Object. */
7180 if (!super_name)
7182 error ("no super class declared in interface for `%s'",
7183 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7184 return error_mark_node;
7187 if (flag_next_runtime)
7189 super_class = get_class_reference (super_name);
7190 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7191 super_class
7192 = build_component_ref (build_indirect_ref (super_class, "->"),
7193 get_identifier ("isa"));
7195 else
7197 add_class_reference (super_name);
7198 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7199 ? objc_get_class_decl : objc_get_meta_class_decl);
7200 assemble_external (super_class);
7201 super_class
7202 = build_function_call
7203 (super_class,
7204 build_tree_list
7205 (NULL_TREE,
7206 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7207 IDENTIFIER_POINTER (super_name))));
7210 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7211 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7214 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7216 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7217 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7219 return build_compound_expr (super_expr_list);
7221 else
7223 error ("[super ...] must appear in a method context");
7224 return error_mark_node;
7228 static tree
7229 encode_method_def (func_decl)
7230 tree func_decl;
7232 tree parms;
7233 int stack_size;
7234 HOST_WIDE_INT max_parm_end = 0;
7235 char buffer[40];
7236 tree result;
7238 /* Return type. */
7239 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7240 obstack_object_size (&util_obstack),
7241 OBJC_ENCODE_INLINE_DEFS);
7243 /* Stack size. */
7244 for (parms = DECL_ARGUMENTS (func_decl); parms;
7245 parms = TREE_CHAIN (parms))
7247 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7248 + int_size_in_bytes (TREE_TYPE (parms)));
7250 if (! offset_is_register && parm_end > max_parm_end)
7251 max_parm_end = parm_end;
7254 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7256 sprintf (buffer, "%d", stack_size);
7257 obstack_grow (&util_obstack, buffer, strlen (buffer));
7259 /* Argument types. */
7260 for (parms = DECL_ARGUMENTS (func_decl); parms;
7261 parms = TREE_CHAIN (parms))
7263 /* Type. */
7264 encode_type (TREE_TYPE (parms),
7265 obstack_object_size (&util_obstack),
7266 OBJC_ENCODE_INLINE_DEFS);
7268 /* Compute offset. */
7269 sprintf (buffer, "%d", forwarding_offset (parms));
7271 /* Indicate register. */
7272 if (offset_is_register)
7273 obstack_1grow (&util_obstack, '+');
7275 obstack_grow (&util_obstack, buffer, strlen (buffer));
7278 /* Null terminate string. */
7279 obstack_1grow (&util_obstack, 0);
7280 result = get_identifier (obstack_finish (&util_obstack));
7281 obstack_free (&util_obstack, util_firstobj);
7282 return result;
7285 static void
7286 objc_expand_function_end ()
7288 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7291 void
7292 finish_method_def ()
7294 lang_expand_function_end = objc_expand_function_end;
7295 finish_function (0);
7296 lang_expand_function_end = NULL;
7298 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7299 since the optimizer may find "may be used before set" errors. */
7300 objc_method_context = NULL_TREE;
7303 #if 0
7305 lang_report_error_function (decl)
7306 tree decl;
7308 if (objc_method_context)
7310 fprintf (stderr, "In method `%s'\n",
7311 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7312 return 1;
7315 else
7316 return 0;
7318 #endif
7320 static int
7321 is_complex_decl (type)
7322 tree type;
7324 return (TREE_CODE (type) == ARRAY_TYPE
7325 || TREE_CODE (type) == FUNCTION_TYPE
7326 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7330 /* Code to convert a decl node into text for a declaration in C. */
7332 static char tmpbuf[256];
7334 static void
7335 adorn_decl (decl, str)
7336 tree decl;
7337 char *str;
7339 enum tree_code code = TREE_CODE (decl);
7341 if (code == ARRAY_REF)
7343 tree an_int_cst = TREE_OPERAND (decl, 1);
7345 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7346 sprintf (str + strlen (str), "[%ld]",
7347 (long) TREE_INT_CST_LOW (an_int_cst));
7348 else
7349 strcat (str, "[]");
7352 else if (code == ARRAY_TYPE)
7354 tree an_int_cst = TYPE_SIZE (decl);
7355 tree array_of = TREE_TYPE (decl);
7357 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7358 sprintf (str + strlen (str), "[%ld]",
7359 (long) (TREE_INT_CST_LOW (an_int_cst)
7360 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7361 else
7362 strcat (str, "[]");
7365 else if (code == CALL_EXPR)
7367 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7369 strcat (str, "(");
7370 while (chain)
7372 gen_declaration_1 (chain, str);
7373 chain = TREE_CHAIN (chain);
7374 if (chain)
7375 strcat (str, ", ");
7377 strcat (str, ")");
7380 else if (code == FUNCTION_TYPE)
7382 tree chain = TYPE_ARG_TYPES (decl);
7384 strcat (str, "(");
7385 while (chain && TREE_VALUE (chain) != void_type_node)
7387 gen_declaration_1 (TREE_VALUE (chain), str);
7388 chain = TREE_CHAIN (chain);
7389 if (chain && TREE_VALUE (chain) != void_type_node)
7390 strcat (str, ", ");
7392 strcat (str, ")");
7395 else if (code == INDIRECT_REF)
7397 strcpy (tmpbuf, "*");
7398 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7400 tree chain;
7402 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7403 chain;
7404 chain = TREE_CHAIN (chain))
7406 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7408 strcat (tmpbuf, " ");
7409 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7412 if (str[0])
7413 strcat (tmpbuf, " ");
7415 strcat (tmpbuf, str);
7416 strcpy (str, tmpbuf);
7419 else if (code == POINTER_TYPE)
7421 strcpy (tmpbuf, "*");
7422 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7424 if (TREE_READONLY (decl))
7425 strcat (tmpbuf, " const");
7426 if (TYPE_VOLATILE (decl))
7427 strcat (tmpbuf, " volatile");
7428 if (str[0])
7429 strcat (tmpbuf, " ");
7431 strcat (tmpbuf, str);
7432 strcpy (str, tmpbuf);
7436 static char *
7437 gen_declarator (decl, buf, name)
7438 tree decl;
7439 char *buf;
7440 const char *name;
7442 if (decl)
7444 enum tree_code code = TREE_CODE (decl);
7445 char *str;
7446 tree op;
7447 int wrap = 0;
7449 switch (code)
7451 case ARRAY_REF:
7452 case INDIRECT_REF:
7453 case CALL_EXPR:
7454 op = TREE_OPERAND (decl, 0);
7456 /* We have a pointer to a function or array...(*)(), (*)[] */
7457 if ((code == ARRAY_REF || code == CALL_EXPR)
7458 && op && TREE_CODE (op) == INDIRECT_REF)
7459 wrap = 1;
7461 str = gen_declarator (op, buf, name);
7463 if (wrap)
7465 strcpy (tmpbuf, "(");
7466 strcat (tmpbuf, str);
7467 strcat (tmpbuf, ")");
7468 strcpy (str, tmpbuf);
7471 adorn_decl (decl, str);
7472 break;
7474 case ARRAY_TYPE:
7475 case FUNCTION_TYPE:
7476 case POINTER_TYPE:
7477 strcpy (buf, name);
7478 str = buf;
7480 /* This clause is done iteratively rather than recursively. */
7483 op = (is_complex_decl (TREE_TYPE (decl))
7484 ? TREE_TYPE (decl) : NULL_TREE);
7486 adorn_decl (decl, str);
7488 /* We have a pointer to a function or array...(*)(), (*)[] */
7489 if (code == POINTER_TYPE
7490 && op && (TREE_CODE (op) == FUNCTION_TYPE
7491 || TREE_CODE (op) == ARRAY_TYPE))
7493 strcpy (tmpbuf, "(");
7494 strcat (tmpbuf, str);
7495 strcat (tmpbuf, ")");
7496 strcpy (str, tmpbuf);
7499 decl = (is_complex_decl (TREE_TYPE (decl))
7500 ? TREE_TYPE (decl) : NULL_TREE);
7503 while (decl && (code = TREE_CODE (decl)))
7506 break;
7508 case IDENTIFIER_NODE:
7509 /* Will only happen if we are processing a "raw" expr-decl. */
7510 strcpy (buf, IDENTIFIER_POINTER (decl));
7511 return buf;
7513 default:
7514 abort ();
7517 return str;
7520 else
7521 /* We have an abstract declarator or a _DECL node. */
7523 strcpy (buf, name);
7524 return buf;
7528 static void
7529 gen_declspecs (declspecs, buf, raw)
7530 tree declspecs;
7531 char *buf;
7532 int raw;
7534 if (raw)
7536 tree chain;
7538 for (chain = nreverse (copy_list (declspecs));
7539 chain; chain = TREE_CHAIN (chain))
7541 tree aspec = TREE_VALUE (chain);
7543 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7544 strcat (buf, IDENTIFIER_POINTER (aspec));
7545 else if (TREE_CODE (aspec) == RECORD_TYPE)
7547 if (TYPE_NAME (aspec))
7549 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7551 if (! TREE_STATIC_TEMPLATE (aspec))
7552 strcat (buf, "struct ");
7553 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7555 /* NEW!!! */
7556 if (protocol_list)
7558 tree chain = protocol_list;
7560 strcat (buf, " <");
7561 while (chain)
7563 strcat (buf,
7564 IDENTIFIER_POINTER
7565 (PROTOCOL_NAME (TREE_VALUE (chain))));
7566 chain = TREE_CHAIN (chain);
7567 if (chain)
7568 strcat (buf, ", ");
7570 strcat (buf, ">");
7574 else
7575 strcat (buf, "untagged struct");
7578 else if (TREE_CODE (aspec) == UNION_TYPE)
7580 if (TYPE_NAME (aspec))
7582 if (! TREE_STATIC_TEMPLATE (aspec))
7583 strcat (buf, "union ");
7584 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7586 else
7587 strcat (buf, "untagged union");
7590 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7592 if (TYPE_NAME (aspec))
7594 if (! TREE_STATIC_TEMPLATE (aspec))
7595 strcat (buf, "enum ");
7596 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7598 else
7599 strcat (buf, "untagged enum");
7602 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7603 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7605 else if (IS_ID (aspec))
7607 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7609 strcat (buf, "id");
7610 if (protocol_list)
7612 tree chain = protocol_list;
7614 strcat (buf, " <");
7615 while (chain)
7617 strcat (buf,
7618 IDENTIFIER_POINTER
7619 (PROTOCOL_NAME (TREE_VALUE (chain))));
7620 chain = TREE_CHAIN (chain);
7621 if (chain)
7622 strcat (buf, ", ");
7624 strcat (buf, ">");
7627 if (TREE_CHAIN (chain))
7628 strcat (buf, " ");
7631 else
7633 /* Type qualifiers. */
7634 if (TREE_READONLY (declspecs))
7635 strcat (buf, "const ");
7636 if (TYPE_VOLATILE (declspecs))
7637 strcat (buf, "volatile ");
7639 switch (TREE_CODE (declspecs))
7641 /* Type specifiers. */
7643 case INTEGER_TYPE:
7644 declspecs = TYPE_MAIN_VARIANT (declspecs);
7646 /* Signed integer types. */
7648 if (declspecs == short_integer_type_node)
7649 strcat (buf, "short int ");
7650 else if (declspecs == integer_type_node)
7651 strcat (buf, "int ");
7652 else if (declspecs == long_integer_type_node)
7653 strcat (buf, "long int ");
7654 else if (declspecs == long_long_integer_type_node)
7655 strcat (buf, "long long int ");
7656 else if (declspecs == signed_char_type_node
7657 || declspecs == char_type_node)
7658 strcat (buf, "char ");
7660 /* Unsigned integer types. */
7662 else if (declspecs == short_unsigned_type_node)
7663 strcat (buf, "unsigned short ");
7664 else if (declspecs == unsigned_type_node)
7665 strcat (buf, "unsigned int ");
7666 else if (declspecs == long_unsigned_type_node)
7667 strcat (buf, "unsigned long ");
7668 else if (declspecs == long_long_unsigned_type_node)
7669 strcat (buf, "unsigned long long ");
7670 else if (declspecs == unsigned_char_type_node)
7671 strcat (buf, "unsigned char ");
7672 break;
7674 case REAL_TYPE:
7675 declspecs = TYPE_MAIN_VARIANT (declspecs);
7677 if (declspecs == float_type_node)
7678 strcat (buf, "float ");
7679 else if (declspecs == double_type_node)
7680 strcat (buf, "double ");
7681 else if (declspecs == long_double_type_node)
7682 strcat (buf, "long double ");
7683 break;
7685 case RECORD_TYPE:
7686 if (TYPE_NAME (declspecs)
7687 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7689 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7691 if (! TREE_STATIC_TEMPLATE (declspecs))
7692 strcat (buf, "struct ");
7693 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7695 if (protocol_list)
7697 tree chain = protocol_list;
7699 strcat (buf, " <");
7700 while (chain)
7702 strcat (buf,
7703 IDENTIFIER_POINTER
7704 (PROTOCOL_NAME (TREE_VALUE (chain))));
7705 chain = TREE_CHAIN (chain);
7706 if (chain)
7707 strcat (buf, ", ");
7709 strcat (buf, ">");
7713 else
7714 strcat (buf, "untagged struct");
7716 strcat (buf, " ");
7717 break;
7719 case UNION_TYPE:
7720 if (TYPE_NAME (declspecs)
7721 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7723 strcat (buf, "union ");
7724 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7725 strcat (buf, " ");
7728 else
7729 strcat (buf, "untagged union ");
7730 break;
7732 case ENUMERAL_TYPE:
7733 if (TYPE_NAME (declspecs)
7734 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7736 strcat (buf, "enum ");
7737 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7738 strcat (buf, " ");
7741 else
7742 strcat (buf, "untagged enum ");
7743 break;
7745 case VOID_TYPE:
7746 strcat (buf, "void ");
7747 break;
7749 case POINTER_TYPE:
7751 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7753 strcat (buf, "id");
7754 if (protocol_list)
7756 tree chain = protocol_list;
7758 strcat (buf, " <");
7759 while (chain)
7761 strcat (buf,
7762 IDENTIFIER_POINTER
7763 (PROTOCOL_NAME (TREE_VALUE (chain))));
7764 chain = TREE_CHAIN (chain);
7765 if (chain)
7766 strcat (buf, ", ");
7769 strcat (buf, ">");
7772 break;
7774 default:
7775 break;
7780 /* Given a tree node, produce a printable description of it in the given
7781 buffer, overwriting the buffer. */
7783 static char *
7784 gen_declaration (atype_or_adecl, buf)
7785 tree atype_or_adecl;
7786 char *buf;
7788 buf[0] = '\0';
7789 gen_declaration_1 (atype_or_adecl, buf);
7790 return buf;
7793 /* Given a tree node, append a printable description to the end of the
7794 given buffer. */
7796 static void
7797 gen_declaration_1 (atype_or_adecl, buf)
7798 tree atype_or_adecl;
7799 char *buf;
7801 char declbuf[256];
7803 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7805 tree declspecs; /* "identifier_node", "record_type" */
7806 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7808 /* We have a "raw", abstract declarator (typename). */
7809 declarator = TREE_VALUE (atype_or_adecl);
7810 declspecs = TREE_PURPOSE (atype_or_adecl);
7812 gen_declspecs (declspecs, buf, 1);
7813 if (declarator)
7815 strcat (buf, " ");
7816 strcat (buf, gen_declarator (declarator, declbuf, ""));
7820 else
7822 tree atype;
7823 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7824 tree declarator; /* "array_type", "function_type", "pointer_type". */
7826 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7827 || TREE_CODE (atype_or_adecl) == PARM_DECL
7828 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7829 atype = TREE_TYPE (atype_or_adecl);
7830 else
7831 /* Assume we have a *_type node. */
7832 atype = atype_or_adecl;
7834 if (is_complex_decl (atype))
7836 tree chain;
7838 /* Get the declaration specifier; it is at the end of the list. */
7839 declarator = chain = atype;
7841 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7842 while (is_complex_decl (chain));
7843 declspecs = chain;
7846 else
7848 declspecs = atype;
7849 declarator = NULL_TREE;
7852 gen_declspecs (declspecs, buf, 0);
7854 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7855 || TREE_CODE (atype_or_adecl) == PARM_DECL
7856 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7858 const char *const decl_name =
7859 (DECL_NAME (atype_or_adecl)
7860 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7862 if (declarator)
7864 strcat (buf, " ");
7865 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7868 else if (decl_name[0])
7870 strcat (buf, " ");
7871 strcat (buf, decl_name);
7874 else if (declarator)
7876 strcat (buf, " ");
7877 strcat (buf, gen_declarator (declarator, declbuf, ""));
7882 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7884 /* Given a method tree, put a printable description into the given
7885 buffer (overwriting) and return a pointer to the buffer. */
7887 static char *
7888 gen_method_decl (method, buf)
7889 tree method;
7890 char *buf;
7892 tree chain;
7894 buf[0] = '\0';
7895 if (RAW_TYPESPEC (method) != objc_object_reference)
7897 strcat (buf, "(");
7898 gen_declaration_1 (TREE_TYPE (method), buf);
7899 strcat (buf, ")");
7902 chain = METHOD_SEL_ARGS (method);
7903 if (chain)
7905 /* We have a chain of keyword_decls. */
7908 if (KEYWORD_KEY_NAME (chain))
7909 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7911 strcat (buf, ":");
7912 if (RAW_TYPESPEC (chain) != objc_object_reference)
7914 strcat (buf, "(");
7915 gen_declaration_1 (TREE_TYPE (chain), buf);
7916 strcat (buf, ")");
7919 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7920 if ((chain = TREE_CHAIN (chain)))
7921 strcat (buf, " ");
7923 while (chain);
7925 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7926 strcat (buf, ", ...");
7927 else if (METHOD_ADD_ARGS (method))
7929 /* We have a tree list node as generate by get_parm_info. */
7930 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7932 /* Know we have a chain of parm_decls. */
7933 while (chain)
7935 strcat (buf, ", ");
7936 gen_declaration_1 (chain, buf);
7937 chain = TREE_CHAIN (chain);
7942 else
7943 /* We have a unary selector. */
7944 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7946 return buf;
7949 /* Debug info. */
7951 static void
7952 dump_interface (fp, chain)
7953 FILE *fp;
7954 tree chain;
7956 char *buf = (char *)xmalloc (256);
7957 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7958 tree ivar_decls = CLASS_RAW_IVARS (chain);
7959 tree nst_methods = CLASS_NST_METHODS (chain);
7960 tree cls_methods = CLASS_CLS_METHODS (chain);
7962 fprintf (fp, "\n@interface %s", my_name);
7964 if (CLASS_SUPER_NAME (chain))
7966 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7967 fprintf (fp, " : %s\n", super_name);
7969 else
7970 fprintf (fp, "\n");
7972 if (ivar_decls)
7974 fprintf (fp, "{\n");
7977 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7978 ivar_decls = TREE_CHAIN (ivar_decls);
7980 while (ivar_decls);
7981 fprintf (fp, "}\n");
7984 while (nst_methods)
7986 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7987 nst_methods = TREE_CHAIN (nst_methods);
7990 while (cls_methods)
7992 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7993 cls_methods = TREE_CHAIN (cls_methods);
7995 fprintf (fp, "\n@end");
7998 /* Demangle function for Objective-C */
7999 static const char *
8000 objc_demangle (mangled)
8001 const char *mangled;
8003 char *demangled, *cp;
8005 if (mangled[0] == '_' &&
8006 (mangled[1] == 'i' || mangled[1] == 'c') &&
8007 mangled[2] == '_')
8009 cp = demangled = xmalloc(strlen(mangled) + 2);
8010 if (mangled[1] == 'i')
8011 *cp++ = '-'; /* for instance method */
8012 else
8013 *cp++ = '+'; /* for class method */
8014 *cp++ = '['; /* opening left brace */
8015 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8016 while (*cp && *cp == '_')
8017 cp++; /* skip any initial underbars in class name */
8018 cp = strchr(cp, '_'); /* find first non-initial underbar */
8019 if (cp == NULL)
8021 free(demangled); /* not mangled name */
8022 return mangled;
8024 if (cp[1] == '_') /* easy case: no category name */
8026 *cp++ = ' '; /* replace two '_' with one ' ' */
8027 strcpy(cp, mangled + (cp - demangled) + 2);
8029 else
8031 *cp++ = '('; /* less easy case: category name */
8032 cp = strchr(cp, '_');
8033 if (cp == 0)
8035 free(demangled); /* not mangled name */
8036 return mangled;
8038 *cp++ = ')';
8039 *cp++ = ' '; /* overwriting 1st char of method name... */
8040 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8042 while (*cp && *cp == '_')
8043 cp++; /* skip any initial underbars in method name */
8044 for (; *cp; cp++)
8045 if (*cp == '_')
8046 *cp = ':'; /* replace remaining '_' with ':' */
8047 *cp++ = ']'; /* closing right brace */
8048 *cp++ = 0; /* string terminator */
8049 return demangled;
8051 else
8052 return mangled; /* not an objc mangled name */
8055 static const char *
8056 objc_printable_name (decl, kind)
8057 tree decl;
8058 int kind ATTRIBUTE_UNUSED;
8060 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8063 /* Adds the tree codes specific to the ObjC/ObjC++ front end to the
8064 list of all tree codes. */
8066 static void
8067 add_objc_tree_codes ()
8069 int add = (int) LAST_OBJC_TREE_CODE - (int) LAST_BASE_TREE_CODE;
8071 memcpy (tree_code_type + (int) LAST_BASE_TREE_CODE,
8072 objc_tree_code_type, add);
8073 memcpy (tree_code_length + (int) LAST_BASE_TREE_CODE,
8074 objc_tree_code_length, add * sizeof (int));
8075 memcpy (tree_code_name + (int) LAST_BASE_TREE_CODE,
8076 objc_tree_code_name, add * sizeof (char *));
8079 static void
8080 init_objc ()
8082 gcc_obstack_init (&util_obstack);
8083 util_firstobj = (char *) obstack_finish (&util_obstack);
8085 errbuf = (char *)xmalloc (BUFSIZE);
8086 hash_init ();
8087 synth_module_prologue ();
8090 static void
8091 finish_objc ()
8093 struct imp_entry *impent;
8094 tree chain;
8095 /* The internally generated initializers appear to have missing braces.
8096 Don't warn about this. */
8097 int save_warn_missing_braces = warn_missing_braces;
8098 warn_missing_braces = 0;
8100 /* A missing @end may not be detected by the parser. */
8101 if (objc_implementation_context)
8103 warning ("`@end' missing in implementation context");
8104 finish_class (objc_implementation_context);
8105 objc_ivar_chain = NULL_TREE;
8106 objc_implementation_context = NULL_TREE;
8109 generate_forward_declaration_to_string_table ();
8111 #ifdef OBJC_PROLOGUE
8112 OBJC_PROLOGUE;
8113 #endif
8115 /* Process the static instances here because initialization of objc_symtab
8116 depends on them. */
8117 if (objc_static_instances)
8118 generate_static_references ();
8120 if (imp_list || class_names_chain
8121 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8122 generate_objc_symtab_decl ();
8124 for (impent = imp_list; impent; impent = impent->next)
8126 objc_implementation_context = impent->imp_context;
8127 implementation_template = impent->imp_template;
8129 UOBJC_CLASS_decl = impent->class_decl;
8130 UOBJC_METACLASS_decl = impent->meta_decl;
8132 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8134 /* all of the following reference the string pool... */
8135 generate_ivar_lists ();
8136 generate_dispatch_tables ();
8137 generate_shared_structures ();
8139 else
8141 generate_dispatch_tables ();
8142 generate_category (objc_implementation_context);
8146 /* If we are using an array of selectors, we must always
8147 finish up the array decl even if no selectors were used. */
8148 if (! flag_next_runtime || sel_ref_chain)
8149 build_selector_translation_table ();
8151 if (protocol_chain)
8152 generate_protocols ();
8154 if (objc_implementation_context || class_names_chain || objc_static_instances
8155 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8157 /* Arrange for Objc data structures to be initialized at run time. */
8158 rtx init_sym = build_module_descriptor ();
8159 if (init_sym && targetm.have_ctors_dtors)
8160 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8163 /* Dump the class references. This forces the appropriate classes
8164 to be linked into the executable image, preserving unix archive
8165 semantics. This can be removed when we move to a more dynamically
8166 linked environment. */
8168 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8170 handle_class_ref (chain);
8171 if (TREE_PURPOSE (chain))
8172 generate_classref_translation_entry (chain);
8175 for (impent = imp_list; impent; impent = impent->next)
8176 handle_impent (impent);
8178 /* Dump the string table last. */
8180 generate_strings ();
8182 if (flag_gen_declaration)
8184 add_class (objc_implementation_context);
8185 dump_interface (gen_declaration_file, objc_implementation_context);
8188 if (warn_selector)
8190 int slot;
8191 hash hsh;
8193 /* Run through the selector hash tables and print a warning for any
8194 selector which has multiple methods. */
8196 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8197 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8198 if (hsh->list)
8200 tree meth = hsh->key;
8201 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8202 ? '-' : '+');
8203 attr loop;
8205 warning ("potential selector conflict for method `%s'",
8206 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8207 warn_with_method ("found", type, meth);
8208 for (loop = hsh->list; loop; loop = loop->next)
8209 warn_with_method ("found", type, loop->value);
8212 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8213 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8214 if (hsh->list)
8216 tree meth = hsh->key;
8217 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8218 ? '-' : '+');
8219 attr loop;
8221 warning ("potential selector conflict for method `%s'",
8222 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8223 warn_with_method ("found", type, meth);
8224 for (loop = hsh->list; loop; loop = loop->next)
8225 warn_with_method ("found", type, loop->value);
8229 warn_missing_braces = save_warn_missing_braces;
8232 /* Subroutines of finish_objc. */
8234 static void
8235 generate_classref_translation_entry (chain)
8236 tree chain;
8238 tree expr, name, decl_specs, decl, sc_spec;
8239 tree type;
8241 type = TREE_TYPE (TREE_PURPOSE (chain));
8243 expr = add_objc_string (TREE_VALUE (chain), class_names);
8244 expr = build_c_cast (type, expr); /* cast! */
8246 name = DECL_NAME (TREE_PURPOSE (chain));
8248 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8250 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8251 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8253 /* The decl that is returned from start_decl is the one that we
8254 forward declared in build_class_reference. */
8255 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8256 DECL_CONTEXT (decl) = NULL_TREE;
8257 finish_decl (decl, expr, NULL_TREE);
8258 return;
8261 static void
8262 handle_class_ref (chain)
8263 tree chain;
8265 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8266 char *string = (char *) alloca (strlen (name) + 30);
8267 tree decl;
8268 tree exp;
8270 sprintf (string, "%sobjc_class_name_%s",
8271 (flag_next_runtime ? "." : "__"), name);
8273 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8274 if (flag_next_runtime)
8276 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8277 return;
8279 #endif
8281 /* Make a decl for this name, so we can use its address in a tree. */
8282 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8283 DECL_EXTERNAL (decl) = 1;
8284 TREE_PUBLIC (decl) = 1;
8286 pushdecl (decl);
8287 rest_of_decl_compilation (decl, 0, 0, 0);
8289 /* Make a decl for the address. */
8290 sprintf (string, "%sobjc_class_ref_%s",
8291 (flag_next_runtime ? "." : "__"), name);
8292 exp = build1 (ADDR_EXPR, string_type_node, decl);
8293 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8294 DECL_INITIAL (decl) = exp;
8295 TREE_STATIC (decl) = 1;
8297 pushdecl (decl);
8298 rest_of_decl_compilation (decl, 0, 0, 0);
8301 static void
8302 handle_impent (impent)
8303 struct imp_entry *impent;
8305 char *string;
8307 objc_implementation_context = impent->imp_context;
8308 implementation_template = impent->imp_template;
8310 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8312 const char *const class_name =
8313 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8315 string = (char *) alloca (strlen (class_name) + 30);
8317 sprintf (string, "*%sobjc_class_name_%s",
8318 (flag_next_runtime ? "." : "__"), class_name);
8320 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8322 const char *const class_name =
8323 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8324 const char *const class_super_name =
8325 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8327 string = (char *) alloca (strlen (class_name)
8328 + strlen (class_super_name) + 30);
8330 /* Do the same for categories. Even though no references to
8331 these symbols are generated automatically by the compiler, it
8332 gives you a handle to pull them into an archive by hand. */
8333 sprintf (string, "*%sobjc_category_name_%s_%s",
8334 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8336 else
8337 return;
8339 #ifdef ASM_DECLARE_CLASS_REFERENCE
8340 if (flag_next_runtime)
8342 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8343 return;
8345 #endif
8347 /* (Should this be a routine in varasm.c?) */
8348 readonly_data_section ();
8349 assemble_global (string);
8350 assemble_align (UNITS_PER_WORD);
8351 assemble_label (string);
8352 assemble_zeros (UNITS_PER_WORD);
8355 static void
8356 ggc_mark_imp_list (arg)
8357 void *arg;
8359 struct imp_entry *impent;
8361 for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
8363 ggc_mark_tree (impent->imp_context);
8364 ggc_mark_tree (impent->imp_template);
8365 ggc_mark_tree (impent->class_decl);
8366 ggc_mark_tree (impent->meta_decl);
8370 static void
8371 ggc_mark_hash_table (arg)
8372 void *arg;
8374 hash *hash_table = *(hash **)arg;
8375 hash hst;
8376 attr list;
8377 int i;
8379 if (hash_table == NULL)
8380 return;
8381 for (i = 0; i < SIZEHASHTABLE; i++)
8382 for (hst = hash_table [i]; hst; hst = hst->next)
8384 ggc_mark_tree (hst->key);
8385 for (list = hst->list; list; list = list->next)
8386 ggc_mark_tree (list->value);
8390 /* Add GC roots for variables local to this file. */
8391 static void
8392 objc_act_parse_init ()
8394 ggc_add_tree_root (objc_global_trees, OCTI_MAX);
8395 ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
8396 ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
8397 ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
8400 /* Look up ID as an instance variable. */
8401 tree
8402 lookup_objc_ivar (id)
8403 tree id;
8405 tree decl;
8407 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8408 /* we have a message to super */
8409 return get_super_receiver ();
8410 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8412 if (is_private (decl))
8413 return error_mark_node;
8414 else
8415 return build_ivar_reference (id);
8417 else
8418 return 0;