objc-act.c (adjust_type_for_id_default): Do not allow an object as parameter.
[official-gcc.git] / gcc / objc / objc-act.c
blobe8f97ac4bcbe419a0f18d3d9c72efef1642ee35a
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
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-common.h"
49 #include "flags.h"
50 #include "objc-act.h"
51 #include "input.h"
52 #include "except.h"
53 #include "function.h"
54 #include "output.h"
55 #include "toplev.h"
56 #include "ggc.h"
57 #include "debug.h"
58 #include "target.h"
59 #include "diagnostic.h"
61 /* This is the default way of generating a method name. */
62 /* I am not sure it is really correct.
63 Perhaps there's a danger that it will make name conflicts
64 if method names contain underscores. -- rms. */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
67 do { \
68 char *temp; \
69 sprintf ((BUF), "_%s_%s_%s_%s", \
70 ((IS_INST) ? "i" : "c"), \
71 (CLASS_NAME), \
72 ((CAT_NAME)? (CAT_NAME) : ""), \
73 (SEL_NAME)); \
74 for (temp = (BUF); *temp; temp++) \
75 if (*temp == ':') *temp = '_'; \
76 } while (0)
77 #endif
79 /* These need specifying. */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
82 #endif
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
86 #endif
89 /* Set up for use of obstacks. */
91 #include "obstack.h"
93 #define obstack_chunk_alloc xmalloc
94 #define obstack_chunk_free free
96 /* This obstack is used to accumulate the encoding of a data type. */
97 static struct obstack util_obstack;
98 /* This points to the beginning of obstack contents,
99 so we can free the whole contents. */
100 char *util_firstobj;
102 /* for encode_method_def */
103 #include "rtl.h"
105 /* The version identifies which language generation and runtime
106 the module (file) was compiled for, and is recorded in the
107 module descriptor. */
109 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
110 #define PROTOCOL_VERSION 2
112 /* (Decide if these can ever be validly changed.) */
113 #define OBJC_ENCODE_INLINE_DEFS 0
114 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
116 /*** Private Interface (procedures) ***/
118 /* Used by compile_file. */
120 static void init_objc PARAMS ((void));
121 static void finish_objc PARAMS ((void));
123 /* Code generation. */
125 static void synth_module_prologue PARAMS ((void));
126 static tree build_constructor PARAMS ((tree, tree));
127 static rtx build_module_descriptor PARAMS ((void));
128 static tree init_module_descriptor PARAMS ((tree));
129 static tree build_objc_method_call PARAMS ((int, tree, tree,
130 tree, tree, tree));
131 static void generate_strings PARAMS ((void));
132 static tree get_proto_encoding PARAMS ((tree));
133 static void build_selector_translation_table PARAMS ((void));
134 static tree build_ivar_chain PARAMS ((tree, int));
136 static tree objc_add_static_instance PARAMS ((tree, tree));
138 static tree build_ivar_template PARAMS ((void));
139 static tree build_method_template PARAMS ((void));
140 static tree build_private_template PARAMS ((tree));
141 static void build_class_template PARAMS ((void));
142 static void build_selector_template PARAMS ((void));
143 static void build_category_template PARAMS ((void));
144 static tree build_super_template PARAMS ((void));
145 static tree build_category_initializer PARAMS ((tree, tree, tree,
146 tree, tree, tree));
147 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
148 tree, tree));
150 static void synth_forward_declarations PARAMS ((void));
151 static void generate_ivar_lists PARAMS ((void));
152 static void generate_dispatch_tables PARAMS ((void));
153 static void generate_shared_structures PARAMS ((void));
154 static tree generate_protocol_list PARAMS ((tree));
155 static void generate_forward_declaration_to_string_table PARAMS ((void));
156 static void build_protocol_reference PARAMS ((tree));
158 static tree build_keyword_selector PARAMS ((tree));
159 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
161 static void generate_static_references PARAMS ((void));
162 static int check_methods_accessible PARAMS ((tree, tree,
163 int));
164 static void encode_aggregate_within PARAMS ((tree, int, int,
165 int, int));
166 static const char *objc_demangle PARAMS ((const char *));
167 static void objc_expand_function_end PARAMS ((void));
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash *nst_method_hash_list = 0;
172 hash *cls_method_hash_list = 0;
174 static size_t hash_func PARAMS ((tree));
175 static void hash_init PARAMS ((void));
176 static void hash_enter PARAMS ((hash *, tree));
177 static hash hash_lookup PARAMS ((hash *, tree));
178 static void hash_add_attr PARAMS ((hash, tree));
179 static tree lookup_method PARAMS ((tree, tree));
180 static tree lookup_instance_method_static PARAMS ((tree, tree));
181 static tree lookup_class_method_static PARAMS ((tree, tree));
182 static tree add_class PARAMS ((tree));
183 static void add_category PARAMS ((tree, tree));
185 enum string_section
187 class_names, /* class, category, protocol, module names */
188 meth_var_names, /* method and variable names */
189 meth_var_types /* method and variable type descriptors */
192 static tree add_objc_string PARAMS ((tree,
193 enum string_section));
194 static tree get_objc_string_decl PARAMS ((tree,
195 enum string_section));
196 static tree build_objc_string_decl PARAMS ((enum string_section));
197 static tree build_selector_reference_decl PARAMS ((void));
199 /* Protocol additions. */
201 static tree add_protocol PARAMS ((tree));
202 static tree lookup_protocol PARAMS ((tree));
203 static void check_protocol_recursively PARAMS ((tree, tree));
204 static tree lookup_and_install_protocols PARAMS ((tree));
206 /* Type encoding. */
208 static void encode_type_qualifiers PARAMS ((tree));
209 static void encode_pointer PARAMS ((tree, int, int));
210 static void encode_array PARAMS ((tree, int, int));
211 static void encode_aggregate PARAMS ((tree, int, int));
212 static void encode_bitfield PARAMS ((int));
213 static void encode_type PARAMS ((tree, int, int));
214 static void encode_field_decl PARAMS ((tree, int, int));
216 static void really_start_method PARAMS ((tree, tree));
217 static int comp_method_with_proto PARAMS ((tree, tree));
218 static int comp_proto_with_proto PARAMS ((tree, tree));
219 static tree get_arg_type_list PARAMS ((tree, int, int));
220 static tree expr_last PARAMS ((tree));
222 /* Utilities for debugging and error diagnostics. */
224 static void warn_with_method PARAMS ((const char *, int, tree));
225 static void error_with_ivar PARAMS ((const char *, tree, tree));
226 static char *gen_method_decl PARAMS ((tree, char *));
227 static char *gen_declaration PARAMS ((tree, char *));
228 static void gen_declaration_1 PARAMS ((tree, char *));
229 static char *gen_declarator PARAMS ((tree, char *,
230 const char *));
231 static int is_complex_decl PARAMS ((tree));
232 static void adorn_decl PARAMS ((tree, char *));
233 static void dump_interface PARAMS ((FILE *, tree));
235 /* Everything else. */
237 static tree define_decl PARAMS ((tree, tree));
238 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
239 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
240 static tree create_builtin_decl PARAMS ((enum tree_code,
241 tree, const char *));
242 static void setup_string_decl PARAMS ((void));
243 static void build_string_class_template PARAMS ((void));
244 static tree my_build_string PARAMS ((int, const char *));
245 static void build_objc_symtab_template PARAMS ((void));
246 static tree init_def_list PARAMS ((tree));
247 static tree init_objc_symtab PARAMS ((tree));
248 static void forward_declare_categories PARAMS ((void));
249 static void generate_objc_symtab_decl PARAMS ((void));
250 static tree build_selector PARAMS ((tree));
251 static tree build_typed_selector_reference PARAMS ((tree, tree));
252 static tree build_selector_reference PARAMS ((tree));
253 static tree build_class_reference_decl PARAMS ((void));
254 static void add_class_reference PARAMS ((tree));
255 static tree objc_copy_list PARAMS ((tree, tree *));
256 static tree build_protocol_template PARAMS ((void));
257 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
258 static tree build_method_prototype_list_template PARAMS ((tree, int));
259 static tree build_method_prototype_template PARAMS ((void));
260 static int forwarding_offset PARAMS ((tree));
261 static tree encode_method_prototype PARAMS ((tree, tree));
262 static tree generate_descriptor_table PARAMS ((tree, const char *,
263 int, tree, tree));
264 static void generate_method_descriptors PARAMS ((tree));
265 static tree build_tmp_function_decl PARAMS ((void));
266 static void hack_method_prototype PARAMS ((tree, tree));
267 static void generate_protocol_references PARAMS ((tree));
268 static void generate_protocols PARAMS ((void));
269 static void check_ivars PARAMS ((tree, tree));
270 static tree build_ivar_list_template PARAMS ((tree, int));
271 static tree build_method_list_template PARAMS ((tree, int));
272 static tree build_ivar_list_initializer PARAMS ((tree, tree));
273 static tree generate_ivars_list PARAMS ((tree, const char *,
274 int, tree));
275 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
276 static tree generate_dispatch_table PARAMS ((tree, const char *,
277 int, tree));
278 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
279 tree, int, tree, tree,
280 tree));
281 static void generate_category PARAMS ((tree));
282 static int is_objc_type_qualifier PARAMS ((tree));
283 static tree adjust_type_for_id_default PARAMS ((tree));
284 static tree check_duplicates PARAMS ((hash));
285 static tree receiver_is_class_object PARAMS ((tree));
286 static int check_methods PARAMS ((tree, tree, int));
287 static int conforms_to_protocol PARAMS ((tree, tree));
288 static void check_protocol PARAMS ((tree, const char *,
289 const char *));
290 static void check_protocols PARAMS ((tree, const char *,
291 const char *));
292 static tree encode_method_def PARAMS ((tree));
293 static void gen_declspecs PARAMS ((tree, char *, int));
294 static void generate_classref_translation_entry PARAMS ((tree));
295 static void handle_class_ref PARAMS ((tree));
296 static void generate_struct_by_value_array PARAMS ((void))
297 ATTRIBUTE_NORETURN;
299 /*** Private Interface (data) ***/
301 /* Reserved tag definitions. */
303 #define TYPE_ID "id"
304 #define TAG_OBJECT "objc_object"
305 #define TAG_CLASS "objc_class"
306 #define TAG_SUPER "objc_super"
307 #define TAG_SELECTOR "objc_selector"
309 #define UTAG_CLASS "_objc_class"
310 #define UTAG_IVAR "_objc_ivar"
311 #define UTAG_IVAR_LIST "_objc_ivar_list"
312 #define UTAG_METHOD "_objc_method"
313 #define UTAG_METHOD_LIST "_objc_method_list"
314 #define UTAG_CATEGORY "_objc_category"
315 #define UTAG_MODULE "_objc_module"
316 #define UTAG_STATICS "_objc_statics"
317 #define UTAG_SYMTAB "_objc_symtab"
318 #define UTAG_SUPER "_objc_super"
319 #define UTAG_SELECTOR "_objc_selector"
321 #define UTAG_PROTOCOL "_objc_protocol"
322 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
323 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
324 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
326 /* Note that the string object global name is only needed for the
327 NeXT runtime. */
328 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
330 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
332 static const char *constant_string_class_name = NULL;
334 static const char *TAG_GETCLASS;
335 static const char *TAG_GETMETACLASS;
336 static const char *TAG_MSGSEND;
337 static const char *TAG_MSGSENDSUPER;
338 static const char *TAG_EXECCLASS;
339 static const char *default_constant_string_class_name;
341 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
342 tree objc_global_trees[OCTI_MAX];
344 static void handle_impent PARAMS ((struct imp_entry *));
346 struct imp_entry *imp_list = 0;
347 int imp_count = 0; /* `@implementation' */
348 int cat_count = 0; /* `@category' */
350 static int method_slot = 0; /* Used by start_method_def, */
352 #define BUFSIZE 1024
354 static char *errbuf; /* Buffer for error diagnostics */
356 /* Data imported from tree.c. */
358 extern enum debug_info_type write_symbols;
360 /* Data imported from toplev.c. */
362 extern const char *dump_base_name;
364 /* Generate code for GNU or NeXT runtime environment. */
366 #ifdef NEXT_OBJC_RUNTIME
367 int flag_next_runtime = 1;
368 #else
369 int flag_next_runtime = 0;
370 #endif
372 int flag_typed_selectors;
374 /* Open and close the file for outputting class declarations, if requested. */
376 int flag_gen_declaration = 0;
378 FILE *gen_declaration_file;
380 /* Warn if multiple methods are seen for the same selector, but with
381 different argument types. */
383 int warn_selector = 0;
385 /* Warn if methods required by a protocol are not implemented in the
386 class adopting it. When turned off, methods inherited to that
387 class are also considered implemented */
389 int flag_warn_protocol = 1;
391 /* Tells "encode_pointer/encode_aggregate" whether we are generating
392 type descriptors for instance variables (as opposed to methods).
393 Type descriptors for instance variables contain more information
394 than methods (for static typing and embedded structures). */
396 static int generating_instance_variables = 0;
398 /* Tells the compiler that this is a special run. Do not perform any
399 compiling, instead we are to test some platform dependent features
400 and output a C header file with appropriate definitions. */
402 static int print_struct_values = 0;
404 /* Some platforms pass small structures through registers versus
405 through an invisible pointer. Determine at what size structure is
406 the transition point between the two possibilities. */
408 static void
409 generate_struct_by_value_array ()
411 tree type;
412 tree field_decl, field_decl_chain;
413 int i, j;
414 int aggregate_in_mem[32];
415 int found = 0;
417 /* Presumably no platform passes 32 byte structures in a register. */
418 for (i = 1; i < 32; i++)
420 char buffer[5];
422 /* Create an unnamed struct that has `i' character components */
423 type = start_struct (RECORD_TYPE, NULL_TREE);
425 strcpy (buffer, "c1");
426 field_decl = create_builtin_decl (FIELD_DECL,
427 char_type_node,
428 buffer);
429 field_decl_chain = field_decl;
431 for (j = 1; j < i; j++)
433 sprintf (buffer, "c%d", j + 1);
434 field_decl = create_builtin_decl (FIELD_DECL,
435 char_type_node,
436 buffer);
437 chainon (field_decl_chain, field_decl);
439 finish_struct (type, field_decl_chain, NULL_TREE);
441 aggregate_in_mem[i] = aggregate_value_p (type);
442 if (!aggregate_in_mem[i])
443 found = 1;
446 /* We found some structures that are returned in registers instead of memory
447 so output the necessary data. */
448 if (found)
450 for (i = 31; i >= 0; i--)
451 if (!aggregate_in_mem[i])
452 break;
453 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
455 /* The first member of the structure is always 0 because we don't handle
456 structures with 0 members */
457 printf ("static int struct_forward_array[] = {\n 0");
459 for (j = 1; j <= i; j++)
460 printf (", %d", aggregate_in_mem[j]);
461 printf ("\n};\n");
464 exit (0);
467 const char *
468 objc_init (filename)
469 const char *filename;
471 filename = c_objc_common_init (filename);
473 /* Force the line number back to 0; check_newline will have
474 raised it to 1, which will make the builtin functions appear
475 not to be built in. */
476 lineno = 0;
478 /* If gen_declaration desired, open the output file. */
479 if (flag_gen_declaration)
481 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
482 gen_declaration_file = fopen (dumpname, "w");
483 if (gen_declaration_file == 0)
484 fatal_io_error ("can't open %s", dumpname);
485 free (dumpname);
488 if (flag_next_runtime)
490 TAG_GETCLASS = "objc_getClass";
491 TAG_GETMETACLASS = "objc_getMetaClass";
492 TAG_MSGSEND = "objc_msgSend";
493 TAG_MSGSENDSUPER = "objc_msgSendSuper";
494 TAG_EXECCLASS = "__objc_execClass";
495 default_constant_string_class_name = "NSConstantString";
497 else
499 TAG_GETCLASS = "objc_get_class";
500 TAG_GETMETACLASS = "objc_get_meta_class";
501 TAG_MSGSEND = "objc_msg_lookup";
502 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
503 TAG_EXECCLASS = "__objc_exec_class";
504 default_constant_string_class_name = "NXConstantString";
505 flag_typed_selectors = 1;
508 objc_ellipsis_node = make_node (ERROR_MARK);
510 init_objc ();
512 if (print_struct_values)
513 generate_struct_by_value_array ();
515 return filename;
518 void
519 finish_file ()
521 c_objc_common_finish_file ();
523 /* Finalize Objective-C runtime data. No need to generate tables
524 and code if only checking syntax. */
525 if (!flag_syntax_only)
526 finish_objc ();
528 if (gen_declaration_file)
529 fclose (gen_declaration_file);
533 objc_decode_option (argc, argv)
534 int argc;
535 char **argv;
537 const char *p = argv[0];
539 if (!strcmp (p, "-gen-decls"))
540 flag_gen_declaration = 1;
541 else if (!strcmp (p, "-Wselector"))
542 warn_selector = 1;
543 else if (!strcmp (p, "-Wno-selector"))
544 warn_selector = 0;
545 else if (!strcmp (p, "-Wprotocol"))
546 flag_warn_protocol = 1;
547 else if (!strcmp (p, "-Wno-protocol"))
548 flag_warn_protocol = 0;
549 else if (!strcmp (p, "-fgnu-runtime"))
550 flag_next_runtime = 0;
551 else if (!strcmp (p, "-fno-next-runtime"))
552 flag_next_runtime = 0;
553 else if (!strcmp (p, "-fno-gnu-runtime"))
554 flag_next_runtime = 1;
555 else if (!strcmp (p, "-fnext-runtime"))
556 flag_next_runtime = 1;
557 else if (!strcmp (p, "-print-objc-runtime-info"))
558 print_struct_values = 1;
559 #define CSTSTRCLASS "-fconstant-string-class="
560 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
561 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
562 error ("no class name specified as argument to -fconstant-string-class");
563 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
565 #undef CSTSTRCLASS
566 else
567 return c_decode_option (argc, argv);
569 return 1;
573 static tree
574 define_decl (declarator, declspecs)
575 tree declarator;
576 tree declspecs;
578 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
579 finish_decl (decl, NULL_TREE, NULL_TREE);
580 return decl;
583 /* Return 1 if LHS and RHS are compatible types for assignment or
584 various other operations. Return 0 if they are incompatible, and
585 return -1 if we choose to not decide. When the operation is
586 REFLEXIVE, check for compatibility in either direction.
588 For statically typed objects, an assignment of the form `a' = `b'
589 is permitted if:
591 `a' is of type "id",
592 `a' and `b' are the same class type, or
593 `a' and `b' are of class types A and B such that B is a descendant of A. */
596 maybe_objc_comptypes (lhs, rhs, reflexive)
597 tree lhs, rhs;
598 int reflexive;
600 return objc_comptypes (lhs, rhs, reflexive);
603 static tree
604 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
605 tree rproto_list;
606 tree sel_name;
607 int class_meth;
609 tree rproto, p;
610 tree fnd = 0;
612 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
614 p = TREE_VALUE (rproto);
616 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
618 if ((fnd = lookup_method (class_meth
619 ? PROTOCOL_CLS_METHODS (p)
620 : PROTOCOL_NST_METHODS (p), sel_name)))
622 else if (PROTOCOL_LIST (p))
623 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
624 sel_name, class_meth);
626 else
628 ; /* An identifier...if we could not find a protocol. */
631 if (fnd)
632 return fnd;
635 return 0;
638 static tree
639 lookup_protocol_in_reflist (rproto_list, lproto)
640 tree rproto_list;
641 tree lproto;
643 tree rproto, p;
645 /* Make sure the protocol is supported by the object on the rhs. */
646 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
648 tree fnd = 0;
649 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
651 p = TREE_VALUE (rproto);
653 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
655 if (lproto == p)
656 fnd = lproto;
658 else if (PROTOCOL_LIST (p))
659 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
662 if (fnd)
663 return fnd;
666 else
668 ; /* An identifier...if we could not find a protocol. */
671 return 0;
674 /* Return 1 if LHS and RHS are compatible types for assignment
675 or various other operations. Return 0 if they are incompatible,
676 and return -1 if we choose to not decide. When the operation
677 is REFLEXIVE, check for compatibility in either direction. */
680 objc_comptypes (lhs, rhs, reflexive)
681 tree lhs;
682 tree rhs;
683 int reflexive;
685 /* New clause for protocols. */
687 if (TREE_CODE (lhs) == POINTER_TYPE
688 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
689 && TREE_CODE (rhs) == POINTER_TYPE
690 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
692 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
693 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
695 if (lhs_is_proto)
697 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
698 tree rproto, rproto_list;
699 tree p;
701 if (rhs_is_proto)
703 rproto_list = TYPE_PROTOCOL_LIST (rhs);
705 /* Make sure the protocol is supported by the object
706 on the rhs. */
707 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
709 p = TREE_VALUE (lproto);
710 rproto = lookup_protocol_in_reflist (rproto_list, p);
712 if (!rproto)
713 warning ("object does not conform to the `%s' protocol",
714 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
717 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
719 tree rname = TYPE_NAME (TREE_TYPE (rhs));
720 tree rinter;
722 /* Make sure the protocol is supported by the object
723 on the rhs. */
724 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
726 p = TREE_VALUE (lproto);
727 rproto = 0;
728 rinter = lookup_interface (rname);
730 while (rinter && !rproto)
732 tree cat;
734 rproto_list = CLASS_PROTOCOL_LIST (rinter);
735 /* If the underlying ObjC class does not have
736 protocols attached to it, perhaps there are
737 "one-off" protocols attached to the rhs?
738 E.g., 'id<MyProt> foo;'. */
739 if (!rproto_list)
740 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
741 rproto = lookup_protocol_in_reflist (rproto_list, p);
743 /* Check for protocols adopted by categories. */
744 cat = CLASS_CATEGORY_LIST (rinter);
745 while (cat && !rproto)
747 rproto_list = CLASS_PROTOCOL_LIST (cat);
748 rproto = lookup_protocol_in_reflist (rproto_list, p);
750 cat = CLASS_CATEGORY_LIST (cat);
753 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
756 if (!rproto)
757 warning ("class `%s' does not implement the `%s' protocol",
758 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
759 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
763 /* May change...based on whether there was any mismatch */
764 return 1;
766 else if (rhs_is_proto)
767 /* Lhs is not a protocol...warn if it is statically typed */
768 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
770 else
771 /* Defer to comptypes. */
772 return -1;
775 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
776 ; /* Fall thru. This is the case we have been handling all along */
777 else
778 /* Defer to comptypes. */
779 return -1;
781 /* `id' = `<class> *', `<class> *' = `id' */
783 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
784 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
785 return 1;
787 /* `id' = `Class', `Class' = `id' */
789 else if ((TYPE_NAME (lhs) == objc_object_id
790 && TYPE_NAME (rhs) == objc_class_id)
791 || (TYPE_NAME (lhs) == objc_class_id
792 && TYPE_NAME (rhs) == objc_object_id))
793 return 1;
795 /* `<class> *' = `<class> *' */
797 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
799 tree lname = TYPE_NAME (lhs);
800 tree rname = TYPE_NAME (rhs);
801 tree inter;
803 if (lname == rname)
804 return 1;
806 /* If the left hand side is a super class of the right hand side,
807 allow it. */
808 for (inter = lookup_interface (rname); inter;
809 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
810 if (lname == CLASS_SUPER_NAME (inter))
811 return 1;
813 /* Allow the reverse when reflexive. */
814 if (reflexive)
815 for (inter = lookup_interface (lname); inter;
816 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
817 if (rname == CLASS_SUPER_NAME (inter))
818 return 1;
820 return 0;
822 else
823 /* Defer to comptypes. */
824 return -1;
827 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
829 void
830 objc_check_decl (decl)
831 tree decl;
833 tree type = TREE_TYPE (decl);
835 if (TREE_CODE (type) == RECORD_TYPE
836 && TREE_STATIC_TEMPLATE (type)
837 && type != constant_string_type)
838 error_with_decl (decl, "`%s' cannot be statically allocated");
841 void
842 maybe_objc_check_decl (decl)
843 tree decl;
845 objc_check_decl (decl);
848 /* Implement static typing. At this point, we know we have an interface. */
850 tree
851 get_static_reference (interface, protocols)
852 tree interface;
853 tree protocols;
855 tree type = xref_tag (RECORD_TYPE, interface);
857 if (protocols)
859 tree t, m = TYPE_MAIN_VARIANT (type);
861 t = copy_node (type);
862 TYPE_BINFO (t) = make_tree_vec (2);
864 /* Add this type to the chain of variants of TYPE. */
865 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
866 TYPE_NEXT_VARIANT (m) = t;
868 /* Look up protocols and install in lang specific list. Note
869 that the protocol list can have a different lifetime than T! */
870 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
872 /* This forces a new pointer type to be created later
873 (in build_pointer_type)...so that the new template
874 we just created will actually be used...what a hack! */
875 if (TYPE_POINTER_TO (t))
876 TYPE_POINTER_TO (t) = NULL_TREE;
878 type = t;
881 return type;
884 tree
885 get_object_reference (protocols)
886 tree protocols;
888 tree type_decl = lookup_name (objc_id_id);
889 tree type;
891 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
893 type = TREE_TYPE (type_decl);
894 if (TYPE_MAIN_VARIANT (type) != id_type)
895 warning ("unexpected type for `id' (%s)",
896 gen_declaration (type, errbuf));
898 else
900 error ("undefined type `id', please import <objc/objc.h>");
901 return error_mark_node;
904 /* This clause creates a new pointer type that is qualified with
905 the protocol specification...this info is used later to do more
906 elaborate type checking. */
908 if (protocols)
910 tree t, m = TYPE_MAIN_VARIANT (type);
912 t = copy_node (type);
913 TYPE_BINFO (t) = make_tree_vec (2);
915 /* Add this type to the chain of variants of TYPE. */
916 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
917 TYPE_NEXT_VARIANT (m) = t;
919 /* Look up protocols...and install in lang specific list */
920 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
922 /* This forces a new pointer type to be created later
923 (in build_pointer_type)...so that the new template
924 we just created will actually be used...what a hack! */
925 if (TYPE_POINTER_TO (t))
926 TYPE_POINTER_TO (t) = NULL_TREE;
928 type = t;
930 return type;
933 /* Check for circular dependencies in protocols. The arguments are
934 PROTO, the protocol to check, and LIST, a list of protocol it
935 conforms to. */
937 static void
938 check_protocol_recursively (proto, list)
939 tree proto;
940 tree list;
942 tree p;
944 for (p = list; p; p = TREE_CHAIN (p))
946 tree pp = TREE_VALUE (p);
948 if (TREE_CODE (pp) == IDENTIFIER_NODE)
949 pp = lookup_protocol (pp);
951 if (pp == proto)
952 fatal_error ("protocol `%s' has circular dependency",
953 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
954 if (pp)
955 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
959 static tree
960 lookup_and_install_protocols (protocols)
961 tree protocols;
963 tree proto;
964 tree prev = NULL;
965 tree return_value = protocols;
967 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
969 tree ident = TREE_VALUE (proto);
970 tree p = lookup_protocol (ident);
972 if (!p)
974 error ("cannot find protocol declaration for `%s'",
975 IDENTIFIER_POINTER (ident));
976 if (prev)
977 TREE_CHAIN (prev) = TREE_CHAIN (proto);
978 else
979 return_value = TREE_CHAIN (proto);
981 else
983 /* Replace identifier with actual protocol node. */
984 TREE_VALUE (proto) = p;
985 prev = proto;
989 return return_value;
992 /* Create and push a decl for a built-in external variable or field NAME.
993 CODE says which.
994 TYPE is its data type. */
996 static tree
997 create_builtin_decl (code, type, name)
998 enum tree_code code;
999 tree type;
1000 const char *name;
1002 tree decl = build_decl (code, get_identifier (name), type);
1004 if (code == VAR_DECL)
1006 TREE_STATIC (decl) = 1;
1007 make_decl_rtl (decl, 0);
1008 pushdecl (decl);
1011 DECL_ARTIFICIAL (decl) = 1;
1012 return decl;
1015 /* Find the decl for the constant string class. */
1017 static void
1018 setup_string_decl ()
1020 if (!string_class_decl)
1022 if (!constant_string_global_id)
1023 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1024 string_class_decl = lookup_name (constant_string_global_id);
1028 /* Purpose: "play" parser, creating/installing representations
1029 of the declarations that are required by Objective-C.
1031 Model:
1033 type_spec--------->sc_spec
1034 (tree_list) (tree_list)
1037 identifier_node identifier_node */
1039 static void
1040 synth_module_prologue ()
1042 tree temp_type;
1043 tree super_p;
1045 /* Defined in `objc.h' */
1046 objc_object_id = get_identifier (TAG_OBJECT);
1048 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1050 id_type = build_pointer_type (objc_object_reference);
1052 objc_id_id = get_identifier (TYPE_ID);
1053 objc_class_id = get_identifier (TAG_CLASS);
1055 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1056 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1057 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1059 /* Declare type of selector-objects that represent an operation name. */
1061 /* `struct objc_selector *' */
1062 selector_type
1063 = build_pointer_type (xref_tag (RECORD_TYPE,
1064 get_identifier (TAG_SELECTOR)));
1066 /* Forward declare type, or else the prototype for msgSendSuper will
1067 complain. */
1069 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1070 get_identifier (TAG_SUPER)));
1073 /* id objc_msgSend (id, SEL, ...); */
1075 temp_type
1076 = build_function_type (id_type,
1077 tree_cons (NULL_TREE, id_type,
1078 tree_cons (NULL_TREE, selector_type,
1079 NULL_TREE)));
1081 if (! flag_next_runtime)
1083 umsg_decl = build_decl (FUNCTION_DECL,
1084 get_identifier (TAG_MSGSEND), temp_type);
1085 DECL_EXTERNAL (umsg_decl) = 1;
1086 TREE_PUBLIC (umsg_decl) = 1;
1087 DECL_INLINE (umsg_decl) = 1;
1088 DECL_ARTIFICIAL (umsg_decl) = 1;
1090 make_decl_rtl (umsg_decl, NULL);
1091 pushdecl (umsg_decl);
1093 else
1094 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
1095 NULL, NULL_TREE);
1097 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1099 temp_type
1100 = build_function_type (id_type,
1101 tree_cons (NULL_TREE, super_p,
1102 tree_cons (NULL_TREE, selector_type,
1103 NULL_TREE)));
1105 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1106 temp_type, 0, NOT_BUILT_IN,
1107 NULL, NULL_TREE);
1109 /* id objc_getClass (const char *); */
1111 temp_type = build_function_type (id_type,
1112 tree_cons (NULL_TREE,
1113 const_string_type_node,
1114 tree_cons (NULL_TREE, void_type_node,
1115 NULL_TREE)));
1117 objc_get_class_decl
1118 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1119 NULL, NULL_TREE);
1121 /* id objc_getMetaClass (const char *); */
1123 objc_get_meta_class_decl
1124 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
1125 NULL, NULL_TREE);
1127 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1129 if (! flag_next_runtime)
1131 if (flag_typed_selectors)
1133 /* Suppress outputting debug symbols, because
1134 dbxout_init hasn'r been called yet. */
1135 enum debug_info_type save_write_symbols = write_symbols;
1136 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1137 write_symbols = NO_DEBUG;
1138 debug_hooks = &do_nothing_debug_hooks;
1140 build_selector_template ();
1141 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1143 write_symbols = save_write_symbols;
1144 debug_hooks = save_hooks;
1146 else
1147 temp_type = build_array_type (selector_type, NULL_TREE);
1149 layout_type (temp_type);
1150 UOBJC_SELECTOR_TABLE_decl
1151 = create_builtin_decl (VAR_DECL, temp_type,
1152 "_OBJC_SELECTOR_TABLE");
1154 /* Avoid warning when not sending messages. */
1155 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1158 generate_forward_declaration_to_string_table ();
1160 /* Forward declare constant_string_id and constant_string_type. */
1161 if (!constant_string_class_name)
1162 constant_string_class_name = default_constant_string_class_name;
1164 constant_string_id = get_identifier (constant_string_class_name);
1165 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1168 /* Predefine the following data type:
1170 struct STRING_OBJECT_CLASS_NAME
1172 Object isa;
1173 char *cString;
1174 unsigned int length;
1175 }; */
1177 static void
1178 build_string_class_template ()
1180 tree field_decl, field_decl_chain;
1182 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1183 field_decl_chain = field_decl;
1185 field_decl = create_builtin_decl (FIELD_DECL,
1186 build_pointer_type (char_type_node),
1187 "cString");
1188 chainon (field_decl_chain, field_decl);
1190 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1191 chainon (field_decl_chain, field_decl);
1193 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1196 /* Custom build_string which sets TREE_TYPE! */
1198 static tree
1199 my_build_string (len, str)
1200 int len;
1201 const char *str;
1203 return fix_string_type (build_string (len, str));
1206 /* Given a chain of STRING_CST's, build a static instance of
1207 NXConstantString which points at the concatenation of those strings.
1208 We place the string object in the __string_objects section of the
1209 __OBJC segment. The Objective-C runtime will initialize the isa
1210 pointers of the string objects to point at the NXConstantString
1211 class object. */
1213 tree
1214 build_objc_string_object (strings)
1215 tree strings;
1217 tree string, initlist, constructor;
1218 int length;
1220 if (lookup_interface (constant_string_id) == NULL_TREE)
1222 error ("cannot find interface declaration for `%s'",
1223 IDENTIFIER_POINTER (constant_string_id));
1224 return error_mark_node;
1227 add_class_reference (constant_string_id);
1229 if (TREE_CHAIN (strings))
1231 varray_type vstrings;
1232 VARRAY_TREE_INIT (vstrings, 32, "strings");
1234 for (; strings ; strings = TREE_CHAIN (strings))
1235 VARRAY_PUSH_TREE (vstrings, strings);
1237 string = combine_strings (vstrings);
1239 else
1240 string = strings;
1242 string = fix_string_type (string);
1244 TREE_SET_CODE (string, STRING_CST);
1245 length = TREE_STRING_LENGTH (string) - 1;
1247 /* We could not properly create NXConstantString in synth_module_prologue,
1248 because that's called before debugging is initialized. Do it now. */
1249 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1250 build_string_class_template ();
1252 /* & ((NXConstantString) { NULL, string, length }) */
1254 if (flag_next_runtime)
1256 /* For the NeXT runtime, we can generate a literal reference
1257 to the string class, don't need to run a constructor. */
1258 setup_string_decl ();
1259 if (string_class_decl == NULL_TREE)
1261 error ("cannot find reference tag for class `%s'",
1262 IDENTIFIER_POINTER (constant_string_id));
1263 return error_mark_node;
1265 initlist = build_tree_list
1266 (NULL_TREE,
1267 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1269 else
1271 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1274 initlist
1275 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1276 initlist);
1277 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1278 constructor = build_constructor (constant_string_type, nreverse (initlist));
1280 if (!flag_next_runtime)
1282 constructor
1283 = objc_add_static_instance (constructor, constant_string_type);
1286 return (build_unary_op (ADDR_EXPR, constructor, 1));
1289 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1291 static tree
1292 objc_add_static_instance (constructor, class_decl)
1293 tree constructor, class_decl;
1295 static int num_static_inst;
1296 tree *chain, decl;
1297 char buf[256];
1299 /* Find the list of static instances for the CLASS_DECL. Create one if
1300 not found. */
1301 for (chain = &objc_static_instances;
1302 *chain && TREE_VALUE (*chain) != class_decl;
1303 chain = &TREE_CHAIN (*chain));
1304 if (!*chain)
1306 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1307 add_objc_string (TYPE_NAME (class_decl), class_names);
1310 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1311 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1312 DECL_COMMON (decl) = 1;
1313 TREE_STATIC (decl) = 1;
1314 DECL_ARTIFICIAL (decl) = 1;
1315 DECL_INITIAL (decl) = constructor;
1317 /* We may be writing something else just now.
1318 Postpone till end of input. */
1319 DECL_DEFER_OUTPUT (decl) = 1;
1320 pushdecl_top_level (decl);
1321 rest_of_decl_compilation (decl, 0, 1, 0);
1323 /* Add the DECL to the head of this CLASS' list. */
1324 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1326 return decl;
1329 /* Build a static constant CONSTRUCTOR
1330 with type TYPE and elements ELTS. */
1332 static tree
1333 build_constructor (type, elts)
1334 tree type, elts;
1336 tree constructor, f, e;
1338 /* ??? Most of the places that we build constructors, we don't fill in
1339 the type of integers properly. Convert them all en masse. */
1340 if (TREE_CODE (type) == ARRAY_TYPE)
1342 f = TREE_TYPE (type);
1343 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1344 for (e = elts; e ; e = TREE_CHAIN (e))
1345 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1347 else
1349 f = TYPE_FIELDS (type);
1350 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1351 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1352 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1353 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1356 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1357 TREE_CONSTANT (constructor) = 1;
1358 TREE_STATIC (constructor) = 1;
1359 TREE_READONLY (constructor) = 1;
1361 return constructor;
1364 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1366 /* Predefine the following data type:
1368 struct _objc_symtab
1370 long sel_ref_cnt;
1371 SEL *refs;
1372 short cls_def_cnt;
1373 short cat_def_cnt;
1374 void *defs[cls_def_cnt + cat_def_cnt];
1375 }; */
1377 static void
1378 build_objc_symtab_template ()
1380 tree field_decl, field_decl_chain, index;
1382 objc_symtab_template
1383 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1385 /* long sel_ref_cnt; */
1387 field_decl = create_builtin_decl (FIELD_DECL,
1388 long_integer_type_node,
1389 "sel_ref_cnt");
1390 field_decl_chain = field_decl;
1392 /* SEL *refs; */
1394 field_decl = create_builtin_decl (FIELD_DECL,
1395 build_pointer_type (selector_type),
1396 "refs");
1397 chainon (field_decl_chain, field_decl);
1399 /* short cls_def_cnt; */
1401 field_decl = create_builtin_decl (FIELD_DECL,
1402 short_integer_type_node,
1403 "cls_def_cnt");
1404 chainon (field_decl_chain, field_decl);
1406 /* short cat_def_cnt; */
1408 field_decl = create_builtin_decl (FIELD_DECL,
1409 short_integer_type_node,
1410 "cat_def_cnt");
1411 chainon (field_decl_chain, field_decl);
1413 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1415 if (!flag_next_runtime)
1416 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1417 else
1418 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1419 imp_count == 0 && cat_count == 0
1420 ? -1 : 0));
1421 field_decl = create_builtin_decl (FIELD_DECL,
1422 build_array_type (ptr_type_node, index),
1423 "defs");
1424 chainon (field_decl_chain, field_decl);
1426 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1429 /* Create the initial value for the `defs' field of _objc_symtab.
1430 This is a CONSTRUCTOR. */
1432 static tree
1433 init_def_list (type)
1434 tree type;
1436 tree expr, initlist = NULL_TREE;
1437 struct imp_entry *impent;
1439 if (imp_count)
1440 for (impent = imp_list; impent; impent = impent->next)
1442 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1444 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1445 initlist = tree_cons (NULL_TREE, expr, initlist);
1449 if (cat_count)
1450 for (impent = imp_list; impent; impent = impent->next)
1452 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1454 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1455 initlist = tree_cons (NULL_TREE, expr, initlist);
1459 if (!flag_next_runtime)
1461 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1462 tree expr;
1464 if (static_instances_decl)
1465 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1466 else
1467 expr = build_int_2 (0, 0);
1469 initlist = tree_cons (NULL_TREE, expr, initlist);
1472 return build_constructor (type, nreverse (initlist));
1475 /* Construct the initial value for all of _objc_symtab. */
1477 static tree
1478 init_objc_symtab (type)
1479 tree type;
1481 tree initlist;
1483 /* sel_ref_cnt = { ..., 5, ... } */
1485 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1487 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1489 if (flag_next_runtime || ! sel_ref_chain)
1490 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1491 else
1492 initlist = tree_cons (NULL_TREE,
1493 build_unary_op (ADDR_EXPR,
1494 UOBJC_SELECTOR_TABLE_decl, 1),
1495 initlist);
1497 /* cls_def_cnt = { ..., 5, ... } */
1499 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1501 /* cat_def_cnt = { ..., 5, ... } */
1503 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1505 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1507 if (imp_count || cat_count || static_instances_decl)
1510 tree field = TYPE_FIELDS (type);
1511 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1513 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1514 initlist);
1517 return build_constructor (type, nreverse (initlist));
1520 /* Push forward-declarations of all the categories so that
1521 init_def_list can use them in a CONSTRUCTOR. */
1523 static void
1524 forward_declare_categories ()
1526 struct imp_entry *impent;
1527 tree sav = objc_implementation_context;
1529 for (impent = imp_list; impent; impent = impent->next)
1531 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1533 /* Set an invisible arg to synth_id_with_class_suffix. */
1534 objc_implementation_context = impent->imp_context;
1535 impent->class_decl
1536 = create_builtin_decl (VAR_DECL, objc_category_template,
1537 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1540 objc_implementation_context = sav;
1543 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1544 and initialized appropriately. */
1546 static void
1547 generate_objc_symtab_decl ()
1549 tree sc_spec;
1551 if (!objc_category_template)
1552 build_category_template ();
1554 /* forward declare categories */
1555 if (cat_count)
1556 forward_declare_categories ();
1558 if (!objc_symtab_template)
1559 build_objc_symtab_template ();
1561 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1563 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1564 tree_cons (NULL_TREE,
1565 objc_symtab_template, sc_spec),
1567 NULL_TREE);
1569 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1570 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1571 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1572 finish_decl (UOBJC_SYMBOLS_decl,
1573 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1574 NULL_TREE);
1577 static tree
1578 init_module_descriptor (type)
1579 tree type;
1581 tree initlist, expr;
1583 /* version = { 1, ... } */
1585 expr = build_int_2 (OBJC_VERSION, 0);
1586 initlist = build_tree_list (NULL_TREE, expr);
1588 /* size = { ..., sizeof (struct objc_module), ... } */
1590 expr = size_in_bytes (objc_module_template);
1591 initlist = tree_cons (NULL_TREE, expr, initlist);
1593 /* name = { ..., "foo.m", ... } */
1595 expr = add_objc_string (get_identifier (input_filename), class_names);
1596 initlist = tree_cons (NULL_TREE, expr, initlist);
1598 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1600 if (UOBJC_SYMBOLS_decl)
1601 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1602 else
1603 expr = build_int_2 (0, 0);
1604 initlist = tree_cons (NULL_TREE, expr, initlist);
1606 return build_constructor (type, nreverse (initlist));
1609 /* Write out the data structures to describe Objective C classes defined.
1610 If appropriate, compile and output a setup function to initialize them.
1611 Return a symbol_ref to the function to call to initialize the Objective C
1612 data structures for this file (and perhaps for other files also).
1614 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1616 static rtx
1617 build_module_descriptor ()
1619 tree decl_specs, field_decl, field_decl_chain;
1621 objc_module_template
1622 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1624 /* Long version; */
1626 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1627 field_decl = get_identifier ("version");
1628 field_decl
1629 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1630 field_decl_chain = field_decl;
1632 /* long size; */
1634 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1635 field_decl = get_identifier ("size");
1636 field_decl
1637 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1638 chainon (field_decl_chain, field_decl);
1640 /* char *name; */
1642 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1643 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1644 field_decl
1645 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1646 chainon (field_decl_chain, field_decl);
1648 /* struct objc_symtab *symtab; */
1650 decl_specs = get_identifier (UTAG_SYMTAB);
1651 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1652 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1653 field_decl
1654 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1655 chainon (field_decl_chain, field_decl);
1657 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1659 /* Create an instance of "objc_module". */
1661 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1662 build_tree_list (NULL_TREE,
1663 ridpointers[(int) RID_STATIC]));
1665 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1666 decl_specs, 1, NULL_TREE);
1668 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1669 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1670 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1672 finish_decl (UOBJC_MODULES_decl,
1673 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1674 NULL_TREE);
1676 /* Mark the decl to avoid "defined but not used" warning. */
1677 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1679 /* Generate a constructor call for the module descriptor.
1680 This code was generated by reading the grammar rules
1681 of c-parse.in; Therefore, it may not be the most efficient
1682 way of generating the requisite code. */
1684 if (flag_next_runtime)
1685 return NULL_RTX;
1688 tree parms, execclass_decl, decelerator, void_list_node_1;
1689 tree init_function_name, init_function_decl;
1691 /* Declare void __objc_execClass (void *); */
1693 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1694 execclass_decl = build_decl (FUNCTION_DECL,
1695 get_identifier (TAG_EXECCLASS),
1696 build_function_type (void_type_node,
1697 tree_cons (NULL_TREE, ptr_type_node,
1698 void_list_node_1)));
1699 DECL_EXTERNAL (execclass_decl) = 1;
1700 DECL_ARTIFICIAL (execclass_decl) = 1;
1701 TREE_PUBLIC (execclass_decl) = 1;
1702 pushdecl (execclass_decl);
1703 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1704 assemble_external (execclass_decl);
1706 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1708 init_function_name = get_file_function_name ('I');
1709 start_function (void_list_node_1,
1710 build_nt (CALL_EXPR, init_function_name,
1711 tree_cons (NULL_TREE, NULL_TREE,
1712 void_list_node_1),
1713 NULL_TREE),
1714 NULL_TREE);
1715 store_parm_decls ();
1717 init_function_decl = current_function_decl;
1718 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1719 TREE_USED (init_function_decl) = 1;
1720 /* Don't let this one be deferred. */
1721 DECL_INLINE (init_function_decl) = 0;
1722 DECL_UNINLINABLE (init_function_decl) = 1;
1723 current_function_cannot_inline
1724 = "static constructors and destructors cannot be inlined";
1726 parms
1727 = build_tree_list (NULL_TREE,
1728 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1729 decelerator = build_function_call (execclass_decl, parms);
1731 c_expand_expr_stmt (decelerator);
1733 finish_function (0, 0);
1735 return XEXP (DECL_RTL (init_function_decl), 0);
1739 /* extern const char _OBJC_STRINGS[]; */
1741 static void
1742 generate_forward_declaration_to_string_table ()
1744 tree sc_spec, decl_specs, expr_decl;
1746 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1747 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1749 expr_decl
1750 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1752 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1755 /* Return the DECL of the string IDENT in the SECTION. */
1757 static tree
1758 get_objc_string_decl (ident, section)
1759 tree ident;
1760 enum string_section section;
1762 tree chain;
1764 if (section == class_names)
1765 chain = class_names_chain;
1766 else if (section == meth_var_names)
1767 chain = meth_var_names_chain;
1768 else if (section == meth_var_types)
1769 chain = meth_var_types_chain;
1770 else
1771 abort ();
1773 for (; chain != 0; chain = TREE_VALUE (chain))
1774 if (TREE_VALUE (chain) == ident)
1775 return (TREE_PURPOSE (chain));
1777 abort ();
1778 return NULL_TREE;
1781 /* Output references to all statically allocated objects. Return the DECL
1782 for the array built. */
1784 static void
1785 generate_static_references ()
1787 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1788 tree class_name, class, decl, initlist;
1789 tree cl_chain, in_chain, type;
1790 int num_inst, num_class;
1791 char buf[256];
1793 if (flag_next_runtime)
1794 abort ();
1796 for (cl_chain = objc_static_instances, num_class = 0;
1797 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1799 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1800 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1802 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1803 ident = get_identifier (buf);
1805 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1806 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1807 build_tree_list (NULL_TREE,
1808 ridpointers[(int) RID_STATIC]));
1809 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1810 DECL_CONTEXT (decl) = 0;
1811 DECL_ARTIFICIAL (decl) = 1;
1813 /* Output {class_name, ...}. */
1814 class = TREE_VALUE (cl_chain);
1815 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1816 initlist = build_tree_list (NULL_TREE,
1817 build_unary_op (ADDR_EXPR, class_name, 1));
1819 /* Output {..., instance, ...}. */
1820 for (in_chain = TREE_PURPOSE (cl_chain);
1821 in_chain; in_chain = TREE_CHAIN (in_chain))
1823 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1824 initlist = tree_cons (NULL_TREE, expr, initlist);
1827 /* Output {..., NULL}. */
1828 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1830 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1831 finish_decl (decl, expr, NULL_TREE);
1832 TREE_USED (decl) = 1;
1834 type = build_array_type (build_pointer_type (void_type_node), 0);
1835 decl = build_decl (VAR_DECL, ident, type);
1836 TREE_USED (decl) = 1;
1837 TREE_STATIC (decl) = 1;
1838 decls
1839 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1842 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1843 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1844 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1845 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1846 build_tree_list (NULL_TREE,
1847 ridpointers[(int) RID_STATIC]));
1848 static_instances_decl
1849 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1850 TREE_USED (static_instances_decl) = 1;
1851 DECL_CONTEXT (static_instances_decl) = 0;
1852 DECL_ARTIFICIAL (static_instances_decl) = 1;
1853 expr = build_constructor (TREE_TYPE (static_instances_decl),
1854 nreverse (decls));
1855 finish_decl (static_instances_decl, expr, NULL_TREE);
1858 /* Output all strings. */
1860 static void
1861 generate_strings ()
1863 tree sc_spec, decl_specs, expr_decl;
1864 tree chain, string_expr;
1865 tree string, decl;
1867 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1869 string = TREE_VALUE (chain);
1870 decl = TREE_PURPOSE (chain);
1871 sc_spec
1872 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1873 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1874 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1875 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1876 DECL_CONTEXT (decl) = NULL_TREE;
1877 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1878 IDENTIFIER_POINTER (string));
1879 finish_decl (decl, string_expr, NULL_TREE);
1882 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1884 string = TREE_VALUE (chain);
1885 decl = TREE_PURPOSE (chain);
1886 sc_spec
1887 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1888 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1889 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1890 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1891 DECL_CONTEXT (decl) = NULL_TREE;
1892 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1893 IDENTIFIER_POINTER (string));
1894 finish_decl (decl, string_expr, NULL_TREE);
1897 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1899 string = TREE_VALUE (chain);
1900 decl = TREE_PURPOSE (chain);
1901 sc_spec
1902 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1903 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1904 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1905 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1906 DECL_CONTEXT (decl) = NULL_TREE;
1907 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1908 IDENTIFIER_POINTER (string));
1909 finish_decl (decl, string_expr, NULL_TREE);
1913 static tree
1914 build_selector_reference_decl ()
1916 tree decl, ident;
1917 char buf[256];
1918 static int idx = 0;
1920 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1922 ident = get_identifier (buf);
1924 decl = build_decl (VAR_DECL, ident, selector_type);
1925 DECL_EXTERNAL (decl) = 1;
1926 TREE_PUBLIC (decl) = 1;
1927 TREE_USED (decl) = 1;
1928 TREE_READONLY (decl) = 1;
1929 DECL_ARTIFICIAL (decl) = 1;
1930 DECL_CONTEXT (decl) = 0;
1932 make_decl_rtl (decl, 0);
1933 pushdecl_top_level (decl);
1935 return decl;
1938 /* Just a handy wrapper for add_objc_string. */
1940 static tree
1941 build_selector (ident)
1942 tree ident;
1944 tree expr = add_objc_string (ident, meth_var_names);
1945 if (flag_typed_selectors)
1946 return expr;
1947 else
1948 return build_c_cast (selector_type, expr); /* cast! */
1951 static void
1952 build_selector_translation_table ()
1954 tree sc_spec, decl_specs;
1955 tree chain, initlist = NULL_TREE;
1956 int offset = 0;
1957 tree decl = NULL_TREE, var_decl, name;
1959 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1961 tree expr;
1963 expr = build_selector (TREE_VALUE (chain));
1965 if (flag_next_runtime)
1967 name = DECL_NAME (TREE_PURPOSE (chain));
1969 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1971 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1972 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1974 var_decl = name;
1976 /* The `decl' that is returned from start_decl is the one that we
1977 forward declared in `build_selector_reference' */
1978 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
1981 /* add one for the '\0' character */
1982 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1984 if (flag_next_runtime)
1985 finish_decl (decl, expr, NULL_TREE);
1986 else
1988 if (flag_typed_selectors)
1990 tree eltlist = NULL_TREE;
1991 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1992 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
1993 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
1994 expr = build_constructor (objc_selector_template,
1995 nreverse (eltlist));
1997 initlist = tree_cons (NULL_TREE, expr, initlist);
2002 if (! flag_next_runtime)
2004 /* Cause the variable and its initial value to be actually output. */
2005 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2006 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2007 /* NULL terminate the list and fix the decl for output. */
2008 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2009 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2010 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2011 nreverse (initlist));
2012 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2013 current_function_decl = NULL_TREE;
2017 static tree
2018 get_proto_encoding (proto)
2019 tree proto;
2021 tree encoding;
2022 if (proto)
2024 tree tmp_decl;
2026 if (! METHOD_ENCODING (proto))
2028 tmp_decl = build_tmp_function_decl ();
2029 hack_method_prototype (proto, tmp_decl);
2030 encoding = encode_method_prototype (proto, tmp_decl);
2031 METHOD_ENCODING (proto) = encoding;
2033 else
2034 encoding = METHOD_ENCODING (proto);
2036 return add_objc_string (encoding, meth_var_types);
2038 else
2039 return build_int_2 (0, 0);
2042 /* sel_ref_chain is a list whose "value" fields will be instances of
2043 identifier_node that represent the selector. */
2045 static tree
2046 build_typed_selector_reference (ident, proto)
2047 tree ident, proto;
2049 tree *chain = &sel_ref_chain;
2050 tree expr;
2051 int index = 0;
2053 while (*chain)
2055 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2056 goto return_at_index;
2058 index++;
2059 chain = &TREE_CHAIN (*chain);
2062 *chain = tree_cons (proto, ident, NULL_TREE);
2064 return_at_index:
2065 expr = build_unary_op (ADDR_EXPR,
2066 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2067 build_int_2 (index, 0)),
2069 return build_c_cast (selector_type, expr);
2072 static tree
2073 build_selector_reference (ident)
2074 tree ident;
2076 tree *chain = &sel_ref_chain;
2077 tree expr;
2078 int index = 0;
2080 while (*chain)
2082 if (TREE_VALUE (*chain) == ident)
2083 return (flag_next_runtime
2084 ? TREE_PURPOSE (*chain)
2085 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2086 build_int_2 (index, 0)));
2088 index++;
2089 chain = &TREE_CHAIN (*chain);
2092 expr = build_selector_reference_decl ();
2094 *chain = tree_cons (expr, ident, NULL_TREE);
2096 return (flag_next_runtime
2097 ? expr
2098 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2099 build_int_2 (index, 0)));
2102 static tree
2103 build_class_reference_decl ()
2105 tree decl, ident;
2106 char buf[256];
2107 static int idx = 0;
2109 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2111 ident = get_identifier (buf);
2113 decl = build_decl (VAR_DECL, ident, objc_class_type);
2114 DECL_EXTERNAL (decl) = 1;
2115 TREE_PUBLIC (decl) = 1;
2116 TREE_USED (decl) = 1;
2117 TREE_READONLY (decl) = 1;
2118 DECL_CONTEXT (decl) = 0;
2119 DECL_ARTIFICIAL (decl) = 1;
2121 make_decl_rtl (decl, 0);
2122 pushdecl_top_level (decl);
2124 return decl;
2127 /* Create a class reference, but don't create a variable to reference
2128 it. */
2130 static void
2131 add_class_reference (ident)
2132 tree ident;
2134 tree chain;
2136 if ((chain = cls_ref_chain))
2138 tree tail;
2141 if (ident == TREE_VALUE (chain))
2142 return;
2144 tail = chain;
2145 chain = TREE_CHAIN (chain);
2147 while (chain);
2149 /* Append to the end of the list */
2150 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2152 else
2153 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2156 /* Get a class reference, creating it if necessary. Also create the
2157 reference variable. */
2159 tree
2160 get_class_reference (ident)
2161 tree ident;
2163 if (flag_next_runtime)
2165 tree *chain;
2166 tree decl;
2168 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2169 if (TREE_VALUE (*chain) == ident)
2171 if (! TREE_PURPOSE (*chain))
2172 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2174 return TREE_PURPOSE (*chain);
2177 decl = build_class_reference_decl ();
2178 *chain = tree_cons (decl, ident, NULL_TREE);
2179 return decl;
2181 else
2183 tree params;
2185 add_class_reference (ident);
2187 params = build_tree_list (NULL_TREE,
2188 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2189 IDENTIFIER_POINTER (ident)));
2191 assemble_external (objc_get_class_decl);
2192 return build_function_call (objc_get_class_decl, params);
2196 /* For each string section we have a chain which maps identifier nodes
2197 to decls for the strings. */
2199 static tree
2200 add_objc_string (ident, section)
2201 tree ident;
2202 enum string_section section;
2204 tree *chain, decl;
2206 if (section == class_names)
2207 chain = &class_names_chain;
2208 else if (section == meth_var_names)
2209 chain = &meth_var_names_chain;
2210 else if (section == meth_var_types)
2211 chain = &meth_var_types_chain;
2212 else
2213 abort ();
2215 while (*chain)
2217 if (TREE_VALUE (*chain) == ident)
2218 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2220 chain = &TREE_CHAIN (*chain);
2223 decl = build_objc_string_decl (section);
2225 *chain = tree_cons (decl, ident, NULL_TREE);
2227 return build_unary_op (ADDR_EXPR, decl, 1);
2230 static tree
2231 build_objc_string_decl (section)
2232 enum string_section section;
2234 tree decl, ident;
2235 char buf[256];
2236 static int class_names_idx = 0;
2237 static int meth_var_names_idx = 0;
2238 static int meth_var_types_idx = 0;
2240 if (section == class_names)
2241 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2242 else if (section == meth_var_names)
2243 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2244 else if (section == meth_var_types)
2245 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2247 ident = get_identifier (buf);
2249 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2250 DECL_EXTERNAL (decl) = 1;
2251 TREE_PUBLIC (decl) = 1;
2252 TREE_USED (decl) = 1;
2253 TREE_READONLY (decl) = 1;
2254 TREE_CONSTANT (decl) = 1;
2255 DECL_CONTEXT (decl) = 0;
2256 DECL_ARTIFICIAL (decl) = 1;
2258 make_decl_rtl (decl, 0);
2259 pushdecl_top_level (decl);
2261 return decl;
2265 void
2266 objc_declare_alias (alias_ident, class_ident)
2267 tree alias_ident;
2268 tree class_ident;
2270 if (is_class_name (class_ident) != class_ident)
2271 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2272 else if (is_class_name (alias_ident))
2273 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2274 else
2275 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2278 void
2279 objc_declare_class (ident_list)
2280 tree ident_list;
2282 tree list;
2284 for (list = ident_list; list; list = TREE_CHAIN (list))
2286 tree ident = TREE_VALUE (list);
2287 tree decl;
2289 if ((decl = lookup_name (ident)))
2291 error ("`%s' redeclared as different kind of symbol",
2292 IDENTIFIER_POINTER (ident));
2293 error_with_decl (decl, "previous declaration of `%s'");
2296 if (! is_class_name (ident))
2298 tree record = xref_tag (RECORD_TYPE, ident);
2299 TREE_STATIC_TEMPLATE (record) = 1;
2300 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2305 tree
2306 is_class_name (ident)
2307 tree ident;
2309 tree chain;
2311 if (lookup_interface (ident))
2312 return ident;
2314 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2316 if (ident == TREE_VALUE (chain))
2317 return ident;
2320 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2322 if (ident == TREE_VALUE (chain))
2323 return TREE_PURPOSE (chain);
2326 return 0;
2329 tree
2330 lookup_interface (ident)
2331 tree ident;
2333 tree chain;
2335 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2337 if (ident == CLASS_NAME (chain))
2338 return chain;
2340 return NULL_TREE;
2343 static tree
2344 objc_copy_list (list, head)
2345 tree list;
2346 tree *head;
2348 tree newlist = NULL_TREE, tail = NULL_TREE;
2350 while (list)
2352 tail = copy_node (list);
2354 /* The following statement fixes a bug when inheriting instance
2355 variables that are declared to be bitfields. finish_struct
2356 expects to find the width of the bitfield in DECL_INITIAL. */
2357 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2358 DECL_INITIAL (tail) = DECL_SIZE (tail);
2360 newlist = chainon (newlist, tail);
2361 list = TREE_CHAIN (list);
2364 *head = newlist;
2365 return tail;
2368 /* Used by: build_private_template, get_class_ivars, and
2369 continue_class. COPY is 1 when called from @defs. In this case
2370 copy all fields. Otherwise don't copy leaf ivars since we rely on
2371 them being side-effected exactly once by finish_struct. */
2373 static tree
2374 build_ivar_chain (interface, copy)
2375 tree interface;
2376 int copy;
2378 tree my_name, super_name, ivar_chain;
2380 my_name = CLASS_NAME (interface);
2381 super_name = CLASS_SUPER_NAME (interface);
2383 /* Possibly copy leaf ivars. */
2384 if (copy)
2385 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2386 else
2387 ivar_chain = CLASS_IVARS (interface);
2389 while (super_name)
2391 tree op1;
2392 tree super_interface = lookup_interface (super_name);
2394 if (!super_interface)
2396 /* fatal did not work with 2 args...should fix */
2397 error ("cannot find interface declaration for `%s', superclass of `%s'",
2398 IDENTIFIER_POINTER (super_name),
2399 IDENTIFIER_POINTER (my_name));
2400 exit (FATAL_EXIT_CODE);
2403 if (super_interface == interface)
2404 fatal_error ("circular inheritance in interface declaration for `%s'",
2405 IDENTIFIER_POINTER (super_name));
2407 interface = super_interface;
2408 my_name = CLASS_NAME (interface);
2409 super_name = CLASS_SUPER_NAME (interface);
2411 op1 = CLASS_IVARS (interface);
2412 if (op1)
2414 tree head, tail = objc_copy_list (op1, &head);
2416 /* Prepend super class ivars...make a copy of the list, we
2417 do not want to alter the original. */
2418 TREE_CHAIN (tail) = ivar_chain;
2419 ivar_chain = head;
2422 return ivar_chain;
2425 /* struct <classname> {
2426 struct objc_class *isa;
2428 }; */
2430 static tree
2431 build_private_template (class)
2432 tree class;
2434 tree ivar_context;
2436 if (CLASS_STATIC_TEMPLATE (class))
2438 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2439 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2441 else
2443 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2445 ivar_context = build_ivar_chain (class, 0);
2447 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2449 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2451 /* mark this record as class template - for class type checking */
2452 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2455 instance_type
2456 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2457 uprivate_record),
2458 build1 (INDIRECT_REF, NULL_TREE,
2459 NULL_TREE)));
2461 return ivar_context;
2464 /* Begin code generation for protocols... */
2466 /* struct objc_protocol {
2467 char *protocol_name;
2468 struct objc_protocol **protocol_list;
2469 struct objc_method_desc *instance_methods;
2470 struct objc_method_desc *class_methods;
2471 }; */
2473 static tree
2474 build_protocol_template ()
2476 tree decl_specs, field_decl, field_decl_chain;
2477 tree template;
2479 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2481 /* struct objc_class *isa; */
2483 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2484 get_identifier (UTAG_CLASS)));
2485 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2486 field_decl
2487 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2488 field_decl_chain = field_decl;
2490 /* char *protocol_name; */
2492 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2493 field_decl
2494 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2495 field_decl
2496 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2497 chainon (field_decl_chain, field_decl);
2499 /* struct objc_protocol **protocol_list; */
2501 decl_specs = build_tree_list (NULL_TREE, template);
2502 field_decl
2503 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2504 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2505 field_decl
2506 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2507 chainon (field_decl_chain, field_decl);
2509 /* struct objc_method_list *instance_methods; */
2511 decl_specs
2512 = build_tree_list (NULL_TREE,
2513 xref_tag (RECORD_TYPE,
2514 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2515 field_decl
2516 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2517 field_decl
2518 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2519 chainon (field_decl_chain, field_decl);
2521 /* struct objc_method_list *class_methods; */
2523 decl_specs
2524 = build_tree_list (NULL_TREE,
2525 xref_tag (RECORD_TYPE,
2526 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2527 field_decl
2528 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2529 field_decl
2530 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2531 chainon (field_decl_chain, field_decl);
2533 return finish_struct (template, field_decl_chain, NULL_TREE);
2536 static tree
2537 build_descriptor_table_initializer (type, entries)
2538 tree type;
2539 tree entries;
2541 tree initlist = NULL_TREE;
2545 tree eltlist = NULL_TREE;
2547 eltlist
2548 = tree_cons (NULL_TREE,
2549 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2550 eltlist
2551 = tree_cons (NULL_TREE,
2552 add_objc_string (METHOD_ENCODING (entries),
2553 meth_var_types),
2554 eltlist);
2556 initlist
2557 = tree_cons (NULL_TREE,
2558 build_constructor (type, nreverse (eltlist)), initlist);
2560 entries = TREE_CHAIN (entries);
2562 while (entries);
2564 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2567 /* struct objc_method_prototype_list {
2568 int count;
2569 struct objc_method_prototype {
2570 SEL name;
2571 char *types;
2572 } list[1];
2573 }; */
2575 static tree
2576 build_method_prototype_list_template (list_type, size)
2577 tree list_type;
2578 int size;
2580 tree objc_ivar_list_record;
2581 tree decl_specs, field_decl, field_decl_chain;
2583 /* Generate an unnamed struct definition. */
2585 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2587 /* int method_count; */
2589 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2590 field_decl = get_identifier ("method_count");
2592 field_decl
2593 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2594 field_decl_chain = field_decl;
2596 /* struct objc_method method_list[]; */
2598 decl_specs = build_tree_list (NULL_TREE, list_type);
2599 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2600 build_int_2 (size, 0));
2602 field_decl
2603 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2604 chainon (field_decl_chain, field_decl);
2606 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2608 return objc_ivar_list_record;
2611 static tree
2612 build_method_prototype_template ()
2614 tree proto_record;
2615 tree decl_specs, field_decl, field_decl_chain;
2617 proto_record
2618 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2620 /* struct objc_selector *_cmd; */
2621 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2622 get_identifier (TAG_SELECTOR)), NULL_TREE);
2623 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2625 field_decl
2626 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2627 field_decl_chain = field_decl;
2629 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2630 field_decl
2631 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2632 field_decl
2633 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2634 chainon (field_decl_chain, field_decl);
2636 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2638 return proto_record;
2641 /* True if last call to forwarding_offset yielded a register offset. */
2642 static int offset_is_register;
2644 static int
2645 forwarding_offset (parm)
2646 tree parm;
2648 int offset_in_bytes;
2650 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2652 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2654 /* ??? Here we assume that the parm address is indexed
2655 off the frame pointer or arg pointer.
2656 If that is not true, we produce meaningless results,
2657 but do not crash. */
2658 if (GET_CODE (addr) == PLUS
2659 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2660 offset_in_bytes = INTVAL (XEXP (addr, 1));
2661 else
2662 offset_in_bytes = 0;
2664 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2665 offset_is_register = 0;
2667 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2669 int regno = REGNO (DECL_INCOMING_RTL (parm));
2670 offset_in_bytes = apply_args_register_offset (regno);
2671 offset_is_register = 1;
2673 else
2674 return 0;
2676 /* This is the case where the parm is passed as an int or double
2677 and it is converted to a char, short or float and stored back
2678 in the parmlist. In this case, describe the parm
2679 with the variable's declared type, and adjust the address
2680 if the least significant bytes (which we are using) are not
2681 the first ones. */
2682 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2683 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2684 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2686 return offset_in_bytes;
2689 static tree
2690 encode_method_prototype (method_decl, func_decl)
2691 tree method_decl;
2692 tree func_decl;
2694 tree parms;
2695 int stack_size, i;
2696 tree user_args;
2697 HOST_WIDE_INT max_parm_end = 0;
2698 char buf[40];
2699 tree result;
2701 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2702 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2704 /* C type. */
2705 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2706 obstack_object_size (&util_obstack),
2707 OBJC_ENCODE_INLINE_DEFS);
2709 /* Stack size. */
2710 for (parms = DECL_ARGUMENTS (func_decl); parms;
2711 parms = TREE_CHAIN (parms))
2713 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2714 + int_size_in_bytes (TREE_TYPE (parms)));
2716 if (!offset_is_register && max_parm_end < parm_end)
2717 max_parm_end = parm_end;
2720 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2722 sprintf (buf, "%d", stack_size);
2723 obstack_grow (&util_obstack, buf, strlen (buf));
2725 user_args = METHOD_SEL_ARGS (method_decl);
2727 /* Argument types. */
2728 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2729 parms = TREE_CHAIN (parms), i++)
2731 /* Process argument qualifiers for user supplied arguments. */
2732 if (i > 1)
2734 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2735 user_args = TREE_CHAIN (user_args);
2738 /* Type. */
2739 encode_type (TREE_TYPE (parms),
2740 obstack_object_size (&util_obstack),
2741 OBJC_ENCODE_INLINE_DEFS);
2743 /* Compute offset. */
2744 sprintf (buf, "%d", forwarding_offset (parms));
2746 /* Indicate register. */
2747 if (offset_is_register)
2748 obstack_1grow (&util_obstack, '+');
2750 obstack_grow (&util_obstack, buf, strlen (buf));
2753 obstack_1grow (&util_obstack, '\0');
2754 result = get_identifier (obstack_finish (&util_obstack));
2755 obstack_free (&util_obstack, util_firstobj);
2756 return result;
2759 static tree
2760 generate_descriptor_table (type, name, size, list, proto)
2761 tree type;
2762 const char *name;
2763 int size;
2764 tree list;
2765 tree proto;
2767 tree sc_spec, decl_specs, decl, initlist;
2769 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2770 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2772 decl = start_decl (synth_id_with_class_suffix (name, proto),
2773 decl_specs, 1, NULL_TREE);
2774 DECL_CONTEXT (decl) = NULL_TREE;
2776 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2777 initlist = tree_cons (NULL_TREE, list, initlist);
2779 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2780 NULL_TREE);
2782 return decl;
2785 static void
2786 generate_method_descriptors (protocol)
2787 tree protocol;
2789 tree initlist, chain, method_list_template;
2790 tree cast, variable_length_type;
2791 int size;
2793 if (!objc_method_prototype_template)
2794 objc_method_prototype_template = build_method_prototype_template ();
2796 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2797 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2798 NULL_TREE);
2799 variable_length_type = groktypename (cast);
2801 chain = PROTOCOL_CLS_METHODS (protocol);
2802 if (chain)
2804 size = list_length (chain);
2806 method_list_template
2807 = build_method_prototype_list_template (objc_method_prototype_template,
2808 size);
2810 initlist
2811 = build_descriptor_table_initializer (objc_method_prototype_template,
2812 chain);
2814 UOBJC_CLASS_METHODS_decl
2815 = generate_descriptor_table (method_list_template,
2816 "_OBJC_PROTOCOL_CLASS_METHODS",
2817 size, initlist, protocol);
2818 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2820 else
2821 UOBJC_CLASS_METHODS_decl = 0;
2823 chain = PROTOCOL_NST_METHODS (protocol);
2824 if (chain)
2826 size = list_length (chain);
2828 method_list_template
2829 = build_method_prototype_list_template (objc_method_prototype_template,
2830 size);
2831 initlist
2832 = build_descriptor_table_initializer (objc_method_prototype_template,
2833 chain);
2835 UOBJC_INSTANCE_METHODS_decl
2836 = generate_descriptor_table (method_list_template,
2837 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2838 size, initlist, protocol);
2839 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2841 else
2842 UOBJC_INSTANCE_METHODS_decl = 0;
2845 /* Generate a temporary FUNCTION_DECL node to be used in
2846 hack_method_prototype below. */
2848 static tree
2849 build_tmp_function_decl ()
2851 tree decl_specs, expr_decl, parms;
2852 static int xxx = 0;
2853 char buffer[80];
2855 /* struct objc_object *objc_xxx (id, SEL, ...); */
2856 pushlevel (0);
2857 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2858 push_parm_decl (build_tree_list
2859 (build_tree_list (decl_specs,
2860 build1 (INDIRECT_REF, NULL_TREE,
2861 NULL_TREE)),
2862 NULL_TREE));
2864 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2865 get_identifier (TAG_SELECTOR)));
2866 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2868 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2869 NULL_TREE));
2870 parms = get_parm_info (0);
2871 poplevel (0, 0, 0);
2873 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2874 sprintf (buffer, "__objc_tmp_%x", xxx++);
2875 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2876 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2878 return define_decl (expr_decl, decl_specs);
2881 /* Generate the prototypes for protocol methods. This is used to
2882 generate method encodings for these.
2884 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2885 a decl node to be used. This is also where the return value is
2886 given. */
2888 static void
2889 hack_method_prototype (nst_methods, tmp_decl)
2890 tree nst_methods;
2891 tree tmp_decl;
2893 tree parms;
2894 tree parm;
2896 /* Hack to avoid problem with static typing of self arg. */
2897 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2898 start_method_def (nst_methods);
2899 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2901 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2902 parms = get_parm_info (0); /* we have a `, ...' */
2903 else
2904 parms = get_parm_info (1); /* place a `void_at_end' */
2906 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2908 /* Usually called from store_parm_decls -> init_function_start. */
2910 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2912 if (current_function_decl)
2913 abort ();
2914 current_function_decl = tmp_decl;
2917 /* Code taken from start_function. */
2918 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2919 /* Promote the value to int before returning it. */
2920 if (TREE_CODE (restype) == INTEGER_TYPE
2921 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2922 restype = integer_type_node;
2923 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2926 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2927 DECL_CONTEXT (parm) = tmp_decl;
2929 init_function_start (tmp_decl, "objc-act", 0);
2931 /* Typically called from expand_function_start for function definitions. */
2932 assign_parms (tmp_decl);
2934 /* install return type */
2935 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2937 current_function_decl = NULL;
2940 static void
2941 generate_protocol_references (plist)
2942 tree plist;
2944 tree lproto;
2946 /* Forward declare protocols referenced. */
2947 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2949 tree proto = TREE_VALUE (lproto);
2951 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2952 && PROTOCOL_NAME (proto))
2954 if (! PROTOCOL_FORWARD_DECL (proto))
2955 build_protocol_reference (proto);
2957 if (PROTOCOL_LIST (proto))
2958 generate_protocol_references (PROTOCOL_LIST (proto));
2963 static void
2964 generate_protocols ()
2966 tree p, tmp_decl, encoding;
2967 tree sc_spec, decl_specs, decl;
2968 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2969 tree cast_type2;
2971 tmp_decl = build_tmp_function_decl ();
2973 if (! objc_protocol_template)
2974 objc_protocol_template = build_protocol_template ();
2976 /* If a protocol was directly referenced, pull in indirect references. */
2977 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2978 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2979 generate_protocol_references (PROTOCOL_LIST (p));
2981 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2983 tree nst_methods = PROTOCOL_NST_METHODS (p);
2984 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2986 /* If protocol wasn't referenced, don't generate any code. */
2987 if (! PROTOCOL_FORWARD_DECL (p))
2988 continue;
2990 /* Make sure we link in the Protocol class. */
2991 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2993 while (nst_methods)
2995 if (! METHOD_ENCODING (nst_methods))
2997 hack_method_prototype (nst_methods, tmp_decl);
2998 encoding = encode_method_prototype (nst_methods, tmp_decl);
2999 METHOD_ENCODING (nst_methods) = encoding;
3001 nst_methods = TREE_CHAIN (nst_methods);
3004 while (cls_methods)
3006 if (! METHOD_ENCODING (cls_methods))
3008 hack_method_prototype (cls_methods, tmp_decl);
3009 encoding = encode_method_prototype (cls_methods, tmp_decl);
3010 METHOD_ENCODING (cls_methods) = encoding;
3013 cls_methods = TREE_CHAIN (cls_methods);
3015 generate_method_descriptors (p);
3017 if (PROTOCOL_LIST (p))
3018 refs_decl = generate_protocol_list (p);
3019 else
3020 refs_decl = 0;
3022 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3024 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3025 NULL_TREE);
3026 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3028 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3029 decl_specs, 1, NULL_TREE);
3031 DECL_CONTEXT (decl) = NULL_TREE;
3033 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3035 if (refs_decl)
3037 cast_type2
3038 = groktypename
3039 (build_tree_list (build_tree_list (NULL_TREE,
3040 objc_protocol_template),
3041 build1 (INDIRECT_REF, NULL_TREE,
3042 build1 (INDIRECT_REF, NULL_TREE,
3043 NULL_TREE))));
3045 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3046 TREE_TYPE (refs_expr) = cast_type2;
3048 else
3049 refs_expr = build_int_2 (0, 0);
3051 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3052 by generate_method_descriptors, which is called above. */
3053 initlist = build_protocol_initializer (TREE_TYPE (decl),
3054 protocol_name_expr, refs_expr,
3055 UOBJC_INSTANCE_METHODS_decl,
3056 UOBJC_CLASS_METHODS_decl);
3057 finish_decl (decl, initlist, NULL_TREE);
3059 /* Mark the decl as used to avoid "defined but not used" warning. */
3060 TREE_USED (decl) = 1;
3064 static tree
3065 build_protocol_initializer (type, protocol_name, protocol_list,
3066 instance_methods, class_methods)
3067 tree type;
3068 tree protocol_name;
3069 tree protocol_list;
3070 tree instance_methods;
3071 tree class_methods;
3073 tree initlist = NULL_TREE, expr;
3074 tree cast_type;
3076 cast_type = groktypename
3077 (build_tree_list
3078 (build_tree_list (NULL_TREE,
3079 xref_tag (RECORD_TYPE,
3080 get_identifier (UTAG_CLASS))),
3081 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3083 /* Filling the "isa" in with one allows the runtime system to
3084 detect that the version change...should remove before final release. */
3086 expr = build_int_2 (PROTOCOL_VERSION, 0);
3087 TREE_TYPE (expr) = cast_type;
3088 initlist = tree_cons (NULL_TREE, expr, initlist);
3089 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3090 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3092 if (!instance_methods)
3093 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3094 else
3096 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3097 initlist = tree_cons (NULL_TREE, expr, initlist);
3100 if (!class_methods)
3101 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3102 else
3104 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3105 initlist = tree_cons (NULL_TREE, expr, initlist);
3108 return build_constructor (type, nreverse (initlist));
3111 /* struct objc_category {
3112 char *category_name;
3113 char *class_name;
3114 struct objc_method_list *instance_methods;
3115 struct objc_method_list *class_methods;
3116 struct objc_protocol_list *protocols;
3117 }; */
3119 static void
3120 build_category_template ()
3122 tree decl_specs, field_decl, field_decl_chain;
3124 objc_category_template = start_struct (RECORD_TYPE,
3125 get_identifier (UTAG_CATEGORY));
3126 /* char *category_name; */
3128 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3129 field_decl
3130 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3131 field_decl
3132 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3133 field_decl_chain = field_decl;
3135 /* char *class_name; */
3137 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3138 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3139 field_decl
3140 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3141 chainon (field_decl_chain, field_decl);
3143 /* struct objc_method_list *instance_methods; */
3145 decl_specs = build_tree_list (NULL_TREE,
3146 xref_tag (RECORD_TYPE,
3147 get_identifier (UTAG_METHOD_LIST)));
3148 field_decl
3149 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3150 field_decl
3151 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3152 chainon (field_decl_chain, field_decl);
3154 /* struct objc_method_list *class_methods; */
3156 decl_specs = build_tree_list (NULL_TREE,
3157 xref_tag (RECORD_TYPE,
3158 get_identifier (UTAG_METHOD_LIST)));
3159 field_decl
3160 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3161 field_decl
3162 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3163 chainon (field_decl_chain, field_decl);
3165 /* struct objc_protocol **protocol_list; */
3167 decl_specs = build_tree_list (NULL_TREE,
3168 xref_tag (RECORD_TYPE,
3169 get_identifier (UTAG_PROTOCOL)));
3170 field_decl
3171 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3172 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3173 field_decl
3174 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3175 chainon (field_decl_chain, field_decl);
3177 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3180 /* struct objc_selector {
3181 void *sel_id;
3182 char *sel_type;
3183 }; */
3185 static void
3186 build_selector_template ()
3189 tree decl_specs, field_decl, field_decl_chain;
3191 objc_selector_template
3192 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3194 /* void *sel_id; */
3196 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3197 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3198 field_decl
3199 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3200 field_decl_chain = field_decl;
3202 /* char *sel_type; */
3204 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3205 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
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_selector_template, field_decl_chain, NULL_TREE);
3213 /* struct objc_class {
3214 struct objc_class *isa;
3215 struct objc_class *super_class;
3216 char *name;
3217 long version;
3218 long info;
3219 long instance_size;
3220 struct objc_ivar_list *ivars;
3221 struct objc_method_list *methods;
3222 if (flag_next_runtime)
3223 struct objc_cache *cache;
3224 else {
3225 struct sarray *dtable;
3226 struct objc_class *subclass_list;
3227 struct objc_class *sibling_class;
3229 struct objc_protocol_list *protocols;
3230 void *gc_object_type;
3231 }; */
3233 static void
3234 build_class_template ()
3236 tree decl_specs, field_decl, field_decl_chain;
3238 objc_class_template
3239 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3241 /* struct objc_class *isa; */
3243 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3244 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3245 field_decl
3246 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3247 field_decl_chain = field_decl;
3249 /* struct objc_class *super_class; */
3251 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3252 field_decl
3253 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3254 field_decl
3255 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3256 chainon (field_decl_chain, field_decl);
3258 /* char *name; */
3260 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3261 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3262 field_decl
3263 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3264 chainon (field_decl_chain, field_decl);
3266 /* long version; */
3268 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3269 field_decl = get_identifier ("version");
3270 field_decl
3271 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3272 chainon (field_decl_chain, field_decl);
3274 /* long info; */
3276 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3277 field_decl = get_identifier ("info");
3278 field_decl
3279 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3280 chainon (field_decl_chain, field_decl);
3282 /* long instance_size; */
3284 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3285 field_decl = get_identifier ("instance_size");
3286 field_decl
3287 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3288 chainon (field_decl_chain, field_decl);
3290 /* struct objc_ivar_list *ivars; */
3292 decl_specs = build_tree_list (NULL_TREE,
3293 xref_tag (RECORD_TYPE,
3294 get_identifier (UTAG_IVAR_LIST)));
3295 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3296 field_decl
3297 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3298 chainon (field_decl_chain, field_decl);
3300 /* struct objc_method_list *methods; */
3302 decl_specs = build_tree_list (NULL_TREE,
3303 xref_tag (RECORD_TYPE,
3304 get_identifier (UTAG_METHOD_LIST)));
3305 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3306 field_decl
3307 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3308 chainon (field_decl_chain, field_decl);
3310 if (flag_next_runtime)
3312 /* struct objc_cache *cache; */
3314 decl_specs = build_tree_list (NULL_TREE,
3315 xref_tag (RECORD_TYPE,
3316 get_identifier ("objc_cache")));
3317 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3318 field_decl = grokfield (input_filename, lineno, field_decl,
3319 decl_specs, NULL_TREE);
3320 chainon (field_decl_chain, field_decl);
3322 else
3324 /* struct sarray *dtable; */
3326 decl_specs = build_tree_list (NULL_TREE,
3327 xref_tag (RECORD_TYPE,
3328 get_identifier ("sarray")));
3329 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3330 field_decl = grokfield (input_filename, lineno, field_decl,
3331 decl_specs, NULL_TREE);
3332 chainon (field_decl_chain, field_decl);
3334 /* struct objc_class *subclass_list; */
3336 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3337 field_decl
3338 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3339 field_decl = grokfield (input_filename, lineno, field_decl,
3340 decl_specs, NULL_TREE);
3341 chainon (field_decl_chain, field_decl);
3343 /* struct objc_class *sibling_class; */
3345 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3346 field_decl
3347 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3348 field_decl = grokfield (input_filename, lineno, field_decl,
3349 decl_specs, NULL_TREE);
3350 chainon (field_decl_chain, field_decl);
3353 /* struct objc_protocol **protocol_list; */
3355 decl_specs = build_tree_list (NULL_TREE,
3356 xref_tag (RECORD_TYPE,
3357 get_identifier (UTAG_PROTOCOL)));
3358 field_decl
3359 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3360 field_decl
3361 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3362 field_decl = grokfield (input_filename, lineno, field_decl,
3363 decl_specs, NULL_TREE);
3364 chainon (field_decl_chain, field_decl);
3366 /* void *sel_id; */
3368 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3369 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3370 field_decl
3371 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3372 chainon (field_decl_chain, field_decl);
3374 /* void *gc_object_type; */
3376 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3377 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3378 field_decl
3379 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3380 chainon (field_decl_chain, field_decl);
3382 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3385 /* Generate appropriate forward declarations for an implementation. */
3387 static void
3388 synth_forward_declarations ()
3390 tree sc_spec, decl_specs, an_id;
3392 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3394 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3396 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3397 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3398 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3399 TREE_USED (UOBJC_CLASS_decl) = 1;
3400 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3402 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3404 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3405 objc_implementation_context);
3407 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3408 TREE_USED (UOBJC_METACLASS_decl) = 1;
3409 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3411 /* Pre-build the following entities - for speed/convenience. */
3413 an_id = get_identifier ("super_class");
3414 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3415 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3418 static void
3419 error_with_ivar (message, decl, rawdecl)
3420 const char *message;
3421 tree decl;
3422 tree rawdecl;
3424 diagnostic_count_diagnostic (global_dc, DK_ERROR);
3426 diagnostic_report_current_function (global_dc);
3428 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3429 DECL_SOURCE_LINE (decl),
3430 "%s `%s'",
3431 message, gen_declaration (rawdecl, errbuf));
3435 #define USERTYPE(t) \
3436 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3437 || TREE_CODE (t) == ENUMERAL_TYPE)
3439 static void
3440 check_ivars (inter, imp)
3441 tree inter;
3442 tree imp;
3444 tree intdecls = CLASS_IVARS (inter);
3445 tree impdecls = CLASS_IVARS (imp);
3446 tree rawintdecls = CLASS_RAW_IVARS (inter);
3447 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3449 while (1)
3451 tree t1, t2;
3453 if (intdecls == 0 && impdecls == 0)
3454 break;
3455 if (intdecls == 0 || impdecls == 0)
3457 error ("inconsistent instance variable specification");
3458 break;
3461 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3463 if (!comptypes (t1, t2))
3465 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3467 error_with_ivar ("conflicting instance variable type",
3468 impdecls, rawimpdecls);
3469 error_with_ivar ("previous declaration of",
3470 intdecls, rawintdecls);
3472 else /* both the type and the name don't match */
3474 error ("inconsistent instance variable specification");
3475 break;
3479 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3481 error_with_ivar ("conflicting instance variable name",
3482 impdecls, rawimpdecls);
3483 error_with_ivar ("previous declaration of",
3484 intdecls, rawintdecls);
3487 intdecls = TREE_CHAIN (intdecls);
3488 impdecls = TREE_CHAIN (impdecls);
3489 rawintdecls = TREE_CHAIN (rawintdecls);
3490 rawimpdecls = TREE_CHAIN (rawimpdecls);
3494 /* Set super_type to the data type node for struct objc_super *,
3495 first defining struct objc_super itself.
3496 This needs to be done just once per compilation. */
3498 static tree
3499 build_super_template ()
3501 tree record, decl_specs, field_decl, field_decl_chain;
3503 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3505 /* struct objc_object *self; */
3507 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3508 field_decl = get_identifier ("self");
3509 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3510 field_decl = grokfield (input_filename, lineno,
3511 field_decl, decl_specs, NULL_TREE);
3512 field_decl_chain = field_decl;
3514 /* struct objc_class *class; */
3516 decl_specs = get_identifier (UTAG_CLASS);
3517 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3518 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3520 field_decl = grokfield (input_filename, lineno,
3521 field_decl, decl_specs, NULL_TREE);
3522 chainon (field_decl_chain, field_decl);
3524 finish_struct (record, field_decl_chain, NULL_TREE);
3526 /* `struct objc_super *' */
3527 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3528 record),
3529 build1 (INDIRECT_REF,
3530 NULL_TREE, NULL_TREE)));
3531 return record;
3534 /* struct objc_ivar {
3535 char *ivar_name;
3536 char *ivar_type;
3537 int ivar_offset;
3538 }; */
3540 static tree
3541 build_ivar_template ()
3543 tree objc_ivar_id, objc_ivar_record;
3544 tree decl_specs, field_decl, field_decl_chain;
3546 objc_ivar_id = get_identifier (UTAG_IVAR);
3547 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3549 /* char *ivar_name; */
3551 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3552 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3554 field_decl = grokfield (input_filename, lineno, field_decl,
3555 decl_specs, NULL_TREE);
3556 field_decl_chain = field_decl;
3558 /* char *ivar_type; */
3560 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3561 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3563 field_decl = grokfield (input_filename, lineno, field_decl,
3564 decl_specs, NULL_TREE);
3565 chainon (field_decl_chain, field_decl);
3567 /* int ivar_offset; */
3569 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3570 field_decl = get_identifier ("ivar_offset");
3572 field_decl = grokfield (input_filename, lineno, field_decl,
3573 decl_specs, NULL_TREE);
3574 chainon (field_decl_chain, field_decl);
3576 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3578 return objc_ivar_record;
3581 /* struct {
3582 int ivar_count;
3583 struct objc_ivar ivar_list[ivar_count];
3584 }; */
3586 static tree
3587 build_ivar_list_template (list_type, size)
3588 tree list_type;
3589 int size;
3591 tree objc_ivar_list_record;
3592 tree decl_specs, field_decl, field_decl_chain;
3594 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3596 /* int ivar_count; */
3598 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3599 field_decl = get_identifier ("ivar_count");
3601 field_decl = grokfield (input_filename, lineno, field_decl,
3602 decl_specs, NULL_TREE);
3603 field_decl_chain = field_decl;
3605 /* struct objc_ivar ivar_list[]; */
3607 decl_specs = build_tree_list (NULL_TREE, list_type);
3608 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3609 build_int_2 (size, 0));
3611 field_decl = grokfield (input_filename, lineno,
3612 field_decl, decl_specs, NULL_TREE);
3613 chainon (field_decl_chain, field_decl);
3615 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3617 return objc_ivar_list_record;
3620 /* struct {
3621 int method_next;
3622 int method_count;
3623 struct objc_method method_list[method_count];
3624 }; */
3626 static tree
3627 build_method_list_template (list_type, size)
3628 tree list_type;
3629 int size;
3631 tree objc_ivar_list_record;
3632 tree decl_specs, field_decl, field_decl_chain;
3634 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3636 /* int method_next; */
3638 decl_specs
3639 = build_tree_list
3640 (NULL_TREE,
3641 xref_tag (RECORD_TYPE,
3642 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3643 field_decl
3644 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3645 field_decl = grokfield (input_filename, lineno, field_decl,
3646 decl_specs, NULL_TREE);
3647 field_decl_chain = field_decl;
3649 /* int method_count; */
3651 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3652 field_decl = get_identifier ("method_count");
3654 field_decl = grokfield (input_filename, lineno,
3655 field_decl, decl_specs, NULL_TREE);
3656 chainon (field_decl_chain, field_decl);
3658 /* struct objc_method method_list[]; */
3660 decl_specs = build_tree_list (NULL_TREE, list_type);
3661 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3662 build_int_2 (size, 0));
3664 field_decl = grokfield (input_filename, lineno,
3665 field_decl, decl_specs, NULL_TREE);
3666 chainon (field_decl_chain, field_decl);
3668 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3670 return objc_ivar_list_record;
3673 static tree
3674 build_ivar_list_initializer (type, field_decl)
3675 tree type;
3676 tree field_decl;
3678 tree initlist = NULL_TREE;
3682 tree ivar = NULL_TREE;
3684 /* Set name. */
3685 if (DECL_NAME (field_decl))
3686 ivar = tree_cons (NULL_TREE,
3687 add_objc_string (DECL_NAME (field_decl),
3688 meth_var_names),
3689 ivar);
3690 else
3691 /* Unnamed bit-field ivar (yuck). */
3692 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3694 /* Set type. */
3695 encode_field_decl (field_decl,
3696 obstack_object_size (&util_obstack),
3697 OBJC_ENCODE_DONT_INLINE_DEFS);
3699 /* Null terminate string. */
3700 obstack_1grow (&util_obstack, 0);
3701 ivar
3702 = tree_cons
3703 (NULL_TREE,
3704 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3705 meth_var_types),
3706 ivar);
3707 obstack_free (&util_obstack, util_firstobj);
3709 /* Set offset. */
3710 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3711 initlist = tree_cons (NULL_TREE,
3712 build_constructor (type, nreverse (ivar)),
3713 initlist);
3715 field_decl = TREE_CHAIN (field_decl);
3717 while (field_decl);
3719 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3722 static tree
3723 generate_ivars_list (type, name, size, list)
3724 tree type;
3725 const char *name;
3726 int size;
3727 tree list;
3729 tree sc_spec, decl_specs, decl, initlist;
3731 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3732 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3734 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3735 decl_specs, 1, NULL_TREE);
3737 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3738 initlist = tree_cons (NULL_TREE, list, initlist);
3740 finish_decl (decl,
3741 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3742 NULL_TREE);
3744 return decl;
3747 static void
3748 generate_ivar_lists ()
3750 tree initlist, ivar_list_template, chain;
3751 tree cast, variable_length_type;
3752 int size;
3754 generating_instance_variables = 1;
3756 if (!objc_ivar_template)
3757 objc_ivar_template = build_ivar_template ();
3759 cast
3760 = build_tree_list
3761 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3762 get_identifier (UTAG_IVAR_LIST))),
3763 NULL_TREE);
3764 variable_length_type = groktypename (cast);
3766 /* Only generate class variables for the root of the inheritance
3767 hierarchy since these will be the same for every class. */
3769 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3770 && (chain = TYPE_FIELDS (objc_class_template)))
3772 size = list_length (chain);
3774 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3775 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3777 UOBJC_CLASS_VARIABLES_decl
3778 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3779 size, initlist);
3780 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3782 else
3783 UOBJC_CLASS_VARIABLES_decl = 0;
3785 chain = CLASS_IVARS (implementation_template);
3786 if (chain)
3788 size = list_length (chain);
3789 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3790 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3792 UOBJC_INSTANCE_VARIABLES_decl
3793 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3794 size, initlist);
3795 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3797 else
3798 UOBJC_INSTANCE_VARIABLES_decl = 0;
3800 generating_instance_variables = 0;
3803 static tree
3804 build_dispatch_table_initializer (type, entries)
3805 tree type;
3806 tree entries;
3808 tree initlist = NULL_TREE;
3812 tree elemlist = NULL_TREE;
3814 elemlist = tree_cons (NULL_TREE,
3815 build_selector (METHOD_SEL_NAME (entries)),
3816 NULL_TREE);
3818 /* Generate the method encoding if we don't have one already. */
3819 if (! METHOD_ENCODING (entries))
3820 METHOD_ENCODING (entries) =
3821 encode_method_def (METHOD_DEFINITION (entries));
3823 elemlist = tree_cons (NULL_TREE,
3824 add_objc_string (METHOD_ENCODING (entries),
3825 meth_var_types),
3826 elemlist);
3828 elemlist = tree_cons (NULL_TREE,
3829 build_unary_op (ADDR_EXPR,
3830 METHOD_DEFINITION (entries), 1),
3831 elemlist);
3833 initlist = tree_cons (NULL_TREE,
3834 build_constructor (type, nreverse (elemlist)),
3835 initlist);
3837 entries = TREE_CHAIN (entries);
3839 while (entries);
3841 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3844 /* To accomplish method prototyping without generating all kinds of
3845 inane warnings, the definition of the dispatch table entries were
3846 changed from:
3848 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3850 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3852 static tree
3853 build_method_template ()
3855 tree _SLT_record;
3856 tree decl_specs, field_decl, field_decl_chain;
3858 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3860 /* struct objc_selector *_cmd; */
3861 decl_specs = tree_cons (NULL_TREE,
3862 xref_tag (RECORD_TYPE,
3863 get_identifier (TAG_SELECTOR)),
3864 NULL_TREE);
3865 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3867 field_decl = grokfield (input_filename, lineno, field_decl,
3868 decl_specs, NULL_TREE);
3869 field_decl_chain = field_decl;
3871 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3872 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3873 get_identifier ("method_types"));
3874 field_decl = grokfield (input_filename, lineno, field_decl,
3875 decl_specs, NULL_TREE);
3876 chainon (field_decl_chain, field_decl);
3878 /* void *_imp; */
3880 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3881 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3882 field_decl = grokfield (input_filename, lineno, field_decl,
3883 decl_specs, NULL_TREE);
3884 chainon (field_decl_chain, field_decl);
3886 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3888 return _SLT_record;
3892 static tree
3893 generate_dispatch_table (type, name, size, list)
3894 tree type;
3895 const char *name;
3896 int size;
3897 tree list;
3899 tree sc_spec, decl_specs, decl, initlist;
3901 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3902 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3904 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3905 decl_specs, 1, NULL_TREE);
3907 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3908 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3909 initlist = tree_cons (NULL_TREE, list, initlist);
3911 finish_decl (decl,
3912 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3913 NULL_TREE);
3915 return decl;
3918 static void
3919 generate_dispatch_tables ()
3921 tree initlist, chain, method_list_template;
3922 tree cast, variable_length_type;
3923 int size;
3925 if (!objc_method_template)
3926 objc_method_template = build_method_template ();
3928 cast
3929 = build_tree_list
3930 (build_tree_list (NULL_TREE,
3931 xref_tag (RECORD_TYPE,
3932 get_identifier (UTAG_METHOD_LIST))),
3933 NULL_TREE);
3935 variable_length_type = groktypename (cast);
3937 chain = CLASS_CLS_METHODS (objc_implementation_context);
3938 if (chain)
3940 size = list_length (chain);
3942 method_list_template
3943 = build_method_list_template (objc_method_template, size);
3944 initlist
3945 = build_dispatch_table_initializer (objc_method_template, chain);
3947 UOBJC_CLASS_METHODS_decl
3948 = generate_dispatch_table (method_list_template,
3949 ((TREE_CODE (objc_implementation_context)
3950 == CLASS_IMPLEMENTATION_TYPE)
3951 ? "_OBJC_CLASS_METHODS"
3952 : "_OBJC_CATEGORY_CLASS_METHODS"),
3953 size, initlist);
3954 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3956 else
3957 UOBJC_CLASS_METHODS_decl = 0;
3959 chain = CLASS_NST_METHODS (objc_implementation_context);
3960 if (chain)
3962 size = list_length (chain);
3964 method_list_template
3965 = build_method_list_template (objc_method_template, size);
3966 initlist
3967 = build_dispatch_table_initializer (objc_method_template, chain);
3969 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3970 UOBJC_INSTANCE_METHODS_decl
3971 = generate_dispatch_table (method_list_template,
3972 "_OBJC_INSTANCE_METHODS",
3973 size, initlist);
3974 else
3975 /* We have a category. */
3976 UOBJC_INSTANCE_METHODS_decl
3977 = generate_dispatch_table (method_list_template,
3978 "_OBJC_CATEGORY_INSTANCE_METHODS",
3979 size, initlist);
3980 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3982 else
3983 UOBJC_INSTANCE_METHODS_decl = 0;
3986 static tree
3987 generate_protocol_list (i_or_p)
3988 tree i_or_p;
3990 tree initlist, decl_specs, sc_spec;
3991 tree refs_decl, expr_decl, lproto, e, plist;
3992 tree cast_type;
3993 int size = 0;
3995 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3996 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
3997 plist = CLASS_PROTOCOL_LIST (i_or_p);
3998 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
3999 plist = PROTOCOL_LIST (i_or_p);
4000 else
4001 abort ();
4003 cast_type = groktypename
4004 (build_tree_list
4005 (build_tree_list (NULL_TREE,
4006 xref_tag (RECORD_TYPE,
4007 get_identifier (UTAG_PROTOCOL))),
4008 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4010 /* Compute size. */
4011 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4012 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4013 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4014 size++;
4016 /* Build initializer. */
4017 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4019 e = build_int_2 (size, 0);
4020 TREE_TYPE (e) = cast_type;
4021 initlist = tree_cons (NULL_TREE, e, initlist);
4023 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4025 tree pval = TREE_VALUE (lproto);
4027 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4028 && PROTOCOL_FORWARD_DECL (pval))
4030 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4031 initlist = tree_cons (NULL_TREE, e, initlist);
4035 /* static struct objc_protocol *refs[n]; */
4037 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4038 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4039 get_identifier (UTAG_PROTOCOL)),
4040 sc_spec);
4042 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4043 expr_decl = build_nt (ARRAY_REF,
4044 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4045 i_or_p),
4046 build_int_2 (size + 2, 0));
4047 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4048 expr_decl = build_nt (ARRAY_REF,
4049 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4050 i_or_p),
4051 build_int_2 (size + 2, 0));
4052 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4053 expr_decl
4054 = build_nt (ARRAY_REF,
4055 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4056 i_or_p),
4057 build_int_2 (size + 2, 0));
4058 else
4059 abort ();
4061 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4063 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4064 DECL_CONTEXT (refs_decl) = NULL_TREE;
4066 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4067 nreverse (initlist)),
4068 NULL_TREE);
4070 return refs_decl;
4073 static tree
4074 build_category_initializer (type, cat_name, class_name,
4075 instance_methods, class_methods, protocol_list)
4076 tree type;
4077 tree cat_name;
4078 tree class_name;
4079 tree instance_methods;
4080 tree class_methods;
4081 tree protocol_list;
4083 tree initlist = NULL_TREE, expr;
4085 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4086 initlist = tree_cons (NULL_TREE, class_name, initlist);
4088 if (!instance_methods)
4089 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4090 else
4092 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4093 initlist = tree_cons (NULL_TREE, expr, initlist);
4095 if (!class_methods)
4096 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4097 else
4099 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4100 initlist = tree_cons (NULL_TREE, expr, initlist);
4103 /* protocol_list = */
4104 if (!protocol_list)
4105 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4106 else
4108 tree cast_type2 = groktypename
4109 (build_tree_list
4110 (build_tree_list (NULL_TREE,
4111 xref_tag (RECORD_TYPE,
4112 get_identifier (UTAG_PROTOCOL))),
4113 build1 (INDIRECT_REF, NULL_TREE,
4114 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4116 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4117 TREE_TYPE (expr) = cast_type2;
4118 initlist = tree_cons (NULL_TREE, expr, initlist);
4121 return build_constructor (type, nreverse (initlist));
4124 /* struct objc_class {
4125 struct objc_class *isa;
4126 struct objc_class *super_class;
4127 char *name;
4128 long version;
4129 long info;
4130 long instance_size;
4131 struct objc_ivar_list *ivars;
4132 struct objc_method_list *methods;
4133 if (flag_next_runtime)
4134 struct objc_cache *cache;
4135 else {
4136 struct sarray *dtable;
4137 struct objc_class *subclass_list;
4138 struct objc_class *sibling_class;
4140 struct objc_protocol_list *protocols;
4141 void *gc_object_type;
4142 }; */
4144 static tree
4145 build_shared_structure_initializer (type, isa, super, name, size, status,
4146 dispatch_table, ivar_list, protocol_list)
4147 tree type;
4148 tree isa;
4149 tree super;
4150 tree name;
4151 tree size;
4152 int status;
4153 tree dispatch_table;
4154 tree ivar_list;
4155 tree protocol_list;
4157 tree initlist = NULL_TREE, expr;
4159 /* isa = */
4160 initlist = tree_cons (NULL_TREE, isa, initlist);
4162 /* super_class = */
4163 initlist = tree_cons (NULL_TREE, super, initlist);
4165 /* name = */
4166 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4168 /* version = */
4169 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4171 /* info = */
4172 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4174 /* instance_size = */
4175 initlist = tree_cons (NULL_TREE, size, initlist);
4177 /* objc_ivar_list = */
4178 if (!ivar_list)
4179 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4180 else
4182 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4183 initlist = tree_cons (NULL_TREE, expr, initlist);
4186 /* objc_method_list = */
4187 if (!dispatch_table)
4188 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4189 else
4191 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4192 initlist = tree_cons (NULL_TREE, expr, initlist);
4195 if (flag_next_runtime)
4196 /* method_cache = */
4197 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4198 else
4200 /* dtable = */
4201 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4203 /* subclass_list = */
4204 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4206 /* sibling_class = */
4207 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4210 /* protocol_list = */
4211 if (! protocol_list)
4212 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4213 else
4215 tree cast_type2
4216 = groktypename
4217 (build_tree_list
4218 (build_tree_list (NULL_TREE,
4219 xref_tag (RECORD_TYPE,
4220 get_identifier (UTAG_PROTOCOL))),
4221 build1 (INDIRECT_REF, NULL_TREE,
4222 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4224 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4225 TREE_TYPE (expr) = cast_type2;
4226 initlist = tree_cons (NULL_TREE, expr, initlist);
4229 /* gc_object_type = NULL */
4230 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4232 return build_constructor (type, nreverse (initlist));
4235 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4237 static void
4238 generate_category (cat)
4239 tree cat;
4241 tree sc_spec, decl_specs, decl;
4242 tree initlist, cat_name_expr, class_name_expr;
4243 tree protocol_decl, category;
4245 add_class_reference (CLASS_NAME (cat));
4246 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4248 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4250 category = CLASS_CATEGORY_LIST (implementation_template);
4252 /* find the category interface from the class it is associated with */
4253 while (category)
4255 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4256 break;
4257 category = CLASS_CATEGORY_LIST (category);
4260 if (category && CLASS_PROTOCOL_LIST (category))
4262 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4263 protocol_decl = generate_protocol_list (category);
4265 else
4266 protocol_decl = 0;
4268 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4269 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4271 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4272 objc_implementation_context),
4273 decl_specs, 1, NULL_TREE);
4275 initlist = build_category_initializer (TREE_TYPE (decl),
4276 cat_name_expr, class_name_expr,
4277 UOBJC_INSTANCE_METHODS_decl,
4278 UOBJC_CLASS_METHODS_decl,
4279 protocol_decl);
4281 TREE_USED (decl) = 1;
4282 finish_decl (decl, initlist, NULL_TREE);
4285 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4286 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4288 static void
4289 generate_shared_structures ()
4291 tree sc_spec, decl_specs, decl;
4292 tree name_expr, super_expr, root_expr;
4293 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4294 tree cast_type, initlist, protocol_decl;
4296 my_super_id = CLASS_SUPER_NAME (implementation_template);
4297 if (my_super_id)
4299 add_class_reference (my_super_id);
4301 /* Compute "my_root_id" - this is required for code generation.
4302 the "isa" for all meta class structures points to the root of
4303 the inheritance hierarchy (e.g. "__Object")... */
4304 my_root_id = my_super_id;
4307 tree my_root_int = lookup_interface (my_root_id);
4309 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4310 my_root_id = CLASS_SUPER_NAME (my_root_int);
4311 else
4312 break;
4314 while (1);
4316 else
4317 /* No super class. */
4318 my_root_id = CLASS_NAME (implementation_template);
4320 cast_type
4321 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4322 objc_class_template),
4323 build1 (INDIRECT_REF,
4324 NULL_TREE, NULL_TREE)));
4326 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4327 class_names);
4329 /* Install class `isa' and `super' pointers at runtime. */
4330 if (my_super_id)
4332 super_expr = add_objc_string (my_super_id, class_names);
4333 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4335 else
4336 super_expr = build_int_2 (0, 0);
4338 root_expr = add_objc_string (my_root_id, class_names);
4339 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4341 if (CLASS_PROTOCOL_LIST (implementation_template))
4343 generate_protocol_references
4344 (CLASS_PROTOCOL_LIST (implementation_template));
4345 protocol_decl = generate_protocol_list (implementation_template);
4347 else
4348 protocol_decl = 0;
4350 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4352 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4353 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4355 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4356 NULL_TREE);
4358 initlist
4359 = build_shared_structure_initializer
4360 (TREE_TYPE (decl),
4361 root_expr, super_expr, name_expr,
4362 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4363 2 /*CLS_META*/,
4364 UOBJC_CLASS_METHODS_decl,
4365 UOBJC_CLASS_VARIABLES_decl,
4366 protocol_decl);
4368 finish_decl (decl, initlist, NULL_TREE);
4370 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4372 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4373 NULL_TREE);
4375 initlist
4376 = build_shared_structure_initializer
4377 (TREE_TYPE (decl),
4378 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4379 super_expr, name_expr,
4380 convert (integer_type_node,
4381 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4382 (implementation_template))),
4383 1 /*CLS_FACTORY*/,
4384 UOBJC_INSTANCE_METHODS_decl,
4385 UOBJC_INSTANCE_VARIABLES_decl,
4386 protocol_decl);
4388 finish_decl (decl, initlist, NULL_TREE);
4391 static tree
4392 synth_id_with_class_suffix (preamble, ctxt)
4393 const char *preamble;
4394 tree ctxt;
4396 char *string;
4397 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4398 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4400 const char *const class_name
4401 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4402 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4403 sprintf (string, "%s_%s", preamble,
4404 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4406 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4407 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4409 /* We have a category. */
4410 const char *const class_name
4411 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4412 const char *const class_super_name
4413 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4414 string = (char *) alloca (strlen (preamble)
4415 + strlen (class_name)
4416 + strlen (class_super_name)
4417 + 3);
4418 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4420 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4422 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4423 string
4424 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4425 sprintf (string, "%s_%s", preamble, protocol_name);
4427 else
4428 abort ();
4430 return get_identifier (string);
4433 static int
4434 is_objc_type_qualifier (node)
4435 tree node;
4437 return (TREE_CODE (node) == IDENTIFIER_NODE
4438 && (node == ridpointers [(int) RID_CONST]
4439 || node == ridpointers [(int) RID_VOLATILE]
4440 || node == ridpointers [(int) RID_IN]
4441 || node == ridpointers [(int) RID_OUT]
4442 || node == ridpointers [(int) RID_INOUT]
4443 || node == ridpointers [(int) RID_BYCOPY]
4444 || node == ridpointers [(int) RID_BYREF]
4445 || node == ridpointers [(int) RID_ONEWAY]));
4448 /* If type is empty or only type qualifiers are present, add default
4449 type of id (otherwise grokdeclarator will default to int). */
4451 static tree
4452 adjust_type_for_id_default (type)
4453 tree type;
4455 tree declspecs, chain;
4457 if (!type)
4458 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4459 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4461 declspecs = TREE_PURPOSE (type);
4463 /* Determine if a typespec is present. */
4464 for (chain = declspecs;
4465 chain;
4466 chain = TREE_CHAIN (chain))
4468 if (TREE_CODE (TREE_VALUE (chain)) == RECORD_TYPE
4469 && !(TREE_VALUE (type)
4470 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
4471 error ("can not use an object as parameter to a method\n");
4472 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4473 return type;
4476 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4477 declspecs),
4478 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4481 /* Usage:
4482 keyworddecl:
4483 selector ':' '(' typename ')' identifier
4485 Purpose:
4486 Transform an Objective-C keyword argument into
4487 the C equivalent parameter declarator.
4489 In: key_name, an "identifier_node" (optional).
4490 arg_type, a "tree_list" (optional).
4491 arg_name, an "identifier_node".
4493 Note: It would be really nice to strongly type the preceding
4494 arguments in the function prototype; however, then I
4495 could not use the "accessor" macros defined in "tree.h".
4497 Out: an instance of "keyword_decl". */
4499 tree
4500 build_keyword_decl (key_name, arg_type, arg_name)
4501 tree key_name;
4502 tree arg_type;
4503 tree arg_name;
4505 tree keyword_decl;
4507 /* If no type is specified, default to "id". */
4508 arg_type = adjust_type_for_id_default (arg_type);
4510 keyword_decl = make_node (KEYWORD_DECL);
4512 TREE_TYPE (keyword_decl) = arg_type;
4513 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4514 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4516 return keyword_decl;
4519 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4521 static tree
4522 build_keyword_selector (selector)
4523 tree selector;
4525 int len = 0;
4526 tree key_chain, key_name;
4527 char *buf;
4529 /* Scan the selector to see how much space we'll need. */
4530 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4532 if (TREE_CODE (selector) == KEYWORD_DECL)
4533 key_name = KEYWORD_KEY_NAME (key_chain);
4534 else if (TREE_CODE (selector) == TREE_LIST)
4535 key_name = TREE_PURPOSE (key_chain);
4536 else
4537 abort ();
4539 if (key_name)
4540 len += IDENTIFIER_LENGTH (key_name) + 1;
4541 else
4542 /* Just a ':' arg. */
4543 len++;
4546 buf = (char *) alloca (len + 1);
4547 /* Start the buffer out as an empty string. */
4548 buf[0] = '\0';
4550 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4552 if (TREE_CODE (selector) == KEYWORD_DECL)
4553 key_name = KEYWORD_KEY_NAME (key_chain);
4554 else if (TREE_CODE (selector) == TREE_LIST)
4555 key_name = TREE_PURPOSE (key_chain);
4556 else
4557 abort ();
4559 if (key_name)
4560 strcat (buf, IDENTIFIER_POINTER (key_name));
4561 strcat (buf, ":");
4564 return get_identifier (buf);
4567 /* Used for declarations and definitions. */
4569 tree
4570 build_method_decl (code, ret_type, selector, add_args)
4571 enum tree_code code;
4572 tree ret_type;
4573 tree selector;
4574 tree add_args;
4576 tree method_decl;
4578 /* If no type is specified, default to "id". */
4579 ret_type = adjust_type_for_id_default (ret_type);
4581 method_decl = make_node (code);
4582 TREE_TYPE (method_decl) = ret_type;
4584 /* If we have a keyword selector, create an identifier_node that
4585 represents the full selector name (`:' included)... */
4586 if (TREE_CODE (selector) == KEYWORD_DECL)
4588 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4589 METHOD_SEL_ARGS (method_decl) = selector;
4590 METHOD_ADD_ARGS (method_decl) = add_args;
4592 else
4594 METHOD_SEL_NAME (method_decl) = selector;
4595 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4596 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4599 return method_decl;
4602 #define METHOD_DEF 0
4603 #define METHOD_REF 1
4605 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4606 an argument list for method METH. CONTEXT is either METHOD_DEF or
4607 METHOD_REF, saying whether we are trying to define a method or call
4608 one. SUPERFLAG says this is for a send to super; this makes a
4609 difference for the NeXT calling sequence in which the lookup and
4610 the method call are done together. */
4612 static tree
4613 get_arg_type_list (meth, context, superflag)
4614 tree meth;
4615 int context;
4616 int superflag;
4618 tree arglist, akey;
4620 /* Receiver type. */
4621 if (flag_next_runtime && superflag)
4622 arglist = build_tree_list (NULL_TREE, super_type);
4623 else if (context == METHOD_DEF)
4624 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4625 else
4626 arglist = build_tree_list (NULL_TREE, id_type);
4628 /* Selector type - will eventually change to `int'. */
4629 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4631 /* Build a list of argument types. */
4632 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4634 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4635 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4638 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4639 /* We have a `, ...' immediately following the selector,
4640 finalize the arglist...simulate get_parm_info (0). */
4642 else if (METHOD_ADD_ARGS (meth))
4644 /* we have a variable length selector */
4645 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4646 chainon (arglist, add_arg_list);
4648 else
4649 /* finalize the arglist...simulate get_parm_info (1) */
4650 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4652 return arglist;
4655 static tree
4656 check_duplicates (hsh)
4657 hash hsh;
4659 tree meth = NULL_TREE;
4661 if (hsh)
4663 meth = hsh->key;
4665 if (hsh->list)
4667 /* We have two methods with the same name and different types. */
4668 attr loop;
4669 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4671 warning ("multiple declarations for method `%s'",
4672 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4674 warn_with_method ("using", type, meth);
4675 for (loop = hsh->list; loop; loop = loop->next)
4676 warn_with_method ("also found", type, loop->value);
4679 return meth;
4682 /* If RECEIVER is a class reference, return the identifier node for
4683 the referenced class. RECEIVER is created by get_class_reference,
4684 so we check the exact form created depending on which runtimes are
4685 used. */
4687 static tree
4688 receiver_is_class_object (receiver)
4689 tree receiver;
4691 tree chain, exp, arg;
4693 /* The receiver is 'self' in the context of a class method. */
4694 if (objc_method_context
4695 && receiver == self_decl
4696 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4698 return CLASS_NAME (objc_implementation_context);
4701 if (flag_next_runtime)
4703 /* The receiver is a variable created by
4704 build_class_reference_decl. */
4705 if (TREE_CODE (receiver) == VAR_DECL
4706 && TREE_TYPE (receiver) == objc_class_type)
4707 /* Look up the identifier. */
4708 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4709 if (TREE_PURPOSE (chain) == receiver)
4710 return TREE_VALUE (chain);
4712 else
4714 /* The receiver is a function call that returns an id. Check if
4715 it is a call to objc_getClass, if so, pick up the class name. */
4716 if (TREE_CODE (receiver) == CALL_EXPR
4717 && (exp = TREE_OPERAND (receiver, 0))
4718 && TREE_CODE (exp) == ADDR_EXPR
4719 && (exp = TREE_OPERAND (exp, 0))
4720 && TREE_CODE (exp) == FUNCTION_DECL
4721 && exp == objc_get_class_decl
4722 /* We have a call to objc_getClass! */
4723 && (arg = TREE_OPERAND (receiver, 1))
4724 && TREE_CODE (arg) == TREE_LIST
4725 && (arg = TREE_VALUE (arg)))
4727 STRIP_NOPS (arg);
4728 if (TREE_CODE (arg) == ADDR_EXPR
4729 && (arg = TREE_OPERAND (arg, 0))
4730 && TREE_CODE (arg) == STRING_CST)
4731 /* Finally, we have the class name. */
4732 return get_identifier (TREE_STRING_POINTER (arg));
4735 return 0;
4738 /* If we are currently building a message expr, this holds
4739 the identifier of the selector of the message. This is
4740 used when printing warnings about argument mismatches. */
4742 static tree building_objc_message_expr = 0;
4744 tree
4745 maybe_building_objc_message_expr ()
4747 return building_objc_message_expr;
4750 /* Construct an expression for sending a message.
4751 MESS has the object to send to in TREE_PURPOSE
4752 and the argument list (including selector) in TREE_VALUE.
4754 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4755 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4757 tree
4758 build_message_expr (mess)
4759 tree mess;
4761 tree receiver = TREE_PURPOSE (mess);
4762 tree sel_name;
4763 tree args = TREE_VALUE (mess);
4764 tree method_params = NULL_TREE;
4766 if (TREE_CODE (receiver) == ERROR_MARK)
4767 return error_mark_node;
4769 /* Obtain the full selector name. */
4770 if (TREE_CODE (args) == IDENTIFIER_NODE)
4771 /* A unary selector. */
4772 sel_name = args;
4773 else if (TREE_CODE (args) == TREE_LIST)
4774 sel_name = build_keyword_selector (args);
4775 else
4776 abort ();
4778 /* Build the parameter list to give to the method. */
4779 if (TREE_CODE (args) == TREE_LIST)
4781 tree chain = args, prev = NULL_TREE;
4783 /* We have a keyword selector--check for comma expressions. */
4784 while (chain)
4786 tree element = TREE_VALUE (chain);
4788 /* We have a comma expression, must collapse... */
4789 if (TREE_CODE (element) == TREE_LIST)
4791 if (prev)
4792 TREE_CHAIN (prev) = element;
4793 else
4794 args = element;
4796 prev = chain;
4797 chain = TREE_CHAIN (chain);
4799 method_params = args;
4802 return finish_message_expr (receiver, sel_name, method_params);
4805 /* The 'finish_message_expr' routine is called from within
4806 'build_message_expr' for non-template functions. In the case of
4807 C++ template functions, it is called from 'build_expr_from_tree'
4808 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4810 tree
4811 finish_message_expr (receiver, sel_name, method_params)
4812 tree receiver, sel_name, method_params;
4814 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4815 tree selector, self_object, retval;
4816 int statically_typed = 0, statically_allocated = 0;
4818 /* Determine receiver type. */
4819 tree rtype = TREE_TYPE (receiver);
4820 int super = IS_SUPER (rtype);
4822 if (! super)
4824 if (TREE_STATIC_TEMPLATE (rtype))
4825 statically_allocated = 1;
4826 else if (TREE_CODE (rtype) == POINTER_TYPE
4827 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4828 statically_typed = 1;
4829 else if ((flag_next_runtime
4830 || (IS_ID (rtype)))
4831 && (class_ident = receiver_is_class_object (receiver)))
4833 else if (! IS_ID (rtype)
4834 /* Allow any type that matches objc_class_type. */
4835 && ! comptypes (rtype, objc_class_type))
4837 warning ("invalid receiver type `%s'",
4838 gen_declaration (rtype, errbuf));
4840 if (statically_allocated)
4841 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4843 /* Don't evaluate the receiver twice. */
4844 receiver = save_expr (receiver);
4845 self_object = receiver;
4847 else
4848 /* If sending to `super', use current self as the object. */
4849 self_object = self_decl;
4851 /* Determine operation return type. */
4853 if (super)
4855 tree iface;
4857 if (CLASS_SUPER_NAME (implementation_template))
4859 iface
4860 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4862 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4863 method_prototype = lookup_instance_method_static (iface, sel_name);
4864 else
4865 method_prototype = lookup_class_method_static (iface, sel_name);
4867 if (iface && !method_prototype)
4868 warning ("`%s' does not respond to `%s'",
4869 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4870 IDENTIFIER_POINTER (sel_name));
4872 else
4874 error ("no super class declared in interface for `%s'",
4875 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4876 return error_mark_node;
4880 else if (statically_allocated)
4882 tree ctype = TREE_TYPE (rtype);
4883 tree iface = lookup_interface (TYPE_NAME (rtype));
4885 if (iface)
4886 method_prototype = lookup_instance_method_static (iface, sel_name);
4888 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4889 method_prototype
4890 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4891 sel_name, 0);
4893 if (!method_prototype)
4894 warning ("`%s' does not respond to `%s'",
4895 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4896 IDENTIFIER_POINTER (sel_name));
4898 else if (statically_typed)
4900 tree ctype = TREE_TYPE (rtype);
4902 /* `self' is now statically_typed. All methods should be visible
4903 within the context of the implementation. */
4904 if (objc_implementation_context
4905 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4907 method_prototype
4908 = lookup_instance_method_static (implementation_template,
4909 sel_name);
4911 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4912 method_prototype
4913 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4914 sel_name, 0);
4916 if (! method_prototype
4917 && implementation_template != objc_implementation_context)
4918 /* The method is not published in the interface. Check
4919 locally. */
4920 method_prototype
4921 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4922 sel_name);
4924 else
4926 tree iface;
4928 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4929 method_prototype = lookup_instance_method_static (iface, sel_name);
4931 if (! method_prototype)
4933 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4934 if (protocol_list)
4935 method_prototype
4936 = lookup_method_in_protocol_list (protocol_list,
4937 sel_name, 0);
4941 if (!method_prototype)
4942 warning ("`%s' does not respond to `%s'",
4943 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4944 IDENTIFIER_POINTER (sel_name));
4946 else if (class_ident)
4948 if (objc_implementation_context
4949 && CLASS_NAME (objc_implementation_context) == class_ident)
4951 method_prototype
4952 = lookup_class_method_static (implementation_template, sel_name);
4954 if (!method_prototype
4955 && implementation_template != objc_implementation_context)
4956 /* The method is not published in the interface. Check
4957 locally. */
4958 method_prototype
4959 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4960 sel_name);
4962 else
4964 tree iface;
4966 if ((iface = lookup_interface (class_ident)))
4967 method_prototype = lookup_class_method_static (iface, sel_name);
4970 if (!method_prototype)
4972 warning ("cannot find class (factory) method");
4973 warning ("return type for `%s' defaults to id",
4974 IDENTIFIER_POINTER (sel_name));
4977 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4979 /* An anonymous object that has been qualified with a protocol. */
4981 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4983 method_prototype = lookup_method_in_protocol_list (protocol_list,
4984 sel_name, 0);
4986 if (!method_prototype)
4988 hash hsh;
4990 warning ("method `%s' not implemented by protocol",
4991 IDENTIFIER_POINTER (sel_name));
4993 /* Try and find the method signature in the global pools. */
4995 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4996 hsh = hash_lookup (cls_method_hash_list, sel_name);
4998 if (!(method_prototype = check_duplicates (hsh)))
4999 warning ("return type defaults to id");
5002 else
5004 hash hsh;
5006 /* We think we have an instance...loophole: extern id Object; */
5007 hsh = hash_lookup (nst_method_hash_list, sel_name);
5009 if (!hsh)
5010 /* For various loopholes */
5011 hsh = hash_lookup (cls_method_hash_list, sel_name);
5013 method_prototype = check_duplicates (hsh);
5014 if (!method_prototype)
5016 warning ("cannot find method");
5017 warning ("return type for `%s' defaults to id",
5018 IDENTIFIER_POINTER (sel_name));
5022 /* Save the selector name for printing error messages. */
5023 building_objc_message_expr = sel_name;
5025 /* Build the parameters list for looking up the method.
5026 These are the object itself and the selector. */
5028 if (flag_typed_selectors)
5029 selector = build_typed_selector_reference (sel_name, method_prototype);
5030 else
5031 selector = build_selector_reference (sel_name);
5033 retval = build_objc_method_call (super, method_prototype,
5034 receiver, self_object,
5035 selector, method_params);
5037 building_objc_message_expr = 0;
5039 return retval;
5042 /* Build a tree expression to send OBJECT the operation SELECTOR,
5043 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5044 assuming the method has prototype METHOD_PROTOTYPE.
5045 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5046 Use METHOD_PARAMS as list of args to pass to the method.
5047 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5049 static tree
5050 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5051 selector, method_params)
5052 int super_flag;
5053 tree method_prototype, lookup_object, object, selector, method_params;
5055 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5056 tree rcv_p = (super_flag
5057 ? build_pointer_type (xref_tag (RECORD_TYPE,
5058 get_identifier (TAG_SUPER)))
5059 : id_type);
5061 if (flag_next_runtime)
5063 if (! method_prototype)
5065 method_params = tree_cons (NULL_TREE, lookup_object,
5066 tree_cons (NULL_TREE, selector,
5067 method_params));
5068 assemble_external (sender);
5069 return build_function_call (sender, method_params);
5071 else
5073 /* This is a real kludge, but it is used only for the Next.
5074 Clobber the data type of SENDER temporarily to accept
5075 all the arguments for this operation, and to return
5076 whatever this operation returns. */
5077 tree arglist = NULL_TREE, retval, savarg, savret;
5078 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5080 /* Save the proper contents of SENDER's data type. */
5081 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5082 savret = TREE_TYPE (TREE_TYPE (sender));
5084 /* Install this method's argument types. */
5085 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5086 super_flag);
5087 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5089 /* Install this method's return type. */
5090 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5092 /* Call SENDER with all the parameters. This will do type
5093 checking using the arg types for this method. */
5094 method_params = tree_cons (NULL_TREE, lookup_object,
5095 tree_cons (NULL_TREE, selector,
5096 method_params));
5097 assemble_external (sender);
5098 retval = build_function_call (sender, method_params);
5100 /* Restore SENDER's return/argument types. */
5101 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5102 TREE_TYPE (TREE_TYPE (sender)) = savret;
5103 return retval;
5106 else
5108 /* This is the portable way.
5109 First call the lookup function to get a pointer to the method,
5110 then cast the pointer, then call it with the method arguments. */
5111 tree method;
5113 /* Avoid trouble since we may evaluate each of these twice. */
5114 object = save_expr (object);
5115 selector = save_expr (selector);
5117 lookup_object = build_c_cast (rcv_p, lookup_object);
5119 assemble_external (sender);
5120 method
5121 = build_function_call (sender,
5122 tree_cons (NULL_TREE, lookup_object,
5123 tree_cons (NULL_TREE, selector,
5124 NULL_TREE)));
5126 /* If we have a method prototype, construct the data type this
5127 method needs, and cast what we got from SENDER into a pointer
5128 to that type. */
5129 if (method_prototype)
5131 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5132 super_flag);
5133 tree valtype = groktypename (TREE_TYPE (method_prototype));
5134 tree fake_function_type = build_function_type (valtype, arglist);
5135 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5137 else
5138 TREE_TYPE (method)
5139 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5141 /* Pass the object to the method. */
5142 assemble_external (method);
5143 return build_function_call (method,
5144 tree_cons (NULL_TREE, object,
5145 tree_cons (NULL_TREE, selector,
5146 method_params)));
5150 static void
5151 build_protocol_reference (p)
5152 tree p;
5154 tree decl, ident, ptype;
5156 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5158 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5159 ptype
5160 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5161 objc_protocol_template),
5162 NULL_TREE));
5164 if (IDENTIFIER_GLOBAL_VALUE (ident))
5165 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5166 else
5168 decl = build_decl (VAR_DECL, ident, ptype);
5169 DECL_EXTERNAL (decl) = 1;
5170 TREE_PUBLIC (decl) = 1;
5171 TREE_USED (decl) = 1;
5172 DECL_ARTIFICIAL (decl) = 1;
5174 make_decl_rtl (decl, 0);
5175 pushdecl_top_level (decl);
5178 PROTOCOL_FORWARD_DECL (p) = decl;
5181 tree
5182 build_protocol_expr (protoname)
5183 tree protoname;
5185 tree expr;
5186 tree p = lookup_protocol (protoname);
5188 if (!p)
5190 error ("cannot find protocol declaration for `%s'",
5191 IDENTIFIER_POINTER (protoname));
5192 return error_mark_node;
5195 if (!PROTOCOL_FORWARD_DECL (p))
5196 build_protocol_reference (p);
5198 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5200 TREE_TYPE (expr) = protocol_type;
5202 return expr;
5205 tree
5206 build_selector_expr (selnamelist)
5207 tree selnamelist;
5209 tree selname;
5211 /* Obtain the full selector name. */
5212 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5213 /* A unary selector. */
5214 selname = selnamelist;
5215 else if (TREE_CODE (selnamelist) == TREE_LIST)
5216 selname = build_keyword_selector (selnamelist);
5217 else
5218 abort ();
5220 if (flag_typed_selectors)
5221 return build_typed_selector_reference (selname, 0);
5222 else
5223 return build_selector_reference (selname);
5226 tree
5227 build_encode_expr (type)
5228 tree type;
5230 tree result;
5231 const char *string;
5233 encode_type (type, obstack_object_size (&util_obstack),
5234 OBJC_ENCODE_INLINE_DEFS);
5235 obstack_1grow (&util_obstack, 0); /* null terminate string */
5236 string = obstack_finish (&util_obstack);
5238 /* Synthesize a string that represents the encoded struct/union. */
5239 result = my_build_string (strlen (string) + 1, string);
5240 obstack_free (&util_obstack, util_firstobj);
5241 return result;
5244 tree
5245 build_ivar_reference (id)
5246 tree id;
5248 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5250 /* Historically, a class method that produced objects (factory
5251 method) would assign `self' to the instance that it
5252 allocated. This would effectively turn the class method into
5253 an instance method. Following this assignment, the instance
5254 variables could be accessed. That practice, while safe,
5255 violates the simple rule that a class method should not refer
5256 to an instance variable. It's better to catch the cases
5257 where this is done unknowingly than to support the above
5258 paradigm. */
5259 warning ("instance variable `%s' accessed in class method",
5260 IDENTIFIER_POINTER (id));
5261 TREE_TYPE (self_decl) = instance_type; /* cast */
5264 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5267 /* Compute a hash value for a given method SEL_NAME. */
5269 static size_t
5270 hash_func (sel_name)
5271 tree sel_name;
5273 const unsigned char *s
5274 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5275 size_t h = 0;
5277 while (*s)
5278 h = h * 67 + *s++ - 113;
5279 return h;
5282 static void
5283 hash_init ()
5285 nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5286 cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
5289 /* WARNING!!!! hash_enter is called with a method, and will peek
5290 inside to find its selector! But hash_lookup is given a selector
5291 directly, and looks for the selector that's inside the found
5292 entry's key (method) for comparison. */
5294 static void
5295 hash_enter (hashlist, method)
5296 hash *hashlist;
5297 tree method;
5299 hash obj;
5300 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5302 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5303 obj->list = 0;
5304 obj->next = hashlist[slot];
5305 obj->key = method;
5307 hashlist[slot] = obj; /* append to front */
5310 static hash
5311 hash_lookup (hashlist, sel_name)
5312 hash *hashlist;
5313 tree sel_name;
5315 hash target;
5317 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5319 while (target)
5321 if (sel_name == METHOD_SEL_NAME (target->key))
5322 return target;
5324 target = target->next;
5326 return 0;
5329 static void
5330 hash_add_attr (entry, value)
5331 hash entry;
5332 tree value;
5334 attr obj;
5336 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5337 obj->next = entry->list;
5338 obj->value = value;
5340 entry->list = obj; /* append to front */
5343 static tree
5344 lookup_method (mchain, method)
5345 tree mchain;
5346 tree method;
5348 tree key;
5350 if (TREE_CODE (method) == IDENTIFIER_NODE)
5351 key = method;
5352 else
5353 key = METHOD_SEL_NAME (method);
5355 while (mchain)
5357 if (METHOD_SEL_NAME (mchain) == key)
5358 return mchain;
5359 mchain = TREE_CHAIN (mchain);
5361 return NULL_TREE;
5364 static tree
5365 lookup_instance_method_static (interface, ident)
5366 tree interface;
5367 tree ident;
5369 tree inter = interface;
5370 tree chain = CLASS_NST_METHODS (inter);
5371 tree meth = NULL_TREE;
5375 if ((meth = lookup_method (chain, ident)))
5376 return meth;
5378 if (CLASS_CATEGORY_LIST (inter))
5380 tree category = CLASS_CATEGORY_LIST (inter);
5381 chain = CLASS_NST_METHODS (category);
5385 if ((meth = lookup_method (chain, ident)))
5386 return meth;
5388 /* Check for instance methods in protocols in categories. */
5389 if (CLASS_PROTOCOL_LIST (category))
5391 if ((meth = (lookup_method_in_protocol_list
5392 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5393 return meth;
5396 if ((category = CLASS_CATEGORY_LIST (category)))
5397 chain = CLASS_NST_METHODS (category);
5399 while (category);
5402 if (CLASS_PROTOCOL_LIST (inter))
5404 if ((meth = (lookup_method_in_protocol_list
5405 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5406 return meth;
5409 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5410 chain = CLASS_NST_METHODS (inter);
5412 while (inter);
5414 return meth;
5417 static tree
5418 lookup_class_method_static (interface, ident)
5419 tree interface;
5420 tree ident;
5422 tree inter = interface;
5423 tree chain = CLASS_CLS_METHODS (inter);
5424 tree meth = NULL_TREE;
5425 tree root_inter = NULL_TREE;
5429 if ((meth = lookup_method (chain, ident)))
5430 return meth;
5432 if (CLASS_CATEGORY_LIST (inter))
5434 tree category = CLASS_CATEGORY_LIST (inter);
5435 chain = CLASS_CLS_METHODS (category);
5439 if ((meth = lookup_method (chain, ident)))
5440 return meth;
5442 /* Check for class methods in protocols in categories. */
5443 if (CLASS_PROTOCOL_LIST (category))
5445 if ((meth = (lookup_method_in_protocol_list
5446 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5447 return meth;
5450 if ((category = CLASS_CATEGORY_LIST (category)))
5451 chain = CLASS_CLS_METHODS (category);
5453 while (category);
5456 /* Check for class methods in protocols. */
5457 if (CLASS_PROTOCOL_LIST (inter))
5459 if ((meth = (lookup_method_in_protocol_list
5460 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5461 return meth;
5464 root_inter = inter;
5465 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5466 chain = CLASS_CLS_METHODS (inter);
5468 while (inter);
5470 /* If no class (factory) method was found, check if an _instance_
5471 method of the same name exists in the root class. This is what
5472 the Objective-C runtime will do. */
5473 return lookup_instance_method_static (root_inter, ident);
5476 tree
5477 add_class_method (class, method)
5478 tree class;
5479 tree method;
5481 tree mth;
5482 hash hsh;
5484 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5486 /* put method on list in reverse order */
5487 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5488 CLASS_CLS_METHODS (class) = method;
5490 else
5492 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5493 error ("duplicate definition of class method `%s'",
5494 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5495 else
5497 /* Check types; if different, complain. */
5498 if (!comp_proto_with_proto (method, mth))
5499 error ("duplicate declaration of class method `%s'",
5500 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5504 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5506 /* Install on a global chain. */
5507 hash_enter (cls_method_hash_list, method);
5509 else
5511 /* Check types; if different, add to a list. */
5512 if (!comp_proto_with_proto (method, hsh->key))
5513 hash_add_attr (hsh, method);
5515 return method;
5518 tree
5519 add_instance_method (class, method)
5520 tree class;
5521 tree method;
5523 tree mth;
5524 hash hsh;
5526 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5528 /* Put method on list in reverse order. */
5529 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5530 CLASS_NST_METHODS (class) = method;
5532 else
5534 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5535 error ("duplicate definition of instance method `%s'",
5536 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5537 else
5539 /* Check types; if different, complain. */
5540 if (!comp_proto_with_proto (method, mth))
5541 error ("duplicate declaration of instance method `%s'",
5542 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5546 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5548 /* Install on a global chain. */
5549 hash_enter (nst_method_hash_list, method);
5551 else
5553 /* Check types; if different, add to a list. */
5554 if (!comp_proto_with_proto (method, hsh->key))
5555 hash_add_attr (hsh, method);
5557 return method;
5560 static tree
5561 add_class (class)
5562 tree class;
5564 /* Put interfaces on list in reverse order. */
5565 TREE_CHAIN (class) = interface_chain;
5566 interface_chain = class;
5567 return interface_chain;
5570 static void
5571 add_category (class, category)
5572 tree class;
5573 tree category;
5575 /* Put categories on list in reverse order. */
5576 tree cat = CLASS_CATEGORY_LIST (class);
5578 while (cat)
5580 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5581 warning ("duplicate interface declaration for category `%s(%s)'",
5582 IDENTIFIER_POINTER (CLASS_NAME (class)),
5583 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5584 cat = CLASS_CATEGORY_LIST (cat);
5587 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5588 CLASS_CATEGORY_LIST (class) = category;
5591 /* Called after parsing each instance variable declaration. Necessary to
5592 preserve typedefs and implement public/private...
5594 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5596 tree
5597 add_instance_variable (class, public, declarator, declspecs, width)
5598 tree class;
5599 int public;
5600 tree declarator;
5601 tree declspecs;
5602 tree width;
5604 tree field_decl, raw_decl;
5606 raw_decl = build_tree_list (declspecs, declarator);
5608 if (CLASS_RAW_IVARS (class))
5609 chainon (CLASS_RAW_IVARS (class), raw_decl);
5610 else
5611 CLASS_RAW_IVARS (class) = raw_decl;
5613 field_decl = grokfield (input_filename, lineno,
5614 declarator, declspecs, width);
5616 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5617 switch (public)
5619 case 0:
5620 TREE_PUBLIC (field_decl) = 0;
5621 TREE_PRIVATE (field_decl) = 0;
5622 TREE_PROTECTED (field_decl) = 1;
5623 break;
5625 case 1:
5626 TREE_PUBLIC (field_decl) = 1;
5627 TREE_PRIVATE (field_decl) = 0;
5628 TREE_PROTECTED (field_decl) = 0;
5629 break;
5631 case 2:
5632 TREE_PUBLIC (field_decl) = 0;
5633 TREE_PRIVATE (field_decl) = 1;
5634 TREE_PROTECTED (field_decl) = 0;
5635 break;
5639 if (CLASS_IVARS (class))
5640 chainon (CLASS_IVARS (class), field_decl);
5641 else
5642 CLASS_IVARS (class) = field_decl;
5644 return class;
5647 tree
5648 is_ivar (decl_chain, ident)
5649 tree decl_chain;
5650 tree ident;
5652 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5653 if (DECL_NAME (decl_chain) == ident)
5654 return decl_chain;
5655 return NULL_TREE;
5658 /* True if the ivar is private and we are not in its implementation. */
5661 is_private (decl)
5662 tree decl;
5664 if (TREE_PRIVATE (decl)
5665 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5667 error ("instance variable `%s' is declared private",
5668 IDENTIFIER_POINTER (DECL_NAME (decl)));
5669 return 1;
5671 else
5672 return 0;
5675 /* We have an instance variable reference;, check to see if it is public. */
5678 is_public (expr, identifier)
5679 tree expr;
5680 tree identifier;
5682 tree basetype = TREE_TYPE (expr);
5683 enum tree_code code = TREE_CODE (basetype);
5684 tree decl;
5686 if (code == RECORD_TYPE)
5688 if (TREE_STATIC_TEMPLATE (basetype))
5690 if (!lookup_interface (TYPE_NAME (basetype)))
5692 error ("cannot find interface declaration for `%s'",
5693 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5694 return 0;
5697 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5699 if (TREE_PUBLIC (decl))
5700 return 1;
5702 /* Important difference between the Stepstone translator:
5703 all instance variables should be public within the context
5704 of the implementation. */
5705 if (objc_implementation_context
5706 && (((TREE_CODE (objc_implementation_context)
5707 == CLASS_IMPLEMENTATION_TYPE)
5708 || (TREE_CODE (objc_implementation_context)
5709 == CATEGORY_IMPLEMENTATION_TYPE))
5710 && (CLASS_NAME (objc_implementation_context)
5711 == TYPE_NAME (basetype))))
5712 return ! is_private (decl);
5714 error ("instance variable `%s' is declared %s",
5715 IDENTIFIER_POINTER (identifier),
5716 TREE_PRIVATE (decl) ? "private" : "protected");
5717 return 0;
5721 else if (objc_implementation_context && (basetype == objc_object_reference))
5723 TREE_TYPE (expr) = uprivate_record;
5724 warning ("static access to object of type `id'");
5728 return 1;
5731 /* Implement @defs (<classname>) within struct bodies. */
5733 tree
5734 get_class_ivars (interface)
5735 tree interface;
5737 /* Make sure we copy the leaf ivars in case @defs is used in a local
5738 context. Otherwise finish_struct will overwrite the layout info
5739 using temporary storage. */
5740 return build_ivar_chain (interface, 1);
5743 /* Make sure all entries in CHAIN are also in LIST. */
5745 static int
5746 check_methods (chain, list, mtype)
5747 tree chain;
5748 tree list;
5749 int mtype;
5751 int first = 1;
5753 while (chain)
5755 if (!lookup_method (list, chain))
5757 if (first)
5759 if (TREE_CODE (objc_implementation_context)
5760 == CLASS_IMPLEMENTATION_TYPE)
5761 warning ("incomplete implementation of class `%s'",
5762 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5763 else if (TREE_CODE (objc_implementation_context)
5764 == CATEGORY_IMPLEMENTATION_TYPE)
5765 warning ("incomplete implementation of category `%s'",
5766 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5767 first = 0;
5770 warning ("method definition for `%c%s' not found",
5771 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5774 chain = TREE_CHAIN (chain);
5777 return first;
5780 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5782 static int
5783 conforms_to_protocol (class, protocol)
5784 tree class;
5785 tree protocol;
5787 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5789 tree p = CLASS_PROTOCOL_LIST (class);
5790 while (p && TREE_VALUE (p) != protocol)
5791 p = TREE_CHAIN (p);
5793 if (!p)
5795 tree super = (CLASS_SUPER_NAME (class)
5796 ? lookup_interface (CLASS_SUPER_NAME (class))
5797 : NULL_TREE);
5798 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5799 if (!tmp)
5800 return 0;
5804 return 1;
5807 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5808 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5810 static int
5811 check_methods_accessible (chain, context, mtype)
5812 tree chain;
5813 tree context;
5814 int mtype;
5816 int first = 1;
5817 tree list;
5818 tree base_context = context;
5820 while (chain)
5822 context = base_context;
5823 while (context)
5825 if (mtype == '+')
5826 list = CLASS_CLS_METHODS (context);
5827 else
5828 list = CLASS_NST_METHODS (context);
5830 if (lookup_method (list, chain))
5831 break;
5833 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5834 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5835 context = (CLASS_SUPER_NAME (context)
5836 ? lookup_interface (CLASS_SUPER_NAME (context))
5837 : NULL_TREE);
5839 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5840 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5841 context = (CLASS_NAME (context)
5842 ? lookup_interface (CLASS_NAME (context))
5843 : NULL_TREE);
5844 else
5845 abort ();
5848 if (context == NULL_TREE)
5850 if (first)
5852 if (TREE_CODE (objc_implementation_context)
5853 == CLASS_IMPLEMENTATION_TYPE)
5854 warning ("incomplete implementation of class `%s'",
5855 IDENTIFIER_POINTER
5856 (CLASS_NAME (objc_implementation_context)));
5857 else if (TREE_CODE (objc_implementation_context)
5858 == CATEGORY_IMPLEMENTATION_TYPE)
5859 warning ("incomplete implementation of category `%s'",
5860 IDENTIFIER_POINTER
5861 (CLASS_SUPER_NAME (objc_implementation_context)));
5862 first = 0;
5864 warning ("method definition for `%c%s' not found",
5865 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5868 chain = TREE_CHAIN (chain); /* next method... */
5870 return first;
5873 /* Check whether the current interface (accessible via
5874 'objc_implementation_context') actually implements protocol P, along
5875 with any protocols that P inherits. */
5877 static void
5878 check_protocol (p, type, name)
5879 tree p;
5880 const char *type;
5881 const char *name;
5883 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5885 int f1, f2;
5887 /* Ensure that all protocols have bodies! */
5888 if (flag_warn_protocol)
5890 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5891 CLASS_CLS_METHODS (objc_implementation_context),
5892 '+');
5893 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5894 CLASS_NST_METHODS (objc_implementation_context),
5895 '-');
5897 else
5899 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5900 objc_implementation_context,
5901 '+');
5902 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5903 objc_implementation_context,
5904 '-');
5907 if (!f1 || !f2)
5908 warning ("%s `%s' does not fully implement the `%s' protocol",
5909 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5912 /* Check protocols recursively. */
5913 if (PROTOCOL_LIST (p))
5915 tree subs = PROTOCOL_LIST (p);
5916 tree super_class =
5917 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5919 while (subs)
5921 tree sub = TREE_VALUE (subs);
5923 /* If the superclass does not conform to the protocols
5924 inherited by P, then we must! */
5925 if (!super_class || !conforms_to_protocol (super_class, sub))
5926 check_protocol (sub, type, name);
5927 subs = TREE_CHAIN (subs);
5932 /* Check whether the current interface (accessible via
5933 'objc_implementation_context') actually implements the protocols listed
5934 in PROTO_LIST. */
5936 static void
5937 check_protocols (proto_list, type, name)
5938 tree proto_list;
5939 const char *type;
5940 const char *name;
5942 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5944 tree p = TREE_VALUE (proto_list);
5946 check_protocol (p, type, name);
5950 /* Make sure that the class CLASS_NAME is defined
5951 CODE says which kind of thing CLASS_NAME ought to be.
5952 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5953 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5955 tree
5956 start_class (code, class_name, super_name, protocol_list)
5957 enum tree_code code;
5958 tree class_name;
5959 tree super_name;
5960 tree protocol_list;
5962 tree class, decl;
5964 if (objc_implementation_context)
5966 warning ("`@end' missing in implementation context");
5967 finish_class (objc_implementation_context);
5968 objc_ivar_chain = NULL_TREE;
5969 objc_implementation_context = NULL_TREE;
5972 class = make_node (code);
5973 TYPE_BINFO (class) = make_tree_vec (5);
5975 CLASS_NAME (class) = class_name;
5976 CLASS_SUPER_NAME (class) = super_name;
5977 CLASS_CLS_METHODS (class) = NULL_TREE;
5979 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5981 error ("`%s' redeclared as different kind of symbol",
5982 IDENTIFIER_POINTER (class_name));
5983 error_with_decl (decl, "previous declaration of `%s'");
5986 if (code == CLASS_IMPLEMENTATION_TYPE)
5989 tree chain;
5991 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
5992 if (TREE_VALUE (chain) == class_name)
5994 error ("reimplementation of class `%s'",
5995 IDENTIFIER_POINTER (class_name));
5996 return error_mark_node;
5998 implemented_classes = tree_cons (NULL_TREE, class_name,
5999 implemented_classes);
6002 /* Pre-build the following entities - for speed/convenience. */
6003 if (!self_id)
6004 self_id = get_identifier ("self");
6005 if (!ucmd_id)
6006 ucmd_id = get_identifier ("_cmd");
6007 if (!unused_list)
6008 unused_list
6009 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6010 if (!objc_super_template)
6011 objc_super_template = build_super_template ();
6013 /* Reset for multiple classes per file. */
6014 method_slot = 0;
6016 objc_implementation_context = class;
6018 /* Lookup the interface for this implementation. */
6020 if (!(implementation_template = lookup_interface (class_name)))
6022 warning ("cannot find interface declaration for `%s'",
6023 IDENTIFIER_POINTER (class_name));
6024 add_class (implementation_template = objc_implementation_context);
6027 /* If a super class has been specified in the implementation,
6028 insure it conforms to the one specified in the interface. */
6030 if (super_name
6031 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6033 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6034 const char *const name =
6035 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6036 error ("conflicting super class name `%s'",
6037 IDENTIFIER_POINTER (super_name));
6038 error ("previous declaration of `%s'", name);
6041 else if (! super_name)
6043 CLASS_SUPER_NAME (objc_implementation_context)
6044 = CLASS_SUPER_NAME (implementation_template);
6048 else if (code == CLASS_INTERFACE_TYPE)
6050 if (lookup_interface (class_name))
6051 warning ("duplicate interface declaration for class `%s'",
6052 IDENTIFIER_POINTER (class_name));
6053 else
6054 add_class (class);
6056 if (protocol_list)
6057 CLASS_PROTOCOL_LIST (class)
6058 = lookup_and_install_protocols (protocol_list);
6061 else if (code == CATEGORY_INTERFACE_TYPE)
6063 tree class_category_is_assoc_with;
6065 /* For a category, class_name is really the name of the class that
6066 the following set of methods will be associated with. We must
6067 find the interface so that can derive the objects template. */
6069 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6071 error ("cannot find interface declaration for `%s'",
6072 IDENTIFIER_POINTER (class_name));
6073 exit (FATAL_EXIT_CODE);
6075 else
6076 add_category (class_category_is_assoc_with, class);
6078 if (protocol_list)
6079 CLASS_PROTOCOL_LIST (class)
6080 = lookup_and_install_protocols (protocol_list);
6083 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6085 /* Pre-build the following entities for speed/convenience. */
6086 if (!self_id)
6087 self_id = get_identifier ("self");
6088 if (!ucmd_id)
6089 ucmd_id = get_identifier ("_cmd");
6090 if (!unused_list)
6091 unused_list
6092 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6093 if (!objc_super_template)
6094 objc_super_template = build_super_template ();
6096 /* Reset for multiple classes per file. */
6097 method_slot = 0;
6099 objc_implementation_context = class;
6101 /* For a category, class_name is really the name of the class that
6102 the following set of methods will be associated with. We must
6103 find the interface so that can derive the objects template. */
6105 if (!(implementation_template = lookup_interface (class_name)))
6107 error ("cannot find interface declaration for `%s'",
6108 IDENTIFIER_POINTER (class_name));
6109 exit (FATAL_EXIT_CODE);
6112 return class;
6115 tree
6116 continue_class (class)
6117 tree class;
6119 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6120 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6122 struct imp_entry *imp_entry;
6123 tree ivar_context;
6125 /* Check consistency of the instance variables. */
6127 if (CLASS_IVARS (class))
6128 check_ivars (implementation_template, class);
6130 /* code generation */
6132 ivar_context = build_private_template (implementation_template);
6134 if (!objc_class_template)
6135 build_class_template ();
6137 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6139 imp_entry->next = imp_list;
6140 imp_entry->imp_context = class;
6141 imp_entry->imp_template = implementation_template;
6143 synth_forward_declarations ();
6144 imp_entry->class_decl = UOBJC_CLASS_decl;
6145 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6147 /* Append to front and increment count. */
6148 imp_list = imp_entry;
6149 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6150 imp_count++;
6151 else
6152 cat_count++;
6154 return ivar_context;
6157 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6159 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6161 if (!TYPE_FIELDS (record))
6163 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6164 CLASS_STATIC_TEMPLATE (class) = record;
6166 /* Mark this record as a class template for static typing. */
6167 TREE_STATIC_TEMPLATE (record) = 1;
6170 return NULL_TREE;
6173 else
6174 return error_mark_node;
6177 /* This is called once we see the "@end" in an interface/implementation. */
6179 void
6180 finish_class (class)
6181 tree class;
6183 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6185 /* All code generation is done in finish_objc. */
6187 if (implementation_template != objc_implementation_context)
6189 /* Ensure that all method listed in the interface contain bodies. */
6190 check_methods (CLASS_CLS_METHODS (implementation_template),
6191 CLASS_CLS_METHODS (objc_implementation_context), '+');
6192 check_methods (CLASS_NST_METHODS (implementation_template),
6193 CLASS_NST_METHODS (objc_implementation_context), '-');
6195 if (CLASS_PROTOCOL_LIST (implementation_template))
6196 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6197 "class",
6198 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6202 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6204 tree category = CLASS_CATEGORY_LIST (implementation_template);
6206 /* Find the category interface from the class it is associated with. */
6207 while (category)
6209 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6210 break;
6211 category = CLASS_CATEGORY_LIST (category);
6214 if (category)
6216 /* Ensure all method listed in the interface contain bodies. */
6217 check_methods (CLASS_CLS_METHODS (category),
6218 CLASS_CLS_METHODS (objc_implementation_context), '+');
6219 check_methods (CLASS_NST_METHODS (category),
6220 CLASS_NST_METHODS (objc_implementation_context), '-');
6222 if (CLASS_PROTOCOL_LIST (category))
6223 check_protocols (CLASS_PROTOCOL_LIST (category),
6224 "category",
6225 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6229 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6231 tree decl_specs;
6232 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6233 char *string = (char *) alloca (strlen (class_name) + 3);
6235 /* extern struct objc_object *_<my_name>; */
6237 sprintf (string, "_%s", class_name);
6239 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6240 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6241 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6242 decl_specs);
6246 static tree
6247 add_protocol (protocol)
6248 tree protocol;
6250 /* Put protocol on list in reverse order. */
6251 TREE_CHAIN (protocol) = protocol_chain;
6252 protocol_chain = protocol;
6253 return protocol_chain;
6256 static tree
6257 lookup_protocol (ident)
6258 tree ident;
6260 tree chain;
6262 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6263 if (ident == PROTOCOL_NAME (chain))
6264 return chain;
6266 return NULL_TREE;
6269 /* This function forward declares the protocols named by NAMES. If
6270 they are already declared or defined, the function has no effect. */
6272 void
6273 objc_declare_protocols (names)
6274 tree names;
6276 tree list;
6278 for (list = names; list; list = TREE_CHAIN (list))
6280 tree name = TREE_VALUE (list);
6282 if (lookup_protocol (name) == NULL_TREE)
6284 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6286 TYPE_BINFO (protocol) = make_tree_vec (2);
6287 PROTOCOL_NAME (protocol) = name;
6288 PROTOCOL_LIST (protocol) = NULL_TREE;
6289 add_protocol (protocol);
6290 PROTOCOL_DEFINED (protocol) = 0;
6291 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6296 tree
6297 start_protocol (code, name, list)
6298 enum tree_code code;
6299 tree name;
6300 tree list;
6302 tree protocol;
6304 /* This is as good a place as any. Need to invoke
6305 push_tag_toplevel. */
6306 if (!objc_protocol_template)
6307 objc_protocol_template = build_protocol_template ();
6309 protocol = lookup_protocol (name);
6311 if (!protocol)
6313 protocol = make_node (code);
6314 TYPE_BINFO (protocol) = make_tree_vec (2);
6316 PROTOCOL_NAME (protocol) = name;
6317 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6318 add_protocol (protocol);
6319 PROTOCOL_DEFINED (protocol) = 1;
6320 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6322 check_protocol_recursively (protocol, list);
6324 else if (! PROTOCOL_DEFINED (protocol))
6326 PROTOCOL_DEFINED (protocol) = 1;
6327 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6329 check_protocol_recursively (protocol, list);
6331 else
6333 warning ("duplicate declaration for protocol `%s'",
6334 IDENTIFIER_POINTER (name));
6336 return protocol;
6339 void
6340 finish_protocol (protocol)
6341 tree protocol ATTRIBUTE_UNUSED;
6346 /* "Encode" a data type into a string, which grows in util_obstack.
6347 ??? What is the FORMAT? Someone please document this! */
6349 static void
6350 encode_type_qualifiers (declspecs)
6351 tree declspecs;
6353 tree spec;
6355 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6357 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6358 obstack_1grow (&util_obstack, 'r');
6359 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6360 obstack_1grow (&util_obstack, 'n');
6361 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6362 obstack_1grow (&util_obstack, 'N');
6363 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6364 obstack_1grow (&util_obstack, 'o');
6365 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6366 obstack_1grow (&util_obstack, 'O');
6367 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6368 obstack_1grow (&util_obstack, 'R');
6369 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6370 obstack_1grow (&util_obstack, 'V');
6374 /* Encode a pointer type. */
6376 static void
6377 encode_pointer (type, curtype, format)
6378 tree type;
6379 int curtype;
6380 int format;
6382 tree pointer_to = TREE_TYPE (type);
6384 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6386 if (TYPE_NAME (pointer_to)
6387 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6389 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6391 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6393 obstack_1grow (&util_obstack, '@');
6394 return;
6396 else if (TREE_STATIC_TEMPLATE (pointer_to))
6398 if (generating_instance_variables)
6400 obstack_1grow (&util_obstack, '@');
6401 obstack_1grow (&util_obstack, '"');
6402 obstack_grow (&util_obstack, name, strlen (name));
6403 obstack_1grow (&util_obstack, '"');
6404 return;
6406 else
6408 obstack_1grow (&util_obstack, '@');
6409 return;
6412 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6414 obstack_1grow (&util_obstack, '#');
6415 return;
6417 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6419 obstack_1grow (&util_obstack, ':');
6420 return;
6424 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6425 && TYPE_MODE (pointer_to) == QImode)
6427 obstack_1grow (&util_obstack, '*');
6428 return;
6431 /* We have a type that does not get special treatment. */
6433 /* NeXT extension */
6434 obstack_1grow (&util_obstack, '^');
6435 encode_type (pointer_to, curtype, format);
6438 static void
6439 encode_array (type, curtype, format)
6440 tree type;
6441 int curtype;
6442 int format;
6444 tree an_int_cst = TYPE_SIZE (type);
6445 tree array_of = TREE_TYPE (type);
6446 char buffer[40];
6448 /* An incomplete array is treated like a pointer. */
6449 if (an_int_cst == NULL)
6451 encode_pointer (type, curtype, format);
6452 return;
6455 sprintf (buffer, "[%ld",
6456 (long) (TREE_INT_CST_LOW (an_int_cst)
6457 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6459 obstack_grow (&util_obstack, buffer, strlen (buffer));
6460 encode_type (array_of, curtype, format);
6461 obstack_1grow (&util_obstack, ']');
6462 return;
6465 static void
6466 encode_aggregate_within (type, curtype, format, left, right)
6467 tree type;
6468 int curtype;
6469 int format;
6470 int left;
6471 int right;
6473 /* The RECORD_TYPE may in fact be a typedef! For purposes
6474 of encoding, we need the real underlying enchilada. */
6475 if (TYPE_MAIN_VARIANT (type))
6476 type = TYPE_MAIN_VARIANT (type);
6478 if (obstack_object_size (&util_obstack) > 0
6479 && *(obstack_next_free (&util_obstack) - 1) == '^')
6481 tree name = TYPE_NAME (type);
6483 /* we have a reference; this is a NeXT extension. */
6485 if (obstack_object_size (&util_obstack) - curtype == 1
6486 && format == OBJC_ENCODE_INLINE_DEFS)
6488 /* Output format of struct for first level only. */
6489 tree fields = TYPE_FIELDS (type);
6491 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6493 obstack_1grow (&util_obstack, left);
6494 obstack_grow (&util_obstack,
6495 IDENTIFIER_POINTER (name),
6496 strlen (IDENTIFIER_POINTER (name)));
6497 obstack_1grow (&util_obstack, '=');
6499 else
6501 obstack_1grow (&util_obstack, left);
6502 obstack_grow (&util_obstack, "?=", 2);
6505 for ( ; fields; fields = TREE_CHAIN (fields))
6506 encode_field_decl (fields, curtype, format);
6508 obstack_1grow (&util_obstack, right);
6511 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6513 obstack_1grow (&util_obstack, left);
6514 obstack_grow (&util_obstack,
6515 IDENTIFIER_POINTER (name),
6516 strlen (IDENTIFIER_POINTER (name)));
6517 obstack_1grow (&util_obstack, right);
6520 else
6522 /* We have an untagged structure or a typedef. */
6523 obstack_1grow (&util_obstack, left);
6524 obstack_1grow (&util_obstack, '?');
6525 obstack_1grow (&util_obstack, right);
6529 else
6531 tree name = TYPE_NAME (type);
6532 tree fields = TYPE_FIELDS (type);
6534 if (format == OBJC_ENCODE_INLINE_DEFS
6535 || generating_instance_variables)
6537 obstack_1grow (&util_obstack, left);
6538 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6539 obstack_grow (&util_obstack,
6540 IDENTIFIER_POINTER (name),
6541 strlen (IDENTIFIER_POINTER (name)));
6542 else
6543 obstack_1grow (&util_obstack, '?');
6545 obstack_1grow (&util_obstack, '=');
6547 for (; fields; fields = TREE_CHAIN (fields))
6549 if (generating_instance_variables)
6551 tree fname = DECL_NAME (fields);
6553 obstack_1grow (&util_obstack, '"');
6554 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6556 obstack_grow (&util_obstack,
6557 IDENTIFIER_POINTER (fname),
6558 strlen (IDENTIFIER_POINTER (fname)));
6561 obstack_1grow (&util_obstack, '"');
6564 encode_field_decl (fields, curtype, format);
6567 obstack_1grow (&util_obstack, right);
6570 else
6572 obstack_1grow (&util_obstack, left);
6573 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6574 obstack_grow (&util_obstack,
6575 IDENTIFIER_POINTER (name),
6576 strlen (IDENTIFIER_POINTER (name)));
6577 else
6578 /* We have an untagged structure or a typedef. */
6579 obstack_1grow (&util_obstack, '?');
6581 obstack_1grow (&util_obstack, right);
6586 static void
6587 encode_aggregate (type, curtype, format)
6588 tree type;
6589 int curtype;
6590 int format;
6592 enum tree_code code = TREE_CODE (type);
6594 switch (code)
6596 case RECORD_TYPE:
6598 encode_aggregate_within(type, curtype, format, '{', '}');
6599 break;
6601 case UNION_TYPE:
6603 encode_aggregate_within(type, curtype, format, '(', ')');
6604 break;
6607 case ENUMERAL_TYPE:
6608 obstack_1grow (&util_obstack, 'i');
6609 break;
6611 default:
6612 break;
6616 /* Support bitfields. The current version of Objective-C does not support
6617 them. The string will consist of one or more "b:n"'s where n is an
6618 integer describing the width of the bitfield. Currently, classes in
6619 the kit implement a method "-(char *)describeBitfieldStruct:" that
6620 simulates this. If they do not implement this method, the archiver
6621 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6622 according to the GNU compiler. After looking at the "kit", it appears
6623 that all classes currently rely on this default behavior, rather than
6624 hand generating this string (which is tedious). */
6626 static void
6627 encode_bitfield (width)
6628 int width;
6630 char buffer[40];
6631 sprintf (buffer, "b%d", width);
6632 obstack_grow (&util_obstack, buffer, strlen (buffer));
6635 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6637 static void
6638 encode_type (type, curtype, format)
6639 tree type;
6640 int curtype;
6641 int format;
6643 enum tree_code code = TREE_CODE (type);
6645 if (code == INTEGER_TYPE)
6647 if (integer_zerop (TYPE_MIN_VALUE (type)))
6649 /* Unsigned integer types. */
6651 if (TYPE_MODE (type) == QImode)
6652 obstack_1grow (&util_obstack, 'C');
6653 else if (TYPE_MODE (type) == HImode)
6654 obstack_1grow (&util_obstack, 'S');
6655 else if (TYPE_MODE (type) == SImode)
6657 if (type == long_unsigned_type_node)
6658 obstack_1grow (&util_obstack, 'L');
6659 else
6660 obstack_1grow (&util_obstack, 'I');
6662 else if (TYPE_MODE (type) == DImode)
6663 obstack_1grow (&util_obstack, 'Q');
6666 else
6667 /* Signed integer types. */
6669 if (TYPE_MODE (type) == QImode)
6670 obstack_1grow (&util_obstack, 'c');
6671 else if (TYPE_MODE (type) == HImode)
6672 obstack_1grow (&util_obstack, 's');
6673 else if (TYPE_MODE (type) == SImode)
6675 if (type == long_integer_type_node)
6676 obstack_1grow (&util_obstack, 'l');
6677 else
6678 obstack_1grow (&util_obstack, 'i');
6681 else if (TYPE_MODE (type) == DImode)
6682 obstack_1grow (&util_obstack, 'q');
6686 else if (code == REAL_TYPE)
6688 /* Floating point types. */
6690 if (TYPE_MODE (type) == SFmode)
6691 obstack_1grow (&util_obstack, 'f');
6692 else if (TYPE_MODE (type) == DFmode
6693 || TYPE_MODE (type) == TFmode)
6694 obstack_1grow (&util_obstack, 'd');
6697 else if (code == VOID_TYPE)
6698 obstack_1grow (&util_obstack, 'v');
6700 else if (code == ARRAY_TYPE)
6701 encode_array (type, curtype, format);
6703 else if (code == POINTER_TYPE)
6704 encode_pointer (type, curtype, format);
6706 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6707 encode_aggregate (type, curtype, format);
6709 else if (code == FUNCTION_TYPE) /* '?' */
6710 obstack_1grow (&util_obstack, '?');
6713 static void
6714 encode_complete_bitfield (int position, tree type, int size)
6716 enum tree_code code = TREE_CODE (type);
6717 char buffer[40];
6718 char charType = '?';
6720 if (code == INTEGER_TYPE)
6722 if (integer_zerop (TYPE_MIN_VALUE (type)))
6724 /* Unsigned integer types. */
6726 if (TYPE_MODE (type) == QImode)
6727 charType = 'C';
6728 else if (TYPE_MODE (type) == HImode)
6729 charType = 'S';
6730 else if (TYPE_MODE (type) == SImode)
6732 if (type == long_unsigned_type_node)
6733 charType = 'L';
6734 else
6735 charType = 'I';
6737 else if (TYPE_MODE (type) == DImode)
6738 charType = 'Q';
6741 else
6742 /* Signed integer types. */
6744 if (TYPE_MODE (type) == QImode)
6745 charType = 'c';
6746 else if (TYPE_MODE (type) == HImode)
6747 charType = 's';
6748 else if (TYPE_MODE (type) == SImode)
6750 if (type == long_integer_type_node)
6751 charType = 'l';
6752 else
6753 charType = 'i';
6756 else if (TYPE_MODE (type) == DImode)
6757 charType = 'q';
6760 else if (code == ENUMERAL_TYPE)
6761 charType = 'i';
6762 else
6763 abort ();
6765 sprintf (buffer, "b%d%c%d", position, charType, size);
6766 obstack_grow (&util_obstack, buffer, strlen (buffer));
6769 static void
6770 encode_field_decl (field_decl, curtype, format)
6771 tree field_decl;
6772 int curtype;
6773 int format;
6775 tree type;
6777 type = TREE_TYPE (field_decl);
6779 /* If this field is obviously a bitfield, or is a bitfield that has been
6780 clobbered to look like a ordinary integer mode, go ahead and generate
6781 the bitfield typing information. */
6782 if (flag_next_runtime)
6784 if (DECL_BIT_FIELD (field_decl))
6785 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6786 else
6787 encode_type (TREE_TYPE (field_decl), curtype, format);
6789 else
6791 if (DECL_BIT_FIELD (field_decl))
6792 encode_complete_bitfield (int_bit_position (field_decl),
6793 DECL_BIT_FIELD_TYPE (field_decl),
6794 tree_low_cst (DECL_SIZE (field_decl), 1));
6795 else
6796 encode_type (TREE_TYPE (field_decl), curtype, format);
6800 static tree
6801 expr_last (complex_expr)
6802 tree complex_expr;
6804 tree next;
6806 if (complex_expr)
6807 while ((next = TREE_OPERAND (complex_expr, 0)))
6808 complex_expr = next;
6810 return complex_expr;
6813 /* Transform a method definition into a function definition as follows:
6814 - synthesize the first two arguments, "self" and "_cmd". */
6816 void
6817 start_method_def (method)
6818 tree method;
6820 tree decl_specs;
6822 /* Required to implement _msgSuper. */
6823 objc_method_context = method;
6824 UOBJC_SUPER_decl = NULL_TREE;
6826 /* Must be called BEFORE start_function. */
6827 pushlevel (0);
6829 /* Generate prototype declarations for arguments..."new-style". */
6831 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6832 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6833 else
6834 /* Really a `struct objc_class *'. However, we allow people to
6835 assign to self, which changes its type midstream. */
6836 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6838 push_parm_decl (build_tree_list
6839 (build_tree_list (decl_specs,
6840 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6841 unused_list));
6843 decl_specs = build_tree_list (NULL_TREE,
6844 xref_tag (RECORD_TYPE,
6845 get_identifier (TAG_SELECTOR)));
6846 push_parm_decl (build_tree_list
6847 (build_tree_list (decl_specs,
6848 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6849 unused_list));
6851 /* Generate argument declarations if a keyword_decl. */
6852 if (METHOD_SEL_ARGS (method))
6854 tree arglist = METHOD_SEL_ARGS (method);
6857 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6858 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6860 if (arg_decl)
6862 tree last_expr = expr_last (arg_decl);
6864 /* Unite the abstract decl with its name. */
6865 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6866 push_parm_decl (build_tree_list
6867 (build_tree_list (arg_spec, arg_decl),
6868 NULL_TREE));
6870 /* Unhook: restore the abstract declarator. */
6871 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6874 else
6875 push_parm_decl (build_tree_list
6876 (build_tree_list (arg_spec,
6877 KEYWORD_ARG_NAME (arglist)),
6878 NULL_TREE));
6880 arglist = TREE_CHAIN (arglist);
6882 while (arglist);
6885 if (METHOD_ADD_ARGS (method) != NULL_TREE
6886 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6888 /* We have a variable length selector - in "prototype" format. */
6889 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6890 while (akey)
6892 /* This must be done prior to calling pushdecl. pushdecl is
6893 going to change our chain on us. */
6894 tree nextkey = TREE_CHAIN (akey);
6895 pushdecl (akey);
6896 akey = nextkey;
6901 static void
6902 warn_with_method (message, mtype, method)
6903 const char *message;
6904 int mtype;
6905 tree method;
6907 if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
6908 return;
6910 diagnostic_report_current_function (global_dc);
6912 /* Add a readable method name to the warning. */
6913 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6914 DECL_SOURCE_LINE (method),
6915 "%s `%c%s'",
6916 message, mtype,
6917 gen_method_decl (method, errbuf));
6920 /* Return 1 if METHOD is consistent with PROTO. */
6922 static int
6923 comp_method_with_proto (method, proto)
6924 tree method, proto;
6926 /* Create a function template node at most once. */
6927 if (!function1_template)
6928 function1_template = make_node (FUNCTION_TYPE);
6930 /* Install argument types - normally set by build_function_type. */
6931 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6933 /* install return type */
6934 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6936 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6939 /* Return 1 if PROTO1 is consistent with PROTO2. */
6941 static int
6942 comp_proto_with_proto (proto0, proto1)
6943 tree proto0, proto1;
6945 /* Create a couple of function_template nodes at most once. */
6946 if (!function1_template)
6947 function1_template = make_node (FUNCTION_TYPE);
6948 if (!function2_template)
6949 function2_template = make_node (FUNCTION_TYPE);
6951 /* Install argument types; normally set by build_function_type. */
6952 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6953 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6955 /* Install return type. */
6956 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6957 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6959 return comptypes (function1_template, function2_template);
6962 /* - Generate an identifier for the function. the format is "_n_cls",
6963 where 1 <= n <= nMethods, and cls is the name the implementation we
6964 are processing.
6965 - Install the return type from the method declaration.
6966 - If we have a prototype, check for type consistency. */
6968 static void
6969 really_start_method (method, parmlist)
6970 tree method, parmlist;
6972 tree sc_spec, ret_spec, ret_decl, decl_specs;
6973 tree method_decl, method_id;
6974 const char *sel_name, *class_name, *cat_name;
6975 char *buf;
6977 /* Synth the storage class & assemble the return type. */
6978 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6979 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6980 decl_specs = chainon (sc_spec, ret_spec);
6982 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6983 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6984 cat_name = ((TREE_CODE (objc_implementation_context)
6985 == CLASS_IMPLEMENTATION_TYPE)
6986 ? NULL
6987 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6988 method_slot++;
6990 /* Make sure this is big enough for any plausible method label. */
6991 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
6992 + (cat_name ? strlen (cat_name) : 0));
6994 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
6995 class_name, cat_name, sel_name, method_slot);
6997 method_id = get_identifier (buf);
6999 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7001 /* Check the declarator portion of the return type for the method. */
7002 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7004 /* Unite the complex decl (specified in the abstract decl) with the
7005 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7006 tree save_expr = expr_last (ret_decl);
7008 TREE_OPERAND (save_expr, 0) = method_decl;
7009 method_decl = ret_decl;
7011 /* Fool the parser into thinking it is starting a function. */
7012 start_function (decl_specs, method_decl, NULL_TREE);
7014 /* Unhook: this has the effect of restoring the abstract declarator. */
7015 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7018 else
7020 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7022 /* Fool the parser into thinking it is starting a function. */
7023 start_function (decl_specs, method_decl, NULL_TREE);
7025 /* Unhook: this has the effect of restoring the abstract declarator. */
7026 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7029 METHOD_DEFINITION (method) = current_function_decl;
7031 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7033 if (implementation_template != objc_implementation_context)
7035 tree proto;
7037 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7038 proto = lookup_instance_method_static (implementation_template,
7039 METHOD_SEL_NAME (method));
7040 else
7041 proto = lookup_class_method_static (implementation_template,
7042 METHOD_SEL_NAME (method));
7044 if (proto && ! comp_method_with_proto (method, proto))
7046 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7048 warn_with_method ("conflicting types for", type, method);
7049 warn_with_method ("previous declaration of", type, proto);
7054 /* The following routine is always called...this "architecture" is to
7055 accommodate "old-style" variable length selectors.
7057 - a:a b:b // prototype ; id c; id d; // old-style. */
7059 void
7060 continue_method_def ()
7062 tree parmlist;
7064 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7065 /* We have a `, ...' immediately following the selector. */
7066 parmlist = get_parm_info (0);
7067 else
7068 parmlist = get_parm_info (1); /* place a `void_at_end' */
7070 /* Set self_decl from the first argument...this global is used by
7071 build_ivar_reference calling build_indirect_ref. */
7072 self_decl = TREE_PURPOSE (parmlist);
7074 poplevel (0, 0, 0);
7075 really_start_method (objc_method_context, parmlist);
7076 store_parm_decls ();
7079 /* Called by the parser, from the `pushlevel' production. */
7081 void
7082 add_objc_decls ()
7084 if (!UOBJC_SUPER_decl)
7086 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7087 build_tree_list (NULL_TREE,
7088 objc_super_template),
7089 0, NULL_TREE);
7091 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7093 /* This prevents `unused variable' warnings when compiling with -Wall. */
7094 TREE_USED (UOBJC_SUPER_decl) = 1;
7095 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7099 /* _n_Method (id self, SEL sel, ...)
7101 struct objc_super _S;
7102 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7103 } */
7105 tree
7106 get_super_receiver ()
7108 if (objc_method_context)
7110 tree super_expr, super_expr_list;
7112 /* Set receiver to self. */
7113 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7114 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7115 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7117 /* Set class to begin searching. */
7118 super_expr = build_component_ref (UOBJC_SUPER_decl,
7119 get_identifier ("class"));
7121 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7123 /* [_cls, __cls]Super are "pre-built" in
7124 synth_forward_declarations. */
7126 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7127 ((TREE_CODE (objc_method_context)
7128 == INSTANCE_METHOD_DECL)
7129 ? ucls_super_ref
7130 : uucls_super_ref));
7133 else
7134 /* We have a category. */
7136 tree super_name = CLASS_SUPER_NAME (implementation_template);
7137 tree super_class;
7139 /* Barf if super used in a category of Object. */
7140 if (!super_name)
7142 error ("no super class declared in interface for `%s'",
7143 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7144 return error_mark_node;
7147 if (flag_next_runtime)
7149 super_class = get_class_reference (super_name);
7150 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7151 super_class
7152 = build_component_ref (build_indirect_ref (super_class, "->"),
7153 get_identifier ("isa"));
7155 else
7157 add_class_reference (super_name);
7158 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7159 ? objc_get_class_decl : objc_get_meta_class_decl);
7160 assemble_external (super_class);
7161 super_class
7162 = build_function_call
7163 (super_class,
7164 build_tree_list
7165 (NULL_TREE,
7166 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7167 IDENTIFIER_POINTER (super_name))));
7170 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7171 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7174 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7176 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7177 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7179 return build_compound_expr (super_expr_list);
7181 else
7183 error ("[super ...] must appear in a method context");
7184 return error_mark_node;
7188 static tree
7189 encode_method_def (func_decl)
7190 tree func_decl;
7192 tree parms;
7193 int stack_size;
7194 HOST_WIDE_INT max_parm_end = 0;
7195 char buffer[40];
7196 tree result;
7198 /* Return type. */
7199 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7200 obstack_object_size (&util_obstack),
7201 OBJC_ENCODE_INLINE_DEFS);
7203 /* Stack size. */
7204 for (parms = DECL_ARGUMENTS (func_decl); parms;
7205 parms = TREE_CHAIN (parms))
7207 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7208 + int_size_in_bytes (TREE_TYPE (parms)));
7210 if (! offset_is_register && parm_end > max_parm_end)
7211 max_parm_end = parm_end;
7214 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7216 sprintf (buffer, "%d", stack_size);
7217 obstack_grow (&util_obstack, buffer, strlen (buffer));
7219 /* Argument types. */
7220 for (parms = DECL_ARGUMENTS (func_decl); parms;
7221 parms = TREE_CHAIN (parms))
7223 /* Type. */
7224 encode_type (TREE_TYPE (parms),
7225 obstack_object_size (&util_obstack),
7226 OBJC_ENCODE_INLINE_DEFS);
7228 /* Compute offset. */
7229 sprintf (buffer, "%d", forwarding_offset (parms));
7231 /* Indicate register. */
7232 if (offset_is_register)
7233 obstack_1grow (&util_obstack, '+');
7235 obstack_grow (&util_obstack, buffer, strlen (buffer));
7238 /* Null terminate string. */
7239 obstack_1grow (&util_obstack, 0);
7240 result = get_identifier (obstack_finish (&util_obstack));
7241 obstack_free (&util_obstack, util_firstobj);
7242 return result;
7245 static void
7246 objc_expand_function_end ()
7248 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7251 void
7252 finish_method_def ()
7254 lang_expand_function_end = objc_expand_function_end;
7255 finish_function (0, 1);
7256 lang_expand_function_end = NULL;
7258 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7259 since the optimizer may find "may be used before set" errors. */
7260 objc_method_context = NULL_TREE;
7263 #if 0
7265 lang_report_error_function (decl)
7266 tree decl;
7268 if (objc_method_context)
7270 fprintf (stderr, "In method `%s'\n",
7271 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7272 return 1;
7275 else
7276 return 0;
7278 #endif
7280 static int
7281 is_complex_decl (type)
7282 tree type;
7284 return (TREE_CODE (type) == ARRAY_TYPE
7285 || TREE_CODE (type) == FUNCTION_TYPE
7286 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7290 /* Code to convert a decl node into text for a declaration in C. */
7292 static char tmpbuf[256];
7294 static void
7295 adorn_decl (decl, str)
7296 tree decl;
7297 char *str;
7299 enum tree_code code = TREE_CODE (decl);
7301 if (code == ARRAY_REF)
7303 tree an_int_cst = TREE_OPERAND (decl, 1);
7305 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7306 sprintf (str + strlen (str), "[%ld]",
7307 (long) TREE_INT_CST_LOW (an_int_cst));
7308 else
7309 strcat (str, "[]");
7312 else if (code == ARRAY_TYPE)
7314 tree an_int_cst = TYPE_SIZE (decl);
7315 tree array_of = TREE_TYPE (decl);
7317 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7318 sprintf (str + strlen (str), "[%ld]",
7319 (long) (TREE_INT_CST_LOW (an_int_cst)
7320 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7321 else
7322 strcat (str, "[]");
7325 else if (code == CALL_EXPR)
7327 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7329 strcat (str, "(");
7330 while (chain)
7332 gen_declaration_1 (chain, str);
7333 chain = TREE_CHAIN (chain);
7334 if (chain)
7335 strcat (str, ", ");
7337 strcat (str, ")");
7340 else if (code == FUNCTION_TYPE)
7342 tree chain = TYPE_ARG_TYPES (decl);
7344 strcat (str, "(");
7345 while (chain && TREE_VALUE (chain) != void_type_node)
7347 gen_declaration_1 (TREE_VALUE (chain), str);
7348 chain = TREE_CHAIN (chain);
7349 if (chain && TREE_VALUE (chain) != void_type_node)
7350 strcat (str, ", ");
7352 strcat (str, ")");
7355 else if (code == INDIRECT_REF)
7357 strcpy (tmpbuf, "*");
7358 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7360 tree chain;
7362 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7363 chain;
7364 chain = TREE_CHAIN (chain))
7366 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7368 strcat (tmpbuf, " ");
7369 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7372 if (str[0])
7373 strcat (tmpbuf, " ");
7375 strcat (tmpbuf, str);
7376 strcpy (str, tmpbuf);
7379 else if (code == POINTER_TYPE)
7381 strcpy (tmpbuf, "*");
7382 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7384 if (TREE_READONLY (decl))
7385 strcat (tmpbuf, " const");
7386 if (TYPE_VOLATILE (decl))
7387 strcat (tmpbuf, " volatile");
7388 if (str[0])
7389 strcat (tmpbuf, " ");
7391 strcat (tmpbuf, str);
7392 strcpy (str, tmpbuf);
7396 static char *
7397 gen_declarator (decl, buf, name)
7398 tree decl;
7399 char *buf;
7400 const char *name;
7402 if (decl)
7404 enum tree_code code = TREE_CODE (decl);
7405 char *str;
7406 tree op;
7407 int wrap = 0;
7409 switch (code)
7411 case ARRAY_REF:
7412 case INDIRECT_REF:
7413 case CALL_EXPR:
7414 op = TREE_OPERAND (decl, 0);
7416 /* We have a pointer to a function or array...(*)(), (*)[] */
7417 if ((code == ARRAY_REF || code == CALL_EXPR)
7418 && op && TREE_CODE (op) == INDIRECT_REF)
7419 wrap = 1;
7421 str = gen_declarator (op, buf, name);
7423 if (wrap)
7425 strcpy (tmpbuf, "(");
7426 strcat (tmpbuf, str);
7427 strcat (tmpbuf, ")");
7428 strcpy (str, tmpbuf);
7431 adorn_decl (decl, str);
7432 break;
7434 case ARRAY_TYPE:
7435 case FUNCTION_TYPE:
7436 case POINTER_TYPE:
7437 strcpy (buf, name);
7438 str = buf;
7440 /* This clause is done iteratively rather than recursively. */
7443 op = (is_complex_decl (TREE_TYPE (decl))
7444 ? TREE_TYPE (decl) : NULL_TREE);
7446 adorn_decl (decl, str);
7448 /* We have a pointer to a function or array...(*)(), (*)[] */
7449 if (code == POINTER_TYPE
7450 && op && (TREE_CODE (op) == FUNCTION_TYPE
7451 || TREE_CODE (op) == ARRAY_TYPE))
7453 strcpy (tmpbuf, "(");
7454 strcat (tmpbuf, str);
7455 strcat (tmpbuf, ")");
7456 strcpy (str, tmpbuf);
7459 decl = (is_complex_decl (TREE_TYPE (decl))
7460 ? TREE_TYPE (decl) : NULL_TREE);
7463 while (decl && (code = TREE_CODE (decl)))
7466 break;
7468 case IDENTIFIER_NODE:
7469 /* Will only happen if we are processing a "raw" expr-decl. */
7470 strcpy (buf, IDENTIFIER_POINTER (decl));
7471 return buf;
7473 default:
7474 abort ();
7477 return str;
7480 else
7481 /* We have an abstract declarator or a _DECL node. */
7483 strcpy (buf, name);
7484 return buf;
7488 static void
7489 gen_declspecs (declspecs, buf, raw)
7490 tree declspecs;
7491 char *buf;
7492 int raw;
7494 if (raw)
7496 tree chain;
7498 for (chain = nreverse (copy_list (declspecs));
7499 chain; chain = TREE_CHAIN (chain))
7501 tree aspec = TREE_VALUE (chain);
7503 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7504 strcat (buf, IDENTIFIER_POINTER (aspec));
7505 else if (TREE_CODE (aspec) == RECORD_TYPE)
7507 if (TYPE_NAME (aspec))
7509 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7511 if (! TREE_STATIC_TEMPLATE (aspec))
7512 strcat (buf, "struct ");
7513 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7515 /* NEW!!! */
7516 if (protocol_list)
7518 tree chain = protocol_list;
7520 strcat (buf, " <");
7521 while (chain)
7523 strcat (buf,
7524 IDENTIFIER_POINTER
7525 (PROTOCOL_NAME (TREE_VALUE (chain))));
7526 chain = TREE_CHAIN (chain);
7527 if (chain)
7528 strcat (buf, ", ");
7530 strcat (buf, ">");
7534 else
7535 strcat (buf, "untagged struct");
7538 else if (TREE_CODE (aspec) == UNION_TYPE)
7540 if (TYPE_NAME (aspec))
7542 if (! TREE_STATIC_TEMPLATE (aspec))
7543 strcat (buf, "union ");
7544 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7546 else
7547 strcat (buf, "untagged union");
7550 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7552 if (TYPE_NAME (aspec))
7554 if (! TREE_STATIC_TEMPLATE (aspec))
7555 strcat (buf, "enum ");
7556 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7558 else
7559 strcat (buf, "untagged enum");
7562 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7563 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7565 else if (IS_ID (aspec))
7567 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7569 strcat (buf, "id");
7570 if (protocol_list)
7572 tree chain = protocol_list;
7574 strcat (buf, " <");
7575 while (chain)
7577 strcat (buf,
7578 IDENTIFIER_POINTER
7579 (PROTOCOL_NAME (TREE_VALUE (chain))));
7580 chain = TREE_CHAIN (chain);
7581 if (chain)
7582 strcat (buf, ", ");
7584 strcat (buf, ">");
7587 if (TREE_CHAIN (chain))
7588 strcat (buf, " ");
7591 else
7593 /* Type qualifiers. */
7594 if (TREE_READONLY (declspecs))
7595 strcat (buf, "const ");
7596 if (TYPE_VOLATILE (declspecs))
7597 strcat (buf, "volatile ");
7599 switch (TREE_CODE (declspecs))
7601 /* Type specifiers. */
7603 case INTEGER_TYPE:
7604 declspecs = TYPE_MAIN_VARIANT (declspecs);
7606 /* Signed integer types. */
7608 if (declspecs == short_integer_type_node)
7609 strcat (buf, "short int ");
7610 else if (declspecs == integer_type_node)
7611 strcat (buf, "int ");
7612 else if (declspecs == long_integer_type_node)
7613 strcat (buf, "long int ");
7614 else if (declspecs == long_long_integer_type_node)
7615 strcat (buf, "long long int ");
7616 else if (declspecs == signed_char_type_node
7617 || declspecs == char_type_node)
7618 strcat (buf, "char ");
7620 /* Unsigned integer types. */
7622 else if (declspecs == short_unsigned_type_node)
7623 strcat (buf, "unsigned short ");
7624 else if (declspecs == unsigned_type_node)
7625 strcat (buf, "unsigned int ");
7626 else if (declspecs == long_unsigned_type_node)
7627 strcat (buf, "unsigned long ");
7628 else if (declspecs == long_long_unsigned_type_node)
7629 strcat (buf, "unsigned long long ");
7630 else if (declspecs == unsigned_char_type_node)
7631 strcat (buf, "unsigned char ");
7632 break;
7634 case REAL_TYPE:
7635 declspecs = TYPE_MAIN_VARIANT (declspecs);
7637 if (declspecs == float_type_node)
7638 strcat (buf, "float ");
7639 else if (declspecs == double_type_node)
7640 strcat (buf, "double ");
7641 else if (declspecs == long_double_type_node)
7642 strcat (buf, "long double ");
7643 break;
7645 case RECORD_TYPE:
7646 if (TYPE_NAME (declspecs)
7647 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7649 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7651 if (! TREE_STATIC_TEMPLATE (declspecs))
7652 strcat (buf, "struct ");
7653 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7655 if (protocol_list)
7657 tree chain = protocol_list;
7659 strcat (buf, " <");
7660 while (chain)
7662 strcat (buf,
7663 IDENTIFIER_POINTER
7664 (PROTOCOL_NAME (TREE_VALUE (chain))));
7665 chain = TREE_CHAIN (chain);
7666 if (chain)
7667 strcat (buf, ", ");
7669 strcat (buf, ">");
7673 else
7674 strcat (buf, "untagged struct");
7676 strcat (buf, " ");
7677 break;
7679 case UNION_TYPE:
7680 if (TYPE_NAME (declspecs)
7681 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7683 strcat (buf, "union ");
7684 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7685 strcat (buf, " ");
7688 else
7689 strcat (buf, "untagged union ");
7690 break;
7692 case ENUMERAL_TYPE:
7693 if (TYPE_NAME (declspecs)
7694 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7696 strcat (buf, "enum ");
7697 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7698 strcat (buf, " ");
7701 else
7702 strcat (buf, "untagged enum ");
7703 break;
7705 case VOID_TYPE:
7706 strcat (buf, "void ");
7707 break;
7709 case POINTER_TYPE:
7711 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7713 strcat (buf, "id");
7714 if (protocol_list)
7716 tree chain = protocol_list;
7718 strcat (buf, " <");
7719 while (chain)
7721 strcat (buf,
7722 IDENTIFIER_POINTER
7723 (PROTOCOL_NAME (TREE_VALUE (chain))));
7724 chain = TREE_CHAIN (chain);
7725 if (chain)
7726 strcat (buf, ", ");
7729 strcat (buf, ">");
7732 break;
7734 default:
7735 break;
7740 /* Given a tree node, produce a printable description of it in the given
7741 buffer, overwriting the buffer. */
7743 static char *
7744 gen_declaration (atype_or_adecl, buf)
7745 tree atype_or_adecl;
7746 char *buf;
7748 buf[0] = '\0';
7749 gen_declaration_1 (atype_or_adecl, buf);
7750 return buf;
7753 /* Given a tree node, append a printable description to the end of the
7754 given buffer. */
7756 static void
7757 gen_declaration_1 (atype_or_adecl, buf)
7758 tree atype_or_adecl;
7759 char *buf;
7761 char declbuf[256];
7763 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7765 tree declspecs; /* "identifier_node", "record_type" */
7766 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7768 /* We have a "raw", abstract declarator (typename). */
7769 declarator = TREE_VALUE (atype_or_adecl);
7770 declspecs = TREE_PURPOSE (atype_or_adecl);
7772 gen_declspecs (declspecs, buf, 1);
7773 if (declarator)
7775 strcat (buf, " ");
7776 strcat (buf, gen_declarator (declarator, declbuf, ""));
7780 else
7782 tree atype;
7783 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7784 tree declarator; /* "array_type", "function_type", "pointer_type". */
7786 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7787 || TREE_CODE (atype_or_adecl) == PARM_DECL
7788 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7789 atype = TREE_TYPE (atype_or_adecl);
7790 else
7791 /* Assume we have a *_type node. */
7792 atype = atype_or_adecl;
7794 if (is_complex_decl (atype))
7796 tree chain;
7798 /* Get the declaration specifier; it is at the end of the list. */
7799 declarator = chain = atype;
7801 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7802 while (is_complex_decl (chain));
7803 declspecs = chain;
7806 else
7808 declspecs = atype;
7809 declarator = NULL_TREE;
7812 gen_declspecs (declspecs, buf, 0);
7814 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7815 || TREE_CODE (atype_or_adecl) == PARM_DECL
7816 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7818 const char *const decl_name =
7819 (DECL_NAME (atype_or_adecl)
7820 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7822 if (declarator)
7824 strcat (buf, " ");
7825 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7828 else if (decl_name[0])
7830 strcat (buf, " ");
7831 strcat (buf, decl_name);
7834 else if (declarator)
7836 strcat (buf, " ");
7837 strcat (buf, gen_declarator (declarator, declbuf, ""));
7842 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7844 /* Given a method tree, put a printable description into the given
7845 buffer (overwriting) and return a pointer to the buffer. */
7847 static char *
7848 gen_method_decl (method, buf)
7849 tree method;
7850 char *buf;
7852 tree chain;
7854 buf[0] = '\0';
7855 if (RAW_TYPESPEC (method) != objc_object_reference)
7857 strcat (buf, "(");
7858 gen_declaration_1 (TREE_TYPE (method), buf);
7859 strcat (buf, ")");
7862 chain = METHOD_SEL_ARGS (method);
7863 if (chain)
7865 /* We have a chain of keyword_decls. */
7868 if (KEYWORD_KEY_NAME (chain))
7869 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7871 strcat (buf, ":");
7872 if (RAW_TYPESPEC (chain) != objc_object_reference)
7874 strcat (buf, "(");
7875 gen_declaration_1 (TREE_TYPE (chain), buf);
7876 strcat (buf, ")");
7879 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7880 if ((chain = TREE_CHAIN (chain)))
7881 strcat (buf, " ");
7883 while (chain);
7885 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7886 strcat (buf, ", ...");
7887 else if (METHOD_ADD_ARGS (method))
7889 /* We have a tree list node as generate by get_parm_info. */
7890 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7892 /* Know we have a chain of parm_decls. */
7893 while (chain)
7895 strcat (buf, ", ");
7896 gen_declaration_1 (chain, buf);
7897 chain = TREE_CHAIN (chain);
7902 else
7903 /* We have a unary selector. */
7904 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7906 return buf;
7909 /* Debug info. */
7911 static void
7912 dump_interface (fp, chain)
7913 FILE *fp;
7914 tree chain;
7916 char *buf = (char *) xmalloc (256);
7917 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7918 tree ivar_decls = CLASS_RAW_IVARS (chain);
7919 tree nst_methods = CLASS_NST_METHODS (chain);
7920 tree cls_methods = CLASS_CLS_METHODS (chain);
7922 fprintf (fp, "\n@interface %s", my_name);
7924 if (CLASS_SUPER_NAME (chain))
7926 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7927 fprintf (fp, " : %s\n", super_name);
7929 else
7930 fprintf (fp, "\n");
7932 if (ivar_decls)
7934 fprintf (fp, "{\n");
7937 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7938 ivar_decls = TREE_CHAIN (ivar_decls);
7940 while (ivar_decls);
7941 fprintf (fp, "}\n");
7944 while (nst_methods)
7946 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7947 nst_methods = TREE_CHAIN (nst_methods);
7950 while (cls_methods)
7952 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7953 cls_methods = TREE_CHAIN (cls_methods);
7955 fprintf (fp, "\n@end");
7958 /* Demangle function for Objective-C */
7959 static const char *
7960 objc_demangle (mangled)
7961 const char *mangled;
7963 char *demangled, *cp;
7965 if (mangled[0] == '_' &&
7966 (mangled[1] == 'i' || mangled[1] == 'c') &&
7967 mangled[2] == '_')
7969 cp = demangled = xmalloc(strlen(mangled) + 2);
7970 if (mangled[1] == 'i')
7971 *cp++ = '-'; /* for instance method */
7972 else
7973 *cp++ = '+'; /* for class method */
7974 *cp++ = '['; /* opening left brace */
7975 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7976 while (*cp && *cp == '_')
7977 cp++; /* skip any initial underbars in class name */
7978 cp = strchr(cp, '_'); /* find first non-initial underbar */
7979 if (cp == NULL)
7981 free(demangled); /* not mangled name */
7982 return mangled;
7984 if (cp[1] == '_') /* easy case: no category name */
7986 *cp++ = ' '; /* replace two '_' with one ' ' */
7987 strcpy(cp, mangled + (cp - demangled) + 2);
7989 else
7991 *cp++ = '('; /* less easy case: category name */
7992 cp = strchr(cp, '_');
7993 if (cp == 0)
7995 free(demangled); /* not mangled name */
7996 return mangled;
7998 *cp++ = ')';
7999 *cp++ = ' '; /* overwriting 1st char of method name... */
8000 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8002 while (*cp && *cp == '_')
8003 cp++; /* skip any initial underbars in method name */
8004 for (; *cp; cp++)
8005 if (*cp == '_')
8006 *cp = ':'; /* replace remaining '_' with ':' */
8007 *cp++ = ']'; /* closing right brace */
8008 *cp++ = 0; /* string terminator */
8009 return demangled;
8011 else
8012 return mangled; /* not an objc mangled name */
8015 const char *
8016 objc_printable_name (decl, kind)
8017 tree decl;
8018 int kind ATTRIBUTE_UNUSED;
8020 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8023 static void
8024 init_objc ()
8026 gcc_obstack_init (&util_obstack);
8027 util_firstobj = (char *) obstack_finish (&util_obstack);
8029 errbuf = (char *) xmalloc (BUFSIZE);
8030 hash_init ();
8031 synth_module_prologue ();
8034 static void
8035 finish_objc ()
8037 struct imp_entry *impent;
8038 tree chain;
8039 /* The internally generated initializers appear to have missing braces.
8040 Don't warn about this. */
8041 int save_warn_missing_braces = warn_missing_braces;
8042 warn_missing_braces = 0;
8044 /* A missing @end may not be detected by the parser. */
8045 if (objc_implementation_context)
8047 warning ("`@end' missing in implementation context");
8048 finish_class (objc_implementation_context);
8049 objc_ivar_chain = NULL_TREE;
8050 objc_implementation_context = NULL_TREE;
8053 generate_forward_declaration_to_string_table ();
8055 #ifdef OBJC_PROLOGUE
8056 OBJC_PROLOGUE;
8057 #endif
8059 /* Process the static instances here because initialization of objc_symtab
8060 depends on them. */
8061 if (objc_static_instances)
8062 generate_static_references ();
8064 if (imp_list || class_names_chain
8065 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8066 generate_objc_symtab_decl ();
8068 for (impent = imp_list; impent; impent = impent->next)
8070 objc_implementation_context = impent->imp_context;
8071 implementation_template = impent->imp_template;
8073 UOBJC_CLASS_decl = impent->class_decl;
8074 UOBJC_METACLASS_decl = impent->meta_decl;
8076 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8078 /* all of the following reference the string pool... */
8079 generate_ivar_lists ();
8080 generate_dispatch_tables ();
8081 generate_shared_structures ();
8083 else
8085 generate_dispatch_tables ();
8086 generate_category (objc_implementation_context);
8090 /* If we are using an array of selectors, we must always
8091 finish up the array decl even if no selectors were used. */
8092 if (! flag_next_runtime || sel_ref_chain)
8093 build_selector_translation_table ();
8095 if (protocol_chain)
8096 generate_protocols ();
8098 if (objc_implementation_context || class_names_chain || objc_static_instances
8099 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8101 /* Arrange for ObjC data structures to be initialized at run time. */
8102 rtx init_sym = build_module_descriptor ();
8103 if (init_sym && targetm.have_ctors_dtors)
8104 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8107 /* Dump the class references. This forces the appropriate classes
8108 to be linked into the executable image, preserving unix archive
8109 semantics. This can be removed when we move to a more dynamically
8110 linked environment. */
8112 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8114 handle_class_ref (chain);
8115 if (TREE_PURPOSE (chain))
8116 generate_classref_translation_entry (chain);
8119 for (impent = imp_list; impent; impent = impent->next)
8120 handle_impent (impent);
8122 /* Dump the string table last. */
8124 generate_strings ();
8126 if (flag_gen_declaration)
8128 add_class (objc_implementation_context);
8129 dump_interface (gen_declaration_file, objc_implementation_context);
8132 if (warn_selector)
8134 int slot;
8135 hash hsh;
8137 /* Run through the selector hash tables and print a warning for any
8138 selector which has multiple methods. */
8140 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8141 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8142 if (hsh->list)
8144 tree meth = hsh->key;
8145 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8146 ? '-' : '+');
8147 attr loop;
8149 warning ("potential selector conflict for method `%s'",
8150 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8151 warn_with_method ("found", type, meth);
8152 for (loop = hsh->list; loop; loop = loop->next)
8153 warn_with_method ("found", type, loop->value);
8156 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8157 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8158 if (hsh->list)
8160 tree meth = hsh->key;
8161 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8162 ? '-' : '+');
8163 attr loop;
8165 warning ("potential selector conflict for method `%s'",
8166 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8167 warn_with_method ("found", type, meth);
8168 for (loop = hsh->list; loop; loop = loop->next)
8169 warn_with_method ("found", type, loop->value);
8173 warn_missing_braces = save_warn_missing_braces;
8176 /* Subroutines of finish_objc. */
8178 static void
8179 generate_classref_translation_entry (chain)
8180 tree chain;
8182 tree expr, name, decl_specs, decl, sc_spec;
8183 tree type;
8185 type = TREE_TYPE (TREE_PURPOSE (chain));
8187 expr = add_objc_string (TREE_VALUE (chain), class_names);
8188 expr = build_c_cast (type, expr); /* cast! */
8190 name = DECL_NAME (TREE_PURPOSE (chain));
8192 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8194 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8195 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8197 /* The decl that is returned from start_decl is the one that we
8198 forward declared in build_class_reference. */
8199 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8200 DECL_CONTEXT (decl) = NULL_TREE;
8201 finish_decl (decl, expr, NULL_TREE);
8202 return;
8205 static void
8206 handle_class_ref (chain)
8207 tree chain;
8209 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8210 char *string = (char *) alloca (strlen (name) + 30);
8211 tree decl;
8212 tree exp;
8214 sprintf (string, "%sobjc_class_name_%s",
8215 (flag_next_runtime ? "." : "__"), name);
8217 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8218 if (flag_next_runtime)
8220 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8221 return;
8223 #endif
8225 /* Make a decl for this name, so we can use its address in a tree. */
8226 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8227 DECL_EXTERNAL (decl) = 1;
8228 TREE_PUBLIC (decl) = 1;
8230 pushdecl (decl);
8231 rest_of_decl_compilation (decl, 0, 0, 0);
8233 /* Make a decl for the address. */
8234 sprintf (string, "%sobjc_class_ref_%s",
8235 (flag_next_runtime ? "." : "__"), name);
8236 exp = build1 (ADDR_EXPR, string_type_node, decl);
8237 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8238 DECL_INITIAL (decl) = exp;
8239 TREE_STATIC (decl) = 1;
8240 TREE_USED (decl) = 1;
8242 pushdecl (decl);
8243 rest_of_decl_compilation (decl, 0, 0, 0);
8246 static void
8247 handle_impent (impent)
8248 struct imp_entry *impent;
8250 char *string;
8252 objc_implementation_context = impent->imp_context;
8253 implementation_template = impent->imp_template;
8255 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8257 const char *const class_name =
8258 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8260 string = (char *) alloca (strlen (class_name) + 30);
8262 sprintf (string, "%sobjc_class_name_%s",
8263 (flag_next_runtime ? "." : "__"), class_name);
8265 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8267 const char *const class_name =
8268 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8269 const char *const class_super_name =
8270 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8272 string = (char *) alloca (strlen (class_name)
8273 + strlen (class_super_name) + 30);
8275 /* Do the same for categories. Even though no references to
8276 these symbols are generated automatically by the compiler, it
8277 gives you a handle to pull them into an archive by hand. */
8278 sprintf (string, "*%sobjc_category_name_%s_%s",
8279 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8281 else
8282 return;
8284 #ifdef ASM_DECLARE_CLASS_REFERENCE
8285 if (flag_next_runtime)
8287 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8288 return;
8290 else
8291 #endif
8293 tree decl, init;
8295 init = build_int_2 (0, 0);
8296 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8297 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8298 TREE_PUBLIC (decl) = 1;
8299 TREE_READONLY (decl) = 1;
8300 TREE_USED (decl) = 1;
8301 TREE_CONSTANT (decl) = 1;
8302 DECL_CONTEXT (decl) = 0;
8303 DECL_ARTIFICIAL (decl) = 1;
8304 DECL_INITIAL (decl) = init;
8305 assemble_variable (decl, 1, 0, 0);
8309 /* Look up ID as an instance variable. */
8310 tree
8311 lookup_objc_ivar (id)
8312 tree id;
8314 tree decl;
8316 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8317 /* We have a message to super. */
8318 return get_super_receiver ();
8319 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8321 if (is_private (decl))
8322 return error_mark_node;
8323 else
8324 return build_ivar_reference (id);
8326 else
8327 return 0;
8330 #include "gtype-objc.h"