* function.c: Fix formatting.
[official-gcc.git] / gcc / objc / objc-act.c
blob4795160f09f98afb63784fe0b7d80abbd7915554
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-lex.h"
49 #include "c-common.h"
50 #include "flags.h"
51 #include "objc-act.h"
52 #include "input.h"
53 #include "except.h"
54 #include "function.h"
55 #include "output.h"
56 #include "toplev.h"
57 #include "ggc.h"
58 #include "cpplib.h"
59 #include "debug.h"
60 #include "target.h"
62 /* This is the default way of generating a method name. */
63 /* I am not sure it is really correct.
64 Perhaps there's a danger that it will make name conflicts
65 if method names contain underscores. -- rms. */
66 #ifndef OBJC_GEN_METHOD_LABEL
67 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 do { \
69 char *temp; \
70 sprintf ((BUF), "_%s_%s_%s_%s", \
71 ((IS_INST) ? "i" : "c"), \
72 (CLASS_NAME), \
73 ((CAT_NAME)? (CAT_NAME) : ""), \
74 (SEL_NAME)); \
75 for (temp = (BUF); *temp; temp++) \
76 if (*temp == ':') *temp = '_'; \
77 } while (0)
78 #endif
80 /* These need specifying. */
81 #ifndef OBJC_FORWARDING_STACK_OFFSET
82 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #endif
85 #ifndef OBJC_FORWARDING_MIN_OFFSET
86 #define OBJC_FORWARDING_MIN_OFFSET 0
87 #endif
90 /* Set up for use of obstacks. */
92 #include "obstack.h"
94 #define obstack_chunk_alloc xmalloc
95 #define obstack_chunk_free free
97 /* This obstack is used to accumulate the encoding of a data type. */
98 static struct obstack util_obstack;
99 /* This points to the beginning of obstack contents,
100 so we can free the whole contents. */
101 char *util_firstobj;
103 /* for encode_method_def */
104 #include "rtl.h"
106 /* The version identifies which language generation and runtime
107 the module (file) was compiled for, and is recorded in the
108 module descriptor. */
110 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
111 #define PROTOCOL_VERSION 2
113 /* (Decide if these can ever be validly changed.) */
114 #define OBJC_ENCODE_INLINE_DEFS 0
115 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
117 /*** Private Interface (procedures) ***/
119 /* Used by compile_file. */
121 static void init_objc PARAMS ((void));
122 static void finish_objc PARAMS ((void));
124 /* Code generation. */
126 static void synth_module_prologue PARAMS ((void));
127 static tree build_constructor PARAMS ((tree, tree));
128 static rtx build_module_descriptor PARAMS ((void));
129 static tree init_module_descriptor PARAMS ((tree));
130 static tree build_objc_method_call PARAMS ((int, tree, tree,
131 tree, tree, tree));
132 static void generate_strings PARAMS ((void));
133 static tree get_proto_encoding PARAMS ((tree));
134 static void build_selector_translation_table PARAMS ((void));
135 static tree build_ivar_chain PARAMS ((tree, int));
137 static tree objc_add_static_instance PARAMS ((tree, tree));
139 static tree build_ivar_template PARAMS ((void));
140 static tree build_method_template PARAMS ((void));
141 static tree build_private_template PARAMS ((tree));
142 static void build_class_template PARAMS ((void));
143 static void build_selector_template PARAMS ((void));
144 static void build_category_template PARAMS ((void));
145 static tree build_super_template PARAMS ((void));
146 static tree build_category_initializer PARAMS ((tree, tree, tree,
147 tree, tree, tree));
148 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
149 tree, tree));
151 static void synth_forward_declarations PARAMS ((void));
152 static void generate_ivar_lists PARAMS ((void));
153 static void generate_dispatch_tables PARAMS ((void));
154 static void generate_shared_structures PARAMS ((void));
155 static tree generate_protocol_list PARAMS ((tree));
156 static void generate_forward_declaration_to_string_table PARAMS ((void));
157 static void build_protocol_reference PARAMS ((tree));
159 static tree build_keyword_selector PARAMS ((tree));
160 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
162 static void generate_static_references PARAMS ((void));
163 static int check_methods_accessible PARAMS ((tree, tree,
164 int));
165 static void encode_aggregate_within PARAMS ((tree, int, int,
166 int, int));
167 static const char *objc_demangle PARAMS ((const char *));
168 static void objc_expand_function_end PARAMS ((void));
170 /* Hash tables to manage the global pool of method prototypes. */
172 hash *nst_method_hash_list = 0;
173 hash *cls_method_hash_list = 0;
175 static size_t hash_func PARAMS ((tree));
176 static void hash_init PARAMS ((void));
177 static void hash_enter PARAMS ((hash *, tree));
178 static hash hash_lookup PARAMS ((hash *, tree));
179 static void hash_add_attr PARAMS ((hash, tree));
180 static tree lookup_method PARAMS ((tree, tree));
181 static tree lookup_instance_method_static PARAMS ((tree, tree));
182 static tree lookup_class_method_static PARAMS ((tree, tree));
183 static tree add_class PARAMS ((tree));
184 static void add_category PARAMS ((tree, tree));
186 enum string_section
188 class_names, /* class, category, protocol, module names */
189 meth_var_names, /* method and variable names */
190 meth_var_types /* method and variable type descriptors */
193 static tree add_objc_string PARAMS ((tree,
194 enum string_section));
195 static tree get_objc_string_decl PARAMS ((tree,
196 enum string_section));
197 static tree build_objc_string_decl PARAMS ((enum string_section));
198 static tree build_selector_reference_decl PARAMS ((void));
200 /* Protocol additions. */
202 static tree add_protocol PARAMS ((tree));
203 static tree lookup_protocol PARAMS ((tree));
204 static void check_protocol_recursively PARAMS ((tree, tree));
205 static tree lookup_and_install_protocols PARAMS ((tree));
207 /* Type encoding. */
209 static void encode_type_qualifiers PARAMS ((tree));
210 static void encode_pointer PARAMS ((tree, int, int));
211 static void encode_array PARAMS ((tree, int, int));
212 static void encode_aggregate PARAMS ((tree, int, int));
213 static void encode_bitfield PARAMS ((int));
214 static void encode_type PARAMS ((tree, int, int));
215 static void encode_field_decl PARAMS ((tree, int, int));
217 static void really_start_method PARAMS ((tree, tree));
218 static int comp_method_with_proto PARAMS ((tree, tree));
219 static int comp_proto_with_proto PARAMS ((tree, tree));
220 static tree get_arg_type_list PARAMS ((tree, int, int));
221 static tree expr_last PARAMS ((tree));
223 /* Utilities for debugging and error diagnostics. */
225 static void warn_with_method PARAMS ((const char *, int, tree));
226 static void error_with_ivar PARAMS ((const char *, tree, tree));
227 static char *gen_method_decl PARAMS ((tree, char *));
228 static char *gen_declaration PARAMS ((tree, char *));
229 static void gen_declaration_1 PARAMS ((tree, char *));
230 static char *gen_declarator PARAMS ((tree, char *,
231 const char *));
232 static int is_complex_decl PARAMS ((tree));
233 static void adorn_decl PARAMS ((tree, char *));
234 static void dump_interface PARAMS ((FILE *, tree));
236 /* Everything else. */
238 static tree define_decl PARAMS ((tree, tree));
239 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
240 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
241 static tree create_builtin_decl PARAMS ((enum tree_code,
242 tree, const char *));
243 static void setup_string_decl PARAMS ((void));
244 static void build_string_class_template PARAMS ((void));
245 static tree my_build_string PARAMS ((int, const char *));
246 static void build_objc_symtab_template PARAMS ((void));
247 static tree init_def_list PARAMS ((tree));
248 static tree init_objc_symtab PARAMS ((tree));
249 static void forward_declare_categories PARAMS ((void));
250 static void generate_objc_symtab_decl PARAMS ((void));
251 static tree build_selector PARAMS ((tree));
252 static tree build_typed_selector_reference PARAMS ((tree, tree));
253 static tree build_selector_reference PARAMS ((tree));
254 static tree build_class_reference_decl PARAMS ((void));
255 static void add_class_reference PARAMS ((tree));
256 static tree objc_copy_list PARAMS ((tree, tree *));
257 static tree build_protocol_template PARAMS ((void));
258 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
259 static tree build_method_prototype_list_template PARAMS ((tree, int));
260 static tree build_method_prototype_template PARAMS ((void));
261 static int forwarding_offset PARAMS ((tree));
262 static tree encode_method_prototype PARAMS ((tree, tree));
263 static tree generate_descriptor_table PARAMS ((tree, const char *,
264 int, tree, tree));
265 static void generate_method_descriptors PARAMS ((tree));
266 static tree build_tmp_function_decl PARAMS ((void));
267 static void hack_method_prototype PARAMS ((tree, tree));
268 static void generate_protocol_references PARAMS ((tree));
269 static void generate_protocols PARAMS ((void));
270 static void check_ivars PARAMS ((tree, tree));
271 static tree build_ivar_list_template PARAMS ((tree, int));
272 static tree build_method_list_template PARAMS ((tree, int));
273 static tree build_ivar_list_initializer PARAMS ((tree, tree));
274 static tree generate_ivars_list PARAMS ((tree, const char *,
275 int, tree));
276 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
277 static tree generate_dispatch_table PARAMS ((tree, const char *,
278 int, tree));
279 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
280 tree, int, tree, tree,
281 tree));
282 static void generate_category PARAMS ((tree));
283 static int is_objc_type_qualifier PARAMS ((tree));
284 static tree adjust_type_for_id_default PARAMS ((tree));
285 static tree check_duplicates PARAMS ((hash));
286 static tree receiver_is_class_object PARAMS ((tree));
287 static int check_methods PARAMS ((tree, tree, int));
288 static int conforms_to_protocol PARAMS ((tree, tree));
289 static void check_protocol PARAMS ((tree, const char *,
290 const char *));
291 static void check_protocols PARAMS ((tree, const char *,
292 const char *));
293 static tree encode_method_def PARAMS ((tree));
294 static void gen_declspecs PARAMS ((tree, char *, int));
295 static void generate_classref_translation_entry PARAMS ((tree));
296 static void handle_class_ref PARAMS ((tree));
297 static void generate_struct_by_value_array PARAMS ((void))
298 ATTRIBUTE_NORETURN;
299 static void objc_act_parse_init PARAMS ((void));
300 static void ggc_mark_imp_list PARAMS ((void *));
301 static void ggc_mark_hash_table PARAMS ((void *));
303 /*** Private Interface (data) ***/
305 /* Reserved tag definitions. */
307 #define TYPE_ID "id"
308 #define TAG_OBJECT "objc_object"
309 #define TAG_CLASS "objc_class"
310 #define TAG_SUPER "objc_super"
311 #define TAG_SELECTOR "objc_selector"
313 #define UTAG_CLASS "_objc_class"
314 #define UTAG_IVAR "_objc_ivar"
315 #define UTAG_IVAR_LIST "_objc_ivar_list"
316 #define UTAG_METHOD "_objc_method"
317 #define UTAG_METHOD_LIST "_objc_method_list"
318 #define UTAG_CATEGORY "_objc_category"
319 #define UTAG_MODULE "_objc_module"
320 #define UTAG_STATICS "_objc_statics"
321 #define UTAG_SYMTAB "_objc_symtab"
322 #define UTAG_SUPER "_objc_super"
323 #define UTAG_SELECTOR "_objc_selector"
325 #define UTAG_PROTOCOL "_objc_protocol"
326 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
327 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
328 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
330 /* Note that the string object global name is only needed for the
331 NeXT runtime. */
332 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
334 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
336 static const char *constant_string_class_name = NULL;
338 static const char *TAG_GETCLASS;
339 static const char *TAG_GETMETACLASS;
340 static const char *TAG_MSGSEND;
341 static const char *TAG_MSGSENDSUPER;
342 static const char *TAG_EXECCLASS;
343 static const char *default_constant_string_class_name;
345 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
346 tree objc_global_trees[OCTI_MAX];
348 int objc_receiver_context;
350 static void handle_impent PARAMS ((struct imp_entry *));
352 struct imp_entry *imp_list = 0;
353 int imp_count = 0; /* `@implementation' */
354 int cat_count = 0; /* `@category' */
356 static int method_slot = 0; /* Used by start_method_def, */
358 #define BUFSIZE 1024
360 static char *errbuf; /* Buffer for error diagnostics */
362 /* Data imported from tree.c. */
364 extern enum debug_info_type write_symbols;
366 /* Data imported from toplev.c. */
368 extern const char *dump_base_name;
370 /* Generate code for GNU or NeXT runtime environment. */
372 #ifdef NEXT_OBJC_RUNTIME
373 int flag_next_runtime = 1;
374 #else
375 int flag_next_runtime = 0;
376 #endif
378 int flag_typed_selectors;
380 /* Open and close the file for outputting class declarations, if requested. */
382 int flag_gen_declaration = 0;
384 FILE *gen_declaration_file;
386 /* Warn if multiple methods are seen for the same selector, but with
387 different argument types. */
389 int warn_selector = 0;
391 /* Warn if methods required by a protocol are not implemented in the
392 class adopting it. When turned off, methods inherited to that
393 class are also considered implemented */
395 int flag_warn_protocol = 1;
397 /* Tells "encode_pointer/encode_aggregate" whether we are generating
398 type descriptors for instance variables (as opposed to methods).
399 Type descriptors for instance variables contain more information
400 than methods (for static typing and embedded structures). */
402 static int generating_instance_variables = 0;
404 /* Tells the compiler that this is a special run. Do not perform any
405 compiling, instead we are to test some platform dependent features
406 and output a C header file with appropriate definitions. */
408 static int print_struct_values = 0;
410 /* Some platforms pass small structures through registers versus
411 through an invisible pointer. Determine at what size structure is
412 the transition point between the two possibilities. */
414 static void
415 generate_struct_by_value_array ()
417 tree type;
418 tree field_decl, field_decl_chain;
419 int i, j;
420 int aggregate_in_mem[32];
421 int found = 0;
423 /* Presumably no platform passes 32 byte structures in a register. */
424 for (i = 1; i < 32; i++)
426 char buffer[5];
428 /* Create an unnamed struct that has `i' character components */
429 type = start_struct (RECORD_TYPE, NULL_TREE);
431 strcpy (buffer, "c1");
432 field_decl = create_builtin_decl (FIELD_DECL,
433 char_type_node,
434 buffer);
435 field_decl_chain = field_decl;
437 for (j = 1; j < i; j++)
439 sprintf (buffer, "c%d", j + 1);
440 field_decl = create_builtin_decl (FIELD_DECL,
441 char_type_node,
442 buffer);
443 chainon (field_decl_chain, field_decl);
445 finish_struct (type, field_decl_chain, NULL_TREE);
447 aggregate_in_mem[i] = aggregate_value_p (type);
448 if (!aggregate_in_mem[i])
449 found = 1;
452 /* We found some structures that are returned in registers instead of memory
453 so output the necessary data. */
454 if (found)
456 for (i = 31; i >= 0; i--)
457 if (!aggregate_in_mem[i])
458 break;
459 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
461 /* The first member of the structure is always 0 because we don't handle
462 structures with 0 members */
463 printf ("static int struct_forward_array[] = {\n 0");
465 for (j = 1; j <= i; j++)
466 printf (", %d", aggregate_in_mem[j]);
467 printf ("\n};\n");
470 exit (0);
473 const char *
474 objc_init (filename)
475 const char *filename;
477 filename = c_objc_common_init (filename);
479 /* Force the line number back to 0; check_newline will have
480 raised it to 1, which will make the builtin functions appear
481 not to be built in. */
482 lineno = 0;
484 /* If gen_declaration desired, open the output file. */
485 if (flag_gen_declaration)
487 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
488 gen_declaration_file = fopen (dumpname, "w");
489 if (gen_declaration_file == 0)
490 fatal_io_error ("can't open %s", dumpname);
491 free (dumpname);
494 if (flag_next_runtime)
496 TAG_GETCLASS = "objc_getClass";
497 TAG_GETMETACLASS = "objc_getMetaClass";
498 TAG_MSGSEND = "objc_msgSend";
499 TAG_MSGSENDSUPER = "objc_msgSendSuper";
500 TAG_EXECCLASS = "__objc_execClass";
501 default_constant_string_class_name = "NSConstantString";
503 else
505 TAG_GETCLASS = "objc_get_class";
506 TAG_GETMETACLASS = "objc_get_meta_class";
507 TAG_MSGSEND = "objc_msg_lookup";
508 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
509 TAG_EXECCLASS = "__objc_exec_class";
510 default_constant_string_class_name = "NXConstantString";
511 flag_typed_selectors = 1;
514 objc_ellipsis_node = make_node (ERROR_MARK);
516 init_objc ();
518 if (print_struct_values)
519 generate_struct_by_value_array ();
521 objc_act_parse_init ();
523 return filename;
526 void
527 finish_file ()
529 c_objc_common_finish_file ();
531 finish_objc (); /* Objective-C finalization */
533 if (gen_declaration_file)
534 fclose (gen_declaration_file);
538 objc_decode_option (argc, argv)
539 int argc;
540 char **argv;
542 const char *p = argv[0];
544 if (!strcmp (p, "-gen-decls"))
545 flag_gen_declaration = 1;
546 else if (!strcmp (p, "-Wselector"))
547 warn_selector = 1;
548 else if (!strcmp (p, "-Wno-selector"))
549 warn_selector = 0;
550 else if (!strcmp (p, "-Wprotocol"))
551 flag_warn_protocol = 1;
552 else if (!strcmp (p, "-Wno-protocol"))
553 flag_warn_protocol = 0;
554 else if (!strcmp (p, "-fgnu-runtime"))
555 flag_next_runtime = 0;
556 else if (!strcmp (p, "-fno-next-runtime"))
557 flag_next_runtime = 0;
558 else if (!strcmp (p, "-fno-gnu-runtime"))
559 flag_next_runtime = 1;
560 else if (!strcmp (p, "-fnext-runtime"))
561 flag_next_runtime = 1;
562 else if (!strcmp (p, "-print-objc-runtime-info"))
563 print_struct_values = 1;
564 #define CSTSTRCLASS "-fconstant-string-class="
565 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
566 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
567 error ("no class name specified as argument to -fconstant-string-class");
568 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
570 #undef CSTSTRCLASS
571 else
572 return c_decode_option (argc, argv);
574 return 1;
578 static tree
579 define_decl (declarator, declspecs)
580 tree declarator;
581 tree declspecs;
583 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
584 finish_decl (decl, NULL_TREE, NULL_TREE);
585 return decl;
588 /* Return 1 if LHS and RHS are compatible types for assignment or
589 various other operations. Return 0 if they are incompatible, and
590 return -1 if we choose to not decide. When the operation is
591 REFLEXIVE, check for compatibility in either direction.
593 For statically typed objects, an assignment of the form `a' = `b'
594 is permitted if:
596 `a' is of type "id",
597 `a' and `b' are the same class type, or
598 `a' and `b' are of class types A and B such that B is a descendant of A. */
601 maybe_objc_comptypes (lhs, rhs, reflexive)
602 tree lhs, rhs;
603 int reflexive;
605 return objc_comptypes (lhs, rhs, reflexive);
608 static tree
609 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
610 tree rproto_list;
611 tree sel_name;
612 int class_meth;
614 tree rproto, p;
615 tree fnd = 0;
617 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
619 p = TREE_VALUE (rproto);
621 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
623 if ((fnd = lookup_method (class_meth
624 ? PROTOCOL_CLS_METHODS (p)
625 : PROTOCOL_NST_METHODS (p), sel_name)))
627 else if (PROTOCOL_LIST (p))
628 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
629 sel_name, class_meth);
631 else
633 ; /* An identifier...if we could not find a protocol. */
636 if (fnd)
637 return fnd;
640 return 0;
643 static tree
644 lookup_protocol_in_reflist (rproto_list, lproto)
645 tree rproto_list;
646 tree lproto;
648 tree rproto, p;
650 /* Make sure the protocol is supported by the object on the rhs. */
651 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
653 tree fnd = 0;
654 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
656 p = TREE_VALUE (rproto);
658 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
660 if (lproto == p)
661 fnd = lproto;
663 else if (PROTOCOL_LIST (p))
664 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
667 if (fnd)
668 return fnd;
671 else
673 ; /* An identifier...if we could not find a protocol. */
676 return 0;
679 /* Return 1 if LHS and RHS are compatible types for assignment
680 or various other operations. Return 0 if they are incompatible,
681 and return -1 if we choose to not decide. When the operation
682 is REFLEXIVE, check for compatibility in either direction. */
685 objc_comptypes (lhs, rhs, reflexive)
686 tree lhs;
687 tree rhs;
688 int reflexive;
690 /* New clause for protocols. */
692 if (TREE_CODE (lhs) == POINTER_TYPE
693 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
694 && TREE_CODE (rhs) == POINTER_TYPE
695 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
697 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
698 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
700 if (lhs_is_proto)
702 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
703 tree rproto, rproto_list;
704 tree p;
706 if (rhs_is_proto)
708 rproto_list = TYPE_PROTOCOL_LIST (rhs);
710 /* Make sure the protocol is supported by the object
711 on the rhs. */
712 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
714 p = TREE_VALUE (lproto);
715 rproto = lookup_protocol_in_reflist (rproto_list, p);
717 if (!rproto)
718 warning ("object does not conform to the `%s' protocol",
719 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
722 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
724 tree rname = TYPE_NAME (TREE_TYPE (rhs));
725 tree rinter;
727 /* Make sure the protocol is supported by the object
728 on the rhs. */
729 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
731 p = TREE_VALUE (lproto);
732 rproto = 0;
733 rinter = lookup_interface (rname);
735 while (rinter && !rproto)
737 tree cat;
739 rproto_list = CLASS_PROTOCOL_LIST (rinter);
740 /* If the underlying ObjC class does not have
741 protocols attached to it, perhaps there are
742 "one-off" protocols attached to the rhs?
743 E.g., 'id<MyProt> foo;'. */
744 if (!rproto_list)
745 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
746 rproto = lookup_protocol_in_reflist (rproto_list, p);
748 /* Check for protocols adopted by categories. */
749 cat = CLASS_CATEGORY_LIST (rinter);
750 while (cat && !rproto)
752 rproto_list = CLASS_PROTOCOL_LIST (cat);
753 rproto = lookup_protocol_in_reflist (rproto_list, p);
755 cat = CLASS_CATEGORY_LIST (cat);
758 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
761 if (!rproto)
762 warning ("class `%s' does not implement the `%s' protocol",
763 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
764 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
768 /* May change...based on whether there was any mismatch */
769 return 1;
771 else if (rhs_is_proto)
772 /* Lhs is not a protocol...warn if it is statically typed */
773 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
775 else
776 /* Defer to comptypes. */
777 return -1;
780 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
781 ; /* Fall thru. This is the case we have been handling all along */
782 else
783 /* Defer to comptypes. */
784 return -1;
786 /* `id' = `<class> *', `<class> *' = `id' */
788 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
789 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
790 return 1;
792 /* `id' = `Class', `Class' = `id' */
794 else if ((TYPE_NAME (lhs) == objc_object_id
795 && TYPE_NAME (rhs) == objc_class_id)
796 || (TYPE_NAME (lhs) == objc_class_id
797 && TYPE_NAME (rhs) == objc_object_id))
798 return 1;
800 /* `<class> *' = `<class> *' */
802 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
804 tree lname = TYPE_NAME (lhs);
805 tree rname = TYPE_NAME (rhs);
806 tree inter;
808 if (lname == rname)
809 return 1;
811 /* If the left hand side is a super class of the right hand side,
812 allow it. */
813 for (inter = lookup_interface (rname); inter;
814 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
815 if (lname == CLASS_SUPER_NAME (inter))
816 return 1;
818 /* Allow the reverse when reflexive. */
819 if (reflexive)
820 for (inter = lookup_interface (lname); inter;
821 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
822 if (rname == CLASS_SUPER_NAME (inter))
823 return 1;
825 return 0;
827 else
828 /* Defer to comptypes. */
829 return -1;
832 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
834 void
835 objc_check_decl (decl)
836 tree decl;
838 tree type = TREE_TYPE (decl);
840 if (TREE_CODE (type) == RECORD_TYPE
841 && TREE_STATIC_TEMPLATE (type)
842 && type != constant_string_type)
843 error_with_decl (decl, "`%s' cannot be statically allocated");
846 void
847 maybe_objc_check_decl (decl)
848 tree decl;
850 objc_check_decl (decl);
853 /* Implement static typing. At this point, we know we have an interface. */
855 tree
856 get_static_reference (interface, protocols)
857 tree interface;
858 tree protocols;
860 tree type = xref_tag (RECORD_TYPE, interface);
862 if (protocols)
864 tree t, m = TYPE_MAIN_VARIANT (type);
866 t = copy_node (type);
867 TYPE_BINFO (t) = make_tree_vec (2);
869 /* Add this type to the chain of variants of TYPE. */
870 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
871 TYPE_NEXT_VARIANT (m) = t;
873 /* Look up protocols and install in lang specific list. Note
874 that the protocol list can have a different lifetime than T! */
875 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
877 /* This forces a new pointer type to be created later
878 (in build_pointer_type)...so that the new template
879 we just created will actually be used...what a hack! */
880 if (TYPE_POINTER_TO (t))
881 TYPE_POINTER_TO (t) = NULL_TREE;
883 type = t;
886 return type;
889 tree
890 get_object_reference (protocols)
891 tree protocols;
893 tree type_decl = lookup_name (objc_id_id);
894 tree type;
896 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
898 type = TREE_TYPE (type_decl);
899 if (TYPE_MAIN_VARIANT (type) != id_type)
900 warning ("unexpected type for `id' (%s)",
901 gen_declaration (type, errbuf));
903 else
905 error ("undefined type `id', please import <objc/objc.h>");
906 return error_mark_node;
909 /* This clause creates a new pointer type that is qualified with
910 the protocol specification...this info is used later to do more
911 elaborate type checking. */
913 if (protocols)
915 tree t, m = TYPE_MAIN_VARIANT (type);
917 t = copy_node (type);
918 TYPE_BINFO (t) = make_tree_vec (2);
920 /* Add this type to the chain of variants of TYPE. */
921 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
922 TYPE_NEXT_VARIANT (m) = t;
924 /* Look up protocols...and install in lang specific list */
925 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
927 /* This forces a new pointer type to be created later
928 (in build_pointer_type)...so that the new template
929 we just created will actually be used...what a hack! */
930 if (TYPE_POINTER_TO (t))
931 TYPE_POINTER_TO (t) = NULL_TREE;
933 type = t;
935 return type;
938 /* Check for circular dependencies in protocols. The arguments are
939 PROTO, the protocol to check, and LIST, a list of protocol it
940 conforms to. */
942 static void
943 check_protocol_recursively (proto, list)
944 tree proto;
945 tree list;
947 tree p;
949 for (p = list; p; p = TREE_CHAIN (p))
951 tree pp = TREE_VALUE (p);
953 if (TREE_CODE (pp) == IDENTIFIER_NODE)
954 pp = lookup_protocol (pp);
956 if (pp == proto)
957 fatal_error ("protocol `%s' has circular dependency",
958 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
959 if (pp)
960 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
964 static tree
965 lookup_and_install_protocols (protocols)
966 tree protocols;
968 tree proto;
969 tree prev = NULL;
970 tree return_value = protocols;
972 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
974 tree ident = TREE_VALUE (proto);
975 tree p = lookup_protocol (ident);
977 if (!p)
979 error ("cannot find protocol declaration for `%s'",
980 IDENTIFIER_POINTER (ident));
981 if (prev)
982 TREE_CHAIN (prev) = TREE_CHAIN (proto);
983 else
984 return_value = TREE_CHAIN (proto);
986 else
988 /* Replace identifier with actual protocol node. */
989 TREE_VALUE (proto) = p;
990 prev = proto;
994 return return_value;
997 /* Create and push a decl for a built-in external variable or field NAME.
998 CODE says which.
999 TYPE is its data type. */
1001 static tree
1002 create_builtin_decl (code, type, name)
1003 enum tree_code code;
1004 tree type;
1005 const char *name;
1007 tree decl = build_decl (code, get_identifier (name), type);
1009 if (code == VAR_DECL)
1011 TREE_STATIC (decl) = 1;
1012 make_decl_rtl (decl, 0);
1013 pushdecl (decl);
1016 DECL_ARTIFICIAL (decl) = 1;
1017 return decl;
1020 /* Find the decl for the constant string class. */
1022 static void
1023 setup_string_decl ()
1025 if (!string_class_decl)
1027 if (!constant_string_global_id)
1028 constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
1029 string_class_decl = lookup_name (constant_string_global_id);
1033 /* Purpose: "play" parser, creating/installing representations
1034 of the declarations that are required by Objective-C.
1036 Model:
1038 type_spec--------->sc_spec
1039 (tree_list) (tree_list)
1042 identifier_node identifier_node */
1044 static void
1045 synth_module_prologue ()
1047 tree temp_type;
1048 tree super_p;
1050 /* Defined in `objc.h' */
1051 objc_object_id = get_identifier (TAG_OBJECT);
1053 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1055 id_type = build_pointer_type (objc_object_reference);
1057 objc_id_id = get_identifier (TYPE_ID);
1058 objc_class_id = get_identifier (TAG_CLASS);
1060 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1061 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1062 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1064 /* Declare type of selector-objects that represent an operation name. */
1066 /* `struct objc_selector *' */
1067 selector_type
1068 = build_pointer_type (xref_tag (RECORD_TYPE,
1069 get_identifier (TAG_SELECTOR)));
1071 /* Forward declare type, or else the prototype for msgSendSuper will
1072 complain. */
1074 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1075 get_identifier (TAG_SUPER)));
1078 /* id objc_msgSend (id, SEL, ...); */
1080 temp_type
1081 = build_function_type (id_type,
1082 tree_cons (NULL_TREE, id_type,
1083 tree_cons (NULL_TREE, selector_type,
1084 NULL_TREE)));
1086 if (! flag_next_runtime)
1088 umsg_decl = build_decl (FUNCTION_DECL,
1089 get_identifier (TAG_MSGSEND), temp_type);
1090 DECL_EXTERNAL (umsg_decl) = 1;
1091 TREE_PUBLIC (umsg_decl) = 1;
1092 DECL_INLINE (umsg_decl) = 1;
1093 DECL_ARTIFICIAL (umsg_decl) = 1;
1095 make_decl_rtl (umsg_decl, NULL);
1096 pushdecl (umsg_decl);
1098 else
1099 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1101 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1103 temp_type
1104 = build_function_type (id_type,
1105 tree_cons (NULL_TREE, super_p,
1106 tree_cons (NULL_TREE, selector_type,
1107 NULL_TREE)));
1109 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1110 temp_type, 0, NOT_BUILT_IN, 0);
1112 /* id objc_getClass (const char *); */
1114 temp_type = build_function_type (id_type,
1115 tree_cons (NULL_TREE,
1116 const_string_type_node,
1117 tree_cons (NULL_TREE, void_type_node,
1118 NULL_TREE)));
1120 objc_get_class_decl
1121 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1123 /* id objc_getMetaClass (const char *); */
1125 objc_get_meta_class_decl
1126 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1128 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1130 if (! flag_next_runtime)
1132 if (flag_typed_selectors)
1134 /* Suppress outputting debug symbols, because
1135 dbxout_init hasn'r been called yet. */
1136 enum debug_info_type save_write_symbols = write_symbols;
1137 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1138 write_symbols = NO_DEBUG;
1139 debug_hooks = &do_nothing_debug_hooks;
1141 build_selector_template ();
1142 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1144 write_symbols = save_write_symbols;
1145 debug_hooks = save_hooks;
1147 else
1148 temp_type = build_array_type (selector_type, NULL_TREE);
1150 layout_type (temp_type);
1151 UOBJC_SELECTOR_TABLE_decl
1152 = create_builtin_decl (VAR_DECL, temp_type,
1153 "_OBJC_SELECTOR_TABLE");
1155 /* Avoid warning when not sending messages. */
1156 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1159 generate_forward_declaration_to_string_table ();
1161 /* Forward declare constant_string_id and constant_string_type. */
1162 if (!constant_string_class_name)
1163 constant_string_class_name = default_constant_string_class_name;
1165 constant_string_id = get_identifier (constant_string_class_name);
1166 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1169 /* Predefine the following data type:
1171 struct STRING_OBJECT_CLASS_NAME
1173 Object isa;
1174 char *cString;
1175 unsigned int length;
1176 }; */
1178 static void
1179 build_string_class_template ()
1181 tree field_decl, field_decl_chain;
1183 field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
1184 field_decl_chain = field_decl;
1186 field_decl = create_builtin_decl (FIELD_DECL,
1187 build_pointer_type (char_type_node),
1188 "cString");
1189 chainon (field_decl_chain, field_decl);
1191 field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
1192 chainon (field_decl_chain, field_decl);
1194 finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
1197 /* Custom build_string which sets TREE_TYPE! */
1199 static tree
1200 my_build_string (len, str)
1201 int len;
1202 const char *str;
1204 return fix_string_type (build_string (len, str));
1207 /* Given a chain of STRING_CST's, build a static instance of
1208 NXConstantString which points at the concatenation of those strings.
1209 We place the string object in the __string_objects section of the
1210 __OBJC segment. The Objective-C runtime will initialize the isa
1211 pointers of the string objects to point at the NXConstantString
1212 class object. */
1214 tree
1215 build_objc_string_object (strings)
1216 tree strings;
1218 tree string, initlist, constructor;
1219 int length;
1221 if (lookup_interface (constant_string_id) == NULL_TREE)
1223 error ("cannot find interface declaration for `%s'",
1224 IDENTIFIER_POINTER (constant_string_id));
1225 return error_mark_node;
1228 add_class_reference (constant_string_id);
1230 if (TREE_CHAIN (strings))
1232 varray_type vstrings;
1233 VARRAY_TREE_INIT (vstrings, 32, "strings");
1235 for (; strings ; strings = TREE_CHAIN (strings))
1236 VARRAY_PUSH_TREE (vstrings, strings);
1238 string = combine_strings (vstrings);
1240 VARRAY_FREE (vstrings);
1242 else
1243 string = strings;
1245 string = fix_string_type (string);
1247 TREE_SET_CODE (string, STRING_CST);
1248 length = TREE_STRING_LENGTH (string) - 1;
1250 /* We could not properly create NXConstantString in synth_module_prologue,
1251 because that's called before debugging is initialized. Do it now. */
1252 if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
1253 build_string_class_template ();
1255 /* & ((NXConstantString) { NULL, string, length }) */
1257 if (flag_next_runtime)
1259 /* For the NeXT runtime, we can generate a literal reference
1260 to the string class, don't need to run a constructor. */
1261 setup_string_decl ();
1262 if (string_class_decl == NULL_TREE)
1264 error ("cannot find reference tag for class `%s'",
1265 IDENTIFIER_POINTER (constant_string_id));
1266 return error_mark_node;
1268 initlist = build_tree_list
1269 (NULL_TREE,
1270 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1272 else
1274 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1277 initlist
1278 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1279 initlist);
1280 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1281 constructor = build_constructor (constant_string_type, nreverse (initlist));
1283 if (!flag_next_runtime)
1285 constructor
1286 = objc_add_static_instance (constructor, constant_string_type);
1289 return (build_unary_op (ADDR_EXPR, constructor, 1));
1292 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1294 static tree
1295 objc_add_static_instance (constructor, class_decl)
1296 tree constructor, class_decl;
1298 static int num_static_inst;
1299 tree *chain, decl;
1300 char buf[256];
1302 /* Find the list of static instances for the CLASS_DECL. Create one if
1303 not found. */
1304 for (chain = &objc_static_instances;
1305 *chain && TREE_VALUE (*chain) != class_decl;
1306 chain = &TREE_CHAIN (*chain));
1307 if (!*chain)
1309 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1310 add_objc_string (TYPE_NAME (class_decl), class_names);
1313 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1314 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1315 DECL_COMMON (decl) = 1;
1316 TREE_STATIC (decl) = 1;
1317 DECL_ARTIFICIAL (decl) = 1;
1318 DECL_INITIAL (decl) = constructor;
1320 /* We may be writing something else just now.
1321 Postpone till end of input. */
1322 DECL_DEFER_OUTPUT (decl) = 1;
1323 pushdecl_top_level (decl);
1324 rest_of_decl_compilation (decl, 0, 1, 0);
1326 /* Add the DECL to the head of this CLASS' list. */
1327 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1329 return decl;
1332 /* Build a static constant CONSTRUCTOR
1333 with type TYPE and elements ELTS. */
1335 static tree
1336 build_constructor (type, elts)
1337 tree type, elts;
1339 tree constructor, f, e;
1341 /* ??? Most of the places that we build constructors, we don't fill in
1342 the type of integers properly. Convert them all en masse. */
1343 if (TREE_CODE (type) == ARRAY_TYPE)
1345 f = TREE_TYPE (type);
1346 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1347 for (e = elts; e ; e = TREE_CHAIN (e))
1348 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1350 else
1352 f = TYPE_FIELDS (type);
1353 for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1354 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1355 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1356 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1359 constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1360 TREE_CONSTANT (constructor) = 1;
1361 TREE_STATIC (constructor) = 1;
1362 TREE_READONLY (constructor) = 1;
1364 return constructor;
1367 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1369 /* Predefine the following data type:
1371 struct _objc_symtab
1373 long sel_ref_cnt;
1374 SEL *refs;
1375 short cls_def_cnt;
1376 short cat_def_cnt;
1377 void *defs[cls_def_cnt + cat_def_cnt];
1378 }; */
1380 static void
1381 build_objc_symtab_template ()
1383 tree field_decl, field_decl_chain, index;
1385 objc_symtab_template
1386 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1388 /* long sel_ref_cnt; */
1390 field_decl = create_builtin_decl (FIELD_DECL,
1391 long_integer_type_node,
1392 "sel_ref_cnt");
1393 field_decl_chain = field_decl;
1395 /* SEL *refs; */
1397 field_decl = create_builtin_decl (FIELD_DECL,
1398 build_pointer_type (selector_type),
1399 "refs");
1400 chainon (field_decl_chain, field_decl);
1402 /* short cls_def_cnt; */
1404 field_decl = create_builtin_decl (FIELD_DECL,
1405 short_integer_type_node,
1406 "cls_def_cnt");
1407 chainon (field_decl_chain, field_decl);
1409 /* short cat_def_cnt; */
1411 field_decl = create_builtin_decl (FIELD_DECL,
1412 short_integer_type_node,
1413 "cat_def_cnt");
1414 chainon (field_decl_chain, field_decl);
1416 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1418 if (!flag_next_runtime)
1419 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1420 else
1421 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1422 imp_count == 0 && cat_count == 0
1423 ? -1 : 0));
1424 field_decl = create_builtin_decl (FIELD_DECL,
1425 build_array_type (ptr_type_node, index),
1426 "defs");
1427 chainon (field_decl_chain, field_decl);
1429 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1432 /* Create the initial value for the `defs' field of _objc_symtab.
1433 This is a CONSTRUCTOR. */
1435 static tree
1436 init_def_list (type)
1437 tree type;
1439 tree expr, initlist = NULL_TREE;
1440 struct imp_entry *impent;
1442 if (imp_count)
1443 for (impent = imp_list; impent; impent = impent->next)
1445 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1447 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1448 initlist = tree_cons (NULL_TREE, expr, initlist);
1452 if (cat_count)
1453 for (impent = imp_list; impent; impent = impent->next)
1455 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1457 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1458 initlist = tree_cons (NULL_TREE, expr, initlist);
1462 if (!flag_next_runtime)
1464 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1465 tree expr;
1467 if (static_instances_decl)
1468 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1469 else
1470 expr = build_int_2 (0, 0);
1472 initlist = tree_cons (NULL_TREE, expr, initlist);
1475 return build_constructor (type, nreverse (initlist));
1478 /* Construct the initial value for all of _objc_symtab. */
1480 static tree
1481 init_objc_symtab (type)
1482 tree type;
1484 tree initlist;
1486 /* sel_ref_cnt = { ..., 5, ... } */
1488 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1490 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1492 if (flag_next_runtime || ! sel_ref_chain)
1493 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1494 else
1495 initlist = tree_cons (NULL_TREE,
1496 build_unary_op (ADDR_EXPR,
1497 UOBJC_SELECTOR_TABLE_decl, 1),
1498 initlist);
1500 /* cls_def_cnt = { ..., 5, ... } */
1502 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1504 /* cat_def_cnt = { ..., 5, ... } */
1506 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1508 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1510 if (imp_count || cat_count || static_instances_decl)
1513 tree field = TYPE_FIELDS (type);
1514 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1516 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1517 initlist);
1520 return build_constructor (type, nreverse (initlist));
1523 /* Push forward-declarations of all the categories so that
1524 init_def_list can use them in a CONSTRUCTOR. */
1526 static void
1527 forward_declare_categories ()
1529 struct imp_entry *impent;
1530 tree sav = objc_implementation_context;
1532 for (impent = imp_list; impent; impent = impent->next)
1534 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1536 /* Set an invisible arg to synth_id_with_class_suffix. */
1537 objc_implementation_context = impent->imp_context;
1538 impent->class_decl
1539 = create_builtin_decl (VAR_DECL, objc_category_template,
1540 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
1543 objc_implementation_context = sav;
1546 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1547 and initialized appropriately. */
1549 static void
1550 generate_objc_symtab_decl ()
1552 tree sc_spec;
1554 if (!objc_category_template)
1555 build_category_template ();
1557 /* forward declare categories */
1558 if (cat_count)
1559 forward_declare_categories ();
1561 if (!objc_symtab_template)
1562 build_objc_symtab_template ();
1564 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1566 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1567 tree_cons (NULL_TREE,
1568 objc_symtab_template, sc_spec),
1570 NULL_TREE);
1572 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1573 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1574 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1575 finish_decl (UOBJC_SYMBOLS_decl,
1576 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1577 NULL_TREE);
1580 static tree
1581 init_module_descriptor (type)
1582 tree type;
1584 tree initlist, expr;
1586 /* version = { 1, ... } */
1588 expr = build_int_2 (OBJC_VERSION, 0);
1589 initlist = build_tree_list (NULL_TREE, expr);
1591 /* size = { ..., sizeof (struct objc_module), ... } */
1593 expr = size_in_bytes (objc_module_template);
1594 initlist = tree_cons (NULL_TREE, expr, initlist);
1596 /* name = { ..., "foo.m", ... } */
1598 expr = add_objc_string (get_identifier (input_filename), class_names);
1599 initlist = tree_cons (NULL_TREE, expr, initlist);
1601 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1603 if (UOBJC_SYMBOLS_decl)
1604 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1605 else
1606 expr = build_int_2 (0, 0);
1607 initlist = tree_cons (NULL_TREE, expr, initlist);
1609 return build_constructor (type, nreverse (initlist));
1612 /* Write out the data structures to describe Objective C classes defined.
1613 If appropriate, compile and output a setup function to initialize them.
1614 Return a symbol_ref to the function to call to initialize the Objective C
1615 data structures for this file (and perhaps for other files also).
1617 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1619 static rtx
1620 build_module_descriptor ()
1622 tree decl_specs, field_decl, field_decl_chain;
1624 objc_module_template
1625 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1627 /* Long version; */
1629 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1630 field_decl = get_identifier ("version");
1631 field_decl
1632 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1633 field_decl_chain = field_decl;
1635 /* long size; */
1637 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1638 field_decl = get_identifier ("size");
1639 field_decl
1640 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1641 chainon (field_decl_chain, field_decl);
1643 /* char *name; */
1645 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1646 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1647 field_decl
1648 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1649 chainon (field_decl_chain, field_decl);
1651 /* struct objc_symtab *symtab; */
1653 decl_specs = get_identifier (UTAG_SYMTAB);
1654 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1655 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1656 field_decl
1657 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1658 chainon (field_decl_chain, field_decl);
1660 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1662 /* Create an instance of "objc_module". */
1664 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1665 build_tree_list (NULL_TREE,
1666 ridpointers[(int) RID_STATIC]));
1668 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1669 decl_specs, 1, NULL_TREE);
1671 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1672 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1673 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1675 finish_decl (UOBJC_MODULES_decl,
1676 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1677 NULL_TREE);
1679 /* Mark the decl to avoid "defined but not used" warning. */
1680 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1682 /* Generate a constructor call for the module descriptor.
1683 This code was generated by reading the grammar rules
1684 of c-parse.in; Therefore, it may not be the most efficient
1685 way of generating the requisite code. */
1687 if (flag_next_runtime)
1688 return NULL_RTX;
1691 tree parms, execclass_decl, decelerator, void_list_node_1;
1692 tree init_function_name, init_function_decl;
1694 /* Declare void __objc_execClass (void *); */
1696 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1697 execclass_decl = build_decl (FUNCTION_DECL,
1698 get_identifier (TAG_EXECCLASS),
1699 build_function_type (void_type_node,
1700 tree_cons (NULL_TREE, ptr_type_node,
1701 void_list_node_1)));
1702 DECL_EXTERNAL (execclass_decl) = 1;
1703 DECL_ARTIFICIAL (execclass_decl) = 1;
1704 TREE_PUBLIC (execclass_decl) = 1;
1705 pushdecl (execclass_decl);
1706 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1707 assemble_external (execclass_decl);
1709 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1711 init_function_name = get_file_function_name ('I');
1712 start_function (void_list_node_1,
1713 build_nt (CALL_EXPR, init_function_name,
1714 tree_cons (NULL_TREE, NULL_TREE,
1715 void_list_node_1),
1716 NULL_TREE),
1717 NULL_TREE);
1718 store_parm_decls ();
1720 init_function_decl = current_function_decl;
1721 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1722 TREE_USED (init_function_decl) = 1;
1723 /* Don't let this one be deferred. */
1724 DECL_INLINE (init_function_decl) = 0;
1725 DECL_UNINLINABLE (init_function_decl) = 1;
1726 current_function_cannot_inline
1727 = "static constructors and destructors cannot be inlined";
1729 parms
1730 = build_tree_list (NULL_TREE,
1731 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1732 decelerator = build_function_call (execclass_decl, parms);
1734 c_expand_expr_stmt (decelerator);
1736 finish_function (0, 0);
1738 return XEXP (DECL_RTL (init_function_decl), 0);
1742 /* extern const char _OBJC_STRINGS[]; */
1744 static void
1745 generate_forward_declaration_to_string_table ()
1747 tree sc_spec, decl_specs, expr_decl;
1749 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1750 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1752 expr_decl
1753 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1755 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1758 /* Return the DECL of the string IDENT in the SECTION. */
1760 static tree
1761 get_objc_string_decl (ident, section)
1762 tree ident;
1763 enum string_section section;
1765 tree chain;
1767 if (section == class_names)
1768 chain = class_names_chain;
1769 else if (section == meth_var_names)
1770 chain = meth_var_names_chain;
1771 else if (section == meth_var_types)
1772 chain = meth_var_types_chain;
1773 else
1774 abort ();
1776 for (; chain != 0; chain = TREE_VALUE (chain))
1777 if (TREE_VALUE (chain) == ident)
1778 return (TREE_PURPOSE (chain));
1780 abort ();
1781 return NULL_TREE;
1784 /* Output references to all statically allocated objects. Return the DECL
1785 for the array built. */
1787 static void
1788 generate_static_references ()
1790 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1791 tree class_name, class, decl, initlist;
1792 tree cl_chain, in_chain, type;
1793 int num_inst, num_class;
1794 char buf[256];
1796 if (flag_next_runtime)
1797 abort ();
1799 for (cl_chain = objc_static_instances, num_class = 0;
1800 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1802 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1803 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1805 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1806 ident = get_identifier (buf);
1808 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1809 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1810 build_tree_list (NULL_TREE,
1811 ridpointers[(int) RID_STATIC]));
1812 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1813 DECL_CONTEXT (decl) = 0;
1814 DECL_ARTIFICIAL (decl) = 1;
1816 /* Output {class_name, ...}. */
1817 class = TREE_VALUE (cl_chain);
1818 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1819 initlist = build_tree_list (NULL_TREE,
1820 build_unary_op (ADDR_EXPR, class_name, 1));
1822 /* Output {..., instance, ...}. */
1823 for (in_chain = TREE_PURPOSE (cl_chain);
1824 in_chain; in_chain = TREE_CHAIN (in_chain))
1826 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1827 initlist = tree_cons (NULL_TREE, expr, initlist);
1830 /* Output {..., NULL}. */
1831 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1833 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1834 finish_decl (decl, expr, NULL_TREE);
1835 TREE_USED (decl) = 1;
1837 type = build_array_type (build_pointer_type (void_type_node), 0);
1838 decl = build_decl (VAR_DECL, ident, type);
1839 TREE_USED (decl) = 1;
1840 TREE_STATIC (decl) = 1;
1841 decls
1842 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1845 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1846 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1847 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1848 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1849 build_tree_list (NULL_TREE,
1850 ridpointers[(int) RID_STATIC]));
1851 static_instances_decl
1852 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1853 TREE_USED (static_instances_decl) = 1;
1854 DECL_CONTEXT (static_instances_decl) = 0;
1855 DECL_ARTIFICIAL (static_instances_decl) = 1;
1856 expr = build_constructor (TREE_TYPE (static_instances_decl),
1857 nreverse (decls));
1858 finish_decl (static_instances_decl, expr, NULL_TREE);
1861 /* Output all strings. */
1863 static void
1864 generate_strings ()
1866 tree sc_spec, decl_specs, expr_decl;
1867 tree chain, string_expr;
1868 tree string, decl;
1870 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1872 string = TREE_VALUE (chain);
1873 decl = TREE_PURPOSE (chain);
1874 sc_spec
1875 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1876 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1877 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1878 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1879 DECL_CONTEXT (decl) = NULL_TREE;
1880 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1881 IDENTIFIER_POINTER (string));
1882 finish_decl (decl, string_expr, NULL_TREE);
1885 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1887 string = TREE_VALUE (chain);
1888 decl = TREE_PURPOSE (chain);
1889 sc_spec
1890 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1891 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1892 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1893 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1894 DECL_CONTEXT (decl) = NULL_TREE;
1895 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1896 IDENTIFIER_POINTER (string));
1897 finish_decl (decl, string_expr, NULL_TREE);
1900 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1902 string = TREE_VALUE (chain);
1903 decl = TREE_PURPOSE (chain);
1904 sc_spec
1905 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1906 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1907 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1908 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
1909 DECL_CONTEXT (decl) = NULL_TREE;
1910 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1911 IDENTIFIER_POINTER (string));
1912 finish_decl (decl, string_expr, NULL_TREE);
1916 static tree
1917 build_selector_reference_decl ()
1919 tree decl, ident;
1920 char buf[256];
1921 static int idx = 0;
1923 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1925 ident = get_identifier (buf);
1927 decl = build_decl (VAR_DECL, ident, selector_type);
1928 DECL_EXTERNAL (decl) = 1;
1929 TREE_PUBLIC (decl) = 1;
1930 TREE_USED (decl) = 1;
1931 TREE_READONLY (decl) = 1;
1932 DECL_ARTIFICIAL (decl) = 1;
1933 DECL_CONTEXT (decl) = 0;
1935 make_decl_rtl (decl, 0);
1936 pushdecl_top_level (decl);
1938 return decl;
1941 /* Just a handy wrapper for add_objc_string. */
1943 static tree
1944 build_selector (ident)
1945 tree ident;
1947 tree expr = add_objc_string (ident, meth_var_names);
1948 if (flag_typed_selectors)
1949 return expr;
1950 else
1951 return build_c_cast (selector_type, expr); /* cast! */
1954 static void
1955 build_selector_translation_table ()
1957 tree sc_spec, decl_specs;
1958 tree chain, initlist = NULL_TREE;
1959 int offset = 0;
1960 tree decl = NULL_TREE, var_decl, name;
1962 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1964 tree expr;
1966 expr = build_selector (TREE_VALUE (chain));
1968 if (flag_next_runtime)
1970 name = DECL_NAME (TREE_PURPOSE (chain));
1972 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1974 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1975 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
1977 var_decl = name;
1979 /* The `decl' that is returned from start_decl is the one that we
1980 forward declared in `build_selector_reference' */
1981 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
1984 /* add one for the '\0' character */
1985 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
1987 if (flag_next_runtime)
1988 finish_decl (decl, expr, NULL_TREE);
1989 else
1991 if (flag_typed_selectors)
1993 tree eltlist = NULL_TREE;
1994 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
1995 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
1996 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
1997 expr = build_constructor (objc_selector_template,
1998 nreverse (eltlist));
2000 initlist = tree_cons (NULL_TREE, expr, initlist);
2005 if (! flag_next_runtime)
2007 /* Cause the variable and its initial value to be actually output. */
2008 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2009 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2010 /* NULL terminate the list and fix the decl for output. */
2011 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2012 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2013 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2014 nreverse (initlist));
2015 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2016 current_function_decl = NULL_TREE;
2020 static tree
2021 get_proto_encoding (proto)
2022 tree proto;
2024 tree encoding;
2025 if (proto)
2027 tree tmp_decl;
2029 if (! METHOD_ENCODING (proto))
2031 tmp_decl = build_tmp_function_decl ();
2032 hack_method_prototype (proto, tmp_decl);
2033 encoding = encode_method_prototype (proto, tmp_decl);
2034 METHOD_ENCODING (proto) = encoding;
2036 else
2037 encoding = METHOD_ENCODING (proto);
2039 return add_objc_string (encoding, meth_var_types);
2041 else
2042 return build_int_2 (0, 0);
2045 /* sel_ref_chain is a list whose "value" fields will be instances of
2046 identifier_node that represent the selector. */
2048 static tree
2049 build_typed_selector_reference (ident, proto)
2050 tree ident, proto;
2052 tree *chain = &sel_ref_chain;
2053 tree expr;
2054 int index = 0;
2056 while (*chain)
2058 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2059 goto return_at_index;
2061 index++;
2062 chain = &TREE_CHAIN (*chain);
2065 *chain = tree_cons (proto, ident, NULL_TREE);
2067 return_at_index:
2068 expr = build_unary_op (ADDR_EXPR,
2069 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2070 build_int_2 (index, 0)),
2072 return build_c_cast (selector_type, expr);
2075 static tree
2076 build_selector_reference (ident)
2077 tree ident;
2079 tree *chain = &sel_ref_chain;
2080 tree expr;
2081 int index = 0;
2083 while (*chain)
2085 if (TREE_VALUE (*chain) == ident)
2086 return (flag_next_runtime
2087 ? TREE_PURPOSE (*chain)
2088 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2089 build_int_2 (index, 0)));
2091 index++;
2092 chain = &TREE_CHAIN (*chain);
2095 expr = build_selector_reference_decl ();
2097 *chain = tree_cons (expr, ident, NULL_TREE);
2099 return (flag_next_runtime
2100 ? expr
2101 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2102 build_int_2 (index, 0)));
2105 static tree
2106 build_class_reference_decl ()
2108 tree decl, ident;
2109 char buf[256];
2110 static int idx = 0;
2112 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2114 ident = get_identifier (buf);
2116 decl = build_decl (VAR_DECL, ident, objc_class_type);
2117 DECL_EXTERNAL (decl) = 1;
2118 TREE_PUBLIC (decl) = 1;
2119 TREE_USED (decl) = 1;
2120 TREE_READONLY (decl) = 1;
2121 DECL_CONTEXT (decl) = 0;
2122 DECL_ARTIFICIAL (decl) = 1;
2124 make_decl_rtl (decl, 0);
2125 pushdecl_top_level (decl);
2127 return decl;
2130 /* Create a class reference, but don't create a variable to reference
2131 it. */
2133 static void
2134 add_class_reference (ident)
2135 tree ident;
2137 tree chain;
2139 if ((chain = cls_ref_chain))
2141 tree tail;
2144 if (ident == TREE_VALUE (chain))
2145 return;
2147 tail = chain;
2148 chain = TREE_CHAIN (chain);
2150 while (chain);
2152 /* Append to the end of the list */
2153 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2155 else
2156 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2159 /* Get a class reference, creating it if necessary. Also create the
2160 reference variable. */
2162 tree
2163 get_class_reference (ident)
2164 tree ident;
2166 if (flag_next_runtime)
2168 tree *chain;
2169 tree decl;
2171 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2172 if (TREE_VALUE (*chain) == ident)
2174 if (! TREE_PURPOSE (*chain))
2175 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2177 return TREE_PURPOSE (*chain);
2180 decl = build_class_reference_decl ();
2181 *chain = tree_cons (decl, ident, NULL_TREE);
2182 return decl;
2184 else
2186 tree params;
2188 add_class_reference (ident);
2190 params = build_tree_list (NULL_TREE,
2191 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2192 IDENTIFIER_POINTER (ident)));
2194 assemble_external (objc_get_class_decl);
2195 return build_function_call (objc_get_class_decl, params);
2199 /* For each string section we have a chain which maps identifier nodes
2200 to decls for the strings. */
2202 static tree
2203 add_objc_string (ident, section)
2204 tree ident;
2205 enum string_section section;
2207 tree *chain, decl;
2209 if (section == class_names)
2210 chain = &class_names_chain;
2211 else if (section == meth_var_names)
2212 chain = &meth_var_names_chain;
2213 else if (section == meth_var_types)
2214 chain = &meth_var_types_chain;
2215 else
2216 abort ();
2218 while (*chain)
2220 if (TREE_VALUE (*chain) == ident)
2221 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2223 chain = &TREE_CHAIN (*chain);
2226 decl = build_objc_string_decl (section);
2228 *chain = tree_cons (decl, ident, NULL_TREE);
2230 return build_unary_op (ADDR_EXPR, decl, 1);
2233 static tree
2234 build_objc_string_decl (section)
2235 enum string_section section;
2237 tree decl, ident;
2238 char buf[256];
2239 static int class_names_idx = 0;
2240 static int meth_var_names_idx = 0;
2241 static int meth_var_types_idx = 0;
2243 if (section == class_names)
2244 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2245 else if (section == meth_var_names)
2246 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2247 else if (section == meth_var_types)
2248 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2250 ident = get_identifier (buf);
2252 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2253 DECL_EXTERNAL (decl) = 1;
2254 TREE_PUBLIC (decl) = 1;
2255 TREE_USED (decl) = 1;
2256 TREE_READONLY (decl) = 1;
2257 TREE_CONSTANT (decl) = 1;
2258 DECL_CONTEXT (decl) = 0;
2259 DECL_ARTIFICIAL (decl) = 1;
2261 make_decl_rtl (decl, 0);
2262 pushdecl_top_level (decl);
2264 return decl;
2268 void
2269 objc_declare_alias (alias_ident, class_ident)
2270 tree alias_ident;
2271 tree class_ident;
2273 if (is_class_name (class_ident) != class_ident)
2274 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2275 else if (is_class_name (alias_ident))
2276 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2277 else
2278 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2281 void
2282 objc_declare_class (ident_list)
2283 tree ident_list;
2285 tree list;
2287 for (list = ident_list; list; list = TREE_CHAIN (list))
2289 tree ident = TREE_VALUE (list);
2290 tree decl;
2292 if ((decl = lookup_name (ident)))
2294 error ("`%s' redeclared as different kind of symbol",
2295 IDENTIFIER_POINTER (ident));
2296 error_with_decl (decl, "previous declaration of `%s'");
2299 if (! is_class_name (ident))
2301 tree record = xref_tag (RECORD_TYPE, ident);
2302 TREE_STATIC_TEMPLATE (record) = 1;
2303 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2308 tree
2309 is_class_name (ident)
2310 tree ident;
2312 tree chain;
2314 if (lookup_interface (ident))
2315 return ident;
2317 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2319 if (ident == TREE_VALUE (chain))
2320 return ident;
2323 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2325 if (ident == TREE_VALUE (chain))
2326 return TREE_PURPOSE (chain);
2329 return 0;
2332 tree
2333 lookup_interface (ident)
2334 tree ident;
2336 tree chain;
2338 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2340 if (ident == CLASS_NAME (chain))
2341 return chain;
2343 return NULL_TREE;
2346 static tree
2347 objc_copy_list (list, head)
2348 tree list;
2349 tree *head;
2351 tree newlist = NULL_TREE, tail = NULL_TREE;
2353 while (list)
2355 tail = copy_node (list);
2357 /* The following statement fixes a bug when inheriting instance
2358 variables that are declared to be bitfields. finish_struct
2359 expects to find the width of the bitfield in DECL_INITIAL. */
2360 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2361 DECL_INITIAL (tail) = DECL_SIZE (tail);
2363 newlist = chainon (newlist, tail);
2364 list = TREE_CHAIN (list);
2367 *head = newlist;
2368 return tail;
2371 /* Used by: build_private_template, get_class_ivars, and
2372 continue_class. COPY is 1 when called from @defs. In this case
2373 copy all fields. Otherwise don't copy leaf ivars since we rely on
2374 them being side-effected exactly once by finish_struct. */
2376 static tree
2377 build_ivar_chain (interface, copy)
2378 tree interface;
2379 int copy;
2381 tree my_name, super_name, ivar_chain;
2383 my_name = CLASS_NAME (interface);
2384 super_name = CLASS_SUPER_NAME (interface);
2386 /* Possibly copy leaf ivars. */
2387 if (copy)
2388 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2389 else
2390 ivar_chain = CLASS_IVARS (interface);
2392 while (super_name)
2394 tree op1;
2395 tree super_interface = lookup_interface (super_name);
2397 if (!super_interface)
2399 /* fatal did not work with 2 args...should fix */
2400 error ("cannot find interface declaration for `%s', superclass of `%s'",
2401 IDENTIFIER_POINTER (super_name),
2402 IDENTIFIER_POINTER (my_name));
2403 exit (FATAL_EXIT_CODE);
2406 if (super_interface == interface)
2407 fatal_error ("circular inheritance in interface declaration for `%s'",
2408 IDENTIFIER_POINTER (super_name));
2410 interface = super_interface;
2411 my_name = CLASS_NAME (interface);
2412 super_name = CLASS_SUPER_NAME (interface);
2414 op1 = CLASS_IVARS (interface);
2415 if (op1)
2417 tree head, tail = objc_copy_list (op1, &head);
2419 /* Prepend super class ivars...make a copy of the list, we
2420 do not want to alter the original. */
2421 TREE_CHAIN (tail) = ivar_chain;
2422 ivar_chain = head;
2425 return ivar_chain;
2428 /* struct <classname> {
2429 struct objc_class *isa;
2431 }; */
2433 static tree
2434 build_private_template (class)
2435 tree class;
2437 tree ivar_context;
2439 if (CLASS_STATIC_TEMPLATE (class))
2441 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2442 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2444 else
2446 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2448 ivar_context = build_ivar_chain (class, 0);
2450 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2452 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2454 /* mark this record as class template - for class type checking */
2455 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2458 instance_type
2459 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2460 uprivate_record),
2461 build1 (INDIRECT_REF, NULL_TREE,
2462 NULL_TREE)));
2464 return ivar_context;
2467 /* Begin code generation for protocols... */
2469 /* struct objc_protocol {
2470 char *protocol_name;
2471 struct objc_protocol **protocol_list;
2472 struct objc_method_desc *instance_methods;
2473 struct objc_method_desc *class_methods;
2474 }; */
2476 static tree
2477 build_protocol_template ()
2479 tree decl_specs, field_decl, field_decl_chain;
2480 tree template;
2482 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2484 /* struct objc_class *isa; */
2486 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2487 get_identifier (UTAG_CLASS)));
2488 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2489 field_decl
2490 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2491 field_decl_chain = field_decl;
2493 /* char *protocol_name; */
2495 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2496 field_decl
2497 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2498 field_decl
2499 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2500 chainon (field_decl_chain, field_decl);
2502 /* struct objc_protocol **protocol_list; */
2504 decl_specs = build_tree_list (NULL_TREE, template);
2505 field_decl
2506 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2507 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2508 field_decl
2509 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2510 chainon (field_decl_chain, field_decl);
2512 /* struct objc_method_list *instance_methods; */
2514 decl_specs
2515 = build_tree_list (NULL_TREE,
2516 xref_tag (RECORD_TYPE,
2517 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2518 field_decl
2519 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2520 field_decl
2521 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2522 chainon (field_decl_chain, field_decl);
2524 /* struct objc_method_list *class_methods; */
2526 decl_specs
2527 = build_tree_list (NULL_TREE,
2528 xref_tag (RECORD_TYPE,
2529 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2530 field_decl
2531 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2532 field_decl
2533 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2534 chainon (field_decl_chain, field_decl);
2536 return finish_struct (template, field_decl_chain, NULL_TREE);
2539 static tree
2540 build_descriptor_table_initializer (type, entries)
2541 tree type;
2542 tree entries;
2544 tree initlist = NULL_TREE;
2548 tree eltlist = NULL_TREE;
2550 eltlist
2551 = tree_cons (NULL_TREE,
2552 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2553 eltlist
2554 = tree_cons (NULL_TREE,
2555 add_objc_string (METHOD_ENCODING (entries),
2556 meth_var_types),
2557 eltlist);
2559 initlist
2560 = tree_cons (NULL_TREE,
2561 build_constructor (type, nreverse (eltlist)), initlist);
2563 entries = TREE_CHAIN (entries);
2565 while (entries);
2567 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2570 /* struct objc_method_prototype_list {
2571 int count;
2572 struct objc_method_prototype {
2573 SEL name;
2574 char *types;
2575 } list[1];
2576 }; */
2578 static tree
2579 build_method_prototype_list_template (list_type, size)
2580 tree list_type;
2581 int size;
2583 tree objc_ivar_list_record;
2584 tree decl_specs, field_decl, field_decl_chain;
2586 /* Generate an unnamed struct definition. */
2588 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2590 /* int method_count; */
2592 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2593 field_decl = get_identifier ("method_count");
2595 field_decl
2596 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2597 field_decl_chain = field_decl;
2599 /* struct objc_method method_list[]; */
2601 decl_specs = build_tree_list (NULL_TREE, list_type);
2602 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2603 build_int_2 (size, 0));
2605 field_decl
2606 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2607 chainon (field_decl_chain, field_decl);
2609 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2611 return objc_ivar_list_record;
2614 static tree
2615 build_method_prototype_template ()
2617 tree proto_record;
2618 tree decl_specs, field_decl, field_decl_chain;
2620 proto_record
2621 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2623 /* struct objc_selector *_cmd; */
2624 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2625 get_identifier (TAG_SELECTOR)), NULL_TREE);
2626 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2628 field_decl
2629 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2630 field_decl_chain = field_decl;
2632 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2633 field_decl
2634 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2635 field_decl
2636 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2637 chainon (field_decl_chain, field_decl);
2639 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2641 return proto_record;
2644 /* True if last call to forwarding_offset yielded a register offset. */
2645 static int offset_is_register;
2647 static int
2648 forwarding_offset (parm)
2649 tree parm;
2651 int offset_in_bytes;
2653 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2655 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2657 /* ??? Here we assume that the parm address is indexed
2658 off the frame pointer or arg pointer.
2659 If that is not true, we produce meaningless results,
2660 but do not crash. */
2661 if (GET_CODE (addr) == PLUS
2662 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2663 offset_in_bytes = INTVAL (XEXP (addr, 1));
2664 else
2665 offset_in_bytes = 0;
2667 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2668 offset_is_register = 0;
2670 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2672 int regno = REGNO (DECL_INCOMING_RTL (parm));
2673 offset_in_bytes = apply_args_register_offset (regno);
2674 offset_is_register = 1;
2676 else
2677 return 0;
2679 /* This is the case where the parm is passed as an int or double
2680 and it is converted to a char, short or float and stored back
2681 in the parmlist. In this case, describe the parm
2682 with the variable's declared type, and adjust the address
2683 if the least significant bytes (which we are using) are not
2684 the first ones. */
2685 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2686 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2687 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2689 return offset_in_bytes;
2692 static tree
2693 encode_method_prototype (method_decl, func_decl)
2694 tree method_decl;
2695 tree func_decl;
2697 tree parms;
2698 int stack_size, i;
2699 tree user_args;
2700 HOST_WIDE_INT max_parm_end = 0;
2701 char buf[40];
2702 tree result;
2704 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2705 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2707 /* C type. */
2708 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2709 obstack_object_size (&util_obstack),
2710 OBJC_ENCODE_INLINE_DEFS);
2712 /* Stack size. */
2713 for (parms = DECL_ARGUMENTS (func_decl); parms;
2714 parms = TREE_CHAIN (parms))
2716 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2717 + int_size_in_bytes (TREE_TYPE (parms)));
2719 if (!offset_is_register && max_parm_end < parm_end)
2720 max_parm_end = parm_end;
2723 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2725 sprintf (buf, "%d", stack_size);
2726 obstack_grow (&util_obstack, buf, strlen (buf));
2728 user_args = METHOD_SEL_ARGS (method_decl);
2730 /* Argument types. */
2731 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2732 parms = TREE_CHAIN (parms), i++)
2734 /* Process argument qualifiers for user supplied arguments. */
2735 if (i > 1)
2737 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2738 user_args = TREE_CHAIN (user_args);
2741 /* Type. */
2742 encode_type (TREE_TYPE (parms),
2743 obstack_object_size (&util_obstack),
2744 OBJC_ENCODE_INLINE_DEFS);
2746 /* Compute offset. */
2747 sprintf (buf, "%d", forwarding_offset (parms));
2749 /* Indicate register. */
2750 if (offset_is_register)
2751 obstack_1grow (&util_obstack, '+');
2753 obstack_grow (&util_obstack, buf, strlen (buf));
2756 obstack_1grow (&util_obstack, '\0');
2757 result = get_identifier (obstack_finish (&util_obstack));
2758 obstack_free (&util_obstack, util_firstobj);
2759 return result;
2762 static tree
2763 generate_descriptor_table (type, name, size, list, proto)
2764 tree type;
2765 const char *name;
2766 int size;
2767 tree list;
2768 tree proto;
2770 tree sc_spec, decl_specs, decl, initlist;
2772 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2773 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2775 decl = start_decl (synth_id_with_class_suffix (name, proto),
2776 decl_specs, 1, NULL_TREE);
2777 DECL_CONTEXT (decl) = NULL_TREE;
2779 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2780 initlist = tree_cons (NULL_TREE, list, initlist);
2782 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2783 NULL_TREE);
2785 return decl;
2788 static void
2789 generate_method_descriptors (protocol)
2790 tree protocol;
2792 tree initlist, chain, method_list_template;
2793 tree cast, variable_length_type;
2794 int size;
2796 if (!objc_method_prototype_template)
2797 objc_method_prototype_template = build_method_prototype_template ();
2799 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2800 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2801 NULL_TREE);
2802 variable_length_type = groktypename (cast);
2804 chain = PROTOCOL_CLS_METHODS (protocol);
2805 if (chain)
2807 size = list_length (chain);
2809 method_list_template
2810 = build_method_prototype_list_template (objc_method_prototype_template,
2811 size);
2813 initlist
2814 = build_descriptor_table_initializer (objc_method_prototype_template,
2815 chain);
2817 UOBJC_CLASS_METHODS_decl
2818 = generate_descriptor_table (method_list_template,
2819 "_OBJC_PROTOCOL_CLASS_METHODS",
2820 size, initlist, protocol);
2821 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2823 else
2824 UOBJC_CLASS_METHODS_decl = 0;
2826 chain = PROTOCOL_NST_METHODS (protocol);
2827 if (chain)
2829 size = list_length (chain);
2831 method_list_template
2832 = build_method_prototype_list_template (objc_method_prototype_template,
2833 size);
2834 initlist
2835 = build_descriptor_table_initializer (objc_method_prototype_template,
2836 chain);
2838 UOBJC_INSTANCE_METHODS_decl
2839 = generate_descriptor_table (method_list_template,
2840 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2841 size, initlist, protocol);
2842 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2844 else
2845 UOBJC_INSTANCE_METHODS_decl = 0;
2848 /* Generate a temporary FUNCTION_DECL node to be used in
2849 hack_method_prototype below. */
2851 static tree
2852 build_tmp_function_decl ()
2854 tree decl_specs, expr_decl, parms;
2855 static int xxx = 0;
2856 char buffer[80];
2858 /* struct objc_object *objc_xxx (id, SEL, ...); */
2859 pushlevel (0);
2860 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2861 push_parm_decl (build_tree_list
2862 (build_tree_list (decl_specs,
2863 build1 (INDIRECT_REF, NULL_TREE,
2864 NULL_TREE)),
2865 NULL_TREE));
2867 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2868 get_identifier (TAG_SELECTOR)));
2869 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2871 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2872 NULL_TREE));
2873 parms = get_parm_info (0);
2874 poplevel (0, 0, 0);
2876 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2877 sprintf (buffer, "__objc_tmp_%x", xxx++);
2878 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2879 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
2881 return define_decl (expr_decl, decl_specs);
2884 /* Generate the prototypes for protocol methods. This is used to
2885 generate method encodings for these.
2887 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2888 a decl node to be used. This is also where the return value is
2889 given. */
2891 static void
2892 hack_method_prototype (nst_methods, tmp_decl)
2893 tree nst_methods;
2894 tree tmp_decl;
2896 tree parms;
2897 tree parm;
2899 /* Hack to avoid problem with static typing of self arg. */
2900 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
2901 start_method_def (nst_methods);
2902 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
2904 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
2905 parms = get_parm_info (0); /* we have a `, ...' */
2906 else
2907 parms = get_parm_info (1); /* place a `void_at_end' */
2909 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2911 /* Usually called from store_parm_decls -> init_function_start. */
2913 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
2915 if (current_function_decl)
2916 abort ();
2917 current_function_decl = tmp_decl;
2920 /* Code taken from start_function. */
2921 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
2922 /* Promote the value to int before returning it. */
2923 if (TREE_CODE (restype) == INTEGER_TYPE
2924 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
2925 restype = integer_type_node;
2926 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
2929 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
2930 DECL_CONTEXT (parm) = tmp_decl;
2932 init_function_start (tmp_decl, "objc-act", 0);
2934 /* Typically called from expand_function_start for function definitions. */
2935 assign_parms (tmp_decl);
2937 /* install return type */
2938 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
2940 current_function_decl = NULL;
2943 static void
2944 generate_protocol_references (plist)
2945 tree plist;
2947 tree lproto;
2949 /* Forward declare protocols referenced. */
2950 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2952 tree proto = TREE_VALUE (lproto);
2954 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
2955 && PROTOCOL_NAME (proto))
2957 if (! PROTOCOL_FORWARD_DECL (proto))
2958 build_protocol_reference (proto);
2960 if (PROTOCOL_LIST (proto))
2961 generate_protocol_references (PROTOCOL_LIST (proto));
2966 static void
2967 generate_protocols ()
2969 tree p, tmp_decl, encoding;
2970 tree sc_spec, decl_specs, decl;
2971 tree initlist, protocol_name_expr, refs_decl, refs_expr;
2972 tree cast_type2;
2974 tmp_decl = build_tmp_function_decl ();
2976 if (! objc_protocol_template)
2977 objc_protocol_template = build_protocol_template ();
2979 /* If a protocol was directly referenced, pull in indirect references. */
2980 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2981 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2982 generate_protocol_references (PROTOCOL_LIST (p));
2984 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2986 tree nst_methods = PROTOCOL_NST_METHODS (p);
2987 tree cls_methods = PROTOCOL_CLS_METHODS (p);
2989 /* If protocol wasn't referenced, don't generate any code. */
2990 if (! PROTOCOL_FORWARD_DECL (p))
2991 continue;
2993 /* Make sure we link in the Protocol class. */
2994 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2996 while (nst_methods)
2998 if (! METHOD_ENCODING (nst_methods))
3000 hack_method_prototype (nst_methods, tmp_decl);
3001 encoding = encode_method_prototype (nst_methods, tmp_decl);
3002 METHOD_ENCODING (nst_methods) = encoding;
3004 nst_methods = TREE_CHAIN (nst_methods);
3007 while (cls_methods)
3009 if (! METHOD_ENCODING (cls_methods))
3011 hack_method_prototype (cls_methods, tmp_decl);
3012 encoding = encode_method_prototype (cls_methods, tmp_decl);
3013 METHOD_ENCODING (cls_methods) = encoding;
3016 cls_methods = TREE_CHAIN (cls_methods);
3018 generate_method_descriptors (p);
3020 if (PROTOCOL_LIST (p))
3021 refs_decl = generate_protocol_list (p);
3022 else
3023 refs_decl = 0;
3025 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3027 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3028 NULL_TREE);
3029 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3031 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3032 decl_specs, 1, NULL_TREE);
3034 DECL_CONTEXT (decl) = NULL_TREE;
3036 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3038 if (refs_decl)
3040 cast_type2
3041 = groktypename
3042 (build_tree_list (build_tree_list (NULL_TREE,
3043 objc_protocol_template),
3044 build1 (INDIRECT_REF, NULL_TREE,
3045 build1 (INDIRECT_REF, NULL_TREE,
3046 NULL_TREE))));
3048 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3049 TREE_TYPE (refs_expr) = cast_type2;
3051 else
3052 refs_expr = build_int_2 (0, 0);
3054 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3055 by generate_method_descriptors, which is called above. */
3056 initlist = build_protocol_initializer (TREE_TYPE (decl),
3057 protocol_name_expr, refs_expr,
3058 UOBJC_INSTANCE_METHODS_decl,
3059 UOBJC_CLASS_METHODS_decl);
3060 finish_decl (decl, initlist, NULL_TREE);
3062 /* Mark the decl as used to avoid "defined but not used" warning. */
3063 TREE_USED (decl) = 1;
3067 static tree
3068 build_protocol_initializer (type, protocol_name, protocol_list,
3069 instance_methods, class_methods)
3070 tree type;
3071 tree protocol_name;
3072 tree protocol_list;
3073 tree instance_methods;
3074 tree class_methods;
3076 tree initlist = NULL_TREE, expr;
3077 tree cast_type;
3079 cast_type = groktypename
3080 (build_tree_list
3081 (build_tree_list (NULL_TREE,
3082 xref_tag (RECORD_TYPE,
3083 get_identifier (UTAG_CLASS))),
3084 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3086 /* Filling the "isa" in with one allows the runtime system to
3087 detect that the version change...should remove before final release. */
3089 expr = build_int_2 (PROTOCOL_VERSION, 0);
3090 TREE_TYPE (expr) = cast_type;
3091 initlist = tree_cons (NULL_TREE, expr, initlist);
3092 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3093 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3095 if (!instance_methods)
3096 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3097 else
3099 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3100 initlist = tree_cons (NULL_TREE, expr, initlist);
3103 if (!class_methods)
3104 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3105 else
3107 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3108 initlist = tree_cons (NULL_TREE, expr, initlist);
3111 return build_constructor (type, nreverse (initlist));
3114 /* struct objc_category {
3115 char *category_name;
3116 char *class_name;
3117 struct objc_method_list *instance_methods;
3118 struct objc_method_list *class_methods;
3119 struct objc_protocol_list *protocols;
3120 }; */
3122 static void
3123 build_category_template ()
3125 tree decl_specs, field_decl, field_decl_chain;
3127 objc_category_template = start_struct (RECORD_TYPE,
3128 get_identifier (UTAG_CATEGORY));
3129 /* char *category_name; */
3131 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3132 field_decl
3133 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3134 field_decl
3135 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3136 field_decl_chain = field_decl;
3138 /* char *class_name; */
3140 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3141 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3142 field_decl
3143 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3144 chainon (field_decl_chain, field_decl);
3146 /* struct objc_method_list *instance_methods; */
3148 decl_specs = build_tree_list (NULL_TREE,
3149 xref_tag (RECORD_TYPE,
3150 get_identifier (UTAG_METHOD_LIST)));
3151 field_decl
3152 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3153 field_decl
3154 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3155 chainon (field_decl_chain, field_decl);
3157 /* struct objc_method_list *class_methods; */
3159 decl_specs = build_tree_list (NULL_TREE,
3160 xref_tag (RECORD_TYPE,
3161 get_identifier (UTAG_METHOD_LIST)));
3162 field_decl
3163 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3164 field_decl
3165 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3166 chainon (field_decl_chain, field_decl);
3168 /* struct objc_protocol **protocol_list; */
3170 decl_specs = build_tree_list (NULL_TREE,
3171 xref_tag (RECORD_TYPE,
3172 get_identifier (UTAG_PROTOCOL)));
3173 field_decl
3174 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3175 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3176 field_decl
3177 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3178 chainon (field_decl_chain, field_decl);
3180 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3183 /* struct objc_selector {
3184 void *sel_id;
3185 char *sel_type;
3186 }; */
3188 static void
3189 build_selector_template ()
3192 tree decl_specs, field_decl, field_decl_chain;
3194 objc_selector_template
3195 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3197 /* void *sel_id; */
3199 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3200 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3201 field_decl
3202 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3203 field_decl_chain = field_decl;
3205 /* char *sel_type; */
3207 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3208 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3209 field_decl
3210 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3211 chainon (field_decl_chain, field_decl);
3213 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3216 /* struct objc_class {
3217 struct objc_class *isa;
3218 struct objc_class *super_class;
3219 char *name;
3220 long version;
3221 long info;
3222 long instance_size;
3223 struct objc_ivar_list *ivars;
3224 struct objc_method_list *methods;
3225 if (flag_next_runtime)
3226 struct objc_cache *cache;
3227 else {
3228 struct sarray *dtable;
3229 struct objc_class *subclass_list;
3230 struct objc_class *sibling_class;
3232 struct objc_protocol_list *protocols;
3233 void *gc_object_type;
3234 }; */
3236 static void
3237 build_class_template ()
3239 tree decl_specs, field_decl, field_decl_chain;
3241 objc_class_template
3242 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3244 /* struct objc_class *isa; */
3246 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3247 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3248 field_decl
3249 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3250 field_decl_chain = field_decl;
3252 /* struct objc_class *super_class; */
3254 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3255 field_decl
3256 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3257 field_decl
3258 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3259 chainon (field_decl_chain, field_decl);
3261 /* char *name; */
3263 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3264 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3265 field_decl
3266 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3267 chainon (field_decl_chain, field_decl);
3269 /* long version; */
3271 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3272 field_decl = get_identifier ("version");
3273 field_decl
3274 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3275 chainon (field_decl_chain, field_decl);
3277 /* long info; */
3279 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3280 field_decl = get_identifier ("info");
3281 field_decl
3282 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3283 chainon (field_decl_chain, field_decl);
3285 /* long instance_size; */
3287 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3288 field_decl = get_identifier ("instance_size");
3289 field_decl
3290 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3291 chainon (field_decl_chain, field_decl);
3293 /* struct objc_ivar_list *ivars; */
3295 decl_specs = build_tree_list (NULL_TREE,
3296 xref_tag (RECORD_TYPE,
3297 get_identifier (UTAG_IVAR_LIST)));
3298 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3299 field_decl
3300 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3301 chainon (field_decl_chain, field_decl);
3303 /* struct objc_method_list *methods; */
3305 decl_specs = build_tree_list (NULL_TREE,
3306 xref_tag (RECORD_TYPE,
3307 get_identifier (UTAG_METHOD_LIST)));
3308 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3309 field_decl
3310 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3311 chainon (field_decl_chain, field_decl);
3313 if (flag_next_runtime)
3315 /* struct objc_cache *cache; */
3317 decl_specs = build_tree_list (NULL_TREE,
3318 xref_tag (RECORD_TYPE,
3319 get_identifier ("objc_cache")));
3320 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3321 field_decl = grokfield (input_filename, lineno, field_decl,
3322 decl_specs, NULL_TREE);
3323 chainon (field_decl_chain, field_decl);
3325 else
3327 /* struct sarray *dtable; */
3329 decl_specs = build_tree_list (NULL_TREE,
3330 xref_tag (RECORD_TYPE,
3331 get_identifier ("sarray")));
3332 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3333 field_decl = grokfield (input_filename, lineno, field_decl,
3334 decl_specs, NULL_TREE);
3335 chainon (field_decl_chain, field_decl);
3337 /* struct objc_class *subclass_list; */
3339 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3340 field_decl
3341 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3342 field_decl = grokfield (input_filename, lineno, field_decl,
3343 decl_specs, NULL_TREE);
3344 chainon (field_decl_chain, field_decl);
3346 /* struct objc_class *sibling_class; */
3348 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3349 field_decl
3350 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3351 field_decl = grokfield (input_filename, lineno, field_decl,
3352 decl_specs, NULL_TREE);
3353 chainon (field_decl_chain, field_decl);
3356 /* struct objc_protocol **protocol_list; */
3358 decl_specs = build_tree_list (NULL_TREE,
3359 xref_tag (RECORD_TYPE,
3360 get_identifier (UTAG_PROTOCOL)));
3361 field_decl
3362 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3363 field_decl
3364 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3365 field_decl = grokfield (input_filename, lineno, field_decl,
3366 decl_specs, NULL_TREE);
3367 chainon (field_decl_chain, field_decl);
3369 /* void *sel_id; */
3371 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3372 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3373 field_decl
3374 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3375 chainon (field_decl_chain, field_decl);
3377 /* void *gc_object_type; */
3379 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3380 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3381 field_decl
3382 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3383 chainon (field_decl_chain, field_decl);
3385 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3388 /* Generate appropriate forward declarations for an implementation. */
3390 static void
3391 synth_forward_declarations ()
3393 tree sc_spec, decl_specs, an_id;
3395 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3397 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
3399 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3400 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3401 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3402 TREE_USED (UOBJC_CLASS_decl) = 1;
3403 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3405 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3407 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3408 objc_implementation_context);
3410 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3411 TREE_USED (UOBJC_METACLASS_decl) = 1;
3412 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3414 /* Pre-build the following entities - for speed/convenience. */
3416 an_id = get_identifier ("super_class");
3417 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3418 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3421 static void
3422 error_with_ivar (message, decl, rawdecl)
3423 const char *message;
3424 tree decl;
3425 tree rawdecl;
3427 count_error (0);
3429 report_error_function (DECL_SOURCE_FILE (decl));
3431 error_with_file_and_line (DECL_SOURCE_FILE (decl),
3432 DECL_SOURCE_LINE (decl),
3433 "%s `%s'",
3434 message, gen_declaration (rawdecl, errbuf));
3438 #define USERTYPE(t) \
3439 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3440 || TREE_CODE (t) == ENUMERAL_TYPE)
3442 static void
3443 check_ivars (inter, imp)
3444 tree inter;
3445 tree imp;
3447 tree intdecls = CLASS_IVARS (inter);
3448 tree impdecls = CLASS_IVARS (imp);
3449 tree rawintdecls = CLASS_RAW_IVARS (inter);
3450 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3452 while (1)
3454 tree t1, t2;
3456 if (intdecls == 0 && impdecls == 0)
3457 break;
3458 if (intdecls == 0 || impdecls == 0)
3460 error ("inconsistent instance variable specification");
3461 break;
3464 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3466 if (!comptypes (t1, t2))
3468 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3470 error_with_ivar ("conflicting instance variable type",
3471 impdecls, rawimpdecls);
3472 error_with_ivar ("previous declaration of",
3473 intdecls, rawintdecls);
3475 else /* both the type and the name don't match */
3477 error ("inconsistent instance variable specification");
3478 break;
3482 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3484 error_with_ivar ("conflicting instance variable name",
3485 impdecls, rawimpdecls);
3486 error_with_ivar ("previous declaration of",
3487 intdecls, rawintdecls);
3490 intdecls = TREE_CHAIN (intdecls);
3491 impdecls = TREE_CHAIN (impdecls);
3492 rawintdecls = TREE_CHAIN (rawintdecls);
3493 rawimpdecls = TREE_CHAIN (rawimpdecls);
3497 /* Set super_type to the data type node for struct objc_super *,
3498 first defining struct objc_super itself.
3499 This needs to be done just once per compilation. */
3501 static tree
3502 build_super_template ()
3504 tree record, decl_specs, field_decl, field_decl_chain;
3506 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3508 /* struct objc_object *self; */
3510 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3511 field_decl = get_identifier ("self");
3512 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3513 field_decl = grokfield (input_filename, lineno,
3514 field_decl, decl_specs, NULL_TREE);
3515 field_decl_chain = field_decl;
3517 /* struct objc_class *class; */
3519 decl_specs = get_identifier (UTAG_CLASS);
3520 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3521 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3523 field_decl = grokfield (input_filename, lineno,
3524 field_decl, decl_specs, NULL_TREE);
3525 chainon (field_decl_chain, field_decl);
3527 finish_struct (record, field_decl_chain, NULL_TREE);
3529 /* `struct objc_super *' */
3530 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3531 record),
3532 build1 (INDIRECT_REF,
3533 NULL_TREE, NULL_TREE)));
3534 return record;
3537 /* struct objc_ivar {
3538 char *ivar_name;
3539 char *ivar_type;
3540 int ivar_offset;
3541 }; */
3543 static tree
3544 build_ivar_template ()
3546 tree objc_ivar_id, objc_ivar_record;
3547 tree decl_specs, field_decl, field_decl_chain;
3549 objc_ivar_id = get_identifier (UTAG_IVAR);
3550 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3552 /* char *ivar_name; */
3554 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3555 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3557 field_decl = grokfield (input_filename, lineno, field_decl,
3558 decl_specs, NULL_TREE);
3559 field_decl_chain = field_decl;
3561 /* char *ivar_type; */
3563 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3564 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3566 field_decl = grokfield (input_filename, lineno, field_decl,
3567 decl_specs, NULL_TREE);
3568 chainon (field_decl_chain, field_decl);
3570 /* int ivar_offset; */
3572 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3573 field_decl = get_identifier ("ivar_offset");
3575 field_decl = grokfield (input_filename, lineno, field_decl,
3576 decl_specs, NULL_TREE);
3577 chainon (field_decl_chain, field_decl);
3579 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3581 return objc_ivar_record;
3584 /* struct {
3585 int ivar_count;
3586 struct objc_ivar ivar_list[ivar_count];
3587 }; */
3589 static tree
3590 build_ivar_list_template (list_type, size)
3591 tree list_type;
3592 int size;
3594 tree objc_ivar_list_record;
3595 tree decl_specs, field_decl, field_decl_chain;
3597 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3599 /* int ivar_count; */
3601 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3602 field_decl = get_identifier ("ivar_count");
3604 field_decl = grokfield (input_filename, lineno, field_decl,
3605 decl_specs, NULL_TREE);
3606 field_decl_chain = field_decl;
3608 /* struct objc_ivar ivar_list[]; */
3610 decl_specs = build_tree_list (NULL_TREE, list_type);
3611 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3612 build_int_2 (size, 0));
3614 field_decl = grokfield (input_filename, lineno,
3615 field_decl, decl_specs, NULL_TREE);
3616 chainon (field_decl_chain, field_decl);
3618 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3620 return objc_ivar_list_record;
3623 /* struct {
3624 int method_next;
3625 int method_count;
3626 struct objc_method method_list[method_count];
3627 }; */
3629 static tree
3630 build_method_list_template (list_type, size)
3631 tree list_type;
3632 int size;
3634 tree objc_ivar_list_record;
3635 tree decl_specs, field_decl, field_decl_chain;
3637 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3639 /* int method_next; */
3641 decl_specs
3642 = build_tree_list
3643 (NULL_TREE,
3644 xref_tag (RECORD_TYPE,
3645 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3646 field_decl
3647 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3648 field_decl = grokfield (input_filename, lineno, field_decl,
3649 decl_specs, NULL_TREE);
3650 field_decl_chain = field_decl;
3652 /* int method_count; */
3654 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3655 field_decl = get_identifier ("method_count");
3657 field_decl = grokfield (input_filename, lineno,
3658 field_decl, decl_specs, NULL_TREE);
3659 chainon (field_decl_chain, field_decl);
3661 /* struct objc_method method_list[]; */
3663 decl_specs = build_tree_list (NULL_TREE, list_type);
3664 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3665 build_int_2 (size, 0));
3667 field_decl = grokfield (input_filename, lineno,
3668 field_decl, decl_specs, NULL_TREE);
3669 chainon (field_decl_chain, field_decl);
3671 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3673 return objc_ivar_list_record;
3676 static tree
3677 build_ivar_list_initializer (type, field_decl)
3678 tree type;
3679 tree field_decl;
3681 tree initlist = NULL_TREE;
3685 tree ivar = NULL_TREE;
3687 /* Set name. */
3688 if (DECL_NAME (field_decl))
3689 ivar = tree_cons (NULL_TREE,
3690 add_objc_string (DECL_NAME (field_decl),
3691 meth_var_names),
3692 ivar);
3693 else
3694 /* Unnamed bit-field ivar (yuck). */
3695 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3697 /* Set type. */
3698 encode_field_decl (field_decl,
3699 obstack_object_size (&util_obstack),
3700 OBJC_ENCODE_DONT_INLINE_DEFS);
3702 /* Null terminate string. */
3703 obstack_1grow (&util_obstack, 0);
3704 ivar
3705 = tree_cons
3706 (NULL_TREE,
3707 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3708 meth_var_types),
3709 ivar);
3710 obstack_free (&util_obstack, util_firstobj);
3712 /* Set offset. */
3713 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3714 initlist = tree_cons (NULL_TREE,
3715 build_constructor (type, nreverse (ivar)),
3716 initlist);
3718 field_decl = TREE_CHAIN (field_decl);
3720 while (field_decl);
3722 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3725 static tree
3726 generate_ivars_list (type, name, size, list)
3727 tree type;
3728 const char *name;
3729 int size;
3730 tree list;
3732 tree sc_spec, decl_specs, decl, initlist;
3734 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3735 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3737 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3738 decl_specs, 1, NULL_TREE);
3740 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3741 initlist = tree_cons (NULL_TREE, list, initlist);
3743 finish_decl (decl,
3744 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3745 NULL_TREE);
3747 return decl;
3750 static void
3751 generate_ivar_lists ()
3753 tree initlist, ivar_list_template, chain;
3754 tree cast, variable_length_type;
3755 int size;
3757 generating_instance_variables = 1;
3759 if (!objc_ivar_template)
3760 objc_ivar_template = build_ivar_template ();
3762 cast
3763 = build_tree_list
3764 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3765 get_identifier (UTAG_IVAR_LIST))),
3766 NULL_TREE);
3767 variable_length_type = groktypename (cast);
3769 /* Only generate class variables for the root of the inheritance
3770 hierarchy since these will be the same for every class. */
3772 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3773 && (chain = TYPE_FIELDS (objc_class_template)))
3775 size = list_length (chain);
3777 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3778 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3780 UOBJC_CLASS_VARIABLES_decl
3781 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3782 size, initlist);
3783 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3785 else
3786 UOBJC_CLASS_VARIABLES_decl = 0;
3788 chain = CLASS_IVARS (implementation_template);
3789 if (chain)
3791 size = list_length (chain);
3792 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3793 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3795 UOBJC_INSTANCE_VARIABLES_decl
3796 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3797 size, initlist);
3798 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3800 else
3801 UOBJC_INSTANCE_VARIABLES_decl = 0;
3803 generating_instance_variables = 0;
3806 static tree
3807 build_dispatch_table_initializer (type, entries)
3808 tree type;
3809 tree entries;
3811 tree initlist = NULL_TREE;
3815 tree elemlist = NULL_TREE;
3817 elemlist = tree_cons (NULL_TREE,
3818 build_selector (METHOD_SEL_NAME (entries)),
3819 NULL_TREE);
3821 /* Generate the method encoding if we don't have one already. */
3822 if (! METHOD_ENCODING (entries))
3823 METHOD_ENCODING (entries) =
3824 encode_method_def (METHOD_DEFINITION (entries));
3826 elemlist = tree_cons (NULL_TREE,
3827 add_objc_string (METHOD_ENCODING (entries),
3828 meth_var_types),
3829 elemlist);
3831 elemlist = tree_cons (NULL_TREE,
3832 build_unary_op (ADDR_EXPR,
3833 METHOD_DEFINITION (entries), 1),
3834 elemlist);
3836 initlist = tree_cons (NULL_TREE,
3837 build_constructor (type, nreverse (elemlist)),
3838 initlist);
3840 entries = TREE_CHAIN (entries);
3842 while (entries);
3844 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3847 /* To accomplish method prototyping without generating all kinds of
3848 inane warnings, the definition of the dispatch table entries were
3849 changed from:
3851 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3853 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3855 static tree
3856 build_method_template ()
3858 tree _SLT_record;
3859 tree decl_specs, field_decl, field_decl_chain;
3861 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3863 /* struct objc_selector *_cmd; */
3864 decl_specs = tree_cons (NULL_TREE,
3865 xref_tag (RECORD_TYPE,
3866 get_identifier (TAG_SELECTOR)),
3867 NULL_TREE);
3868 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3870 field_decl = grokfield (input_filename, lineno, field_decl,
3871 decl_specs, NULL_TREE);
3872 field_decl_chain = field_decl;
3874 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3875 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3876 get_identifier ("method_types"));
3877 field_decl = grokfield (input_filename, lineno, field_decl,
3878 decl_specs, NULL_TREE);
3879 chainon (field_decl_chain, field_decl);
3881 /* void *_imp; */
3883 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
3884 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
3885 field_decl = grokfield (input_filename, lineno, field_decl,
3886 decl_specs, NULL_TREE);
3887 chainon (field_decl_chain, field_decl);
3889 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
3891 return _SLT_record;
3895 static tree
3896 generate_dispatch_table (type, name, size, list)
3897 tree type;
3898 const char *name;
3899 int size;
3900 tree list;
3902 tree sc_spec, decl_specs, decl, initlist;
3904 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3905 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3907 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
3908 decl_specs, 1, NULL_TREE);
3910 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
3911 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
3912 initlist = tree_cons (NULL_TREE, list, initlist);
3914 finish_decl (decl,
3915 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3916 NULL_TREE);
3918 return decl;
3921 static void
3922 generate_dispatch_tables ()
3924 tree initlist, chain, method_list_template;
3925 tree cast, variable_length_type;
3926 int size;
3928 if (!objc_method_template)
3929 objc_method_template = build_method_template ();
3931 cast
3932 = build_tree_list
3933 (build_tree_list (NULL_TREE,
3934 xref_tag (RECORD_TYPE,
3935 get_identifier (UTAG_METHOD_LIST))),
3936 NULL_TREE);
3938 variable_length_type = groktypename (cast);
3940 chain = CLASS_CLS_METHODS (objc_implementation_context);
3941 if (chain)
3943 size = list_length (chain);
3945 method_list_template
3946 = build_method_list_template (objc_method_template, size);
3947 initlist
3948 = build_dispatch_table_initializer (objc_method_template, chain);
3950 UOBJC_CLASS_METHODS_decl
3951 = generate_dispatch_table (method_list_template,
3952 ((TREE_CODE (objc_implementation_context)
3953 == CLASS_IMPLEMENTATION_TYPE)
3954 ? "_OBJC_CLASS_METHODS"
3955 : "_OBJC_CATEGORY_CLASS_METHODS"),
3956 size, initlist);
3957 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3959 else
3960 UOBJC_CLASS_METHODS_decl = 0;
3962 chain = CLASS_NST_METHODS (objc_implementation_context);
3963 if (chain)
3965 size = list_length (chain);
3967 method_list_template
3968 = build_method_list_template (objc_method_template, size);
3969 initlist
3970 = build_dispatch_table_initializer (objc_method_template, chain);
3972 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
3973 UOBJC_INSTANCE_METHODS_decl
3974 = generate_dispatch_table (method_list_template,
3975 "_OBJC_INSTANCE_METHODS",
3976 size, initlist);
3977 else
3978 /* We have a category. */
3979 UOBJC_INSTANCE_METHODS_decl
3980 = generate_dispatch_table (method_list_template,
3981 "_OBJC_CATEGORY_INSTANCE_METHODS",
3982 size, initlist);
3983 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3985 else
3986 UOBJC_INSTANCE_METHODS_decl = 0;
3989 static tree
3990 generate_protocol_list (i_or_p)
3991 tree i_or_p;
3993 tree initlist, decl_specs, sc_spec;
3994 tree refs_decl, expr_decl, lproto, e, plist;
3995 tree cast_type;
3996 int size = 0;
3998 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
3999 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4000 plist = CLASS_PROTOCOL_LIST (i_or_p);
4001 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4002 plist = PROTOCOL_LIST (i_or_p);
4003 else
4004 abort ();
4006 cast_type = groktypename
4007 (build_tree_list
4008 (build_tree_list (NULL_TREE,
4009 xref_tag (RECORD_TYPE,
4010 get_identifier (UTAG_PROTOCOL))),
4011 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4013 /* Compute size. */
4014 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4015 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4016 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4017 size++;
4019 /* Build initializer. */
4020 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4022 e = build_int_2 (size, 0);
4023 TREE_TYPE (e) = cast_type;
4024 initlist = tree_cons (NULL_TREE, e, initlist);
4026 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4028 tree pval = TREE_VALUE (lproto);
4030 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4031 && PROTOCOL_FORWARD_DECL (pval))
4033 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4034 initlist = tree_cons (NULL_TREE, e, initlist);
4038 /* static struct objc_protocol *refs[n]; */
4040 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4041 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4042 get_identifier (UTAG_PROTOCOL)),
4043 sc_spec);
4045 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4046 expr_decl = build_nt (ARRAY_REF,
4047 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4048 i_or_p),
4049 build_int_2 (size + 2, 0));
4050 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4051 expr_decl = build_nt (ARRAY_REF,
4052 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4053 i_or_p),
4054 build_int_2 (size + 2, 0));
4055 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4056 expr_decl
4057 = build_nt (ARRAY_REF,
4058 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4059 i_or_p),
4060 build_int_2 (size + 2, 0));
4061 else
4062 abort ();
4064 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4066 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4067 DECL_CONTEXT (refs_decl) = NULL_TREE;
4069 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4070 nreverse (initlist)),
4071 NULL_TREE);
4073 return refs_decl;
4076 static tree
4077 build_category_initializer (type, cat_name, class_name,
4078 instance_methods, class_methods, protocol_list)
4079 tree type;
4080 tree cat_name;
4081 tree class_name;
4082 tree instance_methods;
4083 tree class_methods;
4084 tree protocol_list;
4086 tree initlist = NULL_TREE, expr;
4088 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4089 initlist = tree_cons (NULL_TREE, class_name, initlist);
4091 if (!instance_methods)
4092 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4093 else
4095 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4096 initlist = tree_cons (NULL_TREE, expr, initlist);
4098 if (!class_methods)
4099 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4100 else
4102 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4103 initlist = tree_cons (NULL_TREE, expr, initlist);
4106 /* protocol_list = */
4107 if (!protocol_list)
4108 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4109 else
4111 tree cast_type2 = groktypename
4112 (build_tree_list
4113 (build_tree_list (NULL_TREE,
4114 xref_tag (RECORD_TYPE,
4115 get_identifier (UTAG_PROTOCOL))),
4116 build1 (INDIRECT_REF, NULL_TREE,
4117 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4119 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4120 TREE_TYPE (expr) = cast_type2;
4121 initlist = tree_cons (NULL_TREE, expr, initlist);
4124 return build_constructor (type, nreverse (initlist));
4127 /* struct objc_class {
4128 struct objc_class *isa;
4129 struct objc_class *super_class;
4130 char *name;
4131 long version;
4132 long info;
4133 long instance_size;
4134 struct objc_ivar_list *ivars;
4135 struct objc_method_list *methods;
4136 if (flag_next_runtime)
4137 struct objc_cache *cache;
4138 else {
4139 struct sarray *dtable;
4140 struct objc_class *subclass_list;
4141 struct objc_class *sibling_class;
4143 struct objc_protocol_list *protocols;
4144 void *gc_object_type;
4145 }; */
4147 static tree
4148 build_shared_structure_initializer (type, isa, super, name, size, status,
4149 dispatch_table, ivar_list, protocol_list)
4150 tree type;
4151 tree isa;
4152 tree super;
4153 tree name;
4154 tree size;
4155 int status;
4156 tree dispatch_table;
4157 tree ivar_list;
4158 tree protocol_list;
4160 tree initlist = NULL_TREE, expr;
4162 /* isa = */
4163 initlist = tree_cons (NULL_TREE, isa, initlist);
4165 /* super_class = */
4166 initlist = tree_cons (NULL_TREE, super, initlist);
4168 /* name = */
4169 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4171 /* version = */
4172 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4174 /* info = */
4175 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4177 /* instance_size = */
4178 initlist = tree_cons (NULL_TREE, size, initlist);
4180 /* objc_ivar_list = */
4181 if (!ivar_list)
4182 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4183 else
4185 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4186 initlist = tree_cons (NULL_TREE, expr, initlist);
4189 /* objc_method_list = */
4190 if (!dispatch_table)
4191 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4192 else
4194 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4195 initlist = tree_cons (NULL_TREE, expr, initlist);
4198 if (flag_next_runtime)
4199 /* method_cache = */
4200 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4201 else
4203 /* dtable = */
4204 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4206 /* subclass_list = */
4207 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4209 /* sibling_class = */
4210 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4213 /* protocol_list = */
4214 if (! protocol_list)
4215 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4216 else
4218 tree cast_type2
4219 = groktypename
4220 (build_tree_list
4221 (build_tree_list (NULL_TREE,
4222 xref_tag (RECORD_TYPE,
4223 get_identifier (UTAG_PROTOCOL))),
4224 build1 (INDIRECT_REF, NULL_TREE,
4225 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4227 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4228 TREE_TYPE (expr) = cast_type2;
4229 initlist = tree_cons (NULL_TREE, expr, initlist);
4232 /* gc_object_type = NULL */
4233 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4235 return build_constructor (type, nreverse (initlist));
4238 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4240 static void
4241 generate_category (cat)
4242 tree cat;
4244 tree sc_spec, decl_specs, decl;
4245 tree initlist, cat_name_expr, class_name_expr;
4246 tree protocol_decl, category;
4248 add_class_reference (CLASS_NAME (cat));
4249 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4251 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4253 category = CLASS_CATEGORY_LIST (implementation_template);
4255 /* find the category interface from the class it is associated with */
4256 while (category)
4258 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4259 break;
4260 category = CLASS_CATEGORY_LIST (category);
4263 if (category && CLASS_PROTOCOL_LIST (category))
4265 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4266 protocol_decl = generate_protocol_list (category);
4268 else
4269 protocol_decl = 0;
4271 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4272 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4274 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4275 objc_implementation_context),
4276 decl_specs, 1, NULL_TREE);
4278 initlist = build_category_initializer (TREE_TYPE (decl),
4279 cat_name_expr, class_name_expr,
4280 UOBJC_INSTANCE_METHODS_decl,
4281 UOBJC_CLASS_METHODS_decl,
4282 protocol_decl);
4284 TREE_USED (decl) = 1;
4285 finish_decl (decl, initlist, NULL_TREE);
4288 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4289 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4291 static void
4292 generate_shared_structures ()
4294 tree sc_spec, decl_specs, decl;
4295 tree name_expr, super_expr, root_expr;
4296 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4297 tree cast_type, initlist, protocol_decl;
4299 my_super_id = CLASS_SUPER_NAME (implementation_template);
4300 if (my_super_id)
4302 add_class_reference (my_super_id);
4304 /* Compute "my_root_id" - this is required for code generation.
4305 the "isa" for all meta class structures points to the root of
4306 the inheritance hierarchy (e.g. "__Object")... */
4307 my_root_id = my_super_id;
4310 tree my_root_int = lookup_interface (my_root_id);
4312 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4313 my_root_id = CLASS_SUPER_NAME (my_root_int);
4314 else
4315 break;
4317 while (1);
4319 else
4320 /* No super class. */
4321 my_root_id = CLASS_NAME (implementation_template);
4323 cast_type
4324 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4325 objc_class_template),
4326 build1 (INDIRECT_REF,
4327 NULL_TREE, NULL_TREE)));
4329 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4330 class_names);
4332 /* Install class `isa' and `super' pointers at runtime. */
4333 if (my_super_id)
4335 super_expr = add_objc_string (my_super_id, class_names);
4336 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4338 else
4339 super_expr = build_int_2 (0, 0);
4341 root_expr = add_objc_string (my_root_id, class_names);
4342 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4344 if (CLASS_PROTOCOL_LIST (implementation_template))
4346 generate_protocol_references
4347 (CLASS_PROTOCOL_LIST (implementation_template));
4348 protocol_decl = generate_protocol_list (implementation_template);
4350 else
4351 protocol_decl = 0;
4353 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4355 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4356 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4358 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4359 NULL_TREE);
4361 initlist
4362 = build_shared_structure_initializer
4363 (TREE_TYPE (decl),
4364 root_expr, super_expr, name_expr,
4365 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4366 2 /*CLS_META*/,
4367 UOBJC_CLASS_METHODS_decl,
4368 UOBJC_CLASS_VARIABLES_decl,
4369 protocol_decl);
4371 finish_decl (decl, initlist, NULL_TREE);
4373 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4375 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4376 NULL_TREE);
4378 initlist
4379 = build_shared_structure_initializer
4380 (TREE_TYPE (decl),
4381 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4382 super_expr, name_expr,
4383 convert (integer_type_node,
4384 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4385 (implementation_template))),
4386 1 /*CLS_FACTORY*/,
4387 UOBJC_INSTANCE_METHODS_decl,
4388 UOBJC_INSTANCE_VARIABLES_decl,
4389 protocol_decl);
4391 finish_decl (decl, initlist, NULL_TREE);
4394 static tree
4395 synth_id_with_class_suffix (preamble, ctxt)
4396 const char *preamble;
4397 tree ctxt;
4399 char *string;
4400 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4401 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4403 const char *const class_name
4404 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4405 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4406 sprintf (string, "%s_%s", preamble,
4407 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4409 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4410 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4412 /* We have a category. */
4413 const char *const class_name
4414 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
4415 const char *const class_super_name
4416 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
4417 string = (char *) alloca (strlen (preamble)
4418 + strlen (class_name)
4419 + strlen (class_super_name)
4420 + 3);
4421 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4423 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4425 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4426 string
4427 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4428 sprintf (string, "%s_%s", preamble, protocol_name);
4430 else
4431 abort ();
4433 return get_identifier (string);
4436 static int
4437 is_objc_type_qualifier (node)
4438 tree node;
4440 return (TREE_CODE (node) == IDENTIFIER_NODE
4441 && (node == ridpointers [(int) RID_CONST]
4442 || node == ridpointers [(int) RID_VOLATILE]
4443 || node == ridpointers [(int) RID_IN]
4444 || node == ridpointers [(int) RID_OUT]
4445 || node == ridpointers [(int) RID_INOUT]
4446 || node == ridpointers [(int) RID_BYCOPY]
4447 || node == ridpointers [(int) RID_BYREF]
4448 || node == ridpointers [(int) RID_ONEWAY]));
4451 /* If type is empty or only type qualifiers are present, add default
4452 type of id (otherwise grokdeclarator will default to int). */
4454 static tree
4455 adjust_type_for_id_default (type)
4456 tree type;
4458 tree declspecs, chain;
4460 if (!type)
4461 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4462 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4464 declspecs = TREE_PURPOSE (type);
4466 /* Determine if a typespec is present. */
4467 for (chain = declspecs;
4468 chain;
4469 chain = TREE_CHAIN (chain))
4471 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4472 return type;
4475 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4476 declspecs),
4477 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4480 /* Usage:
4481 keyworddecl:
4482 selector ':' '(' typename ')' identifier
4484 Purpose:
4485 Transform an Objective-C keyword argument into
4486 the C equivalent parameter declarator.
4488 In: key_name, an "identifier_node" (optional).
4489 arg_type, a "tree_list" (optional).
4490 arg_name, an "identifier_node".
4492 Note: It would be really nice to strongly type the preceding
4493 arguments in the function prototype; however, then I
4494 could not use the "accessor" macros defined in "tree.h".
4496 Out: an instance of "keyword_decl". */
4498 tree
4499 build_keyword_decl (key_name, arg_type, arg_name)
4500 tree key_name;
4501 tree arg_type;
4502 tree arg_name;
4504 tree keyword_decl;
4506 /* If no type is specified, default to "id". */
4507 arg_type = adjust_type_for_id_default (arg_type);
4509 keyword_decl = make_node (KEYWORD_DECL);
4511 TREE_TYPE (keyword_decl) = arg_type;
4512 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4513 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4515 return keyword_decl;
4518 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4520 static tree
4521 build_keyword_selector (selector)
4522 tree selector;
4524 int len = 0;
4525 tree key_chain, key_name;
4526 char *buf;
4528 /* Scan the selector to see how much space we'll need. */
4529 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4531 if (TREE_CODE (selector) == KEYWORD_DECL)
4532 key_name = KEYWORD_KEY_NAME (key_chain);
4533 else if (TREE_CODE (selector) == TREE_LIST)
4534 key_name = TREE_PURPOSE (key_chain);
4535 else
4536 abort ();
4538 if (key_name)
4539 len += IDENTIFIER_LENGTH (key_name) + 1;
4540 else
4541 /* Just a ':' arg. */
4542 len++;
4545 buf = (char *) alloca (len + 1);
4546 /* Start the buffer out as an empty string. */
4547 buf[0] = '\0';
4549 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4551 if (TREE_CODE (selector) == KEYWORD_DECL)
4552 key_name = KEYWORD_KEY_NAME (key_chain);
4553 else if (TREE_CODE (selector) == TREE_LIST)
4554 key_name = TREE_PURPOSE (key_chain);
4555 else
4556 abort ();
4558 if (key_name)
4559 strcat (buf, IDENTIFIER_POINTER (key_name));
4560 strcat (buf, ":");
4563 return get_identifier (buf);
4566 /* Used for declarations and definitions. */
4568 tree
4569 build_method_decl (code, ret_type, selector, add_args)
4570 enum tree_code code;
4571 tree ret_type;
4572 tree selector;
4573 tree add_args;
4575 tree method_decl;
4577 /* If no type is specified, default to "id". */
4578 ret_type = adjust_type_for_id_default (ret_type);
4580 method_decl = make_node (code);
4581 TREE_TYPE (method_decl) = ret_type;
4583 /* If we have a keyword selector, create an identifier_node that
4584 represents the full selector name (`:' included)... */
4585 if (TREE_CODE (selector) == KEYWORD_DECL)
4587 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4588 METHOD_SEL_ARGS (method_decl) = selector;
4589 METHOD_ADD_ARGS (method_decl) = add_args;
4591 else
4593 METHOD_SEL_NAME (method_decl) = selector;
4594 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4595 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4598 return method_decl;
4601 #define METHOD_DEF 0
4602 #define METHOD_REF 1
4604 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4605 an argument list for method METH. CONTEXT is either METHOD_DEF or
4606 METHOD_REF, saying whether we are trying to define a method or call
4607 one. SUPERFLAG says this is for a send to super; this makes a
4608 difference for the NeXT calling sequence in which the lookup and
4609 the method call are done together. */
4611 static tree
4612 get_arg_type_list (meth, context, superflag)
4613 tree meth;
4614 int context;
4615 int superflag;
4617 tree arglist, akey;
4619 /* Receiver type. */
4620 if (flag_next_runtime && superflag)
4621 arglist = build_tree_list (NULL_TREE, super_type);
4622 else if (context == METHOD_DEF)
4623 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4624 else
4625 arglist = build_tree_list (NULL_TREE, id_type);
4627 /* Selector type - will eventually change to `int'. */
4628 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4630 /* Build a list of argument types. */
4631 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4633 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4634 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4637 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4638 /* We have a `, ...' immediately following the selector,
4639 finalize the arglist...simulate get_parm_info (0). */
4641 else if (METHOD_ADD_ARGS (meth))
4643 /* we have a variable length selector */
4644 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4645 chainon (arglist, add_arg_list);
4647 else
4648 /* finalize the arglist...simulate get_parm_info (1) */
4649 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4651 return arglist;
4654 static tree
4655 check_duplicates (hsh)
4656 hash hsh;
4658 tree meth = NULL_TREE;
4660 if (hsh)
4662 meth = hsh->key;
4664 if (hsh->list)
4666 /* We have two methods with the same name and different types. */
4667 attr loop;
4668 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4670 warning ("multiple declarations for method `%s'",
4671 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4673 warn_with_method ("using", type, meth);
4674 for (loop = hsh->list; loop; loop = loop->next)
4675 warn_with_method ("also found", type, loop->value);
4678 return meth;
4681 /* If RECEIVER is a class reference, return the identifier node for
4682 the referenced class. RECEIVER is created by get_class_reference,
4683 so we check the exact form created depending on which runtimes are
4684 used. */
4686 static tree
4687 receiver_is_class_object (receiver)
4688 tree receiver;
4690 tree chain, exp, arg;
4692 /* The receiver is 'self' in the context of a class method. */
4693 if (objc_method_context
4694 && receiver == self_decl
4695 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
4697 return CLASS_NAME (objc_implementation_context);
4700 if (flag_next_runtime)
4702 /* The receiver is a variable created by
4703 build_class_reference_decl. */
4704 if (TREE_CODE (receiver) == VAR_DECL
4705 && TREE_TYPE (receiver) == objc_class_type)
4706 /* Look up the identifier. */
4707 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4708 if (TREE_PURPOSE (chain) == receiver)
4709 return TREE_VALUE (chain);
4711 else
4713 /* The receiver is a function call that returns an id. Check if
4714 it is a call to objc_getClass, if so, pick up the class name. */
4715 if (TREE_CODE (receiver) == CALL_EXPR
4716 && (exp = TREE_OPERAND (receiver, 0))
4717 && TREE_CODE (exp) == ADDR_EXPR
4718 && (exp = TREE_OPERAND (exp, 0))
4719 && TREE_CODE (exp) == FUNCTION_DECL
4720 && exp == objc_get_class_decl
4721 /* We have a call to objc_getClass! */
4722 && (arg = TREE_OPERAND (receiver, 1))
4723 && TREE_CODE (arg) == TREE_LIST
4724 && (arg = TREE_VALUE (arg)))
4726 STRIP_NOPS (arg);
4727 if (TREE_CODE (arg) == ADDR_EXPR
4728 && (arg = TREE_OPERAND (arg, 0))
4729 && TREE_CODE (arg) == STRING_CST)
4730 /* Finally, we have the class name. */
4731 return get_identifier (TREE_STRING_POINTER (arg));
4734 return 0;
4737 /* If we are currently building a message expr, this holds
4738 the identifier of the selector of the message. This is
4739 used when printing warnings about argument mismatches. */
4741 static tree building_objc_message_expr = 0;
4743 tree
4744 maybe_building_objc_message_expr ()
4746 return building_objc_message_expr;
4749 /* Construct an expression for sending a message.
4750 MESS has the object to send to in TREE_PURPOSE
4751 and the argument list (including selector) in TREE_VALUE.
4753 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4754 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4756 tree
4757 build_message_expr (mess)
4758 tree mess;
4760 tree receiver = TREE_PURPOSE (mess);
4761 tree sel_name;
4762 tree args = TREE_VALUE (mess);
4763 tree method_params = NULL_TREE;
4765 if (TREE_CODE (receiver) == ERROR_MARK)
4766 return error_mark_node;
4768 /* Obtain the full selector name. */
4769 if (TREE_CODE (args) == IDENTIFIER_NODE)
4770 /* A unary selector. */
4771 sel_name = args;
4772 else if (TREE_CODE (args) == TREE_LIST)
4773 sel_name = build_keyword_selector (args);
4774 else
4775 abort ();
4777 /* Build the parameter list to give to the method. */
4778 if (TREE_CODE (args) == TREE_LIST)
4780 tree chain = args, prev = NULL_TREE;
4782 /* We have a keyword selector--check for comma expressions. */
4783 while (chain)
4785 tree element = TREE_VALUE (chain);
4787 /* We have a comma expression, must collapse... */
4788 if (TREE_CODE (element) == TREE_LIST)
4790 if (prev)
4791 TREE_CHAIN (prev) = element;
4792 else
4793 args = element;
4795 prev = chain;
4796 chain = TREE_CHAIN (chain);
4798 method_params = args;
4801 return finish_message_expr (receiver, sel_name, method_params);
4804 /* The 'finish_message_expr' routine is called from within
4805 'build_message_expr' for non-template functions. In the case of
4806 C++ template functions, it is called from 'build_expr_from_tree'
4807 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4809 tree
4810 finish_message_expr (receiver, sel_name, method_params)
4811 tree receiver, sel_name, method_params;
4813 tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
4814 tree selector, self_object, retval;
4815 int statically_typed = 0, statically_allocated = 0;
4817 /* Determine receiver type. */
4818 tree rtype = TREE_TYPE (receiver);
4819 int super = IS_SUPER (rtype);
4821 if (! super)
4823 if (TREE_STATIC_TEMPLATE (rtype))
4824 statically_allocated = 1;
4825 else if (TREE_CODE (rtype) == POINTER_TYPE
4826 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4827 statically_typed = 1;
4828 else if ((flag_next_runtime
4829 || (IS_ID (rtype)))
4830 && (class_ident = receiver_is_class_object (receiver)))
4832 else if (! IS_ID (rtype)
4833 /* Allow any type that matches objc_class_type. */
4834 && ! comptypes (rtype, objc_class_type))
4836 warning ("invalid receiver type `%s'",
4837 gen_declaration (rtype, errbuf));
4839 if (statically_allocated)
4840 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4842 /* Don't evaluate the receiver twice. */
4843 receiver = save_expr (receiver);
4844 self_object = receiver;
4846 else
4847 /* If sending to `super', use current self as the object. */
4848 self_object = self_decl;
4850 /* Determine operation return type. */
4852 if (super)
4854 tree iface;
4856 if (CLASS_SUPER_NAME (implementation_template))
4858 iface
4859 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4861 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
4862 method_prototype = lookup_instance_method_static (iface, sel_name);
4863 else
4864 method_prototype = lookup_class_method_static (iface, sel_name);
4866 if (iface && !method_prototype)
4867 warning ("`%s' does not respond to `%s'",
4868 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4869 IDENTIFIER_POINTER (sel_name));
4871 else
4873 error ("no super class declared in interface for `%s'",
4874 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4875 return error_mark_node;
4879 else if (statically_allocated)
4881 tree ctype = TREE_TYPE (rtype);
4882 tree iface = lookup_interface (TYPE_NAME (rtype));
4884 if (iface)
4885 method_prototype = lookup_instance_method_static (iface, sel_name);
4887 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4888 method_prototype
4889 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4890 sel_name, 0);
4892 if (!method_prototype)
4893 warning ("`%s' does not respond to `%s'",
4894 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
4895 IDENTIFIER_POINTER (sel_name));
4897 else if (statically_typed)
4899 tree ctype = TREE_TYPE (rtype);
4901 /* `self' is now statically_typed. All methods should be visible
4902 within the context of the implementation. */
4903 if (objc_implementation_context
4904 && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
4906 method_prototype
4907 = lookup_instance_method_static (implementation_template,
4908 sel_name);
4910 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
4911 method_prototype
4912 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
4913 sel_name, 0);
4915 if (! method_prototype
4916 && implementation_template != objc_implementation_context)
4917 /* The method is not published in the interface. Check
4918 locally. */
4919 method_prototype
4920 = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
4921 sel_name);
4923 else
4925 tree iface;
4927 if ((iface = lookup_interface (TYPE_NAME (ctype))))
4928 method_prototype = lookup_instance_method_static (iface, sel_name);
4930 if (! method_prototype)
4932 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
4933 if (protocol_list)
4934 method_prototype
4935 = lookup_method_in_protocol_list (protocol_list,
4936 sel_name, 0);
4940 if (!method_prototype)
4941 warning ("`%s' does not respond to `%s'",
4942 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
4943 IDENTIFIER_POINTER (sel_name));
4945 else if (class_ident)
4947 if (objc_implementation_context
4948 && CLASS_NAME (objc_implementation_context) == class_ident)
4950 method_prototype
4951 = lookup_class_method_static (implementation_template, sel_name);
4953 if (!method_prototype
4954 && implementation_template != objc_implementation_context)
4955 /* The method is not published in the interface. Check
4956 locally. */
4957 method_prototype
4958 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
4959 sel_name);
4961 else
4963 tree iface;
4965 if ((iface = lookup_interface (class_ident)))
4966 method_prototype = lookup_class_method_static (iface, sel_name);
4969 if (!method_prototype)
4971 warning ("cannot find class (factory) method");
4972 warning ("return type for `%s' defaults to id",
4973 IDENTIFIER_POINTER (sel_name));
4976 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
4978 /* An anonymous object that has been qualified with a protocol. */
4980 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
4982 method_prototype = lookup_method_in_protocol_list (protocol_list,
4983 sel_name, 0);
4985 if (!method_prototype)
4987 hash hsh;
4989 warning ("method `%s' not implemented by protocol",
4990 IDENTIFIER_POINTER (sel_name));
4992 /* Try and find the method signature in the global pools. */
4994 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
4995 hsh = hash_lookup (cls_method_hash_list, sel_name);
4997 if (!(method_prototype = check_duplicates (hsh)))
4998 warning ("return type defaults to id");
5001 else
5003 hash hsh;
5005 /* We think we have an instance...loophole: extern id Object; */
5006 hsh = hash_lookup (nst_method_hash_list, sel_name);
5008 if (!hsh)
5009 /* For various loopholes */
5010 hsh = hash_lookup (cls_method_hash_list, sel_name);
5012 method_prototype = check_duplicates (hsh);
5013 if (!method_prototype)
5015 warning ("cannot find method");
5016 warning ("return type for `%s' defaults to id",
5017 IDENTIFIER_POINTER (sel_name));
5021 /* Save the selector name for printing error messages. */
5022 building_objc_message_expr = sel_name;
5024 /* Build the parameters list for looking up the method.
5025 These are the object itself and the selector. */
5027 if (flag_typed_selectors)
5028 selector = build_typed_selector_reference (sel_name, method_prototype);
5029 else
5030 selector = build_selector_reference (sel_name);
5032 retval = build_objc_method_call (super, method_prototype,
5033 receiver, self_object,
5034 selector, method_params);
5036 building_objc_message_expr = 0;
5038 return retval;
5041 /* Build a tree expression to send OBJECT the operation SELECTOR,
5042 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5043 assuming the method has prototype METHOD_PROTOTYPE.
5044 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5045 Use METHOD_PARAMS as list of args to pass to the method.
5046 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5048 static tree
5049 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5050 selector, method_params)
5051 int super_flag;
5052 tree method_prototype, lookup_object, object, selector, method_params;
5054 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5055 tree rcv_p = (super_flag
5056 ? build_pointer_type (xref_tag (RECORD_TYPE,
5057 get_identifier (TAG_SUPER)))
5058 : id_type);
5060 if (flag_next_runtime)
5062 if (! method_prototype)
5064 method_params = tree_cons (NULL_TREE, lookup_object,
5065 tree_cons (NULL_TREE, selector,
5066 method_params));
5067 assemble_external (sender);
5068 return build_function_call (sender, method_params);
5070 else
5072 /* This is a real kludge, but it is used only for the Next.
5073 Clobber the data type of SENDER temporarily to accept
5074 all the arguments for this operation, and to return
5075 whatever this operation returns. */
5076 tree arglist = NULL_TREE, retval, savarg, savret;
5077 tree ret_type = groktypename (TREE_TYPE (method_prototype));
5079 /* Save the proper contents of SENDER's data type. */
5080 savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5081 savret = TREE_TYPE (TREE_TYPE (sender));
5083 /* Install this method's argument types. */
5084 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5085 super_flag);
5086 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5088 /* Install this method's return type. */
5089 TREE_TYPE (TREE_TYPE (sender)) = ret_type;
5091 /* Call SENDER with all the parameters. This will do type
5092 checking using the arg types for this method. */
5093 method_params = tree_cons (NULL_TREE, lookup_object,
5094 tree_cons (NULL_TREE, selector,
5095 method_params));
5096 assemble_external (sender);
5097 retval = build_function_call (sender, method_params);
5099 /* Restore SENDER's return/argument types. */
5100 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5101 TREE_TYPE (TREE_TYPE (sender)) = savret;
5102 return retval;
5105 else
5107 /* This is the portable way.
5108 First call the lookup function to get a pointer to the method,
5109 then cast the pointer, then call it with the method arguments. */
5110 tree method;
5112 /* Avoid trouble since we may evaluate each of these twice. */
5113 object = save_expr (object);
5114 selector = save_expr (selector);
5116 lookup_object = build_c_cast (rcv_p, lookup_object);
5118 assemble_external (sender);
5119 method
5120 = build_function_call (sender,
5121 tree_cons (NULL_TREE, lookup_object,
5122 tree_cons (NULL_TREE, selector,
5123 NULL_TREE)));
5125 /* If we have a method prototype, construct the data type this
5126 method needs, and cast what we got from SENDER into a pointer
5127 to that type. */
5128 if (method_prototype)
5130 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5131 super_flag);
5132 tree valtype = groktypename (TREE_TYPE (method_prototype));
5133 tree fake_function_type = build_function_type (valtype, arglist);
5134 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5136 else
5137 TREE_TYPE (method)
5138 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5140 /* Pass the object to the method. */
5141 assemble_external (method);
5142 return build_function_call (method,
5143 tree_cons (NULL_TREE, object,
5144 tree_cons (NULL_TREE, selector,
5145 method_params)));
5149 static void
5150 build_protocol_reference (p)
5151 tree p;
5153 tree decl, ident, ptype;
5155 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5157 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5158 ptype
5159 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5160 objc_protocol_template),
5161 NULL_TREE));
5163 if (IDENTIFIER_GLOBAL_VALUE (ident))
5164 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5165 else
5167 decl = build_decl (VAR_DECL, ident, ptype);
5168 DECL_EXTERNAL (decl) = 1;
5169 TREE_PUBLIC (decl) = 1;
5170 TREE_USED (decl) = 1;
5171 DECL_ARTIFICIAL (decl) = 1;
5173 make_decl_rtl (decl, 0);
5174 pushdecl_top_level (decl);
5177 PROTOCOL_FORWARD_DECL (p) = decl;
5180 tree
5181 build_protocol_expr (protoname)
5182 tree protoname;
5184 tree expr;
5185 tree p = lookup_protocol (protoname);
5187 if (!p)
5189 error ("cannot find protocol declaration for `%s'",
5190 IDENTIFIER_POINTER (protoname));
5191 return error_mark_node;
5194 if (!PROTOCOL_FORWARD_DECL (p))
5195 build_protocol_reference (p);
5197 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5199 TREE_TYPE (expr) = protocol_type;
5201 return expr;
5204 tree
5205 build_selector_expr (selnamelist)
5206 tree selnamelist;
5208 tree selname;
5210 /* Obtain the full selector name. */
5211 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5212 /* A unary selector. */
5213 selname = selnamelist;
5214 else if (TREE_CODE (selnamelist) == TREE_LIST)
5215 selname = build_keyword_selector (selnamelist);
5216 else
5217 abort ();
5219 if (flag_typed_selectors)
5220 return build_typed_selector_reference (selname, 0);
5221 else
5222 return build_selector_reference (selname);
5225 tree
5226 build_encode_expr (type)
5227 tree type;
5229 tree result;
5230 const char *string;
5232 encode_type (type, obstack_object_size (&util_obstack),
5233 OBJC_ENCODE_INLINE_DEFS);
5234 obstack_1grow (&util_obstack, 0); /* null terminate string */
5235 string = obstack_finish (&util_obstack);
5237 /* Synthesize a string that represents the encoded struct/union. */
5238 result = my_build_string (strlen (string) + 1, string);
5239 obstack_free (&util_obstack, util_firstobj);
5240 return result;
5243 tree
5244 build_ivar_reference (id)
5245 tree id;
5247 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5249 /* Historically, a class method that produced objects (factory
5250 method) would assign `self' to the instance that it
5251 allocated. This would effectively turn the class method into
5252 an instance method. Following this assignment, the instance
5253 variables could be accessed. That practice, while safe,
5254 violates the simple rule that a class method should not refer
5255 to an instance variable. It's better to catch the cases
5256 where this is done unknowingly than to support the above
5257 paradigm. */
5258 warning ("instance variable `%s' accessed in class method",
5259 IDENTIFIER_POINTER (id));
5260 TREE_TYPE (self_decl) = instance_type; /* cast */
5263 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5266 /* Compute a hash value for a given method SEL_NAME. */
5268 static size_t
5269 hash_func (sel_name)
5270 tree sel_name;
5272 const unsigned char *s
5273 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5274 size_t h = 0;
5276 while (*s)
5277 h = h * 67 + *s++ - 113;
5278 return h;
5281 static void
5282 hash_init ()
5284 nst_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5285 cls_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
5288 /* WARNING!!!! hash_enter is called with a method, and will peek
5289 inside to find its selector! But hash_lookup is given a selector
5290 directly, and looks for the selector that's inside the found
5291 entry's key (method) for comparison. */
5293 static void
5294 hash_enter (hashlist, method)
5295 hash *hashlist;
5296 tree method;
5298 static hash hash_alloc_list = 0;
5299 static int hash_alloc_index = 0;
5300 hash obj;
5301 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5303 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5305 hash_alloc_index = 0;
5306 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5307 * HASH_ALLOC_LIST_SIZE);
5309 obj = &hash_alloc_list[hash_alloc_index++];
5310 obj->list = 0;
5311 obj->next = hashlist[slot];
5312 obj->key = method;
5314 hashlist[slot] = obj; /* append to front */
5317 static hash
5318 hash_lookup (hashlist, sel_name)
5319 hash *hashlist;
5320 tree sel_name;
5322 hash target;
5324 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5326 while (target)
5328 if (sel_name == METHOD_SEL_NAME (target->key))
5329 return target;
5331 target = target->next;
5333 return 0;
5336 static void
5337 hash_add_attr (entry, value)
5338 hash entry;
5339 tree value;
5341 static attr attr_alloc_list = 0;
5342 static int attr_alloc_index = 0;
5343 attr obj;
5345 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5347 attr_alloc_index = 0;
5348 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5349 * ATTR_ALLOC_LIST_SIZE);
5351 obj = &attr_alloc_list[attr_alloc_index++];
5352 obj->next = entry->list;
5353 obj->value = value;
5355 entry->list = obj; /* append to front */
5358 static tree
5359 lookup_method (mchain, method)
5360 tree mchain;
5361 tree method;
5363 tree key;
5365 if (TREE_CODE (method) == IDENTIFIER_NODE)
5366 key = method;
5367 else
5368 key = METHOD_SEL_NAME (method);
5370 while (mchain)
5372 if (METHOD_SEL_NAME (mchain) == key)
5373 return mchain;
5374 mchain = TREE_CHAIN (mchain);
5376 return NULL_TREE;
5379 static tree
5380 lookup_instance_method_static (interface, ident)
5381 tree interface;
5382 tree ident;
5384 tree inter = interface;
5385 tree chain = CLASS_NST_METHODS (inter);
5386 tree meth = NULL_TREE;
5390 if ((meth = lookup_method (chain, ident)))
5391 return meth;
5393 if (CLASS_CATEGORY_LIST (inter))
5395 tree category = CLASS_CATEGORY_LIST (inter);
5396 chain = CLASS_NST_METHODS (category);
5400 if ((meth = lookup_method (chain, ident)))
5401 return meth;
5403 /* Check for instance methods in protocols in categories. */
5404 if (CLASS_PROTOCOL_LIST (category))
5406 if ((meth = (lookup_method_in_protocol_list
5407 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5408 return meth;
5411 if ((category = CLASS_CATEGORY_LIST (category)))
5412 chain = CLASS_NST_METHODS (category);
5414 while (category);
5417 if (CLASS_PROTOCOL_LIST (inter))
5419 if ((meth = (lookup_method_in_protocol_list
5420 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5421 return meth;
5424 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5425 chain = CLASS_NST_METHODS (inter);
5427 while (inter);
5429 return meth;
5432 static tree
5433 lookup_class_method_static (interface, ident)
5434 tree interface;
5435 tree ident;
5437 tree inter = interface;
5438 tree chain = CLASS_CLS_METHODS (inter);
5439 tree meth = NULL_TREE;
5440 tree root_inter = NULL_TREE;
5444 if ((meth = lookup_method (chain, ident)))
5445 return meth;
5447 if (CLASS_CATEGORY_LIST (inter))
5449 tree category = CLASS_CATEGORY_LIST (inter);
5450 chain = CLASS_CLS_METHODS (category);
5454 if ((meth = lookup_method (chain, ident)))
5455 return meth;
5457 /* Check for class methods in protocols in categories. */
5458 if (CLASS_PROTOCOL_LIST (category))
5460 if ((meth = (lookup_method_in_protocol_list
5461 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5462 return meth;
5465 if ((category = CLASS_CATEGORY_LIST (category)))
5466 chain = CLASS_CLS_METHODS (category);
5468 while (category);
5471 /* Check for class methods in protocols. */
5472 if (CLASS_PROTOCOL_LIST (inter))
5474 if ((meth = (lookup_method_in_protocol_list
5475 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5476 return meth;
5479 root_inter = inter;
5480 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5481 chain = CLASS_CLS_METHODS (inter);
5483 while (inter);
5485 /* If no class (factory) method was found, check if an _instance_
5486 method of the same name exists in the root class. This is what
5487 the Objective-C runtime will do. */
5488 return lookup_instance_method_static (root_inter, ident);
5491 tree
5492 add_class_method (class, method)
5493 tree class;
5494 tree method;
5496 tree mth;
5497 hash hsh;
5499 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5501 /* put method on list in reverse order */
5502 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5503 CLASS_CLS_METHODS (class) = method;
5505 else
5507 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5508 error ("duplicate definition of class method `%s'",
5509 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5510 else
5512 /* Check types; if different, complain. */
5513 if (!comp_proto_with_proto (method, mth))
5514 error ("duplicate declaration of class method `%s'",
5515 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5519 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5521 /* Install on a global chain. */
5522 hash_enter (cls_method_hash_list, method);
5524 else
5526 /* Check types; if different, add to a list. */
5527 if (!comp_proto_with_proto (method, hsh->key))
5528 hash_add_attr (hsh, method);
5530 return method;
5533 tree
5534 add_instance_method (class, method)
5535 tree class;
5536 tree method;
5538 tree mth;
5539 hash hsh;
5541 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5543 /* Put method on list in reverse order. */
5544 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5545 CLASS_NST_METHODS (class) = method;
5547 else
5549 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5550 error ("duplicate definition of instance method `%s'",
5551 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5552 else
5554 /* Check types; if different, complain. */
5555 if (!comp_proto_with_proto (method, mth))
5556 error ("duplicate declaration of instance method `%s'",
5557 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5561 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5563 /* Install on a global chain. */
5564 hash_enter (nst_method_hash_list, method);
5566 else
5568 /* Check types; if different, add to a list. */
5569 if (!comp_proto_with_proto (method, hsh->key))
5570 hash_add_attr (hsh, method);
5572 return method;
5575 static tree
5576 add_class (class)
5577 tree class;
5579 /* Put interfaces on list in reverse order. */
5580 TREE_CHAIN (class) = interface_chain;
5581 interface_chain = class;
5582 return interface_chain;
5585 static void
5586 add_category (class, category)
5587 tree class;
5588 tree category;
5590 /* Put categories on list in reverse order. */
5591 tree cat = CLASS_CATEGORY_LIST (class);
5593 while (cat)
5595 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5596 warning ("duplicate interface declaration for category `%s(%s)'",
5597 IDENTIFIER_POINTER (CLASS_NAME (class)),
5598 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5599 cat = CLASS_CATEGORY_LIST (cat);
5602 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5603 CLASS_CATEGORY_LIST (class) = category;
5606 /* Called after parsing each instance variable declaration. Necessary to
5607 preserve typedefs and implement public/private...
5609 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5611 tree
5612 add_instance_variable (class, public, declarator, declspecs, width)
5613 tree class;
5614 int public;
5615 tree declarator;
5616 tree declspecs;
5617 tree width;
5619 tree field_decl, raw_decl;
5621 raw_decl = build_tree_list (declspecs, declarator);
5623 if (CLASS_RAW_IVARS (class))
5624 chainon (CLASS_RAW_IVARS (class), raw_decl);
5625 else
5626 CLASS_RAW_IVARS (class) = raw_decl;
5628 field_decl = grokfield (input_filename, lineno,
5629 declarator, declspecs, width);
5631 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5632 switch (public)
5634 case 0:
5635 TREE_PUBLIC (field_decl) = 0;
5636 TREE_PRIVATE (field_decl) = 0;
5637 TREE_PROTECTED (field_decl) = 1;
5638 break;
5640 case 1:
5641 TREE_PUBLIC (field_decl) = 1;
5642 TREE_PRIVATE (field_decl) = 0;
5643 TREE_PROTECTED (field_decl) = 0;
5644 break;
5646 case 2:
5647 TREE_PUBLIC (field_decl) = 0;
5648 TREE_PRIVATE (field_decl) = 1;
5649 TREE_PROTECTED (field_decl) = 0;
5650 break;
5654 if (CLASS_IVARS (class))
5655 chainon (CLASS_IVARS (class), field_decl);
5656 else
5657 CLASS_IVARS (class) = field_decl;
5659 return class;
5662 tree
5663 is_ivar (decl_chain, ident)
5664 tree decl_chain;
5665 tree ident;
5667 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5668 if (DECL_NAME (decl_chain) == ident)
5669 return decl_chain;
5670 return NULL_TREE;
5673 /* True if the ivar is private and we are not in its implementation. */
5676 is_private (decl)
5677 tree decl;
5679 if (TREE_PRIVATE (decl)
5680 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5682 error ("instance variable `%s' is declared private",
5683 IDENTIFIER_POINTER (DECL_NAME (decl)));
5684 return 1;
5686 else
5687 return 0;
5690 /* We have an instance variable reference;, check to see if it is public. */
5693 is_public (expr, identifier)
5694 tree expr;
5695 tree identifier;
5697 tree basetype = TREE_TYPE (expr);
5698 enum tree_code code = TREE_CODE (basetype);
5699 tree decl;
5701 if (code == RECORD_TYPE)
5703 if (TREE_STATIC_TEMPLATE (basetype))
5705 if (!lookup_interface (TYPE_NAME (basetype)))
5707 error ("cannot find interface declaration for `%s'",
5708 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5709 return 0;
5712 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5714 if (TREE_PUBLIC (decl))
5715 return 1;
5717 /* Important difference between the Stepstone translator:
5718 all instance variables should be public within the context
5719 of the implementation. */
5720 if (objc_implementation_context
5721 && (((TREE_CODE (objc_implementation_context)
5722 == CLASS_IMPLEMENTATION_TYPE)
5723 || (TREE_CODE (objc_implementation_context)
5724 == CATEGORY_IMPLEMENTATION_TYPE))
5725 && (CLASS_NAME (objc_implementation_context)
5726 == TYPE_NAME (basetype))))
5727 return ! is_private (decl);
5729 error ("instance variable `%s' is declared %s",
5730 IDENTIFIER_POINTER (identifier),
5731 TREE_PRIVATE (decl) ? "private" : "protected");
5732 return 0;
5736 else if (objc_implementation_context && (basetype == objc_object_reference))
5738 TREE_TYPE (expr) = uprivate_record;
5739 warning ("static access to object of type `id'");
5743 return 1;
5746 /* Implement @defs (<classname>) within struct bodies. */
5748 tree
5749 get_class_ivars (interface)
5750 tree interface;
5752 /* Make sure we copy the leaf ivars in case @defs is used in a local
5753 context. Otherwise finish_struct will overwrite the layout info
5754 using temporary storage. */
5755 return build_ivar_chain (interface, 1);
5758 /* Make sure all entries in CHAIN are also in LIST. */
5760 static int
5761 check_methods (chain, list, mtype)
5762 tree chain;
5763 tree list;
5764 int mtype;
5766 int first = 1;
5768 while (chain)
5770 if (!lookup_method (list, chain))
5772 if (first)
5774 if (TREE_CODE (objc_implementation_context)
5775 == CLASS_IMPLEMENTATION_TYPE)
5776 warning ("incomplete implementation of class `%s'",
5777 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
5778 else if (TREE_CODE (objc_implementation_context)
5779 == CATEGORY_IMPLEMENTATION_TYPE)
5780 warning ("incomplete implementation of category `%s'",
5781 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
5782 first = 0;
5785 warning ("method definition for `%c%s' not found",
5786 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5789 chain = TREE_CHAIN (chain);
5792 return first;
5795 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5797 static int
5798 conforms_to_protocol (class, protocol)
5799 tree class;
5800 tree protocol;
5802 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
5804 tree p = CLASS_PROTOCOL_LIST (class);
5805 while (p && TREE_VALUE (p) != protocol)
5806 p = TREE_CHAIN (p);
5808 if (!p)
5810 tree super = (CLASS_SUPER_NAME (class)
5811 ? lookup_interface (CLASS_SUPER_NAME (class))
5812 : NULL_TREE);
5813 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5814 if (!tmp)
5815 return 0;
5819 return 1;
5822 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5823 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5825 static int
5826 check_methods_accessible (chain, context, mtype)
5827 tree chain;
5828 tree context;
5829 int mtype;
5831 int first = 1;
5832 tree list;
5833 tree base_context = context;
5835 while (chain)
5837 context = base_context;
5838 while (context)
5840 if (mtype == '+')
5841 list = CLASS_CLS_METHODS (context);
5842 else
5843 list = CLASS_NST_METHODS (context);
5845 if (lookup_method (list, chain))
5846 break;
5848 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5849 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5850 context = (CLASS_SUPER_NAME (context)
5851 ? lookup_interface (CLASS_SUPER_NAME (context))
5852 : NULL_TREE);
5854 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5855 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5856 context = (CLASS_NAME (context)
5857 ? lookup_interface (CLASS_NAME (context))
5858 : NULL_TREE);
5859 else
5860 abort ();
5863 if (context == NULL_TREE)
5865 if (first)
5867 if (TREE_CODE (objc_implementation_context)
5868 == CLASS_IMPLEMENTATION_TYPE)
5869 warning ("incomplete implementation of class `%s'",
5870 IDENTIFIER_POINTER
5871 (CLASS_NAME (objc_implementation_context)));
5872 else if (TREE_CODE (objc_implementation_context)
5873 == CATEGORY_IMPLEMENTATION_TYPE)
5874 warning ("incomplete implementation of category `%s'",
5875 IDENTIFIER_POINTER
5876 (CLASS_SUPER_NAME (objc_implementation_context)));
5877 first = 0;
5879 warning ("method definition for `%c%s' not found",
5880 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5883 chain = TREE_CHAIN (chain); /* next method... */
5885 return first;
5888 /* Check whether the current interface (accessible via
5889 'objc_implementation_context') actually implements protocol P, along
5890 with any protocols that P inherits. */
5892 static void
5893 check_protocol (p, type, name)
5894 tree p;
5895 const char *type;
5896 const char *name;
5898 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
5900 int f1, f2;
5902 /* Ensure that all protocols have bodies! */
5903 if (flag_warn_protocol)
5905 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
5906 CLASS_CLS_METHODS (objc_implementation_context),
5907 '+');
5908 f2 = check_methods (PROTOCOL_NST_METHODS (p),
5909 CLASS_NST_METHODS (objc_implementation_context),
5910 '-');
5912 else
5914 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
5915 objc_implementation_context,
5916 '+');
5917 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
5918 objc_implementation_context,
5919 '-');
5922 if (!f1 || !f2)
5923 warning ("%s `%s' does not fully implement the `%s' protocol",
5924 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
5927 /* Check protocols recursively. */
5928 if (PROTOCOL_LIST (p))
5930 tree subs = PROTOCOL_LIST (p);
5931 tree super_class =
5932 lookup_interface (CLASS_SUPER_NAME (implementation_template));
5934 while (subs)
5936 tree sub = TREE_VALUE (subs);
5938 /* If the superclass does not conform to the protocols
5939 inherited by P, then we must! */
5940 if (!super_class || !conforms_to_protocol (super_class, sub))
5941 check_protocol (sub, type, name);
5942 subs = TREE_CHAIN (subs);
5947 /* Check whether the current interface (accessible via
5948 'objc_implementation_context') actually implements the protocols listed
5949 in PROTO_LIST. */
5951 static void
5952 check_protocols (proto_list, type, name)
5953 tree proto_list;
5954 const char *type;
5955 const char *name;
5957 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
5959 tree p = TREE_VALUE (proto_list);
5961 check_protocol (p, type, name);
5965 /* Make sure that the class CLASS_NAME is defined
5966 CODE says which kind of thing CLASS_NAME ought to be.
5967 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5968 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5970 tree
5971 start_class (code, class_name, super_name, protocol_list)
5972 enum tree_code code;
5973 tree class_name;
5974 tree super_name;
5975 tree protocol_list;
5977 tree class, decl;
5979 if (objc_implementation_context)
5981 warning ("`@end' missing in implementation context");
5982 finish_class (objc_implementation_context);
5983 objc_ivar_chain = NULL_TREE;
5984 objc_implementation_context = NULL_TREE;
5987 class = make_node (code);
5988 TYPE_BINFO (class) = make_tree_vec (5);
5990 CLASS_NAME (class) = class_name;
5991 CLASS_SUPER_NAME (class) = super_name;
5992 CLASS_CLS_METHODS (class) = NULL_TREE;
5994 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
5996 error ("`%s' redeclared as different kind of symbol",
5997 IDENTIFIER_POINTER (class_name));
5998 error_with_decl (decl, "previous declaration of `%s'");
6001 if (code == CLASS_IMPLEMENTATION_TYPE)
6004 tree chain;
6006 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6007 if (TREE_VALUE (chain) == class_name)
6009 error ("reimplementation of class `%s'",
6010 IDENTIFIER_POINTER (class_name));
6011 return error_mark_node;
6013 implemented_classes = tree_cons (NULL_TREE, class_name,
6014 implemented_classes);
6017 /* Pre-build the following entities - for speed/convenience. */
6018 if (!self_id)
6019 self_id = get_identifier ("self");
6020 if (!ucmd_id)
6021 ucmd_id = get_identifier ("_cmd");
6022 if (!unused_list)
6023 unused_list
6024 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6025 if (!objc_super_template)
6026 objc_super_template = build_super_template ();
6028 /* Reset for multiple classes per file. */
6029 method_slot = 0;
6031 objc_implementation_context = class;
6033 /* Lookup the interface for this implementation. */
6035 if (!(implementation_template = lookup_interface (class_name)))
6037 warning ("cannot find interface declaration for `%s'",
6038 IDENTIFIER_POINTER (class_name));
6039 add_class (implementation_template = objc_implementation_context);
6042 /* If a super class has been specified in the implementation,
6043 insure it conforms to the one specified in the interface. */
6045 if (super_name
6046 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6048 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6049 const char *const name =
6050 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6051 error ("conflicting super class name `%s'",
6052 IDENTIFIER_POINTER (super_name));
6053 error ("previous declaration of `%s'", name);
6056 else if (! super_name)
6058 CLASS_SUPER_NAME (objc_implementation_context)
6059 = CLASS_SUPER_NAME (implementation_template);
6063 else if (code == CLASS_INTERFACE_TYPE)
6065 if (lookup_interface (class_name))
6066 warning ("duplicate interface declaration for class `%s'",
6067 IDENTIFIER_POINTER (class_name));
6068 else
6069 add_class (class);
6071 if (protocol_list)
6072 CLASS_PROTOCOL_LIST (class)
6073 = lookup_and_install_protocols (protocol_list);
6076 else if (code == CATEGORY_INTERFACE_TYPE)
6078 tree class_category_is_assoc_with;
6080 /* For a category, class_name is really the name of the class that
6081 the following set of methods will be associated with. We must
6082 find the interface so that can derive the objects template. */
6084 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6086 error ("cannot find interface declaration for `%s'",
6087 IDENTIFIER_POINTER (class_name));
6088 exit (FATAL_EXIT_CODE);
6090 else
6091 add_category (class_category_is_assoc_with, class);
6093 if (protocol_list)
6094 CLASS_PROTOCOL_LIST (class)
6095 = lookup_and_install_protocols (protocol_list);
6098 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6100 /* Pre-build the following entities for speed/convenience. */
6101 if (!self_id)
6102 self_id = get_identifier ("self");
6103 if (!ucmd_id)
6104 ucmd_id = get_identifier ("_cmd");
6105 if (!unused_list)
6106 unused_list
6107 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6108 if (!objc_super_template)
6109 objc_super_template = build_super_template ();
6111 /* Reset for multiple classes per file. */
6112 method_slot = 0;
6114 objc_implementation_context = class;
6116 /* For a category, class_name is really the name of the class that
6117 the following set of methods will be associated with. We must
6118 find the interface so that can derive the objects template. */
6120 if (!(implementation_template = lookup_interface (class_name)))
6122 error ("cannot find interface declaration for `%s'",
6123 IDENTIFIER_POINTER (class_name));
6124 exit (FATAL_EXIT_CODE);
6127 return class;
6130 tree
6131 continue_class (class)
6132 tree class;
6134 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6135 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6137 struct imp_entry *imp_entry;
6138 tree ivar_context;
6140 /* Check consistency of the instance variables. */
6142 if (CLASS_IVARS (class))
6143 check_ivars (implementation_template, class);
6145 /* code generation */
6147 ivar_context = build_private_template (implementation_template);
6149 if (!objc_class_template)
6150 build_class_template ();
6152 imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry));
6154 imp_entry->next = imp_list;
6155 imp_entry->imp_context = class;
6156 imp_entry->imp_template = implementation_template;
6158 synth_forward_declarations ();
6159 imp_entry->class_decl = UOBJC_CLASS_decl;
6160 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6162 /* Append to front and increment count. */
6163 imp_list = imp_entry;
6164 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6165 imp_count++;
6166 else
6167 cat_count++;
6169 return ivar_context;
6172 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6174 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6176 if (!TYPE_FIELDS (record))
6178 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6179 CLASS_STATIC_TEMPLATE (class) = record;
6181 /* Mark this record as a class template for static typing. */
6182 TREE_STATIC_TEMPLATE (record) = 1;
6185 return NULL_TREE;
6188 else
6189 return error_mark_node;
6192 /* This is called once we see the "@end" in an interface/implementation. */
6194 void
6195 finish_class (class)
6196 tree class;
6198 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6200 /* All code generation is done in finish_objc. */
6202 if (implementation_template != objc_implementation_context)
6204 /* Ensure that all method listed in the interface contain bodies. */
6205 check_methods (CLASS_CLS_METHODS (implementation_template),
6206 CLASS_CLS_METHODS (objc_implementation_context), '+');
6207 check_methods (CLASS_NST_METHODS (implementation_template),
6208 CLASS_NST_METHODS (objc_implementation_context), '-');
6210 if (CLASS_PROTOCOL_LIST (implementation_template))
6211 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6212 "class",
6213 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6217 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6219 tree category = CLASS_CATEGORY_LIST (implementation_template);
6221 /* Find the category interface from the class it is associated with. */
6222 while (category)
6224 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6225 break;
6226 category = CLASS_CATEGORY_LIST (category);
6229 if (category)
6231 /* Ensure all method listed in the interface contain bodies. */
6232 check_methods (CLASS_CLS_METHODS (category),
6233 CLASS_CLS_METHODS (objc_implementation_context), '+');
6234 check_methods (CLASS_NST_METHODS (category),
6235 CLASS_NST_METHODS (objc_implementation_context), '-');
6237 if (CLASS_PROTOCOL_LIST (category))
6238 check_protocols (CLASS_PROTOCOL_LIST (category),
6239 "category",
6240 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6244 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6246 tree decl_specs;
6247 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6248 char *string = (char *) alloca (strlen (class_name) + 3);
6250 /* extern struct objc_object *_<my_name>; */
6252 sprintf (string, "_%s", class_name);
6254 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6255 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6256 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6257 decl_specs);
6261 static tree
6262 add_protocol (protocol)
6263 tree protocol;
6265 /* Put protocol on list in reverse order. */
6266 TREE_CHAIN (protocol) = protocol_chain;
6267 protocol_chain = protocol;
6268 return protocol_chain;
6271 static tree
6272 lookup_protocol (ident)
6273 tree ident;
6275 tree chain;
6277 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6278 if (ident == PROTOCOL_NAME (chain))
6279 return chain;
6281 return NULL_TREE;
6284 /* This function forward declares the protocols named by NAMES. If
6285 they are already declared or defined, the function has no effect. */
6287 void
6288 objc_declare_protocols (names)
6289 tree names;
6291 tree list;
6293 for (list = names; list; list = TREE_CHAIN (list))
6295 tree name = TREE_VALUE (list);
6297 if (lookup_protocol (name) == NULL_TREE)
6299 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6301 TYPE_BINFO (protocol) = make_tree_vec (2);
6302 PROTOCOL_NAME (protocol) = name;
6303 PROTOCOL_LIST (protocol) = NULL_TREE;
6304 add_protocol (protocol);
6305 PROTOCOL_DEFINED (protocol) = 0;
6306 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6311 tree
6312 start_protocol (code, name, list)
6313 enum tree_code code;
6314 tree name;
6315 tree list;
6317 tree protocol;
6319 /* This is as good a place as any. Need to invoke
6320 push_tag_toplevel. */
6321 if (!objc_protocol_template)
6322 objc_protocol_template = build_protocol_template ();
6324 protocol = lookup_protocol (name);
6326 if (!protocol)
6328 protocol = make_node (code);
6329 TYPE_BINFO (protocol) = make_tree_vec (2);
6331 PROTOCOL_NAME (protocol) = name;
6332 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6333 add_protocol (protocol);
6334 PROTOCOL_DEFINED (protocol) = 1;
6335 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6337 check_protocol_recursively (protocol, list);
6339 else if (! PROTOCOL_DEFINED (protocol))
6341 PROTOCOL_DEFINED (protocol) = 1;
6342 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6344 check_protocol_recursively (protocol, list);
6346 else
6348 warning ("duplicate declaration for protocol `%s'",
6349 IDENTIFIER_POINTER (name));
6351 return protocol;
6354 void
6355 finish_protocol (protocol)
6356 tree protocol ATTRIBUTE_UNUSED;
6361 /* "Encode" a data type into a string, which grows in util_obstack.
6362 ??? What is the FORMAT? Someone please document this! */
6364 static void
6365 encode_type_qualifiers (declspecs)
6366 tree declspecs;
6368 tree spec;
6370 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6372 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6373 obstack_1grow (&util_obstack, 'r');
6374 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6375 obstack_1grow (&util_obstack, 'n');
6376 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6377 obstack_1grow (&util_obstack, 'N');
6378 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6379 obstack_1grow (&util_obstack, 'o');
6380 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6381 obstack_1grow (&util_obstack, 'O');
6382 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6383 obstack_1grow (&util_obstack, 'R');
6384 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6385 obstack_1grow (&util_obstack, 'V');
6389 /* Encode a pointer type. */
6391 static void
6392 encode_pointer (type, curtype, format)
6393 tree type;
6394 int curtype;
6395 int format;
6397 tree pointer_to = TREE_TYPE (type);
6399 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6401 if (TYPE_NAME (pointer_to)
6402 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6404 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6406 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6408 obstack_1grow (&util_obstack, '@');
6409 return;
6411 else if (TREE_STATIC_TEMPLATE (pointer_to))
6413 if (generating_instance_variables)
6415 obstack_1grow (&util_obstack, '@');
6416 obstack_1grow (&util_obstack, '"');
6417 obstack_grow (&util_obstack, name, strlen (name));
6418 obstack_1grow (&util_obstack, '"');
6419 return;
6421 else
6423 obstack_1grow (&util_obstack, '@');
6424 return;
6427 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6429 obstack_1grow (&util_obstack, '#');
6430 return;
6432 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6434 obstack_1grow (&util_obstack, ':');
6435 return;
6439 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6440 && TYPE_MODE (pointer_to) == QImode)
6442 obstack_1grow (&util_obstack, '*');
6443 return;
6446 /* We have a type that does not get special treatment. */
6448 /* NeXT extension */
6449 obstack_1grow (&util_obstack, '^');
6450 encode_type (pointer_to, curtype, format);
6453 static void
6454 encode_array (type, curtype, format)
6455 tree type;
6456 int curtype;
6457 int format;
6459 tree an_int_cst = TYPE_SIZE (type);
6460 tree array_of = TREE_TYPE (type);
6461 char buffer[40];
6463 /* An incomplete array is treated like a pointer. */
6464 if (an_int_cst == NULL)
6466 encode_pointer (type, curtype, format);
6467 return;
6470 sprintf (buffer, "[%ld",
6471 (long) (TREE_INT_CST_LOW (an_int_cst)
6472 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6474 obstack_grow (&util_obstack, buffer, strlen (buffer));
6475 encode_type (array_of, curtype, format);
6476 obstack_1grow (&util_obstack, ']');
6477 return;
6480 static void
6481 encode_aggregate_within (type, curtype, format, left, right)
6482 tree type;
6483 int curtype;
6484 int format;
6485 int left;
6486 int right;
6488 /* The RECORD_TYPE may in fact be a typedef! For purposes
6489 of encoding, we need the real underlying enchilada. */
6490 if (TYPE_MAIN_VARIANT (type))
6491 type = TYPE_MAIN_VARIANT (type);
6493 if (obstack_object_size (&util_obstack) > 0
6494 && *(obstack_next_free (&util_obstack) - 1) == '^')
6496 tree name = TYPE_NAME (type);
6498 /* we have a reference; this is a NeXT extension. */
6500 if (obstack_object_size (&util_obstack) - curtype == 1
6501 && format == OBJC_ENCODE_INLINE_DEFS)
6503 /* Output format of struct for first level only. */
6504 tree fields = TYPE_FIELDS (type);
6506 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6508 obstack_1grow (&util_obstack, left);
6509 obstack_grow (&util_obstack,
6510 IDENTIFIER_POINTER (name),
6511 strlen (IDENTIFIER_POINTER (name)));
6512 obstack_1grow (&util_obstack, '=');
6514 else
6516 obstack_1grow (&util_obstack, left);
6517 obstack_grow (&util_obstack, "?=", 2);
6520 for ( ; fields; fields = TREE_CHAIN (fields))
6521 encode_field_decl (fields, curtype, format);
6523 obstack_1grow (&util_obstack, right);
6526 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6528 obstack_1grow (&util_obstack, left);
6529 obstack_grow (&util_obstack,
6530 IDENTIFIER_POINTER (name),
6531 strlen (IDENTIFIER_POINTER (name)));
6532 obstack_1grow (&util_obstack, right);
6535 else
6537 /* We have an untagged structure or a typedef. */
6538 obstack_1grow (&util_obstack, left);
6539 obstack_1grow (&util_obstack, '?');
6540 obstack_1grow (&util_obstack, right);
6544 else
6546 tree name = TYPE_NAME (type);
6547 tree fields = TYPE_FIELDS (type);
6549 if (format == OBJC_ENCODE_INLINE_DEFS
6550 || generating_instance_variables)
6552 obstack_1grow (&util_obstack, left);
6553 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6554 obstack_grow (&util_obstack,
6555 IDENTIFIER_POINTER (name),
6556 strlen (IDENTIFIER_POINTER (name)));
6557 else
6558 obstack_1grow (&util_obstack, '?');
6560 obstack_1grow (&util_obstack, '=');
6562 for (; fields; fields = TREE_CHAIN (fields))
6564 if (generating_instance_variables)
6566 tree fname = DECL_NAME (fields);
6568 obstack_1grow (&util_obstack, '"');
6569 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6571 obstack_grow (&util_obstack,
6572 IDENTIFIER_POINTER (fname),
6573 strlen (IDENTIFIER_POINTER (fname)));
6576 obstack_1grow (&util_obstack, '"');
6579 encode_field_decl (fields, curtype, format);
6582 obstack_1grow (&util_obstack, right);
6585 else
6587 obstack_1grow (&util_obstack, left);
6588 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6589 obstack_grow (&util_obstack,
6590 IDENTIFIER_POINTER (name),
6591 strlen (IDENTIFIER_POINTER (name)));
6592 else
6593 /* We have an untagged structure or a typedef. */
6594 obstack_1grow (&util_obstack, '?');
6596 obstack_1grow (&util_obstack, right);
6601 static void
6602 encode_aggregate (type, curtype, format)
6603 tree type;
6604 int curtype;
6605 int format;
6607 enum tree_code code = TREE_CODE (type);
6609 switch (code)
6611 case RECORD_TYPE:
6613 encode_aggregate_within(type, curtype, format, '{', '}');
6614 break;
6616 case UNION_TYPE:
6618 encode_aggregate_within(type, curtype, format, '(', ')');
6619 break;
6622 case ENUMERAL_TYPE:
6623 obstack_1grow (&util_obstack, 'i');
6624 break;
6626 default:
6627 break;
6631 /* Support bitfields. The current version of Objective-C does not support
6632 them. The string will consist of one or more "b:n"'s where n is an
6633 integer describing the width of the bitfield. Currently, classes in
6634 the kit implement a method "-(char *)describeBitfieldStruct:" that
6635 simulates this. If they do not implement this method, the archiver
6636 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6637 according to the GNU compiler. After looking at the "kit", it appears
6638 that all classes currently rely on this default behavior, rather than
6639 hand generating this string (which is tedious). */
6641 static void
6642 encode_bitfield (width)
6643 int width;
6645 char buffer[40];
6646 sprintf (buffer, "b%d", width);
6647 obstack_grow (&util_obstack, buffer, strlen (buffer));
6650 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6652 static void
6653 encode_type (type, curtype, format)
6654 tree type;
6655 int curtype;
6656 int format;
6658 enum tree_code code = TREE_CODE (type);
6660 if (code == INTEGER_TYPE)
6662 if (integer_zerop (TYPE_MIN_VALUE (type)))
6664 /* Unsigned integer types. */
6666 if (TYPE_MODE (type) == QImode)
6667 obstack_1grow (&util_obstack, 'C');
6668 else if (TYPE_MODE (type) == HImode)
6669 obstack_1grow (&util_obstack, 'S');
6670 else if (TYPE_MODE (type) == SImode)
6672 if (type == long_unsigned_type_node)
6673 obstack_1grow (&util_obstack, 'L');
6674 else
6675 obstack_1grow (&util_obstack, 'I');
6677 else if (TYPE_MODE (type) == DImode)
6678 obstack_1grow (&util_obstack, 'Q');
6681 else
6682 /* Signed integer types. */
6684 if (TYPE_MODE (type) == QImode)
6685 obstack_1grow (&util_obstack, 'c');
6686 else if (TYPE_MODE (type) == HImode)
6687 obstack_1grow (&util_obstack, 's');
6688 else if (TYPE_MODE (type) == SImode)
6690 if (type == long_integer_type_node)
6691 obstack_1grow (&util_obstack, 'l');
6692 else
6693 obstack_1grow (&util_obstack, 'i');
6696 else if (TYPE_MODE (type) == DImode)
6697 obstack_1grow (&util_obstack, 'q');
6701 else if (code == REAL_TYPE)
6703 /* Floating point types. */
6705 if (TYPE_MODE (type) == SFmode)
6706 obstack_1grow (&util_obstack, 'f');
6707 else if (TYPE_MODE (type) == DFmode
6708 || TYPE_MODE (type) == TFmode)
6709 obstack_1grow (&util_obstack, 'd');
6712 else if (code == VOID_TYPE)
6713 obstack_1grow (&util_obstack, 'v');
6715 else if (code == ARRAY_TYPE)
6716 encode_array (type, curtype, format);
6718 else if (code == POINTER_TYPE)
6719 encode_pointer (type, curtype, format);
6721 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6722 encode_aggregate (type, curtype, format);
6724 else if (code == FUNCTION_TYPE) /* '?' */
6725 obstack_1grow (&util_obstack, '?');
6728 static void
6729 encode_complete_bitfield (int position, tree type, int size)
6731 enum tree_code code = TREE_CODE (type);
6732 char buffer[40];
6733 char charType = '?';
6735 if (code == INTEGER_TYPE)
6737 if (integer_zerop (TYPE_MIN_VALUE (type)))
6739 /* Unsigned integer types. */
6741 if (TYPE_MODE (type) == QImode)
6742 charType = 'C';
6743 else if (TYPE_MODE (type) == HImode)
6744 charType = 'S';
6745 else if (TYPE_MODE (type) == SImode)
6747 if (type == long_unsigned_type_node)
6748 charType = 'L';
6749 else
6750 charType = 'I';
6752 else if (TYPE_MODE (type) == DImode)
6753 charType = 'Q';
6756 else
6757 /* Signed integer types. */
6759 if (TYPE_MODE (type) == QImode)
6760 charType = 'c';
6761 else if (TYPE_MODE (type) == HImode)
6762 charType = 's';
6763 else if (TYPE_MODE (type) == SImode)
6765 if (type == long_integer_type_node)
6766 charType = 'l';
6767 else
6768 charType = 'i';
6771 else if (TYPE_MODE (type) == DImode)
6772 charType = 'q';
6775 else if (code == ENUMERAL_TYPE)
6776 charType = 'i';
6777 else
6778 abort ();
6780 sprintf (buffer, "b%d%c%d", position, charType, size);
6781 obstack_grow (&util_obstack, buffer, strlen (buffer));
6784 static void
6785 encode_field_decl (field_decl, curtype, format)
6786 tree field_decl;
6787 int curtype;
6788 int format;
6790 tree type;
6792 type = TREE_TYPE (field_decl);
6794 /* If this field is obviously a bitfield, or is a bitfield that has been
6795 clobbered to look like a ordinary integer mode, go ahead and generate
6796 the bitfield typing information. */
6797 if (flag_next_runtime)
6799 if (DECL_BIT_FIELD (field_decl))
6800 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6801 else
6802 encode_type (TREE_TYPE (field_decl), curtype, format);
6804 else
6806 if (DECL_BIT_FIELD (field_decl))
6807 encode_complete_bitfield (int_bit_position (field_decl),
6808 DECL_BIT_FIELD_TYPE (field_decl),
6809 tree_low_cst (DECL_SIZE (field_decl), 1));
6810 else
6811 encode_type (TREE_TYPE (field_decl), curtype, format);
6815 static tree
6816 expr_last (complex_expr)
6817 tree complex_expr;
6819 tree next;
6821 if (complex_expr)
6822 while ((next = TREE_OPERAND (complex_expr, 0)))
6823 complex_expr = next;
6825 return complex_expr;
6828 /* Transform a method definition into a function definition as follows:
6829 - synthesize the first two arguments, "self" and "_cmd". */
6831 void
6832 start_method_def (method)
6833 tree method;
6835 tree decl_specs;
6837 /* Required to implement _msgSuper. */
6838 objc_method_context = method;
6839 UOBJC_SUPER_decl = NULL_TREE;
6841 /* Must be called BEFORE start_function. */
6842 pushlevel (0);
6844 /* Generate prototype declarations for arguments..."new-style". */
6846 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
6847 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6848 else
6849 /* Really a `struct objc_class *'. However, we allow people to
6850 assign to self, which changes its type midstream. */
6851 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6853 push_parm_decl (build_tree_list
6854 (build_tree_list (decl_specs,
6855 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6856 unused_list));
6858 decl_specs = build_tree_list (NULL_TREE,
6859 xref_tag (RECORD_TYPE,
6860 get_identifier (TAG_SELECTOR)));
6861 push_parm_decl (build_tree_list
6862 (build_tree_list (decl_specs,
6863 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6864 unused_list));
6866 /* Generate argument declarations if a keyword_decl. */
6867 if (METHOD_SEL_ARGS (method))
6869 tree arglist = METHOD_SEL_ARGS (method);
6872 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6873 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6875 if (arg_decl)
6877 tree last_expr = expr_last (arg_decl);
6879 /* Unite the abstract decl with its name. */
6880 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6881 push_parm_decl (build_tree_list
6882 (build_tree_list (arg_spec, arg_decl),
6883 NULL_TREE));
6885 /* Unhook: restore the abstract declarator. */
6886 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6889 else
6890 push_parm_decl (build_tree_list
6891 (build_tree_list (arg_spec,
6892 KEYWORD_ARG_NAME (arglist)),
6893 NULL_TREE));
6895 arglist = TREE_CHAIN (arglist);
6897 while (arglist);
6900 if (METHOD_ADD_ARGS (method) != NULL_TREE
6901 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
6903 /* We have a variable length selector - in "prototype" format. */
6904 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6905 while (akey)
6907 /* This must be done prior to calling pushdecl. pushdecl is
6908 going to change our chain on us. */
6909 tree nextkey = TREE_CHAIN (akey);
6910 pushdecl (akey);
6911 akey = nextkey;
6916 static void
6917 warn_with_method (message, mtype, method)
6918 const char *message;
6919 int mtype;
6920 tree method;
6922 if (count_error (1) == 0)
6923 return;
6925 report_error_function (DECL_SOURCE_FILE (method));
6927 /* Add a readable method name to the warning. */
6928 warning_with_file_and_line (DECL_SOURCE_FILE (method),
6929 DECL_SOURCE_LINE (method),
6930 "%s `%c%s'",
6931 message, mtype,
6932 gen_method_decl (method, errbuf));
6935 /* Return 1 if METHOD is consistent with PROTO. */
6937 static int
6938 comp_method_with_proto (method, proto)
6939 tree method, proto;
6941 /* Create a function template node at most once. */
6942 if (!function1_template)
6943 function1_template = make_node (FUNCTION_TYPE);
6945 /* Install argument types - normally set by build_function_type. */
6946 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
6948 /* install return type */
6949 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
6951 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
6954 /* Return 1 if PROTO1 is consistent with PROTO2. */
6956 static int
6957 comp_proto_with_proto (proto0, proto1)
6958 tree proto0, proto1;
6960 /* Create a couple of function_template nodes at most once. */
6961 if (!function1_template)
6962 function1_template = make_node (FUNCTION_TYPE);
6963 if (!function2_template)
6964 function2_template = make_node (FUNCTION_TYPE);
6966 /* Install argument types; normally set by build_function_type. */
6967 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
6968 TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
6970 /* Install return type. */
6971 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
6972 TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
6974 return comptypes (function1_template, function2_template);
6977 /* - Generate an identifier for the function. the format is "_n_cls",
6978 where 1 <= n <= nMethods, and cls is the name the implementation we
6979 are processing.
6980 - Install the return type from the method declaration.
6981 - If we have a prototype, check for type consistency. */
6983 static void
6984 really_start_method (method, parmlist)
6985 tree method, parmlist;
6987 tree sc_spec, ret_spec, ret_decl, decl_specs;
6988 tree method_decl, method_id;
6989 const char *sel_name, *class_name, *cat_name;
6990 char *buf;
6992 /* Synth the storage class & assemble the return type. */
6993 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
6994 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
6995 decl_specs = chainon (sc_spec, ret_spec);
6997 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
6998 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6999 cat_name = ((TREE_CODE (objc_implementation_context)
7000 == CLASS_IMPLEMENTATION_TYPE)
7001 ? NULL
7002 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7003 method_slot++;
7005 /* Make sure this is big enough for any plausible method label. */
7006 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7007 + (cat_name ? strlen (cat_name) : 0));
7009 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7010 class_name, cat_name, sel_name, method_slot);
7012 method_id = get_identifier (buf);
7014 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7016 /* Check the declarator portion of the return type for the method. */
7017 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7019 /* Unite the complex decl (specified in the abstract decl) with the
7020 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7021 tree save_expr = expr_last (ret_decl);
7023 TREE_OPERAND (save_expr, 0) = method_decl;
7024 method_decl = ret_decl;
7026 /* Fool the parser into thinking it is starting a function. */
7027 start_function (decl_specs, method_decl, NULL_TREE);
7029 /* Unhook: this has the effect of restoring the abstract declarator. */
7030 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7033 else
7035 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7037 /* Fool the parser into thinking it is starting a function. */
7038 start_function (decl_specs, method_decl, NULL_TREE);
7040 /* Unhook: this has the effect of restoring the abstract declarator. */
7041 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7044 METHOD_DEFINITION (method) = current_function_decl;
7046 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7048 if (implementation_template != objc_implementation_context)
7050 tree proto;
7052 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7053 proto = lookup_instance_method_static (implementation_template,
7054 METHOD_SEL_NAME (method));
7055 else
7056 proto = lookup_class_method_static (implementation_template,
7057 METHOD_SEL_NAME (method));
7059 if (proto && ! comp_method_with_proto (method, proto))
7061 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7063 warn_with_method ("conflicting types for", type, method);
7064 warn_with_method ("previous declaration of", type, proto);
7069 /* The following routine is always called...this "architecture" is to
7070 accommodate "old-style" variable length selectors.
7072 - a:a b:b // prototype ; id c; id d; // old-style. */
7074 void
7075 continue_method_def ()
7077 tree parmlist;
7079 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7080 /* We have a `, ...' immediately following the selector. */
7081 parmlist = get_parm_info (0);
7082 else
7083 parmlist = get_parm_info (1); /* place a `void_at_end' */
7085 /* Set self_decl from the first argument...this global is used by
7086 build_ivar_reference calling build_indirect_ref. */
7087 self_decl = TREE_PURPOSE (parmlist);
7089 poplevel (0, 0, 0);
7090 really_start_method (objc_method_context, parmlist);
7091 store_parm_decls ();
7094 /* Called by the parser, from the `pushlevel' production. */
7096 void
7097 add_objc_decls ()
7099 if (!UOBJC_SUPER_decl)
7101 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7102 build_tree_list (NULL_TREE,
7103 objc_super_template),
7104 0, NULL_TREE);
7106 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7108 /* This prevents `unused variable' warnings when compiling with -Wall. */
7109 TREE_USED (UOBJC_SUPER_decl) = 1;
7110 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7114 /* _n_Method (id self, SEL sel, ...)
7116 struct objc_super _S;
7117 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7118 } */
7120 tree
7121 get_super_receiver ()
7123 if (objc_method_context)
7125 tree super_expr, super_expr_list;
7127 /* Set receiver to self. */
7128 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7129 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7130 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7132 /* Set class to begin searching. */
7133 super_expr = build_component_ref (UOBJC_SUPER_decl,
7134 get_identifier ("class"));
7136 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7138 /* [_cls, __cls]Super are "pre-built" in
7139 synth_forward_declarations. */
7141 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7142 ((TREE_CODE (objc_method_context)
7143 == INSTANCE_METHOD_DECL)
7144 ? ucls_super_ref
7145 : uucls_super_ref));
7148 else
7149 /* We have a category. */
7151 tree super_name = CLASS_SUPER_NAME (implementation_template);
7152 tree super_class;
7154 /* Barf if super used in a category of Object. */
7155 if (!super_name)
7157 error ("no super class declared in interface for `%s'",
7158 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7159 return error_mark_node;
7162 if (flag_next_runtime)
7164 super_class = get_class_reference (super_name);
7165 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7166 super_class
7167 = build_component_ref (build_indirect_ref (super_class, "->"),
7168 get_identifier ("isa"));
7170 else
7172 add_class_reference (super_name);
7173 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7174 ? objc_get_class_decl : objc_get_meta_class_decl);
7175 assemble_external (super_class);
7176 super_class
7177 = build_function_call
7178 (super_class,
7179 build_tree_list
7180 (NULL_TREE,
7181 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7182 IDENTIFIER_POINTER (super_name))));
7185 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7186 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7189 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7191 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7192 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7194 return build_compound_expr (super_expr_list);
7196 else
7198 error ("[super ...] must appear in a method context");
7199 return error_mark_node;
7203 static tree
7204 encode_method_def (func_decl)
7205 tree func_decl;
7207 tree parms;
7208 int stack_size;
7209 HOST_WIDE_INT max_parm_end = 0;
7210 char buffer[40];
7211 tree result;
7213 /* Return type. */
7214 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7215 obstack_object_size (&util_obstack),
7216 OBJC_ENCODE_INLINE_DEFS);
7218 /* Stack size. */
7219 for (parms = DECL_ARGUMENTS (func_decl); parms;
7220 parms = TREE_CHAIN (parms))
7222 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7223 + int_size_in_bytes (TREE_TYPE (parms)));
7225 if (! offset_is_register && parm_end > max_parm_end)
7226 max_parm_end = parm_end;
7229 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7231 sprintf (buffer, "%d", stack_size);
7232 obstack_grow (&util_obstack, buffer, strlen (buffer));
7234 /* Argument types. */
7235 for (parms = DECL_ARGUMENTS (func_decl); parms;
7236 parms = TREE_CHAIN (parms))
7238 /* Type. */
7239 encode_type (TREE_TYPE (parms),
7240 obstack_object_size (&util_obstack),
7241 OBJC_ENCODE_INLINE_DEFS);
7243 /* Compute offset. */
7244 sprintf (buffer, "%d", forwarding_offset (parms));
7246 /* Indicate register. */
7247 if (offset_is_register)
7248 obstack_1grow (&util_obstack, '+');
7250 obstack_grow (&util_obstack, buffer, strlen (buffer));
7253 /* Null terminate string. */
7254 obstack_1grow (&util_obstack, 0);
7255 result = get_identifier (obstack_finish (&util_obstack));
7256 obstack_free (&util_obstack, util_firstobj);
7257 return result;
7260 static void
7261 objc_expand_function_end ()
7263 METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
7266 void
7267 finish_method_def ()
7269 lang_expand_function_end = objc_expand_function_end;
7270 finish_function (0, 1);
7271 lang_expand_function_end = NULL;
7273 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7274 since the optimizer may find "may be used before set" errors. */
7275 objc_method_context = NULL_TREE;
7278 #if 0
7280 lang_report_error_function (decl)
7281 tree decl;
7283 if (objc_method_context)
7285 fprintf (stderr, "In method `%s'\n",
7286 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7287 return 1;
7290 else
7291 return 0;
7293 #endif
7295 static int
7296 is_complex_decl (type)
7297 tree type;
7299 return (TREE_CODE (type) == ARRAY_TYPE
7300 || TREE_CODE (type) == FUNCTION_TYPE
7301 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7305 /* Code to convert a decl node into text for a declaration in C. */
7307 static char tmpbuf[256];
7309 static void
7310 adorn_decl (decl, str)
7311 tree decl;
7312 char *str;
7314 enum tree_code code = TREE_CODE (decl);
7316 if (code == ARRAY_REF)
7318 tree an_int_cst = TREE_OPERAND (decl, 1);
7320 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7321 sprintf (str + strlen (str), "[%ld]",
7322 (long) TREE_INT_CST_LOW (an_int_cst));
7323 else
7324 strcat (str, "[]");
7327 else if (code == ARRAY_TYPE)
7329 tree an_int_cst = TYPE_SIZE (decl);
7330 tree array_of = TREE_TYPE (decl);
7332 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7333 sprintf (str + strlen (str), "[%ld]",
7334 (long) (TREE_INT_CST_LOW (an_int_cst)
7335 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7336 else
7337 strcat (str, "[]");
7340 else if (code == CALL_EXPR)
7342 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7344 strcat (str, "(");
7345 while (chain)
7347 gen_declaration_1 (chain, str);
7348 chain = TREE_CHAIN (chain);
7349 if (chain)
7350 strcat (str, ", ");
7352 strcat (str, ")");
7355 else if (code == FUNCTION_TYPE)
7357 tree chain = TYPE_ARG_TYPES (decl);
7359 strcat (str, "(");
7360 while (chain && TREE_VALUE (chain) != void_type_node)
7362 gen_declaration_1 (TREE_VALUE (chain), str);
7363 chain = TREE_CHAIN (chain);
7364 if (chain && TREE_VALUE (chain) != void_type_node)
7365 strcat (str, ", ");
7367 strcat (str, ")");
7370 else if (code == INDIRECT_REF)
7372 strcpy (tmpbuf, "*");
7373 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7375 tree chain;
7377 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7378 chain;
7379 chain = TREE_CHAIN (chain))
7381 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7383 strcat (tmpbuf, " ");
7384 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7387 if (str[0])
7388 strcat (tmpbuf, " ");
7390 strcat (tmpbuf, str);
7391 strcpy (str, tmpbuf);
7394 else if (code == POINTER_TYPE)
7396 strcpy (tmpbuf, "*");
7397 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7399 if (TREE_READONLY (decl))
7400 strcat (tmpbuf, " const");
7401 if (TYPE_VOLATILE (decl))
7402 strcat (tmpbuf, " volatile");
7403 if (str[0])
7404 strcat (tmpbuf, " ");
7406 strcat (tmpbuf, str);
7407 strcpy (str, tmpbuf);
7411 static char *
7412 gen_declarator (decl, buf, name)
7413 tree decl;
7414 char *buf;
7415 const char *name;
7417 if (decl)
7419 enum tree_code code = TREE_CODE (decl);
7420 char *str;
7421 tree op;
7422 int wrap = 0;
7424 switch (code)
7426 case ARRAY_REF:
7427 case INDIRECT_REF:
7428 case CALL_EXPR:
7429 op = TREE_OPERAND (decl, 0);
7431 /* We have a pointer to a function or array...(*)(), (*)[] */
7432 if ((code == ARRAY_REF || code == CALL_EXPR)
7433 && op && TREE_CODE (op) == INDIRECT_REF)
7434 wrap = 1;
7436 str = gen_declarator (op, buf, name);
7438 if (wrap)
7440 strcpy (tmpbuf, "(");
7441 strcat (tmpbuf, str);
7442 strcat (tmpbuf, ")");
7443 strcpy (str, tmpbuf);
7446 adorn_decl (decl, str);
7447 break;
7449 case ARRAY_TYPE:
7450 case FUNCTION_TYPE:
7451 case POINTER_TYPE:
7452 strcpy (buf, name);
7453 str = buf;
7455 /* This clause is done iteratively rather than recursively. */
7458 op = (is_complex_decl (TREE_TYPE (decl))
7459 ? TREE_TYPE (decl) : NULL_TREE);
7461 adorn_decl (decl, str);
7463 /* We have a pointer to a function or array...(*)(), (*)[] */
7464 if (code == POINTER_TYPE
7465 && op && (TREE_CODE (op) == FUNCTION_TYPE
7466 || TREE_CODE (op) == ARRAY_TYPE))
7468 strcpy (tmpbuf, "(");
7469 strcat (tmpbuf, str);
7470 strcat (tmpbuf, ")");
7471 strcpy (str, tmpbuf);
7474 decl = (is_complex_decl (TREE_TYPE (decl))
7475 ? TREE_TYPE (decl) : NULL_TREE);
7478 while (decl && (code = TREE_CODE (decl)))
7481 break;
7483 case IDENTIFIER_NODE:
7484 /* Will only happen if we are processing a "raw" expr-decl. */
7485 strcpy (buf, IDENTIFIER_POINTER (decl));
7486 return buf;
7488 default:
7489 abort ();
7492 return str;
7495 else
7496 /* We have an abstract declarator or a _DECL node. */
7498 strcpy (buf, name);
7499 return buf;
7503 static void
7504 gen_declspecs (declspecs, buf, raw)
7505 tree declspecs;
7506 char *buf;
7507 int raw;
7509 if (raw)
7511 tree chain;
7513 for (chain = nreverse (copy_list (declspecs));
7514 chain; chain = TREE_CHAIN (chain))
7516 tree aspec = TREE_VALUE (chain);
7518 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7519 strcat (buf, IDENTIFIER_POINTER (aspec));
7520 else if (TREE_CODE (aspec) == RECORD_TYPE)
7522 if (TYPE_NAME (aspec))
7524 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7526 if (! TREE_STATIC_TEMPLATE (aspec))
7527 strcat (buf, "struct ");
7528 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7530 /* NEW!!! */
7531 if (protocol_list)
7533 tree chain = protocol_list;
7535 strcat (buf, " <");
7536 while (chain)
7538 strcat (buf,
7539 IDENTIFIER_POINTER
7540 (PROTOCOL_NAME (TREE_VALUE (chain))));
7541 chain = TREE_CHAIN (chain);
7542 if (chain)
7543 strcat (buf, ", ");
7545 strcat (buf, ">");
7549 else
7550 strcat (buf, "untagged struct");
7553 else if (TREE_CODE (aspec) == UNION_TYPE)
7555 if (TYPE_NAME (aspec))
7557 if (! TREE_STATIC_TEMPLATE (aspec))
7558 strcat (buf, "union ");
7559 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7561 else
7562 strcat (buf, "untagged union");
7565 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7567 if (TYPE_NAME (aspec))
7569 if (! TREE_STATIC_TEMPLATE (aspec))
7570 strcat (buf, "enum ");
7571 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7573 else
7574 strcat (buf, "untagged enum");
7577 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7578 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7580 else if (IS_ID (aspec))
7582 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7584 strcat (buf, "id");
7585 if (protocol_list)
7587 tree chain = protocol_list;
7589 strcat (buf, " <");
7590 while (chain)
7592 strcat (buf,
7593 IDENTIFIER_POINTER
7594 (PROTOCOL_NAME (TREE_VALUE (chain))));
7595 chain = TREE_CHAIN (chain);
7596 if (chain)
7597 strcat (buf, ", ");
7599 strcat (buf, ">");
7602 if (TREE_CHAIN (chain))
7603 strcat (buf, " ");
7606 else
7608 /* Type qualifiers. */
7609 if (TREE_READONLY (declspecs))
7610 strcat (buf, "const ");
7611 if (TYPE_VOLATILE (declspecs))
7612 strcat (buf, "volatile ");
7614 switch (TREE_CODE (declspecs))
7616 /* Type specifiers. */
7618 case INTEGER_TYPE:
7619 declspecs = TYPE_MAIN_VARIANT (declspecs);
7621 /* Signed integer types. */
7623 if (declspecs == short_integer_type_node)
7624 strcat (buf, "short int ");
7625 else if (declspecs == integer_type_node)
7626 strcat (buf, "int ");
7627 else if (declspecs == long_integer_type_node)
7628 strcat (buf, "long int ");
7629 else if (declspecs == long_long_integer_type_node)
7630 strcat (buf, "long long int ");
7631 else if (declspecs == signed_char_type_node
7632 || declspecs == char_type_node)
7633 strcat (buf, "char ");
7635 /* Unsigned integer types. */
7637 else if (declspecs == short_unsigned_type_node)
7638 strcat (buf, "unsigned short ");
7639 else if (declspecs == unsigned_type_node)
7640 strcat (buf, "unsigned int ");
7641 else if (declspecs == long_unsigned_type_node)
7642 strcat (buf, "unsigned long ");
7643 else if (declspecs == long_long_unsigned_type_node)
7644 strcat (buf, "unsigned long long ");
7645 else if (declspecs == unsigned_char_type_node)
7646 strcat (buf, "unsigned char ");
7647 break;
7649 case REAL_TYPE:
7650 declspecs = TYPE_MAIN_VARIANT (declspecs);
7652 if (declspecs == float_type_node)
7653 strcat (buf, "float ");
7654 else if (declspecs == double_type_node)
7655 strcat (buf, "double ");
7656 else if (declspecs == long_double_type_node)
7657 strcat (buf, "long double ");
7658 break;
7660 case RECORD_TYPE:
7661 if (TYPE_NAME (declspecs)
7662 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7664 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7666 if (! TREE_STATIC_TEMPLATE (declspecs))
7667 strcat (buf, "struct ");
7668 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7670 if (protocol_list)
7672 tree chain = protocol_list;
7674 strcat (buf, " <");
7675 while (chain)
7677 strcat (buf,
7678 IDENTIFIER_POINTER
7679 (PROTOCOL_NAME (TREE_VALUE (chain))));
7680 chain = TREE_CHAIN (chain);
7681 if (chain)
7682 strcat (buf, ", ");
7684 strcat (buf, ">");
7688 else
7689 strcat (buf, "untagged struct");
7691 strcat (buf, " ");
7692 break;
7694 case UNION_TYPE:
7695 if (TYPE_NAME (declspecs)
7696 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7698 strcat (buf, "union ");
7699 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7700 strcat (buf, " ");
7703 else
7704 strcat (buf, "untagged union ");
7705 break;
7707 case ENUMERAL_TYPE:
7708 if (TYPE_NAME (declspecs)
7709 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7711 strcat (buf, "enum ");
7712 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7713 strcat (buf, " ");
7716 else
7717 strcat (buf, "untagged enum ");
7718 break;
7720 case VOID_TYPE:
7721 strcat (buf, "void ");
7722 break;
7724 case POINTER_TYPE:
7726 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7728 strcat (buf, "id");
7729 if (protocol_list)
7731 tree chain = protocol_list;
7733 strcat (buf, " <");
7734 while (chain)
7736 strcat (buf,
7737 IDENTIFIER_POINTER
7738 (PROTOCOL_NAME (TREE_VALUE (chain))));
7739 chain = TREE_CHAIN (chain);
7740 if (chain)
7741 strcat (buf, ", ");
7744 strcat (buf, ">");
7747 break;
7749 default:
7750 break;
7755 /* Given a tree node, produce a printable description of it in the given
7756 buffer, overwriting the buffer. */
7758 static char *
7759 gen_declaration (atype_or_adecl, buf)
7760 tree atype_or_adecl;
7761 char *buf;
7763 buf[0] = '\0';
7764 gen_declaration_1 (atype_or_adecl, buf);
7765 return buf;
7768 /* Given a tree node, append a printable description to the end of the
7769 given buffer. */
7771 static void
7772 gen_declaration_1 (atype_or_adecl, buf)
7773 tree atype_or_adecl;
7774 char *buf;
7776 char declbuf[256];
7778 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7780 tree declspecs; /* "identifier_node", "record_type" */
7781 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7783 /* We have a "raw", abstract declarator (typename). */
7784 declarator = TREE_VALUE (atype_or_adecl);
7785 declspecs = TREE_PURPOSE (atype_or_adecl);
7787 gen_declspecs (declspecs, buf, 1);
7788 if (declarator)
7790 strcat (buf, " ");
7791 strcat (buf, gen_declarator (declarator, declbuf, ""));
7795 else
7797 tree atype;
7798 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7799 tree declarator; /* "array_type", "function_type", "pointer_type". */
7801 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7802 || TREE_CODE (atype_or_adecl) == PARM_DECL
7803 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7804 atype = TREE_TYPE (atype_or_adecl);
7805 else
7806 /* Assume we have a *_type node. */
7807 atype = atype_or_adecl;
7809 if (is_complex_decl (atype))
7811 tree chain;
7813 /* Get the declaration specifier; it is at the end of the list. */
7814 declarator = chain = atype;
7816 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7817 while (is_complex_decl (chain));
7818 declspecs = chain;
7821 else
7823 declspecs = atype;
7824 declarator = NULL_TREE;
7827 gen_declspecs (declspecs, buf, 0);
7829 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7830 || TREE_CODE (atype_or_adecl) == PARM_DECL
7831 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7833 const char *const decl_name =
7834 (DECL_NAME (atype_or_adecl)
7835 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7837 if (declarator)
7839 strcat (buf, " ");
7840 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7843 else if (decl_name[0])
7845 strcat (buf, " ");
7846 strcat (buf, decl_name);
7849 else if (declarator)
7851 strcat (buf, " ");
7852 strcat (buf, gen_declarator (declarator, declbuf, ""));
7857 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7859 /* Given a method tree, put a printable description into the given
7860 buffer (overwriting) and return a pointer to the buffer. */
7862 static char *
7863 gen_method_decl (method, buf)
7864 tree method;
7865 char *buf;
7867 tree chain;
7869 buf[0] = '\0';
7870 if (RAW_TYPESPEC (method) != objc_object_reference)
7872 strcat (buf, "(");
7873 gen_declaration_1 (TREE_TYPE (method), buf);
7874 strcat (buf, ")");
7877 chain = METHOD_SEL_ARGS (method);
7878 if (chain)
7880 /* We have a chain of keyword_decls. */
7883 if (KEYWORD_KEY_NAME (chain))
7884 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7886 strcat (buf, ":");
7887 if (RAW_TYPESPEC (chain) != objc_object_reference)
7889 strcat (buf, "(");
7890 gen_declaration_1 (TREE_TYPE (chain), buf);
7891 strcat (buf, ")");
7894 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7895 if ((chain = TREE_CHAIN (chain)))
7896 strcat (buf, " ");
7898 while (chain);
7900 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7901 strcat (buf, ", ...");
7902 else if (METHOD_ADD_ARGS (method))
7904 /* We have a tree list node as generate by get_parm_info. */
7905 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7907 /* Know we have a chain of parm_decls. */
7908 while (chain)
7910 strcat (buf, ", ");
7911 gen_declaration_1 (chain, buf);
7912 chain = TREE_CHAIN (chain);
7917 else
7918 /* We have a unary selector. */
7919 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7921 return buf;
7924 /* Debug info. */
7926 static void
7927 dump_interface (fp, chain)
7928 FILE *fp;
7929 tree chain;
7931 char *buf = (char *) xmalloc (256);
7932 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7933 tree ivar_decls = CLASS_RAW_IVARS (chain);
7934 tree nst_methods = CLASS_NST_METHODS (chain);
7935 tree cls_methods = CLASS_CLS_METHODS (chain);
7937 fprintf (fp, "\n@interface %s", my_name);
7939 if (CLASS_SUPER_NAME (chain))
7941 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7942 fprintf (fp, " : %s\n", super_name);
7944 else
7945 fprintf (fp, "\n");
7947 if (ivar_decls)
7949 fprintf (fp, "{\n");
7952 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
7953 ivar_decls = TREE_CHAIN (ivar_decls);
7955 while (ivar_decls);
7956 fprintf (fp, "}\n");
7959 while (nst_methods)
7961 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
7962 nst_methods = TREE_CHAIN (nst_methods);
7965 while (cls_methods)
7967 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
7968 cls_methods = TREE_CHAIN (cls_methods);
7970 fprintf (fp, "\n@end");
7973 /* Demangle function for Objective-C */
7974 static const char *
7975 objc_demangle (mangled)
7976 const char *mangled;
7978 char *demangled, *cp;
7980 if (mangled[0] == '_' &&
7981 (mangled[1] == 'i' || mangled[1] == 'c') &&
7982 mangled[2] == '_')
7984 cp = demangled = xmalloc(strlen(mangled) + 2);
7985 if (mangled[1] == 'i')
7986 *cp++ = '-'; /* for instance method */
7987 else
7988 *cp++ = '+'; /* for class method */
7989 *cp++ = '['; /* opening left brace */
7990 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
7991 while (*cp && *cp == '_')
7992 cp++; /* skip any initial underbars in class name */
7993 cp = strchr(cp, '_'); /* find first non-initial underbar */
7994 if (cp == NULL)
7996 free(demangled); /* not mangled name */
7997 return mangled;
7999 if (cp[1] == '_') /* easy case: no category name */
8001 *cp++ = ' '; /* replace two '_' with one ' ' */
8002 strcpy(cp, mangled + (cp - demangled) + 2);
8004 else
8006 *cp++ = '('; /* less easy case: category name */
8007 cp = strchr(cp, '_');
8008 if (cp == 0)
8010 free(demangled); /* not mangled name */
8011 return mangled;
8013 *cp++ = ')';
8014 *cp++ = ' '; /* overwriting 1st char of method name... */
8015 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8017 while (*cp && *cp == '_')
8018 cp++; /* skip any initial underbars in method name */
8019 for (; *cp; cp++)
8020 if (*cp == '_')
8021 *cp = ':'; /* replace remaining '_' with ':' */
8022 *cp++ = ']'; /* closing right brace */
8023 *cp++ = 0; /* string terminator */
8024 return demangled;
8026 else
8027 return mangled; /* not an objc mangled name */
8030 const char *
8031 objc_printable_name (decl, kind)
8032 tree decl;
8033 int kind ATTRIBUTE_UNUSED;
8035 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8038 static void
8039 init_objc ()
8041 gcc_obstack_init (&util_obstack);
8042 util_firstobj = (char *) obstack_finish (&util_obstack);
8044 errbuf = (char *) xmalloc (BUFSIZE);
8045 hash_init ();
8046 synth_module_prologue ();
8049 static void
8050 finish_objc ()
8052 struct imp_entry *impent;
8053 tree chain;
8054 /* The internally generated initializers appear to have missing braces.
8055 Don't warn about this. */
8056 int save_warn_missing_braces = warn_missing_braces;
8057 warn_missing_braces = 0;
8059 /* A missing @end may not be detected by the parser. */
8060 if (objc_implementation_context)
8062 warning ("`@end' missing in implementation context");
8063 finish_class (objc_implementation_context);
8064 objc_ivar_chain = NULL_TREE;
8065 objc_implementation_context = NULL_TREE;
8068 generate_forward_declaration_to_string_table ();
8070 #ifdef OBJC_PROLOGUE
8071 OBJC_PROLOGUE;
8072 #endif
8074 /* Process the static instances here because initialization of objc_symtab
8075 depends on them. */
8076 if (objc_static_instances)
8077 generate_static_references ();
8079 if (imp_list || class_names_chain
8080 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8081 generate_objc_symtab_decl ();
8083 for (impent = imp_list; impent; impent = impent->next)
8085 objc_implementation_context = impent->imp_context;
8086 implementation_template = impent->imp_template;
8088 UOBJC_CLASS_decl = impent->class_decl;
8089 UOBJC_METACLASS_decl = impent->meta_decl;
8091 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8093 /* all of the following reference the string pool... */
8094 generate_ivar_lists ();
8095 generate_dispatch_tables ();
8096 generate_shared_structures ();
8098 else
8100 generate_dispatch_tables ();
8101 generate_category (objc_implementation_context);
8105 /* If we are using an array of selectors, we must always
8106 finish up the array decl even if no selectors were used. */
8107 if (! flag_next_runtime || sel_ref_chain)
8108 build_selector_translation_table ();
8110 if (protocol_chain)
8111 generate_protocols ();
8113 if (objc_implementation_context || class_names_chain || objc_static_instances
8114 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8116 /* Arrange for ObjC data structures to be initialized at run time. */
8117 rtx init_sym = build_module_descriptor ();
8118 if (init_sym && targetm.have_ctors_dtors)
8119 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8122 /* Dump the class references. This forces the appropriate classes
8123 to be linked into the executable image, preserving unix archive
8124 semantics. This can be removed when we move to a more dynamically
8125 linked environment. */
8127 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8129 handle_class_ref (chain);
8130 if (TREE_PURPOSE (chain))
8131 generate_classref_translation_entry (chain);
8134 for (impent = imp_list; impent; impent = impent->next)
8135 handle_impent (impent);
8137 /* Dump the string table last. */
8139 generate_strings ();
8141 if (flag_gen_declaration)
8143 add_class (objc_implementation_context);
8144 dump_interface (gen_declaration_file, objc_implementation_context);
8147 if (warn_selector)
8149 int slot;
8150 hash hsh;
8152 /* Run through the selector hash tables and print a warning for any
8153 selector which has multiple methods. */
8155 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8156 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8157 if (hsh->list)
8159 tree meth = hsh->key;
8160 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8161 ? '-' : '+');
8162 attr loop;
8164 warning ("potential selector conflict for method `%s'",
8165 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8166 warn_with_method ("found", type, meth);
8167 for (loop = hsh->list; loop; loop = loop->next)
8168 warn_with_method ("found", type, loop->value);
8171 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8172 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8173 if (hsh->list)
8175 tree meth = hsh->key;
8176 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8177 ? '-' : '+');
8178 attr loop;
8180 warning ("potential selector conflict for method `%s'",
8181 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8182 warn_with_method ("found", type, meth);
8183 for (loop = hsh->list; loop; loop = loop->next)
8184 warn_with_method ("found", type, loop->value);
8188 warn_missing_braces = save_warn_missing_braces;
8191 /* Subroutines of finish_objc. */
8193 static void
8194 generate_classref_translation_entry (chain)
8195 tree chain;
8197 tree expr, name, decl_specs, decl, sc_spec;
8198 tree type;
8200 type = TREE_TYPE (TREE_PURPOSE (chain));
8202 expr = add_objc_string (TREE_VALUE (chain), class_names);
8203 expr = build_c_cast (type, expr); /* cast! */
8205 name = DECL_NAME (TREE_PURPOSE (chain));
8207 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8209 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8210 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8212 /* The decl that is returned from start_decl is the one that we
8213 forward declared in build_class_reference. */
8214 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8215 DECL_CONTEXT (decl) = NULL_TREE;
8216 finish_decl (decl, expr, NULL_TREE);
8217 return;
8220 static void
8221 handle_class_ref (chain)
8222 tree chain;
8224 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8225 char *string = (char *) alloca (strlen (name) + 30);
8226 tree decl;
8227 tree exp;
8229 sprintf (string, "%sobjc_class_name_%s",
8230 (flag_next_runtime ? "." : "__"), name);
8232 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8233 if (flag_next_runtime)
8235 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8236 return;
8238 #endif
8240 /* Make a decl for this name, so we can use its address in a tree. */
8241 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8242 DECL_EXTERNAL (decl) = 1;
8243 TREE_PUBLIC (decl) = 1;
8245 pushdecl (decl);
8246 rest_of_decl_compilation (decl, 0, 0, 0);
8248 /* Make a decl for the address. */
8249 sprintf (string, "%sobjc_class_ref_%s",
8250 (flag_next_runtime ? "." : "__"), name);
8251 exp = build1 (ADDR_EXPR, string_type_node, decl);
8252 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8253 DECL_INITIAL (decl) = exp;
8254 TREE_STATIC (decl) = 1;
8255 TREE_USED (decl) = 1;
8257 pushdecl (decl);
8258 rest_of_decl_compilation (decl, 0, 0, 0);
8261 static void
8262 handle_impent (impent)
8263 struct imp_entry *impent;
8265 char *string;
8267 objc_implementation_context = impent->imp_context;
8268 implementation_template = impent->imp_template;
8270 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8272 const char *const class_name =
8273 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8275 string = (char *) alloca (strlen (class_name) + 30);
8277 sprintf (string, "%sobjc_class_name_%s",
8278 (flag_next_runtime ? "." : "__"), class_name);
8280 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8282 const char *const class_name =
8283 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8284 const char *const class_super_name =
8285 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8287 string = (char *) alloca (strlen (class_name)
8288 + strlen (class_super_name) + 30);
8290 /* Do the same for categories. Even though no references to
8291 these symbols are generated automatically by the compiler, it
8292 gives you a handle to pull them into an archive by hand. */
8293 sprintf (string, "*%sobjc_category_name_%s_%s",
8294 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8296 else
8297 return;
8299 #ifdef ASM_DECLARE_CLASS_REFERENCE
8300 if (flag_next_runtime)
8302 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8303 return;
8305 else
8306 #endif
8308 tree decl, init;
8310 init = build_int_2 (0, 0);
8311 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8312 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8313 TREE_PUBLIC (decl) = 1;
8314 TREE_READONLY (decl) = 1;
8315 TREE_USED (decl) = 1;
8316 TREE_CONSTANT (decl) = 1;
8317 DECL_CONTEXT (decl) = 0;
8318 DECL_ARTIFICIAL (decl) = 1;
8319 DECL_INITIAL (decl) = init;
8320 assemble_variable (decl, 1, 0, 0);
8324 static void
8325 ggc_mark_imp_list (arg)
8326 void *arg;
8328 struct imp_entry *impent;
8330 for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
8332 ggc_mark_tree (impent->imp_context);
8333 ggc_mark_tree (impent->imp_template);
8334 ggc_mark_tree (impent->class_decl);
8335 ggc_mark_tree (impent->meta_decl);
8339 static void
8340 ggc_mark_hash_table (arg)
8341 void *arg;
8343 hash *hash_table = *(hash **)arg;
8344 hash hst;
8345 attr list;
8346 int i;
8348 if (hash_table == NULL)
8349 return;
8350 for (i = 0; i < SIZEHASHTABLE; i++)
8351 for (hst = hash_table [i]; hst; hst = hst->next)
8353 ggc_mark_tree (hst->key);
8354 for (list = hst->list; list; list = list->next)
8355 ggc_mark_tree (list->value);
8359 /* Add GC roots for variables local to this file. */
8360 static void
8361 objc_act_parse_init ()
8363 ggc_add_tree_root (objc_global_trees, OCTI_MAX);
8364 ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
8365 ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
8366 ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
8369 /* Look up ID as an instance variable. */
8370 tree
8371 lookup_objc_ivar (id)
8372 tree id;
8374 tree decl;
8376 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8377 /* we have a message to super */
8378 return get_super_receiver ();
8379 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8381 if (is_private (decl))
8382 return error_mark_node;
8383 else
8384 return build_ivar_reference (id);
8386 else
8387 return 0;