* rtl.h (rtunion_def): Constify member `rtstr'.
[official-gcc.git] / gcc / objc / objc-act.c
blob1817904fdaf134e1457aa5e6779a8209e8cfd2ab
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000 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':
40 - OBJC_INT_SELECTORS */
42 #include "config.h"
43 #include "system.h"
44 #include "tree.h"
45 #include "c-tree.h"
46 #include "c-lex.h"
47 #include "flags.h"
48 #include "objc-act.h"
49 #include "input.h"
50 #include "except.h"
51 #include "function.h"
52 #include "output.h"
53 #include "toplev.h"
55 #if USE_CPPLIB
56 #include "cpplib.h"
57 extern cpp_reader parse_in;
58 extern cpp_options parse_options;
59 #endif
61 /* This is the default way of generating a method name. */
62 /* I am not sure it is really correct.
63 Perhaps there's a danger that it will make name conflicts
64 if method names contain underscores. -- rms. */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
67 do { \
68 char *temp; \
69 sprintf ((BUF), "_%s_%s_%s_%s", \
70 ((IS_INST) ? "i" : "c"), \
71 (CLASS_NAME), \
72 ((CAT_NAME)? (CAT_NAME) : ""), \
73 (SEL_NAME)); \
74 for (temp = (BUF); *temp; temp++) \
75 if (*temp == ':') *temp = '_'; \
76 } while (0)
77 #endif
79 /* These need specifying. */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
82 #endif
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
86 #endif
88 /* Define the special tree codes that we use. */
90 /* Table indexed by tree code giving a string containing a character
91 classifying the tree code. Possibilities are
92 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
94 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
96 static const char objc_tree_code_type[] = {
97 'x',
98 #include "objc-tree.def"
100 #undef DEFTREECODE
102 /* Table indexed by tree code giving number of expression
103 operands beyond the fixed part of the node structure.
104 Not used for types or decls. */
106 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
108 static const int objc_tree_code_length[] = {
110 #include "objc-tree.def"
112 #undef DEFTREECODE
114 /* Names of tree components.
115 Used for printing out the tree and error messages. */
116 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
118 static const char * const objc_tree_code_name[] = {
119 "@@dummy",
120 #include "objc-tree.def"
122 #undef DEFTREECODE
124 /* Set up for use of obstacks. */
126 #include "obstack.h"
128 #define obstack_chunk_alloc xmalloc
129 #define obstack_chunk_free free
131 /* This obstack is used to accumulate the encoding of a data type. */
132 static struct obstack util_obstack;
133 /* This points to the beginning of obstack contents,
134 so we can free the whole contents. */
135 char *util_firstobj;
137 /* List of classes with list of their static instances. */
138 static tree objc_static_instances = NULL_TREE;
140 /* The declaration of the array administrating the static instances. */
141 static tree static_instances_decl = NULL_TREE;
143 /* for encode_method_def */
144 #include "rtl.h"
145 #include "c-parse.h"
147 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
148 #define PROTOCOL_VERSION 2
150 #define OBJC_ENCODE_INLINE_DEFS 0
151 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
153 /*** Private Interface (procedures) ***/
155 /* Used by compile_file. */
157 static void init_objc PARAMS ((void));
158 static void finish_objc PARAMS ((void));
160 /* Code generation. */
162 static void synth_module_prologue PARAMS ((void));
163 static tree build_constructor PARAMS ((tree, tree));
164 static const char *build_module_descriptor PARAMS ((void));
165 static tree init_module_descriptor PARAMS ((tree));
166 static tree build_objc_method_call PARAMS ((int, tree, tree,
167 tree, tree, tree));
168 static void generate_strings PARAMS ((void));
169 static tree get_proto_encoding PARAMS ((tree));
170 static void build_selector_translation_table PARAMS ((void));
171 static tree build_ivar_chain PARAMS ((tree, int));
173 static tree objc_add_static_instance PARAMS ((tree, tree));
175 static tree build_ivar_template PARAMS ((void));
176 static tree build_method_template PARAMS ((void));
177 static tree build_private_template PARAMS ((tree));
178 static void build_class_template PARAMS ((void));
179 static void build_selector_template PARAMS ((void));
180 static void build_category_template PARAMS ((void));
181 static tree build_super_template PARAMS ((void));
182 static tree build_category_initializer PARAMS ((tree, tree, tree,
183 tree, tree, tree));
184 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
185 tree, tree));
187 static void synth_forward_declarations PARAMS ((void));
188 static void generate_ivar_lists PARAMS ((void));
189 static void generate_dispatch_tables PARAMS ((void));
190 static void generate_shared_structures PARAMS ((void));
191 static tree generate_protocol_list PARAMS ((tree));
192 static void generate_forward_declaration_to_string_table PARAMS ((void));
193 static void build_protocol_reference PARAMS ((tree));
195 #if 0
196 static tree init_selector PARAMS ((int));
197 #endif
198 static tree build_keyword_selector PARAMS ((tree));
199 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
201 static void generate_static_references PARAMS ((void));
202 static int check_methods_accessible PARAMS ((tree, tree,
203 int));
204 static void encode_aggregate_within PARAMS ((tree, int, int,
205 int, int));
206 static const char *objc_demangle PARAMS ((const char *));
207 static const char *objc_printable_name PARAMS ((tree, int));
209 /* Misc. bookkeeping */
211 typedef struct hashed_entry *hash;
212 typedef struct hashed_attribute *attr;
214 struct hashed_attribute
216 attr next;
217 tree value;
219 struct hashed_entry
221 attr list;
222 hash next;
223 tree key;
226 static void hash_init PARAMS ((void));
227 static void hash_enter PARAMS ((hash *, tree));
228 static hash hash_lookup PARAMS ((hash *, tree));
229 static void hash_add_attr PARAMS ((hash, tree));
230 static tree lookup_method PARAMS ((tree, tree));
231 static tree lookup_instance_method_static PARAMS ((tree, tree));
232 static tree lookup_class_method_static PARAMS ((tree, tree));
233 static tree add_class PARAMS ((tree));
234 static void add_category PARAMS ((tree, tree));
236 enum string_section
238 class_names, /* class, category, protocol, module names */
239 meth_var_names, /* method and variable names */
240 meth_var_types /* method and variable type descriptors */
243 static tree add_objc_string PARAMS ((tree,
244 enum string_section));
245 static tree get_objc_string_decl PARAMS ((tree,
246 enum string_section));
247 static tree build_objc_string_decl PARAMS ((enum string_section));
248 static tree build_selector_reference_decl PARAMS ((void));
250 /* Protocol additions. */
252 static tree add_protocol PARAMS ((tree));
253 static tree lookup_protocol PARAMS ((tree));
254 static tree lookup_and_install_protocols PARAMS ((tree));
256 /* Type encoding. */
258 static void encode_type_qualifiers PARAMS ((tree));
259 static void encode_pointer PARAMS ((tree, int, int));
260 static void encode_array PARAMS ((tree, int, int));
261 static void encode_aggregate PARAMS ((tree, int, int));
262 static void encode_bitfield PARAMS ((int));
263 static void encode_type PARAMS ((tree, int, int));
264 static void encode_field_decl PARAMS ((tree, int, int));
266 static void really_start_method PARAMS ((tree, tree));
267 static int comp_method_with_proto PARAMS ((tree, tree));
268 static int comp_proto_with_proto PARAMS ((tree, tree));
269 static tree get_arg_type_list PARAMS ((tree, int, int));
270 static tree expr_last PARAMS ((tree));
272 /* Utilities for debugging and error diagnostics. */
274 static void warn_with_method PARAMS ((const char *, int, tree));
275 static void error_with_ivar PARAMS ((const char *, tree, tree));
276 static char *gen_method_decl PARAMS ((tree, char *));
277 static char *gen_declaration PARAMS ((tree, char *));
278 static char *gen_declarator PARAMS ((tree, char *,
279 const char *));
280 static int is_complex_decl PARAMS ((tree));
281 static void adorn_decl PARAMS ((tree, char *));
282 static void dump_interface PARAMS ((FILE *, tree));
284 /* Everything else. */
286 static void objc_fatal PARAMS ((void))
287 ATTRIBUTE_NORETURN;
288 static tree define_decl PARAMS ((tree, tree));
289 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
290 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
291 static tree create_builtin_decl PARAMS ((enum tree_code,
292 tree, const char *));
293 static tree my_build_string PARAMS ((int, const char *));
294 static void build_objc_symtab_template PARAMS ((void));
295 static tree init_def_list PARAMS ((tree));
296 static tree init_objc_symtab PARAMS ((tree));
297 static void forward_declare_categories PARAMS ((void));
298 static void generate_objc_symtab_decl PARAMS ((void));
299 static tree build_selector PARAMS ((tree));
300 #if 0
301 static tree build_msg_pool_reference PARAMS ((int));
302 #endif
303 static tree build_typed_selector_reference PARAMS ((tree, tree));
304 static tree build_selector_reference PARAMS ((tree));
305 static tree build_class_reference_decl PARAMS ((void));
306 static void add_class_reference PARAMS ((tree));
307 static tree objc_copy_list PARAMS ((tree, tree *));
308 static tree build_protocol_template PARAMS ((void));
309 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
310 static tree build_method_prototype_list_template PARAMS ((tree, int));
311 static tree build_method_prototype_template PARAMS ((void));
312 static int forwarding_offset PARAMS ((tree));
313 static tree encode_method_prototype PARAMS ((tree, tree));
314 static tree generate_descriptor_table PARAMS ((tree, const char *,
315 int, tree, tree));
316 static void generate_method_descriptors PARAMS ((tree));
317 static tree build_tmp_function_decl PARAMS ((void));
318 static void hack_method_prototype PARAMS ((tree, tree));
319 static void generate_protocol_references PARAMS ((tree));
320 static void generate_protocols PARAMS ((void));
321 static void check_ivars PARAMS ((tree, tree));
322 static tree build_ivar_list_template PARAMS ((tree, int));
323 static tree build_method_list_template PARAMS ((tree, int));
324 static tree build_ivar_list_initializer PARAMS ((tree, tree));
325 static tree generate_ivars_list PARAMS ((tree, const char *,
326 int, tree));
327 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
328 static tree generate_dispatch_table PARAMS ((tree, const char *,
329 int, tree));
330 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
331 tree, int, tree, tree,
332 tree));
333 static void generate_category PARAMS ((tree));
334 static int is_objc_type_qualifier PARAMS ((tree));
335 static tree adjust_type_for_id_default PARAMS ((tree));
336 static tree check_duplicates PARAMS ((hash));
337 static tree receiver_is_class_object PARAMS ((tree));
338 static int check_methods PARAMS ((tree, tree, int));
339 static int conforms_to_protocol PARAMS ((tree, tree));
340 static void check_protocols PARAMS ((tree, const char *,
341 const char *));
342 static tree encode_method_def PARAMS ((tree));
343 static void gen_declspecs PARAMS ((tree, char *, int));
344 static void generate_classref_translation_entry PARAMS ((tree));
345 static void handle_class_ref PARAMS ((tree));
346 static void generate_struct_by_value_array PARAMS ((void))
347 ATTRIBUTE_NORETURN;
349 /*** Private Interface (data) ***/
351 /* Reserved tag definitions. */
353 #define TYPE_ID "id"
354 #define TAG_OBJECT "objc_object"
355 #define TAG_CLASS "objc_class"
356 #define TAG_SUPER "objc_super"
357 #define TAG_SELECTOR "objc_selector"
359 #define UTAG_CLASS "_objc_class"
360 #define UTAG_IVAR "_objc_ivar"
361 #define UTAG_IVAR_LIST "_objc_ivar_list"
362 #define UTAG_METHOD "_objc_method"
363 #define UTAG_METHOD_LIST "_objc_method_list"
364 #define UTAG_CATEGORY "_objc_category"
365 #define UTAG_MODULE "_objc_module"
366 #define UTAG_STATICS "_objc_statics"
367 #define UTAG_SYMTAB "_objc_symtab"
368 #define UTAG_SUPER "_objc_super"
369 #define UTAG_SELECTOR "_objc_selector"
371 #define UTAG_PROTOCOL "_objc_protocol"
372 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
373 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
374 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
376 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
377 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
379 static const char *TAG_GETCLASS;
380 static const char *TAG_GETMETACLASS;
381 static const char *TAG_MSGSEND;
382 static const char *TAG_MSGSENDSUPER;
383 static const char *TAG_EXECCLASS;
385 /* Set by `continue_class' and checked by `is_public'. */
387 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
388 #define TYPED_OBJECT(type) \
389 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
391 /* Some commonly used instances of "identifier_node". */
393 static tree self_id, ucmd_id;
394 static tree unused_list;
396 static tree self_decl, umsg_decl, umsg_super_decl;
397 static tree objc_get_class_decl, objc_get_meta_class_decl;
399 static tree super_type, selector_type, id_type, objc_class_type;
400 static tree instance_type, protocol_type;
402 /* Type checking macros. */
404 #define IS_ID(TYPE) \
405 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
406 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
407 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
408 #define IS_SUPER(TYPE) \
409 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
411 static tree class_chain = NULL_TREE;
412 static tree alias_chain = NULL_TREE;
413 static tree interface_chain = NULL_TREE;
414 static tree protocol_chain = NULL_TREE;
416 /* Chains to manage selectors that are referenced and defined in the
417 module. */
419 static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */
420 static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. */
422 /* Chains to manage uniquing of strings. */
424 static tree class_names_chain = NULL_TREE;
425 static tree meth_var_names_chain = NULL_TREE;
426 static tree meth_var_types_chain = NULL_TREE;
428 /* Hash tables to manage the global pool of method prototypes. */
430 static hash *nst_method_hash_list = 0;
431 static hash *cls_method_hash_list = 0;
433 /* Backend data declarations. */
435 static tree UOBJC_SYMBOLS_decl;
436 static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
437 static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
438 static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
439 static tree UOBJC_SELECTOR_TABLE_decl;
440 static tree UOBJC_MODULES_decl;
441 static tree UOBJC_STRINGS_decl;
443 /* The following are used when compiling a class implementation.
444 implementation_template will normally be an interface, however if
445 none exists this will be equal to implementation_context...it is
446 set in start_class. */
448 static tree implementation_context = NULL_TREE;
449 static tree implementation_template = NULL_TREE;
451 struct imp_entry
453 struct imp_entry *next;
454 tree imp_context;
455 tree imp_template;
456 tree class_decl; /* _OBJC_CLASS_<my_name>; */
457 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
460 static void handle_impent PARAMS ((struct imp_entry *));
462 static struct imp_entry *imp_list = 0;
463 static int imp_count = 0; /* `@implementation' */
464 static int cat_count = 0; /* `@category' */
466 static tree objc_class_template, objc_category_template, uprivate_record;
467 static tree objc_protocol_template, objc_selector_template;
468 static tree ucls_super_ref, uucls_super_ref;
470 static tree objc_method_template, objc_ivar_template;
471 static tree objc_symtab_template, objc_module_template;
472 static tree objc_super_template, objc_object_reference;
474 static tree objc_object_id, objc_class_id, objc_id_id;
475 static tree constant_string_id;
476 static tree constant_string_type;
477 static tree UOBJC_SUPER_decl;
479 static tree method_context = NULL_TREE;
480 static int method_slot = 0; /* Used by start_method_def, */
482 #define BUFSIZE 1024
484 static char *errbuf; /* Buffer for error diagnostics */
486 /* Data imported from tree.c. */
488 extern enum debug_info_type write_symbols;
490 /* Data imported from toplev.c. */
492 extern const char *dump_base_name;
494 /* Generate code for GNU or NeXT runtime environment. */
496 #ifdef NEXT_OBJC_RUNTIME
497 int flag_next_runtime = 1;
498 #else
499 int flag_next_runtime = 0;
500 #endif
502 int flag_typed_selectors;
504 /* Open and close the file for outputting class declarations, if requested. */
506 int flag_gen_declaration = 0;
508 FILE *gen_declaration_file;
510 /* Warn if multiple methods are seen for the same selector, but with
511 different argument types. */
513 int warn_selector = 0;
515 /* Warn if methods required by a protocol are not implemented in the
516 class adopting it. When turned off, methods inherited to that
517 class are also considered implemented */
519 int flag_warn_protocol = 1;
521 /* Tells "encode_pointer/encode_aggregate" whether we are generating
522 type descriptors for instance variables (as opposed to methods).
523 Type descriptors for instance variables contain more information
524 than methods (for static typing and embedded structures). This
525 was added to support features being planned for dbkit2. */
527 static int generating_instance_variables = 0;
529 /* Tells the compiler that this is a special run. Do not perform
530 any compiling, instead we are to test some platform dependent
531 features and output a C header file with appropriate definitions. */
533 static int print_struct_values = 0;
535 /* Some platforms pass small structures through registers versus through
536 an invisible pointer. Determine at what size structure is the
537 transition point between the two possibilities. */
539 static void
540 generate_struct_by_value_array ()
542 tree type;
543 tree field_decl, field_decl_chain;
544 int i, j;
545 int aggregate_in_mem[32];
546 int found = 0;
548 /* Presumbaly no platform passes 32 byte structures in a register. */
549 for (i = 1; i < 32; i++)
551 char buffer[5];
553 /* Create an unnamed struct that has `i' character components */
554 type = start_struct (RECORD_TYPE, NULL_TREE);
556 strcpy (buffer, "c1");
557 field_decl = create_builtin_decl (FIELD_DECL,
558 char_type_node,
559 buffer);
560 field_decl_chain = field_decl;
562 for (j = 1; j < i; j++)
564 sprintf (buffer, "c%d", j + 1);
565 field_decl = create_builtin_decl (FIELD_DECL,
566 char_type_node,
567 buffer);
568 chainon (field_decl_chain, field_decl);
570 finish_struct (type, field_decl_chain, NULL_TREE);
572 aggregate_in_mem[i] = aggregate_value_p (type);
573 if (!aggregate_in_mem[i])
574 found = 1;
577 /* We found some structures that are returned in registers instead of memory
578 so output the necessary data. */
579 if (found)
581 for (i = 31; i >= 0; i--)
582 if (!aggregate_in_mem[i])
583 break;
584 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
586 /* The first member of the structure is always 0 because we don't handle
587 structures with 0 members */
588 printf ("static int struct_forward_array[] = {\n 0");
590 for (j = 1; j <= i; j++)
591 printf (", %d", aggregate_in_mem[j]);
592 printf ("\n};\n");
595 exit (0);
598 #if USE_CPPLIB
599 extern char *yy_cur;
600 #endif
602 void
603 lang_init_options ()
605 #if USE_CPPLIB
606 cpp_reader_init (&parse_in);
607 parse_in.opts = &parse_options;
608 cpp_options_init (&parse_options);
609 #endif
612 void
613 lang_init ()
615 #if !USE_CPPLIB
616 /* The beginning of the file is a new line; check for #.
617 With luck, we discover the real source file's name from that
618 and put it in input_filename. */
619 ungetc (check_newline (), finput);
620 #else
621 check_newline ();
622 yy_cur--;
623 #endif
625 /* The line number can be -1 if we had -g3 and the input file
626 had a directive specifying line 0. But we want predefined
627 functions to have a line number of 0, not -1. */
628 if (lineno == -1)
629 lineno = 0;
631 /* If gen_declaration desired, open the output file. */
632 if (flag_gen_declaration)
634 register char * const dumpname = concat (dumpname, ".decl", NULL);
635 gen_declaration_file = fopen (dumpname, "w");
636 if (gen_declaration_file == 0)
637 pfatal_with_name (dumpname);
638 free (dumpname);
641 if (flag_next_runtime)
643 TAG_GETCLASS = "objc_getClass";
644 TAG_GETMETACLASS = "objc_getMetaClass";
645 TAG_MSGSEND = "objc_msgSend";
646 TAG_MSGSENDSUPER = "objc_msgSendSuper";
647 TAG_EXECCLASS = "__objc_execClass";
649 else
651 TAG_GETCLASS = "objc_get_class";
652 TAG_GETMETACLASS = "objc_get_meta_class";
653 TAG_MSGSEND = "objc_msg_lookup";
654 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
655 TAG_EXECCLASS = "__objc_exec_class";
656 flag_typed_selectors = 1;
659 if (doing_objc_thang)
660 init_objc ();
662 if (print_struct_values)
663 generate_struct_by_value_array ();
666 static void
667 objc_fatal ()
669 fatal ("Objective-C text in C source file");
672 void
673 finish_file ()
675 if (doing_objc_thang)
676 finish_objc (); /* Objective-C finalization */
678 if (gen_declaration_file)
679 fclose (gen_declaration_file);
682 void
683 lang_finish ()
687 const char *
688 lang_identify ()
690 return "objc";
694 lang_decode_option (argc, argv)
695 int argc;
696 char **argv;
698 const char *p = argv[0];
699 if (!strcmp (p, "-lang-objc"))
700 doing_objc_thang = 1;
701 else if (!strcmp (p, "-gen-decls"))
702 flag_gen_declaration = 1;
703 else if (!strcmp (p, "-Wselector"))
704 warn_selector = 1;
705 else if (!strcmp (p, "-Wno-selector"))
706 warn_selector = 0;
707 else if (!strcmp (p, "-Wprotocol"))
708 flag_warn_protocol = 1;
709 else if (!strcmp (p, "-Wno-protocol"))
710 flag_warn_protocol = 0;
711 else if (!strcmp (p, "-fgnu-runtime"))
712 flag_next_runtime = 0;
713 else if (!strcmp (p, "-fno-next-runtime"))
714 flag_next_runtime = 0;
715 else if (!strcmp (p, "-fno-gnu-runtime"))
716 flag_next_runtime = 1;
717 else if (!strcmp (p, "-fnext-runtime"))
718 flag_next_runtime = 1;
719 else if (!strcmp (p, "-print-objc-runtime-info"))
720 print_struct_values = 1;
721 else
722 return c_decode_option (argc, argv);
724 return 1;
727 /* used by print-tree.c */
729 void
730 lang_print_xnode (file, node, indent)
731 FILE *file ATTRIBUTE_UNUSED;
732 tree node ATTRIBUTE_UNUSED;
733 int indent ATTRIBUTE_UNUSED;
738 static tree
739 define_decl (declarator, declspecs)
740 tree declarator;
741 tree declspecs;
743 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
744 finish_decl (decl, NULL_TREE, NULL_TREE);
745 return decl;
748 /* Return 1 if LHS and RHS are compatible types for assignment or
749 various other operations. Return 0 if they are incompatible, and
750 return -1 if we choose to not decide. When the operation is
751 REFLEXIVE, check for compatibility in either direction.
753 For statically typed objects, an assignment of the form `a' = `b'
754 is permitted if:
756 `a' is of type "id",
757 `a' and `b' are the same class type, or
758 `a' and `b' are of class types A and B such that B is a descendant of A. */
761 maybe_objc_comptypes (lhs, rhs, reflexive)
762 tree lhs, rhs;
763 int reflexive;
765 if (doing_objc_thang)
766 return objc_comptypes (lhs, rhs, reflexive);
767 return -1;
770 static tree
771 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
772 tree rproto_list;
773 tree sel_name;
774 int class_meth;
776 tree rproto, p;
777 tree fnd = 0;
779 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
781 p = TREE_VALUE (rproto);
783 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
785 if ((fnd = lookup_method (class_meth
786 ? PROTOCOL_CLS_METHODS (p)
787 : PROTOCOL_NST_METHODS (p), sel_name)))
789 else if (PROTOCOL_LIST (p))
790 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
791 sel_name, class_meth);
793 else
795 ; /* An identifier...if we could not find a protocol. */
798 if (fnd)
799 return fnd;
802 return 0;
805 static tree
806 lookup_protocol_in_reflist (rproto_list, lproto)
807 tree rproto_list;
808 tree lproto;
810 tree rproto, p;
812 /* Make sure the protocol is support by the object on the rhs. */
813 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
815 tree fnd = 0;
816 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
818 p = TREE_VALUE (rproto);
820 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
822 if (lproto == p)
823 fnd = lproto;
825 else if (PROTOCOL_LIST (p))
826 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
829 if (fnd)
830 return fnd;
833 else
835 ; /* An identifier...if we could not find a protocol. */
838 return 0;
841 /* Return 1 if LHS and RHS are compatible types for assignment
842 or various other operations. Return 0 if they are incompatible,
843 and return -1 if we choose to not decide. When the operation
844 is REFLEXIVE, check for compatibility in either direction. */
847 objc_comptypes (lhs, rhs, reflexive)
848 tree lhs;
849 tree rhs;
850 int reflexive;
852 /* New clause for protocols. */
854 if (TREE_CODE (lhs) == POINTER_TYPE
855 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
856 && TREE_CODE (rhs) == POINTER_TYPE
857 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
859 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
860 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
862 if (lhs_is_proto)
864 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
865 tree rproto, rproto_list;
866 tree p;
868 if (rhs_is_proto)
870 rproto_list = TYPE_PROTOCOL_LIST (rhs);
872 /* Make sure the protocol is supported by the object
873 on the rhs. */
874 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
876 p = TREE_VALUE (lproto);
877 rproto = lookup_protocol_in_reflist (rproto_list, p);
879 if (!rproto)
880 warning ("object does not conform to the `%s' protocol",
881 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
884 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
886 tree rname = TYPE_NAME (TREE_TYPE (rhs));
887 tree rinter;
889 /* Make sure the protocol is supported by the object
890 on the rhs. */
891 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
893 p = TREE_VALUE (lproto);
894 rproto = 0;
895 rinter = lookup_interface (rname);
897 while (rinter && !rproto)
899 tree cat;
901 rproto_list = CLASS_PROTOCOL_LIST (rinter);
902 rproto = lookup_protocol_in_reflist (rproto_list, p);
904 /* Check for protocols adopted by categories. */
905 cat = CLASS_CATEGORY_LIST (rinter);
906 while (cat && !rproto)
908 rproto_list = CLASS_PROTOCOL_LIST (cat);
909 rproto = lookup_protocol_in_reflist (rproto_list, p);
911 cat = CLASS_CATEGORY_LIST (cat);
914 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
917 if (!rproto)
918 warning ("class `%s' does not implement the `%s' protocol",
919 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
920 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
924 /* May change...based on whether there was any mismatch */
925 return 1;
927 else if (rhs_is_proto)
928 /* Lhs is not a protocol...warn if it is statically typed */
929 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
931 else
932 /* Defer to comptypes .*/
933 return -1;
936 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
937 ; /* Fall thru. This is the case we have been handling all along */
938 else
939 /* Defer to comptypes. */
940 return -1;
942 /* `id' = `<class> *', `<class> *' = `id' */
944 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
945 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
946 return 1;
948 /* `id' = `Class', `Class' = `id' */
950 else if ((TYPE_NAME (lhs) == objc_object_id
951 && TYPE_NAME (rhs) == objc_class_id)
952 || (TYPE_NAME (lhs) == objc_class_id
953 && TYPE_NAME (rhs) == objc_object_id))
954 return 1;
956 /* `<class> *' = `<class> *' */
958 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
960 tree lname = TYPE_NAME (lhs);
961 tree rname = TYPE_NAME (rhs);
962 tree inter;
964 if (lname == rname)
965 return 1;
967 /* If the left hand side is a super class of the right hand side,
968 allow it. */
969 for (inter = lookup_interface (rname); inter;
970 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
971 if (lname == CLASS_SUPER_NAME (inter))
972 return 1;
974 /* Allow the reverse when reflexive. */
975 if (reflexive)
976 for (inter = lookup_interface (lname); inter;
977 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
978 if (rname == CLASS_SUPER_NAME (inter))
979 return 1;
981 return 0;
983 else
984 /* Defer to comptypes. */
985 return -1;
988 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
990 void
991 objc_check_decl (decl)
992 tree decl;
994 tree type = TREE_TYPE (decl);
996 if (TREE_CODE (type) == RECORD_TYPE
997 && TREE_STATIC_TEMPLATE (type)
998 && type != constant_string_type)
1000 error_with_decl (decl, "`%s' cannot be statically allocated");
1001 fatal ("statically allocated objects not supported");
1005 void
1006 maybe_objc_check_decl (decl)
1007 tree decl;
1009 if (doing_objc_thang)
1010 objc_check_decl (decl);
1013 /* Implement static typing. At this point, we know we have an interface. */
1015 tree
1016 get_static_reference (interface, protocols)
1017 tree interface;
1018 tree protocols;
1020 tree type = xref_tag (RECORD_TYPE, interface);
1022 if (protocols)
1024 tree t, m = TYPE_MAIN_VARIANT (type);
1026 t = copy_node (type);
1027 TYPE_BINFO (t) = make_tree_vec (2);
1029 /* Add this type to the chain of variants of TYPE. */
1030 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1031 TYPE_NEXT_VARIANT (m) = t;
1033 /* Look up protocols and install in lang specific list. */
1034 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1036 /* This forces a new pointer type to be created later
1037 (in build_pointer_type)...so that the new template
1038 we just created will actually be used...what a hack! */
1039 if (TYPE_POINTER_TO (t))
1040 TYPE_POINTER_TO (t) = 0;
1042 type = t;
1045 return type;
1048 tree
1049 get_object_reference (protocols)
1050 tree protocols;
1052 tree type_decl = lookup_name (objc_id_id);
1053 tree type;
1055 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
1057 type = TREE_TYPE (type_decl);
1058 if (TYPE_MAIN_VARIANT (type) != id_type)
1059 warning ("Unexpected type for `id' (%s)",
1060 gen_declaration (type, errbuf));
1062 else
1063 fatal ("Undefined type `id', please import <objc/objc.h>");
1065 /* This clause creates a new pointer type that is qualified with
1066 the protocol specification...this info is used later to do more
1067 elaborate type checking. */
1069 if (protocols)
1071 tree t, m = TYPE_MAIN_VARIANT (type);
1073 t = copy_node (type);
1074 TYPE_BINFO (t) = make_tree_vec (2);
1076 /* Add this type to the chain of variants of TYPE. */
1077 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1078 TYPE_NEXT_VARIANT (m) = t;
1080 /* Look up protocols...and install in lang specific list */
1081 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1083 /* This forces a new pointer type to be created later
1084 (in build_pointer_type)...so that the new template
1085 we just created will actually be used...what a hack! */
1086 if (TYPE_POINTER_TO (t))
1087 TYPE_POINTER_TO (t) = NULL;
1089 type = t;
1091 return type;
1094 static tree
1095 lookup_and_install_protocols (protocols)
1096 tree protocols;
1098 tree proto;
1099 tree prev = NULL;
1100 tree return_value = protocols;
1102 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1104 tree ident = TREE_VALUE (proto);
1105 tree p = lookup_protocol (ident);
1107 if (!p)
1109 error ("Cannot find protocol declaration for `%s'",
1110 IDENTIFIER_POINTER (ident));
1111 if (prev)
1112 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1113 else
1114 return_value = TREE_CHAIN (proto);
1116 else
1118 /* Replace identifier with actual protocol node. */
1119 TREE_VALUE (proto) = p;
1120 prev = proto;
1124 return return_value;
1127 /* Create and push a decl for a built-in external variable or field NAME.
1128 CODE says which.
1129 TYPE is its data type. */
1131 static tree
1132 create_builtin_decl (code, type, name)
1133 enum tree_code code;
1134 tree type;
1135 const char *name;
1137 tree decl = build_decl (code, get_identifier (name), type);
1139 if (code == VAR_DECL)
1141 TREE_STATIC (decl) = 1;
1142 make_decl_rtl (decl, 0, 1);
1143 pushdecl (decl);
1146 DECL_ARTIFICIAL (decl) = 1;
1147 return decl;
1150 /* Purpose: "play" parser, creating/installing representations
1151 of the declarations that are required by Objective-C.
1153 Model:
1155 type_spec--------->sc_spec
1156 (tree_list) (tree_list)
1159 identifier_node identifier_node */
1161 static void
1162 synth_module_prologue ()
1164 tree temp_type;
1165 tree super_p;
1167 /* Defined in `objc.h' */
1168 objc_object_id = get_identifier (TAG_OBJECT);
1170 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1172 id_type = build_pointer_type (objc_object_reference);
1174 objc_id_id = get_identifier (TYPE_ID);
1175 objc_class_id = get_identifier (TAG_CLASS);
1177 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1178 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1179 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1181 /* Declare type of selector-objects that represent an operation name. */
1183 #ifdef OBJC_INT_SELECTORS
1184 /* `unsigned int' */
1185 selector_type = unsigned_type_node;
1186 #else
1187 /* `struct objc_selector *' */
1188 selector_type
1189 = build_pointer_type (xref_tag (RECORD_TYPE,
1190 get_identifier (TAG_SELECTOR)));
1191 #endif /* not OBJC_INT_SELECTORS */
1193 /* Forward declare type, or else the prototype for msgSendSuper will
1194 complain. */
1196 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1197 get_identifier (TAG_SUPER)));
1200 /* id objc_msgSend (id, SEL, ...); */
1202 temp_type
1203 = build_function_type (id_type,
1204 tree_cons (NULL_TREE, id_type,
1205 tree_cons (NULL_TREE, selector_type,
1206 NULL_TREE)));
1208 if (! flag_next_runtime)
1210 umsg_decl = build_decl (FUNCTION_DECL,
1211 get_identifier (TAG_MSGSEND), temp_type);
1212 DECL_EXTERNAL (umsg_decl) = 1;
1213 TREE_PUBLIC (umsg_decl) = 1;
1214 DECL_INLINE (umsg_decl) = 1;
1215 DECL_ARTIFICIAL (umsg_decl) = 1;
1217 if (flag_traditional && TAG_MSGSEND[0] != '_')
1218 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1220 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1221 pushdecl (umsg_decl);
1223 else
1224 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1226 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1228 temp_type
1229 = build_function_type (id_type,
1230 tree_cons (NULL_TREE, super_p,
1231 tree_cons (NULL_TREE, selector_type,
1232 NULL_TREE)));
1234 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1235 temp_type, 0, NOT_BUILT_IN, 0);
1237 /* id objc_getClass (const char *); */
1239 temp_type = build_function_type (id_type,
1240 tree_cons (NULL_TREE,
1241 const_string_type_node,
1242 tree_cons (NULL_TREE, void_type_node,
1243 NULL_TREE)));
1245 objc_get_class_decl
1246 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1248 /* id objc_getMetaClass (const char *); */
1250 objc_get_meta_class_decl
1251 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1253 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1255 if (! flag_next_runtime)
1257 if (flag_typed_selectors)
1259 /* Suppress outputting debug symbols, because
1260 dbxout_init hasn'r been called yet. */
1261 enum debug_info_type save_write_symbols = write_symbols;
1262 write_symbols = NO_DEBUG;
1264 build_selector_template ();
1265 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1267 write_symbols = save_write_symbols;
1269 else
1270 temp_type = build_array_type (selector_type, NULL_TREE);
1272 layout_type (temp_type);
1273 UOBJC_SELECTOR_TABLE_decl
1274 = create_builtin_decl (VAR_DECL, temp_type,
1275 "_OBJC_SELECTOR_TABLE");
1277 /* Avoid warning when not sending messages. */
1278 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1281 generate_forward_declaration_to_string_table ();
1283 /* Forward declare constant_string_id and constant_string_type. */
1284 constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME);
1285 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1288 /* Custom build_string which sets TREE_TYPE! */
1290 static tree
1291 my_build_string (len, str)
1292 int len;
1293 const char *str;
1295 int wide_flag = 0;
1296 tree a_string = build_string (len, str);
1298 /* Some code from combine_strings, which is local to c-parse.y. */
1299 if (TREE_TYPE (a_string) == int_array_type_node)
1300 wide_flag = 1;
1302 TREE_TYPE (a_string)
1303 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1304 build_index_type (build_int_2 (len - 1, 0)));
1306 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1307 TREE_STATIC (a_string) = 1;
1309 return a_string;
1312 /* Return a newly constructed OBJC_STRING_CST node whose value is
1313 the LEN characters at STR.
1314 The TREE_TYPE is not initialized. */
1316 tree
1317 build_objc_string (len, str)
1318 int len;
1319 const char *str;
1321 tree s = build_string (len, str);
1323 TREE_SET_CODE (s, OBJC_STRING_CST);
1324 return s;
1327 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1328 NXConstanString which points at the concatenation of those strings.
1329 We place the string object in the __string_objects section of the
1330 __OBJC segment. The Objective-C runtime will initialize the isa
1331 pointers of the string objects to point at the NXConstandString class
1332 object. */
1334 tree
1335 build_objc_string_object (strings)
1336 tree strings;
1338 tree string, initlist, constructor;
1339 int length;
1341 if (!doing_objc_thang)
1342 objc_fatal ();
1344 if (lookup_interface (constant_string_id) == NULL_TREE)
1346 error ("Cannot find interface declaration for `%s'",
1347 IDENTIFIER_POINTER (constant_string_id));
1348 return error_mark_node;
1351 add_class_reference (constant_string_id);
1353 /* Combine_strings will work for OBJC_STRING_CST's too. */
1354 string = combine_strings (strings);
1355 TREE_SET_CODE (string, STRING_CST);
1356 length = TREE_STRING_LENGTH (string) - 1;
1358 /* & ((NXConstantString) {0, string, length}) */
1360 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1361 initlist
1362 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1363 initlist);
1364 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1365 constructor = build_constructor (constant_string_type, nreverse (initlist));
1367 if (!flag_next_runtime)
1369 constructor
1370 = objc_add_static_instance (constructor, constant_string_type);
1373 return (build_unary_op (ADDR_EXPR, constructor, 1));
1376 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1378 static tree
1379 objc_add_static_instance (constructor, class_decl)
1380 tree constructor, class_decl;
1382 static int num_static_inst;
1383 tree *chain, decl;
1384 char buf[256];
1386 /* Find the list of static instances for the CLASS_DECL. Create one if
1387 not found. */
1388 for (chain = &objc_static_instances;
1389 *chain && TREE_VALUE (*chain) != class_decl;
1390 chain = &TREE_CHAIN (*chain));
1391 if (!*chain)
1393 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1394 add_objc_string (TYPE_NAME (class_decl), class_names);
1397 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1398 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1399 DECL_COMMON (decl) = 1;
1400 TREE_STATIC (decl) = 1;
1401 DECL_ARTIFICIAL (decl) = 1;
1402 pushdecl_top_level (decl);
1403 rest_of_decl_compilation (decl, 0, 1, 0);
1405 /* Do this here so it gets output later instead of possibly
1406 inside something else we are writing. */
1407 DECL_INITIAL (decl) = constructor;
1409 /* Add the DECL to the head of this CLASS' list. */
1410 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1412 return decl;
1415 /* Build a static constant CONSTRUCTOR
1416 with type TYPE and elements ELTS. */
1418 static tree
1419 build_constructor (type, elts)
1420 tree type, elts;
1422 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1424 TREE_CONSTANT (constructor) = 1;
1425 TREE_STATIC (constructor) = 1;
1426 TREE_READONLY (constructor) = 1;
1428 return constructor;
1431 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1433 /* Predefine the following data type:
1435 struct _objc_symtab
1437 long sel_ref_cnt;
1438 SEL *refs;
1439 short cls_def_cnt;
1440 short cat_def_cnt;
1441 void *defs[cls_def_cnt + cat_def_cnt];
1442 }; */
1444 static void
1445 build_objc_symtab_template ()
1447 tree field_decl, field_decl_chain, index;
1449 objc_symtab_template
1450 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1452 /* long sel_ref_cnt; */
1454 field_decl = create_builtin_decl (FIELD_DECL,
1455 long_integer_type_node,
1456 "sel_ref_cnt");
1457 field_decl_chain = field_decl;
1459 /* SEL *refs; */
1461 field_decl = create_builtin_decl (FIELD_DECL,
1462 build_pointer_type (selector_type),
1463 "refs");
1464 chainon (field_decl_chain, field_decl);
1466 /* short cls_def_cnt; */
1468 field_decl = create_builtin_decl (FIELD_DECL,
1469 short_integer_type_node,
1470 "cls_def_cnt");
1471 chainon (field_decl_chain, field_decl);
1473 /* short cat_def_cnt; */
1475 field_decl = create_builtin_decl (FIELD_DECL,
1476 short_integer_type_node,
1477 "cat_def_cnt");
1478 chainon (field_decl_chain, field_decl);
1480 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1482 if (!flag_next_runtime)
1483 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1484 else
1485 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1486 imp_count == 0 && cat_count == 0
1487 ? -1 : 0));
1488 field_decl = create_builtin_decl (FIELD_DECL,
1489 build_array_type (ptr_type_node, index),
1490 "defs");
1491 chainon (field_decl_chain, field_decl);
1493 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1496 /* Create the initial value for the `defs' field of _objc_symtab.
1497 This is a CONSTRUCTOR. */
1499 static tree
1500 init_def_list (type)
1501 tree type;
1503 tree expr, initlist = NULL_TREE;
1504 struct imp_entry *impent;
1506 if (imp_count)
1507 for (impent = imp_list; impent; impent = impent->next)
1509 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1511 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1512 initlist = tree_cons (NULL_TREE, expr, initlist);
1516 if (cat_count)
1517 for (impent = imp_list; impent; impent = impent->next)
1519 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1521 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1522 initlist = tree_cons (NULL_TREE, expr, initlist);
1526 if (!flag_next_runtime)
1528 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1529 tree expr;
1531 if (static_instances_decl)
1532 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1533 else
1534 expr = build_int_2 (0, 0);
1536 initlist = tree_cons (NULL_TREE, expr, initlist);
1539 return build_constructor (type, nreverse (initlist));
1542 /* Construct the initial value for all of _objc_symtab. */
1544 static tree
1545 init_objc_symtab (type)
1546 tree type;
1548 tree initlist;
1550 /* sel_ref_cnt = { ..., 5, ... } */
1552 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1554 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1556 if (flag_next_runtime || ! sel_ref_chain)
1557 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1558 else
1559 initlist = tree_cons (NULL_TREE,
1560 build_unary_op (ADDR_EXPR,
1561 UOBJC_SELECTOR_TABLE_decl, 1),
1562 initlist);
1564 /* cls_def_cnt = { ..., 5, ... } */
1566 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1568 /* cat_def_cnt = { ..., 5, ... } */
1570 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1572 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1574 if (imp_count || cat_count || static_instances_decl)
1577 tree field = TYPE_FIELDS (type);
1578 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1580 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1581 initlist);
1584 return build_constructor (type, nreverse (initlist));
1587 /* Push forward-declarations of all the categories
1588 so that init_def_list can use them in a CONSTRUCTOR. */
1590 static void
1591 forward_declare_categories ()
1593 struct imp_entry *impent;
1594 tree sav = implementation_context;
1596 for (impent = imp_list; impent; impent = impent->next)
1598 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1600 /* Set an invisible arg to synth_id_with_class_suffix. */
1601 implementation_context = impent->imp_context;
1602 impent->class_decl
1603 = create_builtin_decl (VAR_DECL, objc_category_template,
1604 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1607 implementation_context = sav;
1610 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1611 and initialized appropriately. */
1613 static void
1614 generate_objc_symtab_decl ()
1616 tree sc_spec;
1618 if (!objc_category_template)
1619 build_category_template ();
1621 /* forward declare categories */
1622 if (cat_count)
1623 forward_declare_categories ();
1625 if (!objc_symtab_template)
1626 build_objc_symtab_template ();
1628 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1630 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1631 tree_cons (NULL_TREE,
1632 objc_symtab_template, sc_spec),
1634 NULL_TREE, NULL_TREE);
1636 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1637 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1638 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1639 finish_decl (UOBJC_SYMBOLS_decl,
1640 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1641 NULL_TREE);
1644 static tree
1645 init_module_descriptor (type)
1646 tree type;
1648 tree initlist, expr;
1650 /* version = { 1, ... } */
1652 expr = build_int_2 (OBJC_VERSION, 0);
1653 initlist = build_tree_list (NULL_TREE, expr);
1655 /* size = { ..., sizeof (struct objc_module), ... } */
1657 expr = size_in_bytes (objc_module_template);
1658 initlist = tree_cons (NULL_TREE, expr, initlist);
1660 /* name = { ..., "foo.m", ... } */
1662 expr = add_objc_string (get_identifier (input_filename), class_names);
1663 initlist = tree_cons (NULL_TREE, expr, initlist);
1665 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1667 if (UOBJC_SYMBOLS_decl)
1668 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1669 else
1670 expr = build_int_2 (0, 0);
1671 initlist = tree_cons (NULL_TREE, expr, initlist);
1673 return build_constructor (type, nreverse (initlist));
1676 /* Write out the data structures to describe Objective C classes defined.
1677 If appropriate, compile and output a setup function to initialize them.
1678 Return a string which is the name of a function to call to initialize
1679 the Objective C data structures for this file (and perhaps for other files
1680 also).
1682 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1684 static const char *
1685 build_module_descriptor ()
1687 tree decl_specs, field_decl, field_decl_chain;
1689 objc_module_template
1690 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1692 /* Long version; */
1694 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1695 field_decl = get_identifier ("version");
1696 field_decl
1697 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1698 field_decl_chain = field_decl;
1700 /* long size; */
1702 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1703 field_decl = get_identifier ("size");
1704 field_decl
1705 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1706 chainon (field_decl_chain, field_decl);
1708 /* char *name; */
1710 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1711 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1712 field_decl
1713 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1714 chainon (field_decl_chain, field_decl);
1716 /* struct objc_symtab *symtab; */
1718 decl_specs = get_identifier (UTAG_SYMTAB);
1719 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1720 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1721 field_decl
1722 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1723 chainon (field_decl_chain, field_decl);
1725 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1727 /* Create an instance of "objc_module". */
1729 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1730 build_tree_list (NULL_TREE,
1731 ridpointers[(int) RID_STATIC]));
1733 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1734 decl_specs, 1, NULL_TREE, NULL_TREE);
1736 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1737 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1738 finish_decl (UOBJC_MODULES_decl,
1739 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1740 NULL_TREE);
1742 /* Mark the decl to avoid "defined but not used" warning. */
1743 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1745 /* Generate a constructor call for the module descriptor.
1746 This code was generated by reading the grammar rules
1747 of c-parse.in; Therefore, it may not be the most efficient
1748 way of generating the requisite code. */
1750 if (flag_next_runtime)
1751 return 0;
1754 tree parms, function_decl, decelerator, void_list_node_1;
1755 tree function_type;
1756 tree init_function_name = get_file_function_name ('I');
1758 /* Declare void __objc_execClass (void *); */
1760 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1761 function_type
1762 = build_function_type (void_type_node,
1763 tree_cons (NULL_TREE, ptr_type_node,
1764 void_list_node_1));
1765 function_decl = build_decl (FUNCTION_DECL,
1766 get_identifier (TAG_EXECCLASS),
1767 function_type);
1768 DECL_EXTERNAL (function_decl) = 1;
1769 DECL_ARTIFICIAL (function_decl) = 1;
1770 TREE_PUBLIC (function_decl) = 1;
1772 pushdecl (function_decl);
1773 rest_of_decl_compilation (function_decl, 0, 0, 0);
1775 parms
1776 = build_tree_list (NULL_TREE,
1777 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1778 decelerator = build_function_call (function_decl, parms);
1780 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1782 start_function (void_list_node_1,
1783 build_parse_node (CALL_EXPR, init_function_name,
1784 /* This has the format of the output
1785 of get_parm_info. */
1786 tree_cons (NULL_TREE, NULL_TREE,
1787 void_list_node_1),
1788 NULL_TREE),
1789 NULL_TREE, NULL_TREE);
1790 #if 0 /* This should be turned back on later
1791 for the systems where collect is not needed. */
1792 /* Make these functions nonglobal
1793 so each file can use the same name. */
1794 TREE_PUBLIC (current_function_decl) = 0;
1795 #endif
1796 TREE_USED (current_function_decl) = 1;
1797 store_parm_decls ();
1799 assemble_external (function_decl);
1800 c_expand_expr_stmt (decelerator);
1802 TREE_PUBLIC (current_function_decl) = 1;
1804 function_decl = current_function_decl;
1805 finish_function (0);
1807 /* Return the name of the constructor function. */
1808 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1812 /* extern const char _OBJC_STRINGS[]; */
1814 static void
1815 generate_forward_declaration_to_string_table ()
1817 tree sc_spec, decl_specs, expr_decl;
1819 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1820 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1822 expr_decl
1823 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1825 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1828 /* Return the DECL of the string IDENT in the SECTION. */
1830 static tree
1831 get_objc_string_decl (ident, section)
1832 tree ident;
1833 enum string_section section;
1835 tree chain;
1837 if (section == class_names)
1838 chain = class_names_chain;
1839 else if (section == meth_var_names)
1840 chain = meth_var_names_chain;
1841 else if (section == meth_var_types)
1842 chain = meth_var_types_chain;
1843 else
1844 abort ();
1846 for (; chain != 0; chain = TREE_VALUE (chain))
1847 if (TREE_VALUE (chain) == ident)
1848 return (TREE_PURPOSE (chain));
1850 abort ();
1851 return NULL_TREE;
1854 /* Output references to all statically allocated objects. Return the DECL
1855 for the array built. */
1857 static void
1858 generate_static_references ()
1860 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1861 tree class_name, class, decl, initlist;
1862 tree cl_chain, in_chain, type;
1863 int num_inst, num_class;
1864 char buf[256];
1866 if (flag_next_runtime)
1867 abort ();
1869 for (cl_chain = objc_static_instances, num_class = 0;
1870 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1872 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1873 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1875 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1876 ident = get_identifier (buf);
1878 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1879 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1880 build_tree_list (NULL_TREE,
1881 ridpointers[(int) RID_STATIC]));
1882 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1883 DECL_CONTEXT (decl) = 0;
1884 DECL_ARTIFICIAL (decl) = 1;
1886 /* Output {class_name, ...}. */
1887 class = TREE_VALUE (cl_chain);
1888 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1889 initlist = build_tree_list (NULL_TREE,
1890 build_unary_op (ADDR_EXPR, class_name, 1));
1892 /* Output {..., instance, ...}. */
1893 for (in_chain = TREE_PURPOSE (cl_chain);
1894 in_chain; in_chain = TREE_CHAIN (in_chain))
1896 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1897 initlist = tree_cons (NULL_TREE, expr, initlist);
1900 /* Output {..., NULL}. */
1901 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1903 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1904 finish_decl (decl, expr, NULL_TREE);
1905 TREE_USED (decl) = 1;
1907 type = build_array_type (build_pointer_type (void_type_node), 0);
1908 decl = build_decl (VAR_DECL, ident, type);
1909 make_decl_rtl (decl, 0, 1);
1910 TREE_USED (decl) = 1;
1911 decls
1912 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1915 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1916 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1917 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1918 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1919 build_tree_list (NULL_TREE,
1920 ridpointers[(int) RID_STATIC]));
1921 static_instances_decl
1922 = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1923 TREE_USED (static_instances_decl) = 1;
1924 DECL_CONTEXT (static_instances_decl) = 0;
1925 DECL_ARTIFICIAL (static_instances_decl) = 1;
1926 expr = build_constructor (TREE_TYPE (static_instances_decl),
1927 nreverse (decls));
1928 finish_decl (static_instances_decl, expr, NULL_TREE);
1931 /* Output all strings. */
1933 static void
1934 generate_strings ()
1936 tree sc_spec, decl_specs, expr_decl;
1937 tree chain, string_expr;
1938 tree string, decl;
1940 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
1942 string = TREE_VALUE (chain);
1943 decl = TREE_PURPOSE (chain);
1944 sc_spec
1945 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1946 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1947 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1948 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1949 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1950 IDENTIFIER_POINTER (string));
1951 finish_decl (decl, string_expr, NULL_TREE);
1954 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
1956 string = TREE_VALUE (chain);
1957 decl = TREE_PURPOSE (chain);
1958 sc_spec
1959 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1960 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1961 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1962 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1963 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1964 IDENTIFIER_POINTER (string));
1965 finish_decl (decl, string_expr, NULL_TREE);
1968 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
1970 string = TREE_VALUE (chain);
1971 decl = TREE_PURPOSE (chain);
1972 sc_spec
1973 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
1974 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1975 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
1976 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
1977 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
1978 IDENTIFIER_POINTER (string));
1979 finish_decl (decl, string_expr, NULL_TREE);
1983 static tree
1984 build_selector_reference_decl ()
1986 tree decl, ident;
1987 char buf[256];
1988 static int idx = 0;
1990 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
1992 ident = get_identifier (buf);
1994 decl = build_decl (VAR_DECL, ident, selector_type);
1995 DECL_EXTERNAL (decl) = 1;
1996 TREE_PUBLIC (decl) = 1;
1997 TREE_USED (decl) = 1;
1998 TREE_READONLY (decl) = 1;
1999 DECL_ARTIFICIAL (decl) = 1;
2000 DECL_CONTEXT (decl) = 0;
2002 make_decl_rtl (decl, 0, 1);
2003 pushdecl_top_level (decl);
2005 return decl;
2008 /* Just a handy wrapper for add_objc_string. */
2010 static tree
2011 build_selector (ident)
2012 tree ident;
2014 tree expr = add_objc_string (ident, meth_var_names);
2015 if (flag_typed_selectors)
2016 return expr;
2017 else
2018 return build_c_cast (selector_type, expr); /* cast! */
2021 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2022 The cast stops the compiler from issuing the following message:
2023 grok.m: warning: initialization of non-const * pointer from const *
2024 grok.m: warning: initialization between incompatible pointer types. */
2026 #if 0
2027 static tree
2028 build_msg_pool_reference (offset)
2029 int offset;
2031 tree expr = build_int_2 (offset, 0);
2032 tree cast;
2034 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
2035 expr = build_unary_op (ADDR_EXPR, expr, 0);
2037 cast = build_tree_list (build_tree_list (NULL_TREE,
2038 ridpointers[(int) RID_CHAR]),
2039 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
2040 TREE_TYPE (expr) = groktypename (cast);
2041 return expr;
2044 static tree
2045 init_selector (offset)
2046 int offset;
2048 tree expr = build_msg_pool_reference (offset);
2049 TREE_TYPE (expr) = selector_type;
2050 return expr;
2052 #endif
2054 static void
2055 build_selector_translation_table ()
2057 tree sc_spec, decl_specs;
2058 tree chain, initlist = NULL_TREE;
2059 int offset = 0;
2060 tree decl = NULL_TREE, var_decl, name;
2062 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2064 tree expr;
2066 expr = build_selector (TREE_VALUE (chain));
2068 if (flag_next_runtime)
2070 name = DECL_NAME (TREE_PURPOSE (chain));
2072 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2074 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2075 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2077 var_decl = name;
2079 /* The `decl' that is returned from start_decl is the one that we
2080 forward declared in `build_selector_reference' */
2081 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2084 /* add one for the '\0' character */
2085 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2087 if (flag_next_runtime)
2088 finish_decl (decl, expr, NULL_TREE);
2089 else
2091 if (flag_typed_selectors)
2093 tree eltlist = NULL_TREE;
2094 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2095 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2096 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2097 expr = build_constructor (objc_selector_template,
2098 nreverse (eltlist));
2100 initlist = tree_cons (NULL_TREE, expr, initlist);
2105 if (! flag_next_runtime)
2107 /* Cause the variable and its initial value to be actually output. */
2108 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2109 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2110 /* NULL terminate the list and fix the decl for output. */
2111 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2112 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
2113 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2114 nreverse (initlist));
2115 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2116 current_function_decl = NULL_TREE;
2120 static tree
2121 get_proto_encoding (proto)
2122 tree proto;
2124 tree encoding;
2125 if (proto)
2127 tree tmp_decl;
2129 if (! METHOD_ENCODING (proto))
2131 tmp_decl = build_tmp_function_decl ();
2132 hack_method_prototype (proto, tmp_decl);
2133 encoding = encode_method_prototype (proto, tmp_decl);
2134 METHOD_ENCODING (proto) = encoding;
2136 else
2137 encoding = METHOD_ENCODING (proto);
2139 return add_objc_string (encoding, meth_var_types);
2141 else
2142 return build_int_2 (0, 0);
2145 /* sel_ref_chain is a list whose "value" fields will be instances of
2146 identifier_node that represent the selector. */
2148 static tree
2149 build_typed_selector_reference (ident, proto)
2150 tree ident, proto;
2152 tree *chain = &sel_ref_chain;
2153 tree expr;
2154 int index = 0;
2156 while (*chain)
2158 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2159 goto return_at_index;
2161 index++;
2162 chain = &TREE_CHAIN (*chain);
2165 *chain = tree_cons (proto, ident, NULL_TREE);
2167 return_at_index:
2168 expr = build_unary_op (ADDR_EXPR,
2169 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2170 build_int_2 (index, 0)),
2172 return build_c_cast (selector_type, expr);
2175 static tree
2176 build_selector_reference (ident)
2177 tree ident;
2179 tree *chain = &sel_ref_chain;
2180 tree expr;
2181 int index = 0;
2183 while (*chain)
2185 if (TREE_VALUE (*chain) == ident)
2186 return (flag_next_runtime
2187 ? TREE_PURPOSE (*chain)
2188 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2189 build_int_2 (index, 0)));
2191 index++;
2192 chain = &TREE_CHAIN (*chain);
2195 expr = build_selector_reference_decl ();
2197 *chain = tree_cons (expr, ident, NULL_TREE);
2199 return (flag_next_runtime
2200 ? expr
2201 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2202 build_int_2 (index, 0)));
2205 static tree
2206 build_class_reference_decl ()
2208 tree decl, ident;
2209 char buf[256];
2210 static int idx = 0;
2212 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2214 ident = get_identifier (buf);
2216 decl = build_decl (VAR_DECL, ident, objc_class_type);
2217 DECL_EXTERNAL (decl) = 1;
2218 TREE_PUBLIC (decl) = 1;
2219 TREE_USED (decl) = 1;
2220 TREE_READONLY (decl) = 1;
2221 DECL_CONTEXT (decl) = 0;
2222 DECL_ARTIFICIAL (decl) = 1;
2224 make_decl_rtl (decl, 0, 1);
2225 pushdecl_top_level (decl);
2227 return decl;
2230 /* Create a class reference, but don't create a variable to reference
2231 it. */
2233 static void
2234 add_class_reference (ident)
2235 tree ident;
2237 tree chain;
2239 if ((chain = cls_ref_chain))
2241 tree tail;
2244 if (ident == TREE_VALUE (chain))
2245 return;
2247 tail = chain;
2248 chain = TREE_CHAIN (chain);
2250 while (chain);
2252 /* Append to the end of the list */
2253 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2255 else
2256 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2259 /* Get a class reference, creating it if necessary. Also create the
2260 reference variable. */
2262 tree
2263 get_class_reference (ident)
2264 tree ident;
2266 if (flag_next_runtime)
2268 tree *chain;
2269 tree decl;
2271 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2272 if (TREE_VALUE (*chain) == ident)
2274 if (! TREE_PURPOSE (*chain))
2275 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2277 return TREE_PURPOSE (*chain);
2280 decl = build_class_reference_decl ();
2281 *chain = tree_cons (decl, ident, NULL_TREE);
2282 return decl;
2284 else
2286 tree params;
2288 add_class_reference (ident);
2290 params = build_tree_list (NULL_TREE,
2291 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2292 IDENTIFIER_POINTER (ident)));
2294 assemble_external (objc_get_class_decl);
2295 return build_function_call (objc_get_class_decl, params);
2299 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2300 of identifier_node that represent the selector. It returns the
2301 offset of the selector from the beginning of the _OBJC_STRINGS
2302 pool. This offset is typically used by init_selector during code
2303 generation.
2305 For each string section we have a chain which maps identifier nodes
2306 to decls for the strings. */
2308 static tree
2309 add_objc_string (ident, section)
2310 tree ident;
2311 enum string_section section;
2313 tree *chain, decl;
2315 if (section == class_names)
2316 chain = &class_names_chain;
2317 else if (section == meth_var_names)
2318 chain = &meth_var_names_chain;
2319 else if (section == meth_var_types)
2320 chain = &meth_var_types_chain;
2321 else
2322 abort ();
2324 while (*chain)
2326 if (TREE_VALUE (*chain) == ident)
2327 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2329 chain = &TREE_CHAIN (*chain);
2332 decl = build_objc_string_decl (section);
2334 *chain = tree_cons (decl, ident, NULL_TREE);
2336 return build_unary_op (ADDR_EXPR, decl, 1);
2339 static tree
2340 build_objc_string_decl (section)
2341 enum string_section section;
2343 tree decl, ident;
2344 char buf[256];
2345 static int class_names_idx = 0;
2346 static int meth_var_names_idx = 0;
2347 static int meth_var_types_idx = 0;
2349 if (section == class_names)
2350 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2351 else if (section == meth_var_names)
2352 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2353 else if (section == meth_var_types)
2354 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2356 ident = get_identifier (buf);
2358 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2359 DECL_EXTERNAL (decl) = 1;
2360 TREE_PUBLIC (decl) = 1;
2361 TREE_USED (decl) = 1;
2362 TREE_READONLY (decl) = 1;
2363 TREE_CONSTANT (decl) = 1;
2364 DECL_CONTEXT (decl) = 0;
2365 DECL_ARTIFICIAL (decl) = 1;
2367 make_decl_rtl (decl, 0, 1);
2368 pushdecl_top_level (decl);
2370 return decl;
2374 void
2375 objc_declare_alias (alias_ident, class_ident)
2376 tree alias_ident;
2377 tree class_ident;
2379 if (!doing_objc_thang)
2380 objc_fatal ();
2382 if (is_class_name (class_ident) != class_ident)
2383 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2384 else if (is_class_name (alias_ident))
2385 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2386 else
2387 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2390 void
2391 objc_declare_class (ident_list)
2392 tree ident_list;
2394 tree list;
2396 if (!doing_objc_thang)
2397 objc_fatal ();
2399 for (list = ident_list; list; list = TREE_CHAIN (list))
2401 tree ident = TREE_VALUE (list);
2402 tree decl;
2404 if ((decl = lookup_name (ident)))
2406 error ("`%s' redeclared as different kind of symbol",
2407 IDENTIFIER_POINTER (ident));
2408 error_with_decl (decl, "previous declaration of `%s'");
2411 if (! is_class_name (ident))
2413 tree record = xref_tag (RECORD_TYPE, ident);
2414 TREE_STATIC_TEMPLATE (record) = 1;
2415 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2420 tree
2421 is_class_name (ident)
2422 tree ident;
2424 tree chain;
2426 if (lookup_interface (ident))
2427 return ident;
2429 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2431 if (ident == TREE_VALUE (chain))
2432 return ident;
2435 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2437 if (ident == TREE_VALUE (chain))
2438 return TREE_PURPOSE (chain);
2441 return 0;
2444 tree
2445 lookup_interface (ident)
2446 tree ident;
2448 tree chain;
2450 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2452 if (ident == CLASS_NAME (chain))
2453 return chain;
2455 return NULL_TREE;
2458 static tree
2459 objc_copy_list (list, head)
2460 tree list;
2461 tree *head;
2463 tree newlist = NULL_TREE, tail = NULL_TREE;
2465 while (list)
2467 tail = copy_node (list);
2469 /* The following statement fixes a bug when inheriting instance
2470 variables that are declared to be bitfields. finish_struct
2471 expects to find the width of the bitfield in DECL_INITIAL. */
2472 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2473 DECL_INITIAL (tail) = DECL_SIZE (tail);
2475 newlist = chainon (newlist, tail);
2476 list = TREE_CHAIN (list);
2479 *head = newlist;
2480 return tail;
2483 /* Used by: build_private_template, get_class_ivars, and
2484 continue_class. COPY is 1 when called from @defs. In this case
2485 copy all fields. Otherwise don't copy leaf ivars since we rely on
2486 them being side-effected exactly once by finish_struct. */
2488 static tree
2489 build_ivar_chain (interface, copy)
2490 tree interface;
2491 int copy;
2493 tree my_name, super_name, ivar_chain;
2495 my_name = CLASS_NAME (interface);
2496 super_name = CLASS_SUPER_NAME (interface);
2498 /* Possibly copy leaf ivars. */
2499 if (copy)
2500 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2501 else
2502 ivar_chain = CLASS_IVARS (interface);
2504 while (super_name)
2506 tree op1;
2507 tree super_interface = lookup_interface (super_name);
2509 if (!super_interface)
2511 /* fatal did not work with 2 args...should fix */
2512 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2513 IDENTIFIER_POINTER (super_name),
2514 IDENTIFIER_POINTER (my_name));
2515 exit (FATAL_EXIT_CODE);
2518 if (super_interface == interface)
2520 fatal ("Circular inheritance in interface declaration for `%s'",
2521 IDENTIFIER_POINTER (super_name));
2524 interface = super_interface;
2525 my_name = CLASS_NAME (interface);
2526 super_name = CLASS_SUPER_NAME (interface);
2528 op1 = CLASS_IVARS (interface);
2529 if (op1)
2531 tree head, tail = objc_copy_list (op1, &head);
2533 /* Prepend super class ivars...make a copy of the list, we
2534 do not want to alter the original. */
2535 TREE_CHAIN (tail) = ivar_chain;
2536 ivar_chain = head;
2539 return ivar_chain;
2542 /* struct <classname> {
2543 struct objc_class *isa;
2545 }; */
2547 static tree
2548 build_private_template (class)
2549 tree class;
2551 tree ivar_context;
2553 if (CLASS_STATIC_TEMPLATE (class))
2555 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2556 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2558 else
2560 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2562 ivar_context = build_ivar_chain (class, 0);
2564 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2566 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2568 /* mark this record as class template - for class type checking */
2569 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2572 instance_type
2573 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2574 uprivate_record),
2575 build1 (INDIRECT_REF, NULL_TREE,
2576 NULL_TREE)));
2578 return ivar_context;
2581 /* Begin code generation for protocols... */
2583 /* struct objc_protocol {
2584 char *protocol_name;
2585 struct objc_protocol **protocol_list;
2586 struct objc_method_desc *instance_methods;
2587 struct objc_method_desc *class_methods;
2588 }; */
2590 static tree
2591 build_protocol_template ()
2593 tree decl_specs, field_decl, field_decl_chain;
2594 tree template;
2596 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2598 /* struct objc_class *isa; */
2600 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2601 get_identifier (UTAG_CLASS)));
2602 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2603 field_decl
2604 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2605 field_decl_chain = field_decl;
2607 /* char *protocol_name; */
2609 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2610 field_decl
2611 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2612 field_decl
2613 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2614 chainon (field_decl_chain, field_decl);
2616 /* struct objc_protocol **protocol_list; */
2618 decl_specs = build_tree_list (NULL_TREE, template);
2619 field_decl
2620 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2621 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2622 field_decl
2623 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2624 chainon (field_decl_chain, field_decl);
2626 /* struct objc_method_list *instance_methods; */
2628 decl_specs
2629 = build_tree_list (NULL_TREE,
2630 xref_tag (RECORD_TYPE,
2631 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2632 field_decl
2633 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2634 field_decl
2635 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2636 chainon (field_decl_chain, field_decl);
2638 /* struct objc_method_list *class_methods; */
2640 decl_specs
2641 = build_tree_list (NULL_TREE,
2642 xref_tag (RECORD_TYPE,
2643 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2644 field_decl
2645 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2646 field_decl
2647 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2648 chainon (field_decl_chain, field_decl);
2650 return finish_struct (template, field_decl_chain, NULL_TREE);
2653 static tree
2654 build_descriptor_table_initializer (type, entries)
2655 tree type;
2656 tree entries;
2658 tree initlist = NULL_TREE;
2662 tree eltlist = NULL_TREE;
2664 eltlist
2665 = tree_cons (NULL_TREE,
2666 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2667 eltlist
2668 = tree_cons (NULL_TREE,
2669 add_objc_string (METHOD_ENCODING (entries),
2670 meth_var_types),
2671 eltlist);
2673 initlist
2674 = tree_cons (NULL_TREE,
2675 build_constructor (type, nreverse (eltlist)), initlist);
2677 entries = TREE_CHAIN (entries);
2679 while (entries);
2681 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2684 /* struct objc_method_prototype_list {
2685 int count;
2686 struct objc_method_prototype {
2687 SEL name;
2688 char *types;
2689 } list[1];
2690 }; */
2692 static tree
2693 build_method_prototype_list_template (list_type, size)
2694 tree list_type;
2695 int size;
2697 tree objc_ivar_list_record;
2698 tree decl_specs, field_decl, field_decl_chain;
2700 /* Generate an unnamed struct definition. */
2702 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2704 /* int method_count; */
2706 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2707 field_decl = get_identifier ("method_count");
2709 field_decl
2710 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2711 field_decl_chain = field_decl;
2713 /* struct objc_method method_list[]; */
2715 decl_specs = build_tree_list (NULL_TREE, list_type);
2716 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2717 build_int_2 (size, 0));
2719 field_decl
2720 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2721 chainon (field_decl_chain, field_decl);
2723 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2725 return objc_ivar_list_record;
2728 static tree
2729 build_method_prototype_template ()
2731 tree proto_record;
2732 tree decl_specs, field_decl, field_decl_chain;
2734 proto_record
2735 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2737 #ifdef OBJC_INT_SELECTORS
2738 /* unsigned int _cmd; */
2739 decl_specs
2740 = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2741 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2742 field_decl = get_identifier ("_cmd");
2743 #else /* OBJC_INT_SELECTORS */
2744 /* struct objc_selector *_cmd; */
2745 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2746 get_identifier (TAG_SELECTOR)), NULL_TREE);
2747 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2748 #endif /* OBJC_INT_SELECTORS */
2750 field_decl
2751 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2752 field_decl_chain = field_decl;
2754 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2755 field_decl
2756 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2757 field_decl
2758 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2759 chainon (field_decl_chain, field_decl);
2761 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2763 return proto_record;
2766 /* True if last call to forwarding_offset yielded a register offset. */
2767 static int offset_is_register;
2769 static int
2770 forwarding_offset (parm)
2771 tree parm;
2773 int offset_in_bytes;
2775 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2777 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2779 /* ??? Here we assume that the parm address is indexed
2780 off the frame pointer or arg pointer.
2781 If that is not true, we produce meaningless results,
2782 but do not crash. */
2783 if (GET_CODE (addr) == PLUS
2784 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2785 offset_in_bytes = INTVAL (XEXP (addr, 1));
2786 else
2787 offset_in_bytes = 0;
2789 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2790 offset_is_register = 0;
2792 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2794 int regno = REGNO (DECL_INCOMING_RTL (parm));
2795 offset_in_bytes = apply_args_register_offset (regno);
2796 offset_is_register = 1;
2798 else
2799 return 0;
2801 /* This is the case where the parm is passed as an int or double
2802 and it is converted to a char, short or float and stored back
2803 in the parmlist. In this case, describe the parm
2804 with the variable's declared type, and adjust the address
2805 if the least significant bytes (which we are using) are not
2806 the first ones. */
2807 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2808 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2809 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2811 return offset_in_bytes;
2814 static tree
2815 encode_method_prototype (method_decl, func_decl)
2816 tree method_decl;
2817 tree func_decl;
2819 tree parms;
2820 int stack_size, i;
2821 tree user_args;
2822 int max_parm_end = 0;
2823 char buf[40];
2824 tree result;
2826 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2827 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2829 /* C type. */
2830 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2831 obstack_object_size (&util_obstack),
2832 OBJC_ENCODE_INLINE_DEFS);
2834 /* Stack size. */
2835 for (parms = DECL_ARGUMENTS (func_decl); parms;
2836 parms = TREE_CHAIN (parms))
2838 int parm_end = (forwarding_offset (parms)
2839 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
2840 / BITS_PER_UNIT));
2842 if (!offset_is_register && max_parm_end < parm_end)
2843 max_parm_end = parm_end;
2846 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2848 sprintf (buf, "%d", stack_size);
2849 obstack_grow (&util_obstack, buf, strlen (buf));
2851 user_args = METHOD_SEL_ARGS (method_decl);
2853 /* Argument types. */
2854 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2855 parms = TREE_CHAIN (parms), i++)
2857 /* Process argument qualifiers for user supplied arguments. */
2858 if (i > 1)
2860 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2861 user_args = TREE_CHAIN (user_args);
2864 /* Type. */
2865 encode_type (TREE_TYPE (parms),
2866 obstack_object_size (&util_obstack),
2867 OBJC_ENCODE_INLINE_DEFS);
2869 /* Compute offset. */
2870 sprintf (buf, "%d", forwarding_offset (parms));
2872 /* Indicate register. */
2873 if (offset_is_register)
2874 obstack_1grow (&util_obstack, '+');
2876 obstack_grow (&util_obstack, buf, strlen (buf));
2879 obstack_1grow (&util_obstack, '\0');
2880 result = get_identifier (obstack_finish (&util_obstack));
2881 obstack_free (&util_obstack, util_firstobj);
2882 return result;
2885 static tree
2886 generate_descriptor_table (type, name, size, list, proto)
2887 tree type;
2888 const char *name;
2889 int size;
2890 tree list;
2891 tree proto;
2893 tree sc_spec, decl_specs, decl, initlist;
2895 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2896 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2898 decl = start_decl (synth_id_with_class_suffix (name, proto),
2899 decl_specs, 1, NULL_TREE, NULL_TREE);
2901 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2902 initlist = tree_cons (NULL_TREE, list, initlist);
2904 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2905 NULL_TREE);
2907 return decl;
2910 static void
2911 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2912 tree protocol;
2914 static tree objc_method_prototype_template;
2915 tree initlist, chain, method_list_template;
2916 tree cast, variable_length_type;
2917 int size;
2919 if (!objc_method_prototype_template)
2920 objc_method_prototype_template = build_method_prototype_template ();
2922 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2923 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2924 NULL_TREE);
2925 variable_length_type = groktypename (cast);
2927 chain = PROTOCOL_CLS_METHODS (protocol);
2928 if (chain)
2930 size = list_length (chain);
2932 method_list_template
2933 = build_method_prototype_list_template (objc_method_prototype_template,
2934 size);
2936 initlist
2937 = build_descriptor_table_initializer (objc_method_prototype_template,
2938 chain);
2940 UOBJC_CLASS_METHODS_decl
2941 = generate_descriptor_table (method_list_template,
2942 "_OBJC_PROTOCOL_CLASS_METHODS",
2943 size, initlist, protocol);
2944 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
2946 else
2947 UOBJC_CLASS_METHODS_decl = 0;
2949 chain = PROTOCOL_NST_METHODS (protocol);
2950 if (chain)
2952 size = list_length (chain);
2954 method_list_template
2955 = build_method_prototype_list_template (objc_method_prototype_template,
2956 size);
2957 initlist
2958 = build_descriptor_table_initializer (objc_method_prototype_template,
2959 chain);
2961 UOBJC_INSTANCE_METHODS_decl
2962 = generate_descriptor_table (method_list_template,
2963 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2964 size, initlist, protocol);
2965 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
2967 else
2968 UOBJC_INSTANCE_METHODS_decl = 0;
2971 static tree
2972 build_tmp_function_decl ()
2974 tree decl_specs, expr_decl, parms;
2975 static int xxx = 0;
2976 char buffer[80];
2978 /* struct objc_object *objc_xxx (id, SEL, ...); */
2979 pushlevel (0);
2980 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2981 push_parm_decl (build_tree_list
2982 (build_tree_list (decl_specs,
2983 build1 (INDIRECT_REF, NULL_TREE,
2984 NULL_TREE)),
2985 build_tree_list (NULL_TREE, NULL_TREE)));
2987 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2988 get_identifier (TAG_SELECTOR)));
2989 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
2991 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
2992 build_tree_list (NULL_TREE, NULL_TREE)));
2993 parms = get_parm_info (0);
2994 poplevel (0, 0, 0);
2996 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
2997 sprintf (buffer, "__objc_tmp_%x", xxx++);
2998 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
2999 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
3001 return define_decl (expr_decl, decl_specs);
3004 static void
3005 hack_method_prototype (nst_methods, tmp_decl)
3006 tree nst_methods;
3007 tree tmp_decl;
3009 tree parms;
3010 tree parm;
3012 /* Hack to avoid problem with static typing of self arg. */
3013 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
3014 start_method_def (nst_methods);
3015 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
3017 if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
3018 parms = get_parm_info (0); /* we have a `, ...' */
3019 else
3020 parms = get_parm_info (1); /* place a `void_at_end' */
3022 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3024 /* Usually called from store_parm_decls -> init_function_start. */
3026 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
3027 current_function_decl = tmp_decl;
3030 /* Code taken from start_function. */
3031 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3032 /* Promote the value to int before returning it. */
3033 if (TREE_CODE (restype) == INTEGER_TYPE
3034 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3035 restype = integer_type_node;
3036 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3039 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3040 DECL_CONTEXT (parm) = tmp_decl;
3042 init_function_start (tmp_decl, "objc-act", 0);
3044 /* Typically called from expand_function_start for function definitions. */
3045 assign_parms (tmp_decl);
3047 /* install return type */
3048 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3052 static void
3053 generate_protocol_references (plist)
3054 tree plist;
3056 tree lproto;
3058 /* Forward declare protocols referenced. */
3059 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3061 tree proto = TREE_VALUE (lproto);
3063 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3064 && PROTOCOL_NAME (proto))
3066 if (! PROTOCOL_FORWARD_DECL (proto))
3067 build_protocol_reference (proto);
3069 if (PROTOCOL_LIST (proto))
3070 generate_protocol_references (PROTOCOL_LIST (proto));
3075 static void
3076 generate_protocols ()
3078 tree p, tmp_decl, encoding;
3079 tree sc_spec, decl_specs, decl;
3080 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3081 tree cast_type2 = 0;
3083 tmp_decl = build_tmp_function_decl ();
3085 if (! objc_protocol_template)
3086 objc_protocol_template = build_protocol_template ();
3088 /* If a protocol was directly referenced, pull in indirect references. */
3089 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3090 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3091 generate_protocol_references (PROTOCOL_LIST (p));
3093 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3095 tree nst_methods = PROTOCOL_NST_METHODS (p);
3096 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3098 /* If protocol wasn't referenced, don't generate any code. */
3099 if (! PROTOCOL_FORWARD_DECL (p))
3100 continue;
3102 /* Make sure we link in the Protocol class. */
3103 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3105 while (nst_methods)
3107 if (! METHOD_ENCODING (nst_methods))
3109 hack_method_prototype (nst_methods, tmp_decl);
3110 encoding = encode_method_prototype (nst_methods, tmp_decl);
3111 METHOD_ENCODING (nst_methods) = encoding;
3113 nst_methods = TREE_CHAIN (nst_methods);
3116 while (cls_methods)
3118 if (! METHOD_ENCODING (cls_methods))
3120 hack_method_prototype (cls_methods, tmp_decl);
3121 encoding = encode_method_prototype (cls_methods, tmp_decl);
3122 METHOD_ENCODING (cls_methods) = encoding;
3125 cls_methods = TREE_CHAIN (cls_methods);
3127 generate_method_descriptors (p);
3129 if (PROTOCOL_LIST (p))
3130 refs_decl = generate_protocol_list (p);
3131 else
3132 refs_decl = 0;
3134 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3136 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3137 NULL_TREE);
3138 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3140 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3141 decl_specs, 1, NULL_TREE, NULL_TREE);
3143 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3145 if (refs_decl)
3147 if (!cast_type2)
3148 cast_type2
3149 = groktypename
3150 (build_tree_list (build_tree_list (NULL_TREE,
3151 objc_protocol_template),
3152 build1 (INDIRECT_REF, NULL_TREE,
3153 build1 (INDIRECT_REF, NULL_TREE,
3154 NULL_TREE))));
3156 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3157 TREE_TYPE (refs_expr) = cast_type2;
3159 else
3160 refs_expr = build_int_2 (0, 0);
3162 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3163 by generate_method_descriptors, which is called above. */
3164 initlist = build_protocol_initializer (TREE_TYPE (decl),
3165 protocol_name_expr, refs_expr,
3166 UOBJC_INSTANCE_METHODS_decl,
3167 UOBJC_CLASS_METHODS_decl);
3168 finish_decl (decl, initlist, NULL_TREE);
3170 /* Mark the decl as used to avoid "defined but not used" warning. */
3171 TREE_USED (decl) = 1;
3175 static tree
3176 build_protocol_initializer (type, protocol_name, protocol_list,
3177 instance_methods, class_methods)
3178 tree type;
3179 tree protocol_name;
3180 tree protocol_list;
3181 tree instance_methods;
3182 tree class_methods;
3184 tree initlist = NULL_TREE, expr;
3185 static tree cast_type = 0;
3187 if (!cast_type)
3188 cast_type
3189 = groktypename
3190 (build_tree_list
3191 (build_tree_list (NULL_TREE,
3192 xref_tag (RECORD_TYPE,
3193 get_identifier (UTAG_CLASS))),
3194 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3196 /* Filling the "isa" in with one allows the runtime system to
3197 detect that the version change...should remove before final release. */
3199 expr = build_int_2 (PROTOCOL_VERSION, 0);
3200 TREE_TYPE (expr) = cast_type;
3201 initlist = tree_cons (NULL_TREE, expr, initlist);
3202 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3203 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3205 if (!instance_methods)
3206 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3207 else
3209 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3210 initlist = tree_cons (NULL_TREE, expr, initlist);
3213 if (!class_methods)
3214 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3215 else
3217 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3218 initlist = tree_cons (NULL_TREE, expr, initlist);
3221 return build_constructor (type, nreverse (initlist));
3224 /* struct objc_category {
3225 char *category_name;
3226 char *class_name;
3227 struct objc_method_list *instance_methods;
3228 struct objc_method_list *class_methods;
3229 struct objc_protocol_list *protocols;
3230 }; */
3232 static void
3233 build_category_template ()
3235 tree decl_specs, field_decl, field_decl_chain;
3237 objc_category_template = start_struct (RECORD_TYPE,
3238 get_identifier (UTAG_CATEGORY));
3239 /* char *category_name; */
3241 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3242 field_decl
3243 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3244 field_decl
3245 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3246 field_decl_chain = field_decl;
3248 /* char *class_name; */
3250 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3251 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3252 field_decl
3253 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3254 chainon (field_decl_chain, field_decl);
3256 /* struct objc_method_list *instance_methods; */
3258 decl_specs = build_tree_list (NULL_TREE,
3259 xref_tag (RECORD_TYPE,
3260 get_identifier (UTAG_METHOD_LIST)));
3261 field_decl
3262 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3263 field_decl
3264 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3265 chainon (field_decl_chain, field_decl);
3267 /* struct objc_method_list *class_methods; */
3269 decl_specs = build_tree_list (NULL_TREE,
3270 xref_tag (RECORD_TYPE,
3271 get_identifier (UTAG_METHOD_LIST)));
3272 field_decl
3273 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3274 field_decl
3275 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3276 chainon (field_decl_chain, field_decl);
3278 /* struct objc_protocol **protocol_list; */
3280 decl_specs = build_tree_list (NULL_TREE,
3281 xref_tag (RECORD_TYPE,
3282 get_identifier (UTAG_PROTOCOL)));
3283 field_decl
3284 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3285 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3286 field_decl
3287 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3288 chainon (field_decl_chain, field_decl);
3290 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3293 /* struct objc_selector {
3294 void *sel_id;
3295 char *sel_type;
3296 }; */
3298 static void
3299 build_selector_template ()
3302 tree decl_specs, field_decl, field_decl_chain;
3304 objc_selector_template
3305 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3307 /* void *sel_id; */
3309 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3310 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3311 field_decl
3312 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3313 field_decl_chain = field_decl;
3315 /* char *sel_type; */
3317 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3318 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3319 field_decl
3320 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3321 chainon (field_decl_chain, field_decl);
3323 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3326 /* struct objc_class {
3327 struct objc_class *isa;
3328 struct objc_class *super_class;
3329 char *name;
3330 long version;
3331 long info;
3332 long instance_size;
3333 struct objc_ivar_list *ivars;
3334 struct objc_method_list *methods;
3335 if (flag_next_runtime)
3336 struct objc_cache *cache;
3337 else {
3338 struct sarray *dtable;
3339 struct objc_class *subclass_list;
3340 struct objc_class *sibling_class;
3342 struct objc_protocol_list *protocols;
3343 void *gc_object_type;
3344 }; */
3346 static void
3347 build_class_template ()
3349 tree decl_specs, field_decl, field_decl_chain;
3351 objc_class_template
3352 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3354 /* struct objc_class *isa; */
3356 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3357 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3358 field_decl
3359 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3360 field_decl_chain = field_decl;
3362 /* struct objc_class *super_class; */
3364 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3365 field_decl
3366 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3367 field_decl
3368 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3369 chainon (field_decl_chain, field_decl);
3371 /* char *name; */
3373 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3374 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3375 field_decl
3376 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3377 chainon (field_decl_chain, field_decl);
3379 /* long version; */
3381 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3382 field_decl = get_identifier ("version");
3383 field_decl
3384 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3385 chainon (field_decl_chain, field_decl);
3387 /* long info; */
3389 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3390 field_decl = get_identifier ("info");
3391 field_decl
3392 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3393 chainon (field_decl_chain, field_decl);
3395 /* long instance_size; */
3397 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3398 field_decl = get_identifier ("instance_size");
3399 field_decl
3400 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3401 chainon (field_decl_chain, field_decl);
3403 /* struct objc_ivar_list *ivars; */
3405 decl_specs = build_tree_list (NULL_TREE,
3406 xref_tag (RECORD_TYPE,
3407 get_identifier (UTAG_IVAR_LIST)));
3408 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3409 field_decl
3410 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3411 chainon (field_decl_chain, field_decl);
3413 /* struct objc_method_list *methods; */
3415 decl_specs = build_tree_list (NULL_TREE,
3416 xref_tag (RECORD_TYPE,
3417 get_identifier (UTAG_METHOD_LIST)));
3418 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3419 field_decl
3420 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3421 chainon (field_decl_chain, field_decl);
3423 if (flag_next_runtime)
3425 /* struct objc_cache *cache; */
3427 decl_specs = build_tree_list (NULL_TREE,
3428 xref_tag (RECORD_TYPE,
3429 get_identifier ("objc_cache")));
3430 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3431 field_decl = grokfield (input_filename, lineno, field_decl,
3432 decl_specs, NULL_TREE);
3433 chainon (field_decl_chain, field_decl);
3435 else
3437 /* struct sarray *dtable; */
3439 decl_specs = build_tree_list (NULL_TREE,
3440 xref_tag (RECORD_TYPE,
3441 get_identifier ("sarray")));
3442 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3443 field_decl = grokfield (input_filename, lineno, field_decl,
3444 decl_specs, NULL_TREE);
3445 chainon (field_decl_chain, field_decl);
3447 /* struct objc_class *subclass_list; */
3449 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3450 field_decl
3451 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3452 field_decl = grokfield (input_filename, lineno, field_decl,
3453 decl_specs, NULL_TREE);
3454 chainon (field_decl_chain, field_decl);
3456 /* struct objc_class *sibling_class; */
3458 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3459 field_decl
3460 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3461 field_decl = grokfield (input_filename, lineno, field_decl,
3462 decl_specs, NULL_TREE);
3463 chainon (field_decl_chain, field_decl);
3466 /* struct objc_protocol **protocol_list; */
3468 decl_specs = build_tree_list (NULL_TREE,
3469 xref_tag (RECORD_TYPE,
3470 get_identifier (UTAG_PROTOCOL)));
3471 field_decl
3472 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3473 field_decl
3474 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3475 field_decl = grokfield (input_filename, lineno, field_decl,
3476 decl_specs, NULL_TREE);
3477 chainon (field_decl_chain, field_decl);
3479 /* void *sel_id; */
3481 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3482 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3483 field_decl
3484 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3485 chainon (field_decl_chain, field_decl);
3487 /* void *gc_object_type; */
3489 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3490 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3491 field_decl
3492 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3493 chainon (field_decl_chain, field_decl);
3495 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3498 /* Generate appropriate forward declarations for an implementation. */
3500 static void
3501 synth_forward_declarations ()
3503 tree sc_spec, decl_specs, an_id;
3505 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3507 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3509 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3510 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3511 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3512 TREE_USED (UOBJC_CLASS_decl) = 1;
3513 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3515 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3517 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3518 implementation_context);
3520 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3521 TREE_USED (UOBJC_METACLASS_decl) = 1;
3522 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3524 /* Pre-build the following entities - for speed/convenience. */
3526 an_id = get_identifier ("super_class");
3527 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3528 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3531 static void
3532 error_with_ivar (message, decl, rawdecl)
3533 const char *message;
3534 tree decl;
3535 tree rawdecl;
3537 count_error (0);
3539 report_error_function (DECL_SOURCE_FILE (decl));
3541 fprintf (stderr, "%s:%d: ",
3542 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3543 bzero (errbuf, BUFSIZE);
3544 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3547 #define USERTYPE(t) \
3548 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3549 || TREE_CODE (t) == ENUMERAL_TYPE)
3551 static void
3552 check_ivars (inter, imp)
3553 tree inter;
3554 tree imp;
3556 tree intdecls = CLASS_IVARS (inter);
3557 tree impdecls = CLASS_IVARS (imp);
3558 tree rawintdecls = CLASS_RAW_IVARS (inter);
3559 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3561 while (1)
3563 tree t1, t2;
3565 if (intdecls == 0 && impdecls == 0)
3566 break;
3567 if (intdecls == 0 || impdecls == 0)
3569 error ("inconsistent instance variable specification");
3570 break;
3573 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3575 if (!comptypes (t1, t2))
3577 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3579 error_with_ivar ("conflicting instance variable type",
3580 impdecls, rawimpdecls);
3581 error_with_ivar ("previous declaration of",
3582 intdecls, rawintdecls);
3584 else /* both the type and the name don't match */
3586 error ("inconsistent instance variable specification");
3587 break;
3591 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3593 error_with_ivar ("conflicting instance variable name",
3594 impdecls, rawimpdecls);
3595 error_with_ivar ("previous declaration of",
3596 intdecls, rawintdecls);
3599 intdecls = TREE_CHAIN (intdecls);
3600 impdecls = TREE_CHAIN (impdecls);
3601 rawintdecls = TREE_CHAIN (rawintdecls);
3602 rawimpdecls = TREE_CHAIN (rawimpdecls);
3606 /* Set super_type to the data type node for struct objc_super *,
3607 first defining struct objc_super itself.
3608 This needs to be done just once per compilation. */
3610 static tree
3611 build_super_template ()
3613 tree record, decl_specs, field_decl, field_decl_chain;
3615 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3617 /* struct objc_object *self; */
3619 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3620 field_decl = get_identifier ("self");
3621 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3622 field_decl = grokfield (input_filename, lineno,
3623 field_decl, decl_specs, NULL_TREE);
3624 field_decl_chain = field_decl;
3626 /* struct objc_class *class; */
3628 decl_specs = get_identifier (UTAG_CLASS);
3629 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3630 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3632 field_decl = grokfield (input_filename, lineno,
3633 field_decl, decl_specs, NULL_TREE);
3634 chainon (field_decl_chain, field_decl);
3636 finish_struct (record, field_decl_chain, NULL_TREE);
3638 /* `struct objc_super *' */
3639 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3640 record),
3641 build1 (INDIRECT_REF,
3642 NULL_TREE, NULL_TREE)));
3643 return record;
3646 /* struct objc_ivar {
3647 char *ivar_name;
3648 char *ivar_type;
3649 int ivar_offset;
3650 }; */
3652 static tree
3653 build_ivar_template ()
3655 tree objc_ivar_id, objc_ivar_record;
3656 tree decl_specs, field_decl, field_decl_chain;
3658 objc_ivar_id = get_identifier (UTAG_IVAR);
3659 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3661 /* char *ivar_name; */
3663 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3664 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3666 field_decl = grokfield (input_filename, lineno, field_decl,
3667 decl_specs, NULL_TREE);
3668 field_decl_chain = field_decl;
3670 /* char *ivar_type; */
3672 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3673 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3675 field_decl = grokfield (input_filename, lineno, field_decl,
3676 decl_specs, NULL_TREE);
3677 chainon (field_decl_chain, field_decl);
3679 /* int ivar_offset; */
3681 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3682 field_decl = get_identifier ("ivar_offset");
3684 field_decl = grokfield (input_filename, lineno, field_decl,
3685 decl_specs, NULL_TREE);
3686 chainon (field_decl_chain, field_decl);
3688 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3690 return objc_ivar_record;
3693 /* struct {
3694 int ivar_count;
3695 struct objc_ivar ivar_list[ivar_count];
3696 }; */
3698 static tree
3699 build_ivar_list_template (list_type, size)
3700 tree list_type;
3701 int size;
3703 tree objc_ivar_list_record;
3704 tree decl_specs, field_decl, field_decl_chain;
3706 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3708 /* int ivar_count; */
3710 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3711 field_decl = get_identifier ("ivar_count");
3713 field_decl = grokfield (input_filename, lineno, field_decl,
3714 decl_specs, NULL_TREE);
3715 field_decl_chain = field_decl;
3717 /* struct objc_ivar ivar_list[]; */
3719 decl_specs = build_tree_list (NULL_TREE, list_type);
3720 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3721 build_int_2 (size, 0));
3723 field_decl = grokfield (input_filename, lineno,
3724 field_decl, decl_specs, NULL_TREE);
3725 chainon (field_decl_chain, field_decl);
3727 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3729 return objc_ivar_list_record;
3732 /* struct {
3733 int method_next;
3734 int method_count;
3735 struct objc_method method_list[method_count];
3736 }; */
3738 static tree
3739 build_method_list_template (list_type, size)
3740 tree list_type;
3741 int size;
3743 tree objc_ivar_list_record;
3744 tree decl_specs, field_decl, field_decl_chain;
3746 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3748 /* int method_next; */
3750 decl_specs
3751 = build_tree_list
3752 (NULL_TREE,
3753 xref_tag (RECORD_TYPE,
3754 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3755 field_decl
3756 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3757 field_decl = grokfield (input_filename, lineno, field_decl,
3758 decl_specs, NULL_TREE);
3759 field_decl_chain = field_decl;
3761 /* int method_count; */
3763 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3764 field_decl = get_identifier ("method_count");
3766 field_decl = grokfield (input_filename, lineno,
3767 field_decl, decl_specs, NULL_TREE);
3768 chainon (field_decl_chain, field_decl);
3770 /* struct objc_method method_list[]; */
3772 decl_specs = build_tree_list (NULL_TREE, list_type);
3773 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3774 build_int_2 (size, 0));
3776 field_decl = grokfield (input_filename, lineno,
3777 field_decl, decl_specs, NULL_TREE);
3778 chainon (field_decl_chain, field_decl);
3780 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3782 return objc_ivar_list_record;
3785 static tree
3786 build_ivar_list_initializer (type, field_decl)
3787 tree type;
3788 tree field_decl;
3790 tree initlist = NULL_TREE;
3794 tree ivar = NULL_TREE;
3796 /* Set name. */
3797 if (DECL_NAME (field_decl))
3798 ivar = tree_cons (NULL_TREE,
3799 add_objc_string (DECL_NAME (field_decl),
3800 meth_var_names),
3801 ivar);
3802 else
3803 /* Unnamed bit-field ivar (yuck). */
3804 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3806 /* Set type. */
3807 encode_field_decl (field_decl,
3808 obstack_object_size (&util_obstack),
3809 OBJC_ENCODE_DONT_INLINE_DEFS);
3811 /* Null terminate string. */
3812 obstack_1grow (&util_obstack, 0);
3813 ivar
3814 = tree_cons
3815 (NULL_TREE,
3816 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3817 meth_var_types),
3818 ivar);
3819 obstack_free (&util_obstack, util_firstobj);
3821 /* set offset */
3822 ivar
3823 = tree_cons
3824 (NULL_TREE,
3825 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl))
3826 / BITS_PER_UNIT),
3828 ivar);
3830 initlist = tree_cons (NULL_TREE,
3831 build_constructor (type, nreverse (ivar)),
3832 initlist);
3834 field_decl = TREE_CHAIN (field_decl);
3836 while (field_decl);
3838 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3841 static tree
3842 generate_ivars_list (type, name, size, list)
3843 tree type;
3844 const char *name;
3845 int size;
3846 tree list;
3848 tree sc_spec, decl_specs, decl, initlist;
3850 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3851 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3853 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3854 decl_specs, 1, NULL_TREE, NULL_TREE);
3856 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3857 initlist = tree_cons (NULL_TREE, list, initlist);
3859 finish_decl (decl,
3860 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3861 NULL_TREE);
3863 return decl;
3866 static void
3867 generate_ivar_lists ()
3869 tree initlist, ivar_list_template, chain;
3870 tree cast, variable_length_type;
3871 int size;
3873 generating_instance_variables = 1;
3875 if (!objc_ivar_template)
3876 objc_ivar_template = build_ivar_template ();
3878 cast
3879 = build_tree_list
3880 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3881 get_identifier (UTAG_IVAR_LIST))),
3882 NULL_TREE);
3883 variable_length_type = groktypename (cast);
3885 /* Only generate class variables for the root of the inheritance
3886 hierarchy since these will be the same for every class. */
3888 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3889 && (chain = TYPE_FIELDS (objc_class_template)))
3891 size = list_length (chain);
3893 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3894 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3896 UOBJC_CLASS_VARIABLES_decl
3897 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3898 size, initlist);
3899 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3901 else
3902 UOBJC_CLASS_VARIABLES_decl = 0;
3904 chain = CLASS_IVARS (implementation_template);
3905 if (chain)
3907 size = list_length (chain);
3908 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3909 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3911 UOBJC_INSTANCE_VARIABLES_decl
3912 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3913 size, initlist);
3914 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3916 else
3917 UOBJC_INSTANCE_VARIABLES_decl = 0;
3919 generating_instance_variables = 0;
3922 static tree
3923 build_dispatch_table_initializer (type, entries)
3924 tree type;
3925 tree entries;
3927 tree initlist = NULL_TREE;
3931 tree elemlist = NULL_TREE;
3933 elemlist = tree_cons (NULL_TREE,
3934 build_selector (METHOD_SEL_NAME (entries)),
3935 NULL_TREE);
3937 elemlist = tree_cons (NULL_TREE,
3938 add_objc_string (METHOD_ENCODING (entries),
3939 meth_var_types),
3940 elemlist);
3942 elemlist = tree_cons (NULL_TREE,
3943 build_unary_op (ADDR_EXPR,
3944 METHOD_DEFINITION (entries), 1),
3945 elemlist);
3947 initlist = tree_cons (NULL_TREE,
3948 build_constructor (type, nreverse (elemlist)),
3949 initlist);
3951 entries = TREE_CHAIN (entries);
3953 while (entries);
3955 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3958 /* To accomplish method prototyping without generating all kinds of
3959 inane warnings, the definition of the dispatch table entries were
3960 changed from:
3962 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3964 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3966 static tree
3967 build_method_template ()
3969 tree _SLT_record;
3970 tree decl_specs, field_decl, field_decl_chain;
3972 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
3974 #ifdef OBJC_INT_SELECTORS
3975 /* unsigned int _cmd; */
3976 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
3977 NULL_TREE);
3978 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
3979 field_decl = get_identifier ("_cmd");
3980 #else /* not OBJC_INT_SELECTORS */
3981 /* struct objc_selector *_cmd; */
3982 decl_specs = tree_cons (NULL_TREE,
3983 xref_tag (RECORD_TYPE,
3984 get_identifier (TAG_SELECTOR)),
3985 NULL_TREE);
3986 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3987 #endif /* not OBJC_INT_SELECTORS */
3989 field_decl = grokfield (input_filename, lineno, field_decl,
3990 decl_specs, NULL_TREE);
3991 field_decl_chain = field_decl;
3993 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3994 field_decl = build1 (INDIRECT_REF, NULL_TREE,
3995 get_identifier ("method_types"));
3996 field_decl = grokfield (input_filename, lineno, field_decl,
3997 decl_specs, NULL_TREE);
3998 chainon (field_decl_chain, field_decl);
4000 /* void *_imp; */
4002 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4003 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4004 field_decl = grokfield (input_filename, lineno, field_decl,
4005 decl_specs, NULL_TREE);
4006 chainon (field_decl_chain, field_decl);
4008 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4010 return _SLT_record;
4014 static tree
4015 generate_dispatch_table (type, name, size, list)
4016 tree type;
4017 const char *name;
4018 int size;
4019 tree list;
4021 tree sc_spec, decl_specs, decl, initlist;
4023 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4024 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4026 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
4027 decl_specs, 1, NULL_TREE, NULL_TREE);
4029 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4030 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4031 initlist = tree_cons (NULL_TREE, list, initlist);
4033 finish_decl (decl,
4034 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4035 NULL_TREE);
4037 return decl;
4040 static void
4041 generate_dispatch_tables ()
4043 tree initlist, chain, method_list_template;
4044 tree cast, variable_length_type;
4045 int size;
4047 if (!objc_method_template)
4048 objc_method_template = build_method_template ();
4050 cast
4051 = build_tree_list
4052 (build_tree_list (NULL_TREE,
4053 xref_tag (RECORD_TYPE,
4054 get_identifier (UTAG_METHOD_LIST))),
4055 NULL_TREE);
4057 variable_length_type = groktypename (cast);
4059 chain = CLASS_CLS_METHODS (implementation_context);
4060 if (chain)
4062 size = list_length (chain);
4064 method_list_template
4065 = build_method_list_template (objc_method_template, size);
4066 initlist
4067 = build_dispatch_table_initializer (objc_method_template, chain);
4069 UOBJC_CLASS_METHODS_decl
4070 = generate_dispatch_table (method_list_template,
4071 ((TREE_CODE (implementation_context)
4072 == CLASS_IMPLEMENTATION_TYPE)
4073 ? "_OBJC_CLASS_METHODS"
4074 : "_OBJC_CATEGORY_CLASS_METHODS"),
4075 size, initlist);
4076 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4078 else
4079 UOBJC_CLASS_METHODS_decl = 0;
4081 chain = CLASS_NST_METHODS (implementation_context);
4082 if (chain)
4084 size = list_length (chain);
4086 method_list_template
4087 = build_method_list_template (objc_method_template, size);
4088 initlist
4089 = build_dispatch_table_initializer (objc_method_template, chain);
4091 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4092 UOBJC_INSTANCE_METHODS_decl
4093 = generate_dispatch_table (method_list_template,
4094 "_OBJC_INSTANCE_METHODS",
4095 size, initlist);
4096 else
4097 /* We have a category. */
4098 UOBJC_INSTANCE_METHODS_decl
4099 = generate_dispatch_table (method_list_template,
4100 "_OBJC_CATEGORY_INSTANCE_METHODS",
4101 size, initlist);
4102 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4104 else
4105 UOBJC_INSTANCE_METHODS_decl = 0;
4108 static tree
4109 generate_protocol_list (i_or_p)
4110 tree i_or_p;
4112 static tree cast_type = 0;
4113 tree initlist, decl_specs, sc_spec;
4114 tree refs_decl, expr_decl, lproto, e, plist;
4115 int size = 0;
4117 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4118 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4119 plist = CLASS_PROTOCOL_LIST (i_or_p);
4120 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4121 plist = PROTOCOL_LIST (i_or_p);
4122 else
4123 abort ();
4125 if (!cast_type)
4126 cast_type
4127 = groktypename
4128 (build_tree_list
4129 (build_tree_list (NULL_TREE,
4130 xref_tag (RECORD_TYPE,
4131 get_identifier (UTAG_PROTOCOL))),
4132 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4134 /* Compute size. */
4135 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4136 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4137 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4138 size++;
4140 /* Build initializer. */
4141 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4143 e = build_int_2 (size, 0);
4144 TREE_TYPE (e) = cast_type;
4145 initlist = tree_cons (NULL_TREE, e, initlist);
4147 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4149 tree pval = TREE_VALUE (lproto);
4151 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4152 && PROTOCOL_FORWARD_DECL (pval))
4154 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4155 initlist = tree_cons (NULL_TREE, e, initlist);
4159 /* static struct objc_protocol *refs[n]; */
4161 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4162 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4163 get_identifier (UTAG_PROTOCOL)),
4164 sc_spec);
4166 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4167 expr_decl = build_nt (ARRAY_REF,
4168 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4169 i_or_p),
4170 build_int_2 (size + 2, 0));
4171 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4172 expr_decl = build_nt (ARRAY_REF,
4173 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4174 i_or_p),
4175 build_int_2 (size + 2, 0));
4176 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4177 expr_decl
4178 = build_nt (ARRAY_REF,
4179 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4180 i_or_p),
4181 build_int_2 (size + 2, 0));
4182 else
4183 abort ();
4185 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4187 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
4189 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4190 nreverse (initlist)),
4191 NULL_TREE);
4193 return refs_decl;
4196 static tree
4197 build_category_initializer (type, cat_name, class_name,
4198 instance_methods, class_methods, protocol_list)
4199 tree type;
4200 tree cat_name;
4201 tree class_name;
4202 tree instance_methods;
4203 tree class_methods;
4204 tree protocol_list;
4206 tree initlist = NULL_TREE, expr;
4208 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4209 initlist = tree_cons (NULL_TREE, class_name, initlist);
4211 if (!instance_methods)
4212 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4213 else
4215 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4216 initlist = tree_cons (NULL_TREE, expr, initlist);
4218 if (!class_methods)
4219 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4220 else
4222 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4223 initlist = tree_cons (NULL_TREE, expr, initlist);
4226 /* protocol_list = */
4227 if (!protocol_list)
4228 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4229 else
4231 static tree cast_type2;
4233 if (!cast_type2)
4234 cast_type2
4235 = groktypename
4236 (build_tree_list
4237 (build_tree_list (NULL_TREE,
4238 xref_tag (RECORD_TYPE,
4239 get_identifier (UTAG_PROTOCOL))),
4240 build1 (INDIRECT_REF, NULL_TREE,
4241 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4243 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4244 TREE_TYPE (expr) = cast_type2;
4245 initlist = tree_cons (NULL_TREE, expr, initlist);
4248 return build_constructor (type, nreverse (initlist));
4251 /* struct objc_class {
4252 struct objc_class *isa;
4253 struct objc_class *super_class;
4254 char *name;
4255 long version;
4256 long info;
4257 long instance_size;
4258 struct objc_ivar_list *ivars;
4259 struct objc_method_list *methods;
4260 if (flag_next_runtime)
4261 struct objc_cache *cache;
4262 else {
4263 struct sarray *dtable;
4264 struct objc_class *subclass_list;
4265 struct objc_class *sibling_class;
4267 struct objc_protocol_list *protocols;
4268 void *gc_object_type;
4269 }; */
4271 static tree
4272 build_shared_structure_initializer (type, isa, super, name, size, status,
4273 dispatch_table, ivar_list, protocol_list)
4274 tree type;
4275 tree isa;
4276 tree super;
4277 tree name;
4278 tree size;
4279 int status;
4280 tree dispatch_table;
4281 tree ivar_list;
4282 tree protocol_list;
4284 tree initlist = NULL_TREE, expr;
4286 /* isa = */
4287 initlist = tree_cons (NULL_TREE, isa, initlist);
4289 /* super_class = */
4290 initlist = tree_cons (NULL_TREE, super, initlist);
4292 /* name = */
4293 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4295 /* version = */
4296 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4298 /* info = */
4299 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4301 /* instance_size = */
4302 initlist = tree_cons (NULL_TREE, size, initlist);
4304 /* objc_ivar_list = */
4305 if (!ivar_list)
4306 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4307 else
4309 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4310 initlist = tree_cons (NULL_TREE, expr, initlist);
4313 /* objc_method_list = */
4314 if (!dispatch_table)
4315 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4316 else
4318 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4319 initlist = tree_cons (NULL_TREE, expr, initlist);
4322 if (flag_next_runtime)
4323 /* method_cache = */
4324 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4325 else
4327 /* dtable = */
4328 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4330 /* subclass_list = */
4331 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4333 /* sibling_class = */
4334 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4337 /* protocol_list = */
4338 if (! protocol_list)
4339 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4340 else
4342 static tree cast_type2;
4344 if (!cast_type2)
4345 cast_type2
4346 = groktypename
4347 (build_tree_list
4348 (build_tree_list (NULL_TREE,
4349 xref_tag (RECORD_TYPE,
4350 get_identifier (UTAG_PROTOCOL))),
4351 build1 (INDIRECT_REF, NULL_TREE,
4352 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4354 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4355 TREE_TYPE (expr) = cast_type2;
4356 initlist = tree_cons (NULL_TREE, expr, initlist);
4359 /* gc_object_type = NULL */
4360 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4362 return build_constructor (type, nreverse (initlist));
4365 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4367 static void
4368 generate_category (cat)
4369 tree cat;
4371 tree sc_spec, decl_specs, decl;
4372 tree initlist, cat_name_expr, class_name_expr;
4373 tree protocol_decl, category;
4375 add_class_reference (CLASS_NAME (cat));
4376 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4378 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4380 category = CLASS_CATEGORY_LIST (implementation_template);
4382 /* find the category interface from the class it is associated with */
4383 while (category)
4385 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4386 break;
4387 category = CLASS_CATEGORY_LIST (category);
4390 if (category && CLASS_PROTOCOL_LIST (category))
4392 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4393 protocol_decl = generate_protocol_list (category);
4395 else
4396 protocol_decl = 0;
4398 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4399 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4401 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4402 implementation_context),
4403 decl_specs, 1, NULL_TREE, NULL_TREE);
4405 initlist = build_category_initializer (TREE_TYPE (decl),
4406 cat_name_expr, class_name_expr,
4407 UOBJC_INSTANCE_METHODS_decl,
4408 UOBJC_CLASS_METHODS_decl,
4409 protocol_decl);
4411 TREE_USED (decl) = 1;
4412 finish_decl (decl, initlist, NULL_TREE);
4415 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4416 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4418 static void
4419 generate_shared_structures ()
4421 tree sc_spec, decl_specs, decl;
4422 tree name_expr, super_expr, root_expr;
4423 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4424 tree cast_type, initlist, protocol_decl;
4426 my_super_id = CLASS_SUPER_NAME (implementation_template);
4427 if (my_super_id)
4429 add_class_reference (my_super_id);
4431 /* Compute "my_root_id" - this is required for code generation.
4432 the "isa" for all meta class structures points to the root of
4433 the inheritance hierarchy (e.g. "__Object")... */
4434 my_root_id = my_super_id;
4437 tree my_root_int = lookup_interface (my_root_id);
4439 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4440 my_root_id = CLASS_SUPER_NAME (my_root_int);
4441 else
4442 break;
4444 while (1);
4446 else
4447 /* No super class. */
4448 my_root_id = CLASS_NAME (implementation_template);
4450 cast_type
4451 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4452 objc_class_template),
4453 build1 (INDIRECT_REF,
4454 NULL_TREE, NULL_TREE)));
4456 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4457 class_names);
4459 /* Install class `isa' and `super' pointers at runtime. */
4460 if (my_super_id)
4462 super_expr = add_objc_string (my_super_id, class_names);
4463 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4465 else
4466 super_expr = build_int_2 (0, 0);
4468 root_expr = add_objc_string (my_root_id, class_names);
4469 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4471 if (CLASS_PROTOCOL_LIST (implementation_template))
4473 generate_protocol_references
4474 (CLASS_PROTOCOL_LIST (implementation_template));
4475 protocol_decl = generate_protocol_list (implementation_template);
4477 else
4478 protocol_decl = 0;
4480 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4482 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4483 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4485 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4486 NULL_TREE, NULL_TREE);
4488 initlist
4489 = build_shared_structure_initializer
4490 (TREE_TYPE (decl),
4491 root_expr, super_expr, name_expr,
4492 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template))
4493 / BITS_PER_UNIT),
4495 2 /*CLS_META*/,
4496 UOBJC_CLASS_METHODS_decl,
4497 UOBJC_CLASS_VARIABLES_decl,
4498 protocol_decl);
4500 finish_decl (decl, initlist, NULL_TREE);
4502 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4504 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4505 NULL_TREE, NULL_TREE);
4507 initlist
4508 = build_shared_structure_initializer
4509 (TREE_TYPE (decl),
4510 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4511 super_expr, name_expr,
4512 build_int_2
4513 ((TREE_INT_CST_LOW
4514 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template)))
4515 / BITS_PER_UNIT),
4517 1 /*CLS_FACTORY*/,
4518 UOBJC_INSTANCE_METHODS_decl,
4519 UOBJC_INSTANCE_VARIABLES_decl,
4520 protocol_decl);
4522 finish_decl (decl, initlist, NULL_TREE);
4525 static tree
4526 synth_id_with_class_suffix (preamble, ctxt)
4527 const char *preamble;
4528 tree ctxt;
4530 char *string;
4531 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4532 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4534 const char *class_name
4535 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4536 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4537 sprintf (string, "%s_%s", preamble,
4538 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4540 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4541 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4543 /* We have a category. */
4544 const char *class_name
4545 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4546 const char *class_super_name
4547 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4548 string = (char *) alloca (strlen (preamble)
4549 + strlen (class_name)
4550 + strlen (class_super_name)
4551 + 3);
4552 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4554 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4556 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4557 string
4558 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4559 sprintf (string, "%s_%s", preamble, protocol_name);
4561 else
4562 abort ();
4564 return get_identifier (string);
4567 static int
4568 is_objc_type_qualifier (node)
4569 tree node;
4571 return (TREE_CODE (node) == IDENTIFIER_NODE
4572 && (node == ridpointers [(int) RID_CONST]
4573 || node == ridpointers [(int) RID_VOLATILE]
4574 || node == ridpointers [(int) RID_IN]
4575 || node == ridpointers [(int) RID_OUT]
4576 || node == ridpointers [(int) RID_INOUT]
4577 || node == ridpointers [(int) RID_BYCOPY]
4578 || node == ridpointers [(int) RID_BYREF]
4579 || node == ridpointers [(int) RID_ONEWAY]));
4582 /* If type is empty or only type qualifiers are present, add default
4583 type of id (otherwise grokdeclarator will default to int). */
4585 static tree
4586 adjust_type_for_id_default (type)
4587 tree type;
4589 tree declspecs, chain;
4591 if (!type)
4592 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4593 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4595 declspecs = TREE_PURPOSE (type);
4597 /* Determine if a typespec is present. */
4598 for (chain = declspecs;
4599 chain;
4600 chain = TREE_CHAIN (chain))
4602 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4603 return type;
4606 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4607 declspecs),
4608 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4611 /* Usage:
4612 keyworddecl:
4613 selector ':' '(' typename ')' identifier
4615 Purpose:
4616 Transform an Objective-C keyword argument into
4617 the C equivalent parameter declarator.
4619 In: key_name, an "identifier_node" (optional).
4620 arg_type, a "tree_list" (optional).
4621 arg_name, an "identifier_node".
4623 Note: It would be really nice to strongly type the preceding
4624 arguments in the function prototype; however, then I
4625 could not use the "accessor" macros defined in "tree.h".
4627 Out: an instance of "keyword_decl". */
4629 tree
4630 build_keyword_decl (key_name, arg_type, arg_name)
4631 tree key_name;
4632 tree arg_type;
4633 tree arg_name;
4635 tree keyword_decl;
4637 /* If no type is specified, default to "id". */
4638 arg_type = adjust_type_for_id_default (arg_type);
4640 keyword_decl = make_node (KEYWORD_DECL);
4642 TREE_TYPE (keyword_decl) = arg_type;
4643 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4644 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4646 return keyword_decl;
4649 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4651 static tree
4652 build_keyword_selector (selector)
4653 tree selector;
4655 int len = 0;
4656 tree key_chain, key_name;
4657 char *buf;
4659 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4661 if (TREE_CODE (selector) == KEYWORD_DECL)
4662 key_name = KEYWORD_KEY_NAME (key_chain);
4663 else if (TREE_CODE (selector) == TREE_LIST)
4664 key_name = TREE_PURPOSE (key_chain);
4665 else
4666 abort ();
4668 if (key_name)
4669 len += IDENTIFIER_LENGTH (key_name) + 1;
4670 else
4671 /* Just a ':' arg. */
4672 len++;
4675 buf = (char *)alloca (len + 1);
4676 bzero (buf, len + 1);
4678 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4680 if (TREE_CODE (selector) == KEYWORD_DECL)
4681 key_name = KEYWORD_KEY_NAME (key_chain);
4682 else if (TREE_CODE (selector) == TREE_LIST)
4683 key_name = TREE_PURPOSE (key_chain);
4684 else
4685 abort ();
4687 if (key_name)
4688 strcat (buf, IDENTIFIER_POINTER (key_name));
4689 strcat (buf, ":");
4692 return get_identifier (buf);
4695 /* Used for declarations and definitions. */
4697 tree
4698 build_method_decl (code, ret_type, selector, add_args)
4699 enum tree_code code;
4700 tree ret_type;
4701 tree selector;
4702 tree add_args;
4704 tree method_decl;
4706 /* If no type is specified, default to "id". */
4707 ret_type = adjust_type_for_id_default (ret_type);
4709 method_decl = make_node (code);
4710 TREE_TYPE (method_decl) = ret_type;
4712 /* If we have a keyword selector, create an identifier_node that
4713 represents the full selector name (`:' included)... */
4714 if (TREE_CODE (selector) == KEYWORD_DECL)
4716 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4717 METHOD_SEL_ARGS (method_decl) = selector;
4718 METHOD_ADD_ARGS (method_decl) = add_args;
4720 else
4722 METHOD_SEL_NAME (method_decl) = selector;
4723 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4724 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4727 return method_decl;
4730 #define METHOD_DEF 0
4731 #define METHOD_REF 1
4733 /* Used by `build_message_expr' and `comp_method_types'. Return an
4734 argument list for method METH. CONTEXT is either METHOD_DEF or
4735 METHOD_REF, saying whether we are trying to define a method or call
4736 one. SUPERFLAG says this is for a send to super; this makes a
4737 difference for the NeXT calling sequence in which the lookup and
4738 the method call are done together. */
4740 static tree
4741 get_arg_type_list (meth, context, superflag)
4742 tree meth;
4743 int context;
4744 int superflag;
4746 tree arglist, akey;
4748 /* Receiver type. */
4749 if (flag_next_runtime && superflag)
4750 arglist = build_tree_list (NULL_TREE, super_type);
4751 else if (context == METHOD_DEF)
4752 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4753 else
4754 arglist = build_tree_list (NULL_TREE, id_type);
4756 /* Selector type - will eventually change to `int'. */
4757 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4759 /* Build a list of argument types. */
4760 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4762 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4763 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4766 if (METHOD_ADD_ARGS (meth) == (tree)1)
4767 /* We have a `, ...' immediately following the selector,
4768 finalize the arglist...simulate get_parm_info (0). */
4770 else if (METHOD_ADD_ARGS (meth))
4772 /* we have a variable length selector */
4773 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4774 chainon (arglist, add_arg_list);
4776 else
4777 /* finalize the arglist...simulate get_parm_info (1) */
4778 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4780 return arglist;
4783 static tree
4784 check_duplicates (hsh)
4785 hash hsh;
4787 tree meth = NULL_TREE;
4789 if (hsh)
4791 meth = hsh->key;
4793 if (hsh->list)
4795 /* We have two methods with the same name and different types. */
4796 attr loop;
4797 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4799 warning ("multiple declarations for method `%s'",
4800 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4802 warn_with_method ("using", type, meth);
4803 for (loop = hsh->list; loop; loop = loop->next)
4804 warn_with_method ("also found", type, loop->value);
4807 return meth;
4810 /* If RECEIVER is a class reference, return the identifier node for the
4811 referenced class. RECEIVER is created by get_class_reference, so we
4812 check the exact form created depending on which runtimes are used. */
4814 static tree
4815 receiver_is_class_object (receiver)
4816 tree receiver;
4818 tree chain, exp, arg;
4819 if (flag_next_runtime)
4821 /* The receiver is a variable created by build_class_reference_decl. */
4822 if (TREE_CODE (receiver) == VAR_DECL
4823 && TREE_TYPE (receiver) == objc_class_type)
4824 /* Look up the identifier. */
4825 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4826 if (TREE_PURPOSE (chain) == receiver)
4827 return TREE_VALUE (chain);
4829 else
4831 /* The receiver is a function call that returns an id. Check if
4832 it is a call to objc_getClass, if so, pick up the class name. */
4833 if ((exp = TREE_OPERAND (receiver, 0))
4834 && TREE_CODE (exp) == ADDR_EXPR
4835 && (exp = TREE_OPERAND (exp, 0))
4836 && TREE_CODE (exp) == FUNCTION_DECL
4837 && exp == objc_get_class_decl
4838 /* we have a call to objc_getClass! */
4839 && (arg = TREE_OPERAND (receiver, 1))
4840 && TREE_CODE (arg) == TREE_LIST
4841 && (arg = TREE_VALUE (arg)))
4843 STRIP_NOPS (arg);
4844 if (TREE_CODE (arg) == ADDR_EXPR
4845 && (arg = TREE_OPERAND (arg, 0))
4846 && TREE_CODE (arg) == STRING_CST)
4847 /* Finally, we have the class name. */
4848 return get_identifier (TREE_STRING_POINTER (arg));
4851 return 0;
4854 /* If we are currently building a message expr, this holds
4855 the identifier of the selector of the message. This is
4856 used when printing warnings about argument mismatches. */
4858 static tree building_objc_message_expr = 0;
4860 tree
4861 maybe_building_objc_message_expr ()
4863 return building_objc_message_expr;
4866 /* Construct an expression for sending a message.
4867 MESS has the object to send to in TREE_PURPOSE
4868 and the argument list (including selector) in TREE_VALUE.
4870 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4871 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4873 tree
4874 build_message_expr (mess)
4875 tree mess;
4877 tree receiver = TREE_PURPOSE (mess);
4878 tree selector, self_object;
4879 tree rtype, sel_name;
4880 tree args = TREE_VALUE (mess);
4881 tree method_params = NULL_TREE;
4882 tree method_prototype = NULL_TREE;
4883 tree retval;
4884 int statically_typed = 0, statically_allocated = 0;
4885 tree class_ident = 0;
4887 /* 1 if this is sending to the superclass. */
4888 int super;
4890 if (!doing_objc_thang)
4891 objc_fatal ();
4893 if (TREE_CODE (receiver) == ERROR_MARK)
4894 return error_mark_node;
4896 /* Determine receiver type. */
4897 rtype = TREE_TYPE (receiver);
4898 super = IS_SUPER (rtype);
4900 if (! super)
4902 if (TREE_STATIC_TEMPLATE (rtype))
4903 statically_allocated = 1;
4904 else if (TREE_CODE (rtype) == POINTER_TYPE
4905 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4906 statically_typed = 1;
4907 else if ((flag_next_runtime
4908 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4909 && (class_ident = receiver_is_class_object (receiver)))
4911 else if (! IS_ID (rtype)
4912 /* Allow any type that matches objc_class_type. */
4913 && ! comptypes (rtype, objc_class_type))
4915 bzero (errbuf, BUFSIZE);
4916 warning ("invalid receiver type `%s'",
4917 gen_declaration (rtype, errbuf));
4920 if (statically_allocated)
4921 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4923 /* Don't evaluate the receiver twice. */
4924 receiver = save_expr (receiver);
4925 self_object = receiver;
4927 else
4928 /* If sending to `super', use current self as the object. */
4929 self_object = self_decl;
4931 /* Obtain the full selector name. */
4933 if (TREE_CODE (args) == IDENTIFIER_NODE)
4934 /* A unary selector. */
4935 sel_name = args;
4936 else if (TREE_CODE (args) == TREE_LIST)
4937 sel_name = build_keyword_selector (args);
4938 else
4939 abort ();
4941 /* Build the parameter list to give to the method. */
4943 method_params = NULL_TREE;
4944 if (TREE_CODE (args) == TREE_LIST)
4946 tree chain = args, prev = NULL_TREE;
4948 /* We have a keyword selector--check for comma expressions. */
4949 while (chain)
4951 tree element = TREE_VALUE (chain);
4953 /* We have a comma expression, must collapse... */
4954 if (TREE_CODE (element) == TREE_LIST)
4956 if (prev)
4957 TREE_CHAIN (prev) = element;
4958 else
4959 args = element;
4961 prev = chain;
4962 chain = TREE_CHAIN (chain);
4964 method_params = args;
4967 /* Determine operation return type. */
4969 if (IS_SUPER (rtype))
4971 tree iface;
4973 if (CLASS_SUPER_NAME (implementation_template))
4975 iface
4976 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
4978 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
4979 method_prototype = lookup_instance_method_static (iface, sel_name);
4980 else
4981 method_prototype = lookup_class_method_static (iface, sel_name);
4983 if (iface && !method_prototype)
4984 warning ("`%s' does not respond to `%s'",
4985 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
4986 IDENTIFIER_POINTER (sel_name));
4988 else
4990 error ("no super class declared in interface for `%s'",
4991 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
4992 return error_mark_node;
4996 else if (statically_allocated)
4998 tree ctype = TREE_TYPE (rtype);
4999 tree iface = lookup_interface (TYPE_NAME (rtype));
5001 if (iface)
5002 method_prototype = lookup_instance_method_static (iface, sel_name);
5004 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5005 method_prototype
5006 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5007 sel_name, 0);
5009 if (!method_prototype)
5010 warning ("`%s' does not respond to `%s'",
5011 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5012 IDENTIFIER_POINTER (sel_name));
5014 else if (statically_typed)
5016 tree ctype = TREE_TYPE (rtype);
5018 /* `self' is now statically_typed. All methods should be visible
5019 within the context of the implementation. */
5020 if (implementation_context
5021 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
5023 method_prototype
5024 = lookup_instance_method_static (implementation_template,
5025 sel_name);
5027 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5028 method_prototype
5029 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5030 sel_name, 0);
5032 if (! method_prototype
5033 && implementation_template != implementation_context)
5034 /* The method is not published in the interface. Check
5035 locally. */
5036 method_prototype
5037 = lookup_method (CLASS_NST_METHODS (implementation_context),
5038 sel_name);
5040 else
5042 tree iface;
5044 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5045 method_prototype = lookup_instance_method_static (iface, sel_name);
5047 if (! method_prototype)
5049 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5050 if (protocol_list)
5051 method_prototype
5052 = lookup_method_in_protocol_list (protocol_list,
5053 sel_name, 0);
5057 if (!method_prototype)
5058 warning ("`%s' does not respond to `%s'",
5059 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5060 IDENTIFIER_POINTER (sel_name));
5062 else if (class_ident)
5064 if (implementation_context
5065 && CLASS_NAME (implementation_context) == class_ident)
5067 method_prototype
5068 = lookup_class_method_static (implementation_template, sel_name);
5070 if (!method_prototype
5071 && implementation_template != implementation_context)
5072 /* The method is not published in the interface. Check
5073 locally. */
5074 method_prototype
5075 = lookup_method (CLASS_CLS_METHODS (implementation_context),
5076 sel_name);
5078 else
5080 tree iface;
5082 if ((iface = lookup_interface (class_ident)))
5083 method_prototype = lookup_class_method_static (iface, sel_name);
5086 if (!method_prototype)
5088 warning ("cannot find class (factory) method.");
5089 warning ("return type for `%s' defaults to id",
5090 IDENTIFIER_POINTER (sel_name));
5093 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5095 /* An anonymous object that has been qualified with a protocol. */
5097 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5099 method_prototype = lookup_method_in_protocol_list (protocol_list,
5100 sel_name, 0);
5102 if (!method_prototype)
5104 hash hsh;
5106 warning ("method `%s' not implemented by protocol.",
5107 IDENTIFIER_POINTER (sel_name));
5109 /* Try and find the method signature in the global pools. */
5111 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5112 hsh = hash_lookup (cls_method_hash_list, sel_name);
5114 if (!(method_prototype = check_duplicates (hsh)))
5115 warning ("return type defaults to id");
5118 else
5120 hash hsh;
5122 /* We think we have an instance...loophole: extern id Object; */
5123 hsh = hash_lookup (nst_method_hash_list, sel_name);
5124 if (!hsh)
5125 /* For various loopholes, like sending messages to self in a
5126 factory context. */
5127 hsh = hash_lookup (cls_method_hash_list, sel_name);
5129 method_prototype = check_duplicates (hsh);
5130 if (!method_prototype)
5132 warning ("cannot find method.");
5133 warning ("return type for `%s' defaults to id",
5134 IDENTIFIER_POINTER (sel_name));
5138 /* Save the selector name for printing error messages. */
5139 building_objc_message_expr = sel_name;
5141 /* Build the parameters list for looking up the method.
5142 These are the object itself and the selector. */
5144 if (flag_typed_selectors)
5145 selector = build_typed_selector_reference (sel_name, method_prototype);
5146 else
5147 selector = build_selector_reference (sel_name);
5149 retval = build_objc_method_call (super, method_prototype,
5150 receiver, self_object,
5151 selector, method_params);
5153 building_objc_message_expr = 0;
5155 return retval;
5158 /* Build a tree expression to send OBJECT the operation SELECTOR,
5159 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5160 assuming the method has prototype METHOD_PROTOTYPE.
5161 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5162 Use METHOD_PARAMS as list of args to pass to the method.
5163 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5165 static tree
5166 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5167 selector, method_params)
5168 int super_flag;
5169 tree method_prototype, lookup_object, object, selector, method_params;
5171 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5172 tree rcv_p = (super_flag
5173 ? build_pointer_type (xref_tag (RECORD_TYPE,
5174 get_identifier (TAG_SUPER)))
5175 : id_type);
5177 if (flag_next_runtime)
5179 if (! method_prototype)
5181 method_params = tree_cons (NULL_TREE, lookup_object,
5182 tree_cons (NULL_TREE, selector,
5183 method_params));
5184 assemble_external (sender);
5185 return build_function_call (sender, method_params);
5187 else
5189 /* This is a real kludge, but it is used only for the Next.
5190 Clobber the data type of SENDER temporarily to accept
5191 all the arguments for this operation, and to return
5192 whatever this operation returns. */
5193 tree arglist = NULL_TREE;
5194 tree retval;
5196 /* Save the proper contents of SENDER's data type. */
5197 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5198 tree savret = TREE_TYPE (TREE_TYPE (sender));
5200 /* Install this method's argument types. */
5201 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5202 super_flag);
5203 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5205 /* Install this method's return type. */
5206 TREE_TYPE (TREE_TYPE (sender))
5207 = groktypename (TREE_TYPE (method_prototype));
5209 /* Call SENDER with all the parameters. This will do type
5210 checking using the arg types for this method. */
5211 method_params = tree_cons (NULL_TREE, lookup_object,
5212 tree_cons (NULL_TREE, selector,
5213 method_params));
5214 assemble_external (sender);
5215 retval = build_function_call (sender, method_params);
5217 /* Restore SENDER's return/argument types. */
5218 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5219 TREE_TYPE (TREE_TYPE (sender)) = savret;
5220 return retval;
5223 else
5225 /* This is the portable way.
5226 First call the lookup function to get a pointer to the method,
5227 then cast the pointer, then call it with the method arguments. */
5228 tree method;
5230 /* Avoid trouble since we may evaluate each of these twice. */
5231 object = save_expr (object);
5232 selector = save_expr (selector);
5234 lookup_object = build_c_cast (rcv_p, lookup_object);
5236 assemble_external (sender);
5237 method
5238 = build_function_call (sender,
5239 tree_cons (NULL_TREE, lookup_object,
5240 tree_cons (NULL_TREE, selector,
5241 NULL_TREE)));
5243 /* If we have a method prototype, construct the data type this
5244 method needs, and cast what we got from SENDER into a pointer
5245 to that type. */
5246 if (method_prototype)
5248 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5249 super_flag);
5250 tree valtype = groktypename (TREE_TYPE (method_prototype));
5251 tree fake_function_type = build_function_type (valtype, arglist);
5252 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5254 else
5255 TREE_TYPE (method)
5256 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5258 /* Pass the object to the method. */
5259 assemble_external (method);
5260 return build_function_call (method,
5261 tree_cons (NULL_TREE, object,
5262 tree_cons (NULL_TREE, selector,
5263 method_params)));
5267 static void
5268 build_protocol_reference (p)
5269 tree p;
5271 tree decl, ident, ptype;
5273 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5275 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5276 ptype
5277 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5278 objc_protocol_template),
5279 NULL_TREE));
5281 if (IDENTIFIER_GLOBAL_VALUE (ident))
5282 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5283 else
5285 decl = build_decl (VAR_DECL, ident, ptype);
5286 DECL_EXTERNAL (decl) = 1;
5287 TREE_PUBLIC (decl) = 1;
5288 TREE_USED (decl) = 1;
5289 DECL_ARTIFICIAL (decl) = 1;
5291 make_decl_rtl (decl, 0, 1);
5292 pushdecl_top_level (decl);
5295 PROTOCOL_FORWARD_DECL (p) = decl;
5298 tree
5299 build_protocol_expr (protoname)
5300 tree protoname;
5302 tree expr;
5303 tree p;
5305 if (!doing_objc_thang)
5306 objc_fatal ();
5308 p = lookup_protocol (protoname);
5310 if (!p)
5312 error ("Cannot find protocol declaration for `%s'",
5313 IDENTIFIER_POINTER (protoname));
5314 return error_mark_node;
5317 if (!PROTOCOL_FORWARD_DECL (p))
5318 build_protocol_reference (p);
5320 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5322 TREE_TYPE (expr) = protocol_type;
5324 return expr;
5327 tree
5328 build_selector_expr (selnamelist)
5329 tree selnamelist;
5331 tree selname;
5333 if (!doing_objc_thang)
5334 objc_fatal ();
5336 /* Obtain the full selector name. */
5337 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5338 /* A unary selector. */
5339 selname = selnamelist;
5340 else if (TREE_CODE (selnamelist) == TREE_LIST)
5341 selname = build_keyword_selector (selnamelist);
5342 else
5343 abort ();
5345 if (flag_typed_selectors)
5346 return build_typed_selector_reference (selname, 0);
5347 else
5348 return build_selector_reference (selname);
5351 tree
5352 build_encode_expr (type)
5353 tree type;
5355 tree result;
5356 const char *string;
5358 if (!doing_objc_thang)
5359 objc_fatal ();
5361 encode_type (type, obstack_object_size (&util_obstack),
5362 OBJC_ENCODE_INLINE_DEFS);
5363 obstack_1grow (&util_obstack, 0); /* null terminate string */
5364 string = obstack_finish (&util_obstack);
5366 /* Synthesize a string that represents the encoded struct/union. */
5367 result = my_build_string (strlen (string) + 1, string);
5368 obstack_free (&util_obstack, util_firstobj);
5369 return result;
5372 tree
5373 build_ivar_reference (id)
5374 tree id;
5376 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
5378 /* Historically, a class method that produced objects (factory
5379 method) would assign `self' to the instance that it
5380 allocated. This would effectively turn the class method into
5381 an instance method. Following this assignment, the instance
5382 variables could be accessed. That practice, while safe,
5383 violates the simple rule that a class method should not refer
5384 to an instance variable. It's better to catch the cases
5385 where this is done unknowingly than to support the above
5386 paradigm. */
5387 warning ("instance variable `%s' accessed in class method",
5388 IDENTIFIER_POINTER (id));
5389 TREE_TYPE (self_decl) = instance_type; /* cast */
5392 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5395 #define HASH_ALLOC_LIST_SIZE 170
5396 #define ATTR_ALLOC_LIST_SIZE 170
5397 #define SIZEHASHTABLE 257
5399 /* make positive */
5400 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5402 static void
5403 hash_init ()
5405 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5406 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5408 if (!nst_method_hash_list || !cls_method_hash_list)
5409 perror ("unable to allocate space in objc-tree.c");
5410 else
5412 int i;
5414 for (i = 0; i < SIZEHASHTABLE; i++)
5416 nst_method_hash_list[i] = 0;
5417 cls_method_hash_list[i] = 0;
5422 static void
5423 hash_enter (hashlist, method)
5424 hash *hashlist;
5425 tree method;
5427 static hash hash_alloc_list = 0;
5428 static int hash_alloc_index = 0;
5429 hash obj;
5430 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5432 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5434 hash_alloc_index = 0;
5435 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5436 * HASH_ALLOC_LIST_SIZE);
5437 if (! hash_alloc_list)
5438 perror ("unable to allocate in objc-tree.c");
5440 obj = &hash_alloc_list[hash_alloc_index++];
5441 obj->list = 0;
5442 obj->next = hashlist[slot];
5443 obj->key = method;
5445 hashlist[slot] = obj; /* append to front */
5448 static hash
5449 hash_lookup (hashlist, sel_name)
5450 hash *hashlist;
5451 tree sel_name;
5453 hash target;
5455 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5457 while (target)
5459 if (sel_name == METHOD_SEL_NAME (target->key))
5460 return target;
5462 target = target->next;
5464 return 0;
5467 static void
5468 hash_add_attr (entry, value)
5469 hash entry;
5470 tree value;
5472 static attr attr_alloc_list = 0;
5473 static int attr_alloc_index = 0;
5474 attr obj;
5476 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5478 attr_alloc_index = 0;
5479 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5480 * ATTR_ALLOC_LIST_SIZE);
5481 if (! attr_alloc_list)
5482 perror ("unable to allocate in objc-tree.c");
5484 obj = &attr_alloc_list[attr_alloc_index++];
5485 obj->next = entry->list;
5486 obj->value = value;
5488 entry->list = obj; /* append to front */
5491 static tree
5492 lookup_method (mchain, method)
5493 tree mchain;
5494 tree method;
5496 tree key;
5498 if (TREE_CODE (method) == IDENTIFIER_NODE)
5499 key = method;
5500 else
5501 key = METHOD_SEL_NAME (method);
5503 while (mchain)
5505 if (METHOD_SEL_NAME (mchain) == key)
5506 return mchain;
5507 mchain = TREE_CHAIN (mchain);
5509 return NULL_TREE;
5512 static tree
5513 lookup_instance_method_static (interface, ident)
5514 tree interface;
5515 tree ident;
5517 tree inter = interface;
5518 tree chain = CLASS_NST_METHODS (inter);
5519 tree meth = NULL_TREE;
5523 if ((meth = lookup_method (chain, ident)))
5524 return meth;
5526 if (CLASS_CATEGORY_LIST (inter))
5528 tree category = CLASS_CATEGORY_LIST (inter);
5529 chain = CLASS_NST_METHODS (category);
5533 if ((meth = lookup_method (chain, ident)))
5534 return meth;
5536 /* Check for instance methods in protocols in categories. */
5537 if (CLASS_PROTOCOL_LIST (category))
5539 if ((meth = (lookup_method_in_protocol_list
5540 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5541 return meth;
5544 if ((category = CLASS_CATEGORY_LIST (category)))
5545 chain = CLASS_NST_METHODS (category);
5547 while (category);
5550 if (CLASS_PROTOCOL_LIST (inter))
5552 if ((meth = (lookup_method_in_protocol_list
5553 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5554 return meth;
5557 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5558 chain = CLASS_NST_METHODS (inter);
5560 while (inter);
5562 return meth;
5565 static tree
5566 lookup_class_method_static (interface, ident)
5567 tree interface;
5568 tree ident;
5570 tree inter = interface;
5571 tree chain = CLASS_CLS_METHODS (inter);
5572 tree meth = NULL_TREE;
5573 tree root_inter = NULL_TREE;
5577 if ((meth = lookup_method (chain, ident)))
5578 return meth;
5580 if (CLASS_CATEGORY_LIST (inter))
5582 tree category = CLASS_CATEGORY_LIST (inter);
5583 chain = CLASS_CLS_METHODS (category);
5587 if ((meth = lookup_method (chain, ident)))
5588 return meth;
5590 /* Check for class methods in protocols in categories. */
5591 if (CLASS_PROTOCOL_LIST (category))
5593 if ((meth = (lookup_method_in_protocol_list
5594 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5595 return meth;
5598 if ((category = CLASS_CATEGORY_LIST (category)))
5599 chain = CLASS_CLS_METHODS (category);
5601 while (category);
5604 /* Check for class methods in protocols. */
5605 if (CLASS_PROTOCOL_LIST (inter))
5607 if ((meth = (lookup_method_in_protocol_list
5608 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5609 return meth;
5612 root_inter = inter;
5613 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5614 chain = CLASS_CLS_METHODS (inter);
5616 while (inter);
5618 /* Simulate wrap around. */
5619 return lookup_instance_method_static (root_inter, ident);
5622 tree
5623 add_class_method (class, method)
5624 tree class;
5625 tree method;
5627 tree mth;
5628 hash hsh;
5630 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5632 /* put method on list in reverse order */
5633 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5634 CLASS_CLS_METHODS (class) = method;
5636 else
5638 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5639 error ("duplicate definition of class method `%s'.",
5640 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5641 else
5643 /* Check types; if different, complain. */
5644 if (!comp_proto_with_proto (method, mth))
5645 error ("duplicate declaration of class method `%s'.",
5646 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5650 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5652 /* Install on a global chain. */
5653 hash_enter (cls_method_hash_list, method);
5655 else
5657 /* Check types; if different, add to a list. */
5658 if (!comp_proto_with_proto (method, hsh->key))
5659 hash_add_attr (hsh, method);
5661 return method;
5664 tree
5665 add_instance_method (class, method)
5666 tree class;
5667 tree method;
5669 tree mth;
5670 hash hsh;
5672 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5674 /* Put method on list in reverse order. */
5675 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5676 CLASS_NST_METHODS (class) = method;
5678 else
5680 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5681 error ("duplicate definition of instance method `%s'.",
5682 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5683 else
5685 /* Check types; if different, complain. */
5686 if (!comp_proto_with_proto (method, mth))
5687 error ("duplicate declaration of instance method `%s'.",
5688 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5692 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5694 /* Install on a global chain. */
5695 hash_enter (nst_method_hash_list, method);
5697 else
5699 /* Check types; if different, add to a list. */
5700 if (!comp_proto_with_proto (method, hsh->key))
5701 hash_add_attr (hsh, method);
5703 return method;
5706 static tree
5707 add_class (class)
5708 tree class;
5710 /* Put interfaces on list in reverse order. */
5711 TREE_CHAIN (class) = interface_chain;
5712 interface_chain = class;
5713 return interface_chain;
5716 static void
5717 add_category (class, category)
5718 tree class;
5719 tree category;
5721 /* Put categories on list in reverse order. */
5722 tree cat = CLASS_CATEGORY_LIST (class);
5724 while (cat)
5726 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5727 warning ("duplicate interface declaration for category `%s(%s)'",
5728 IDENTIFIER_POINTER (CLASS_NAME (class)),
5729 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5730 cat = CLASS_CATEGORY_LIST (cat);
5733 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5734 CLASS_CATEGORY_LIST (class) = category;
5737 /* Called after parsing each instance variable declaration. Necessary to
5738 preserve typedefs and implement public/private...
5740 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5742 tree
5743 add_instance_variable (class, public, declarator, declspecs, width)
5744 tree class;
5745 int public;
5746 tree declarator;
5747 tree declspecs;
5748 tree width;
5750 tree field_decl, raw_decl;
5752 raw_decl = build_tree_list (declspecs, declarator);
5754 if (CLASS_RAW_IVARS (class))
5755 chainon (CLASS_RAW_IVARS (class), raw_decl);
5756 else
5757 CLASS_RAW_IVARS (class) = raw_decl;
5759 field_decl = grokfield (input_filename, lineno,
5760 declarator, declspecs, width);
5762 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5763 switch (public)
5765 case 0:
5766 TREE_PUBLIC (field_decl) = 0;
5767 TREE_PRIVATE (field_decl) = 0;
5768 TREE_PROTECTED (field_decl) = 1;
5769 break;
5771 case 1:
5772 TREE_PUBLIC (field_decl) = 1;
5773 TREE_PRIVATE (field_decl) = 0;
5774 TREE_PROTECTED (field_decl) = 0;
5775 break;
5777 case 2:
5778 TREE_PUBLIC (field_decl) = 0;
5779 TREE_PRIVATE (field_decl) = 1;
5780 TREE_PROTECTED (field_decl) = 0;
5781 break;
5785 if (CLASS_IVARS (class))
5786 chainon (CLASS_IVARS (class), field_decl);
5787 else
5788 CLASS_IVARS (class) = field_decl;
5790 return class;
5793 tree
5794 is_ivar (decl_chain, ident)
5795 tree decl_chain;
5796 tree ident;
5798 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5799 if (DECL_NAME (decl_chain) == ident)
5800 return decl_chain;
5801 return NULL_TREE;
5804 /* True if the ivar is private and we are not in its implementation. */
5807 is_private (decl)
5808 tree decl;
5810 if (TREE_PRIVATE (decl)
5811 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5813 error ("instance variable `%s' is declared private",
5814 IDENTIFIER_POINTER (DECL_NAME (decl)));
5815 return 1;
5817 else
5818 return 0;
5821 /* We have an instance variable reference;, check to see if it is public. */
5824 is_public (expr, identifier)
5825 tree expr;
5826 tree identifier;
5828 tree basetype = TREE_TYPE (expr);
5829 enum tree_code code = TREE_CODE (basetype);
5830 tree decl;
5832 if (code == RECORD_TYPE)
5834 if (TREE_STATIC_TEMPLATE (basetype))
5836 if (!lookup_interface (TYPE_NAME (basetype)))
5838 error ("Cannot find interface declaration for `%s'",
5839 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5840 return 0;
5843 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5845 if (TREE_PUBLIC (decl))
5846 return 1;
5848 /* Important difference between the Stepstone translator:
5849 all instance variables should be public within the context
5850 of the implementation. */
5851 if (implementation_context
5852 && (((TREE_CODE (implementation_context)
5853 == CLASS_IMPLEMENTATION_TYPE)
5854 || (TREE_CODE (implementation_context)
5855 == CATEGORY_IMPLEMENTATION_TYPE))
5856 && (CLASS_NAME (implementation_context)
5857 == TYPE_NAME (basetype))))
5858 return ! is_private (decl);
5860 error ("instance variable `%s' is declared %s",
5861 IDENTIFIER_POINTER (identifier),
5862 TREE_PRIVATE (decl) ? "private" : "protected");
5863 return 0;
5867 else if (implementation_context && (basetype == objc_object_reference))
5869 TREE_TYPE (expr) = uprivate_record;
5870 warning ("static access to object of type `id'");
5874 return 1;
5877 /* Implement @defs (<classname>) within struct bodies. */
5879 tree
5880 get_class_ivars (interface)
5881 tree interface;
5883 if (!doing_objc_thang)
5884 objc_fatal ();
5886 return build_ivar_chain (interface, 1);
5889 /* Make sure all entries in CHAIN are also in LIST. */
5891 static int
5892 check_methods (chain, list, mtype)
5893 tree chain;
5894 tree list;
5895 int mtype;
5897 int first = 1;
5899 while (chain)
5901 if (!lookup_method (list, chain))
5903 if (first)
5905 if (TREE_CODE (implementation_context)
5906 == CLASS_IMPLEMENTATION_TYPE)
5907 warning ("incomplete implementation of class `%s'",
5908 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5909 else if (TREE_CODE (implementation_context)
5910 == CATEGORY_IMPLEMENTATION_TYPE)
5911 warning ("incomplete implementation of category `%s'",
5912 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5913 first = 0;
5916 warning ("method definition for `%c%s' not found",
5917 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5920 chain = TREE_CHAIN (chain);
5923 return first;
5926 static int
5927 conforms_to_protocol (class, protocol)
5928 tree class;
5929 tree protocol;
5931 while (protocol)
5933 tree p = CLASS_PROTOCOL_LIST (class);
5935 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5936 p = TREE_CHAIN (p);
5938 if (!p)
5940 tree super = (CLASS_SUPER_NAME (class)
5941 ? lookup_interface (CLASS_SUPER_NAME (class))
5942 : NULL_TREE);
5943 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5944 if (!tmp)
5945 return 0;
5948 protocol = TREE_CHAIN (protocol);
5951 return 1;
5954 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5955 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5957 static int
5958 check_methods_accessible (chain, context, mtype)
5959 tree chain;
5960 tree context;
5961 int mtype;
5963 int first = 1;
5964 tree list;
5965 tree base_context = context;
5967 while (chain)
5969 context = base_context;
5970 while (context)
5972 if (mtype == '+')
5973 list = CLASS_CLS_METHODS (context);
5974 else
5975 list = CLASS_NST_METHODS (context);
5977 if (lookup_method (list, chain))
5978 break;
5980 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
5981 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
5982 context = (CLASS_SUPER_NAME (context)
5983 ? lookup_interface (CLASS_SUPER_NAME (context))
5984 : NULL_TREE);
5986 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
5987 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
5988 context = (CLASS_NAME (context)
5989 ? lookup_interface (CLASS_NAME (context))
5990 : NULL_TREE);
5991 else
5992 abort ();
5995 if (context == NULL_TREE)
5997 if (first)
5999 if (TREE_CODE (implementation_context)
6000 == CLASS_IMPLEMENTATION_TYPE)
6001 warning ("incomplete implementation of class `%s'",
6002 IDENTIFIER_POINTER
6003 (CLASS_NAME (implementation_context)));
6004 else if (TREE_CODE (implementation_context)
6005 == CATEGORY_IMPLEMENTATION_TYPE)
6006 warning ("incomplete implementation of category `%s'",
6007 IDENTIFIER_POINTER
6008 (CLASS_SUPER_NAME (implementation_context)));
6009 first = 0;
6011 warning ("method definition for `%c%s' not found",
6012 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6015 chain = TREE_CHAIN (chain); /* next method... */
6017 return first;
6020 static void
6021 check_protocols (proto_list, type, name)
6022 tree proto_list;
6023 const char *type;
6024 const char *name;
6026 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6028 tree p = TREE_VALUE (proto_list);
6030 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6032 int f1, f2;
6034 /* Ensure that all protocols have bodies. */
6035 if (flag_warn_protocol) {
6036 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6037 CLASS_CLS_METHODS (implementation_context),
6038 '+');
6039 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6040 CLASS_NST_METHODS (implementation_context),
6041 '-');
6042 } else {
6043 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6044 implementation_context,
6045 '+');
6046 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6047 implementation_context,
6048 '-');
6051 if (!f1 || !f2)
6052 warning ("%s `%s' does not fully implement the `%s' protocol",
6053 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6056 else
6058 ; /* An identifier if we could not find a protocol. */
6061 /* Check protocols recursively. */
6062 if (PROTOCOL_LIST (p))
6064 tree super_class
6065 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6066 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
6067 check_protocols (PROTOCOL_LIST (p), type, name);
6072 /* Make sure that the class CLASS_NAME is defined
6073 CODE says which kind of thing CLASS_NAME ought to be.
6074 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6075 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6077 tree
6078 start_class (code, class_name, super_name, protocol_list)
6079 enum tree_code code;
6080 tree class_name;
6081 tree super_name;
6082 tree protocol_list;
6084 tree class, decl;
6086 if (!doing_objc_thang)
6087 objc_fatal ();
6089 class = make_node (code);
6090 TYPE_BINFO (class) = make_tree_vec (5);
6092 CLASS_NAME (class) = class_name;
6093 CLASS_SUPER_NAME (class) = super_name;
6094 CLASS_CLS_METHODS (class) = NULL_TREE;
6096 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6098 error ("`%s' redeclared as different kind of symbol",
6099 IDENTIFIER_POINTER (class_name));
6100 error_with_decl (decl, "previous declaration of `%s'");
6103 if (code == CLASS_IMPLEMENTATION_TYPE)
6106 static tree implemented_classes = 0;
6107 tree chain = implemented_classes;
6108 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6109 if (TREE_VALUE (chain) == class_name)
6111 error ("reimplementation of class `%s'",
6112 IDENTIFIER_POINTER (class_name));
6113 return error_mark_node;
6115 implemented_classes = tree_cons (NULL_TREE, class_name,
6116 implemented_classes);
6119 /* Pre-build the following entities - for speed/convenience. */
6120 if (!self_id)
6121 self_id = get_identifier ("self");
6122 if (!ucmd_id)
6123 ucmd_id = get_identifier ("_cmd");
6124 if (!unused_list)
6125 unused_list
6126 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6127 if (!objc_super_template)
6128 objc_super_template = build_super_template ();
6130 /* Reset for multiple classes per file. */
6131 method_slot = 0;
6133 implementation_context = class;
6135 /* Lookup the interface for this implementation. */
6137 if (!(implementation_template = lookup_interface (class_name)))
6139 warning ("Cannot find interface declaration for `%s'",
6140 IDENTIFIER_POINTER (class_name));
6141 add_class (implementation_template = implementation_context);
6144 /* If a super class has been specified in the implementation,
6145 insure it conforms to the one specified in the interface. */
6147 if (super_name
6148 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6150 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6151 const char *name =
6152 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6153 error ("conflicting super class name `%s'",
6154 IDENTIFIER_POINTER (super_name));
6155 error ("previous declaration of `%s'", name);
6158 else if (! super_name)
6160 CLASS_SUPER_NAME (implementation_context)
6161 = CLASS_SUPER_NAME (implementation_template);
6165 else if (code == CLASS_INTERFACE_TYPE)
6167 if (lookup_interface (class_name))
6168 warning ("duplicate interface declaration for class `%s'",
6169 IDENTIFIER_POINTER (class_name));
6170 else
6171 add_class (class);
6173 if (protocol_list)
6174 CLASS_PROTOCOL_LIST (class)
6175 = lookup_and_install_protocols (protocol_list);
6178 else if (code == CATEGORY_INTERFACE_TYPE)
6180 tree class_category_is_assoc_with;
6182 /* For a category, class_name is really the name of the class that
6183 the following set of methods will be associated with. We must
6184 find the interface so that can derive the objects template. */
6186 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6188 error ("Cannot find interface declaration for `%s'",
6189 IDENTIFIER_POINTER (class_name));
6190 exit (FATAL_EXIT_CODE);
6192 else
6193 add_category (class_category_is_assoc_with, class);
6195 if (protocol_list)
6196 CLASS_PROTOCOL_LIST (class)
6197 = lookup_and_install_protocols (protocol_list);
6200 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6202 /* Pre-build the following entities for speed/convenience. */
6203 if (!self_id)
6204 self_id = get_identifier ("self");
6205 if (!ucmd_id)
6206 ucmd_id = get_identifier ("_cmd");
6207 if (!unused_list)
6208 unused_list
6209 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6210 if (!objc_super_template)
6211 objc_super_template = build_super_template ();
6213 /* Reset for multiple classes per file. */
6214 method_slot = 0;
6216 implementation_context = class;
6218 /* For a category, class_name is really the name of the class that
6219 the following set of methods will be associated with. We must
6220 find the interface so that can derive the objects template. */
6222 if (!(implementation_template = lookup_interface (class_name)))
6224 error ("Cannot find interface declaration for `%s'",
6225 IDENTIFIER_POINTER (class_name));
6226 exit (FATAL_EXIT_CODE);
6229 return class;
6232 tree
6233 continue_class (class)
6234 tree class;
6236 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6237 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6239 struct imp_entry *imp_entry;
6240 tree ivar_context;
6242 /* Check consistency of the instance variables. */
6244 if (CLASS_IVARS (class))
6245 check_ivars (implementation_template, class);
6247 /* code generation */
6249 ivar_context = build_private_template (implementation_template);
6251 if (!objc_class_template)
6252 build_class_template ();
6254 if (!(imp_entry
6255 = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
6256 perror ("unable to allocate in objc-tree.c");
6258 imp_entry->next = imp_list;
6259 imp_entry->imp_context = class;
6260 imp_entry->imp_template = implementation_template;
6262 synth_forward_declarations ();
6263 imp_entry->class_decl = UOBJC_CLASS_decl;
6264 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6266 /* Append to front and increment count. */
6267 imp_list = imp_entry;
6268 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6269 imp_count++;
6270 else
6271 cat_count++;
6273 return ivar_context;
6276 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6278 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6280 if (!TYPE_FIELDS (record))
6282 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6283 CLASS_STATIC_TEMPLATE (class) = record;
6285 /* Mark this record as a class template for static typing. */
6286 TREE_STATIC_TEMPLATE (record) = 1;
6289 return NULL_TREE;
6292 else
6293 return error_mark_node;
6296 /* This is called once we see the "@end" in an interface/implementation. */
6298 void
6299 finish_class (class)
6300 tree class;
6302 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6304 /* All code generation is done in finish_objc. */
6306 if (implementation_template != implementation_context)
6308 /* Ensure that all method listed in the interface contain bodies. */
6309 check_methods (CLASS_CLS_METHODS (implementation_template),
6310 CLASS_CLS_METHODS (implementation_context), '+');
6311 check_methods (CLASS_NST_METHODS (implementation_template),
6312 CLASS_NST_METHODS (implementation_context), '-');
6314 if (CLASS_PROTOCOL_LIST (implementation_template))
6315 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6316 "class",
6317 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
6321 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6323 tree category = CLASS_CATEGORY_LIST (implementation_template);
6325 /* Find the category interface from the class it is associated with. */
6326 while (category)
6328 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6329 break;
6330 category = CLASS_CATEGORY_LIST (category);
6333 if (category)
6335 /* Ensure all method listed in the interface contain bodies. */
6336 check_methods (CLASS_CLS_METHODS (category),
6337 CLASS_CLS_METHODS (implementation_context), '+');
6338 check_methods (CLASS_NST_METHODS (category),
6339 CLASS_NST_METHODS (implementation_context), '-');
6341 if (CLASS_PROTOCOL_LIST (category))
6342 check_protocols (CLASS_PROTOCOL_LIST (category),
6343 "category",
6344 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6348 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6350 tree decl_specs;
6351 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6352 char *string = (char *) alloca (strlen (class_name) + 3);
6354 /* extern struct objc_object *_<my_name>; */
6356 sprintf (string, "_%s", class_name);
6358 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6359 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6360 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6361 decl_specs);
6365 static tree
6366 add_protocol (protocol)
6367 tree protocol;
6369 /* Put protocol on list in reverse order. */
6370 TREE_CHAIN (protocol) = protocol_chain;
6371 protocol_chain = protocol;
6372 return protocol_chain;
6375 static tree
6376 lookup_protocol (ident)
6377 tree ident;
6379 tree chain;
6381 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6383 if (ident == PROTOCOL_NAME (chain))
6384 return chain;
6387 return NULL_TREE;
6390 tree
6391 start_protocol (code, name, list)
6392 enum tree_code code;
6393 tree name;
6394 tree list;
6396 tree protocol;
6398 if (!doing_objc_thang)
6399 objc_fatal ();
6401 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6402 if (!objc_protocol_template)
6403 objc_protocol_template = build_protocol_template ();
6405 protocol = make_node (code);
6406 TYPE_BINFO (protocol) = make_tree_vec (2);
6408 PROTOCOL_NAME (protocol) = name;
6409 PROTOCOL_LIST (protocol) = list;
6411 lookup_and_install_protocols (list);
6413 if (lookup_protocol (name))
6414 warning ("duplicate declaration for protocol `%s'",
6415 IDENTIFIER_POINTER (name));
6416 else
6417 add_protocol (protocol);
6419 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6421 return protocol;
6424 void
6425 finish_protocol (protocol)
6426 tree protocol ATTRIBUTE_UNUSED;
6431 /* "Encode" a data type into a string, which grows in util_obstack.
6432 ??? What is the FORMAT? Someone please document this! */
6434 static void
6435 encode_type_qualifiers (declspecs)
6436 tree declspecs;
6438 tree spec;
6440 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6442 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6443 obstack_1grow (&util_obstack, 'r');
6444 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6445 obstack_1grow (&util_obstack, 'n');
6446 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6447 obstack_1grow (&util_obstack, 'N');
6448 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6449 obstack_1grow (&util_obstack, 'o');
6450 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6451 obstack_1grow (&util_obstack, 'O');
6452 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6453 obstack_1grow (&util_obstack, 'R');
6454 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6455 obstack_1grow (&util_obstack, 'V');
6459 /* Encode a pointer type. */
6461 static void
6462 encode_pointer (type, curtype, format)
6463 tree type;
6464 int curtype;
6465 int format;
6467 tree pointer_to = TREE_TYPE (type);
6469 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6471 if (TYPE_NAME (pointer_to)
6472 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6474 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6476 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6478 obstack_1grow (&util_obstack, '@');
6479 return;
6481 else if (TREE_STATIC_TEMPLATE (pointer_to))
6483 if (generating_instance_variables)
6485 obstack_1grow (&util_obstack, '@');
6486 obstack_1grow (&util_obstack, '"');
6487 obstack_grow (&util_obstack, name, strlen (name));
6488 obstack_1grow (&util_obstack, '"');
6489 return;
6491 else
6493 obstack_1grow (&util_obstack, '@');
6494 return;
6497 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6499 obstack_1grow (&util_obstack, '#');
6500 return;
6502 #ifndef OBJC_INT_SELECTORS
6503 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6505 obstack_1grow (&util_obstack, ':');
6506 return;
6508 #endif /* OBJC_INT_SELECTORS */
6511 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6512 && TYPE_MODE (pointer_to) == QImode)
6514 obstack_1grow (&util_obstack, '*');
6515 return;
6518 /* We have a type that does not get special treatment. */
6520 /* NeXT extension */
6521 obstack_1grow (&util_obstack, '^');
6522 encode_type (pointer_to, curtype, format);
6525 static void
6526 encode_array (type, curtype, format)
6527 tree type;
6528 int curtype;
6529 int format;
6531 tree an_int_cst = TYPE_SIZE (type);
6532 tree array_of = TREE_TYPE (type);
6533 char buffer[40];
6535 /* An incomplete array is treated like a pointer. */
6536 if (an_int_cst == NULL)
6538 encode_pointer (type, curtype, format);
6539 return;
6542 sprintf (buffer, "[%ld",
6543 (long) (TREE_INT_CST_LOW (an_int_cst)
6544 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6546 obstack_grow (&util_obstack, buffer, strlen (buffer));
6547 encode_type (array_of, curtype, format);
6548 obstack_1grow (&util_obstack, ']');
6549 return;
6552 static void
6553 encode_aggregate_within (type, curtype, format, left, right)
6554 tree type;
6555 int curtype;
6556 int format;
6557 int left;
6558 int right;
6560 if (obstack_object_size (&util_obstack) > 0
6561 && *(obstack_next_free (&util_obstack) - 1) == '^')
6563 tree name = TYPE_NAME (type);
6565 /* we have a reference; this is a NeXT extension. */
6567 if (obstack_object_size (&util_obstack) - curtype == 1
6568 && format == OBJC_ENCODE_INLINE_DEFS)
6570 /* Output format of struct for first level only. */
6571 tree fields = TYPE_FIELDS (type);
6573 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6575 obstack_1grow (&util_obstack, left);
6576 obstack_grow (&util_obstack,
6577 IDENTIFIER_POINTER (name),
6578 strlen (IDENTIFIER_POINTER (name)));
6579 obstack_1grow (&util_obstack, '=');
6581 else
6583 obstack_1grow (&util_obstack, left);
6584 obstack_grow (&util_obstack, "?=", 2);
6587 for ( ; fields; fields = TREE_CHAIN (fields))
6588 encode_field_decl (fields, curtype, format);
6590 obstack_1grow (&util_obstack, right);
6593 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6595 obstack_1grow (&util_obstack, left);
6596 obstack_grow (&util_obstack,
6597 IDENTIFIER_POINTER (name),
6598 strlen (IDENTIFIER_POINTER (name)));
6599 obstack_1grow (&util_obstack, right);
6602 else
6604 /* We have an untagged structure or a typedef. */
6605 obstack_1grow (&util_obstack, left);
6606 obstack_1grow (&util_obstack, '?');
6607 obstack_1grow (&util_obstack, right);
6611 else
6613 tree name = TYPE_NAME (type);
6614 tree fields = TYPE_FIELDS (type);
6616 if (format == OBJC_ENCODE_INLINE_DEFS
6617 || generating_instance_variables)
6619 obstack_1grow (&util_obstack, left);
6620 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6621 obstack_grow (&util_obstack,
6622 IDENTIFIER_POINTER (name),
6623 strlen (IDENTIFIER_POINTER (name)));
6624 else
6625 obstack_1grow (&util_obstack, '?');
6627 obstack_1grow (&util_obstack, '=');
6629 for (; fields; fields = TREE_CHAIN (fields))
6631 if (generating_instance_variables)
6633 tree fname = DECL_NAME (fields);
6635 obstack_1grow (&util_obstack, '"');
6636 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6638 obstack_grow (&util_obstack,
6639 IDENTIFIER_POINTER (fname),
6640 strlen (IDENTIFIER_POINTER (fname)));
6643 obstack_1grow (&util_obstack, '"');
6646 encode_field_decl (fields, curtype, format);
6649 obstack_1grow (&util_obstack, right);
6652 else
6654 obstack_1grow (&util_obstack, left);
6655 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6656 obstack_grow (&util_obstack,
6657 IDENTIFIER_POINTER (name),
6658 strlen (IDENTIFIER_POINTER (name)));
6659 else
6660 /* We have an untagged structure or a typedef. */
6661 obstack_1grow (&util_obstack, '?');
6663 obstack_1grow (&util_obstack, right);
6668 static void
6669 encode_aggregate (type, curtype, format)
6670 tree type;
6671 int curtype;
6672 int format;
6674 enum tree_code code = TREE_CODE (type);
6676 switch (code)
6678 case RECORD_TYPE:
6680 encode_aggregate_within(type, curtype, format, '{', '}');
6681 break;
6683 case UNION_TYPE:
6685 encode_aggregate_within(type, curtype, format, '(', ')');
6686 break;
6689 case ENUMERAL_TYPE:
6690 obstack_1grow (&util_obstack, 'i');
6691 break;
6693 default:
6694 break;
6698 /* Support bitfields. The current version of Objective-C does not support
6699 them. The string will consist of one or more "b:n"'s where n is an
6700 integer describing the width of the bitfield. Currently, classes in
6701 the kit implement a method "-(char *)describeBitfieldStruct:" that
6702 simulates this. If they do not implement this method, the archiver
6703 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6704 according to the GNU compiler. After looking at the "kit", it appears
6705 that all classes currently rely on this default behavior, rather than
6706 hand generating this string (which is tedious). */
6708 static void
6709 encode_bitfield (width)
6710 int width;
6712 char buffer[40];
6713 sprintf (buffer, "b%d", width);
6714 obstack_grow (&util_obstack, buffer, strlen (buffer));
6717 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6719 static void
6720 encode_type (type, curtype, format)
6721 tree type;
6722 int curtype;
6723 int format;
6725 enum tree_code code = TREE_CODE (type);
6727 if (code == INTEGER_TYPE)
6729 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
6730 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
6732 /* Unsigned integer types. */
6734 if (TYPE_MODE (type) == QImode)
6735 obstack_1grow (&util_obstack, 'C');
6736 else if (TYPE_MODE (type) == HImode)
6737 obstack_1grow (&util_obstack, 'S');
6738 else if (TYPE_MODE (type) == SImode)
6740 if (type == long_unsigned_type_node)
6741 obstack_1grow (&util_obstack, 'L');
6742 else
6743 obstack_1grow (&util_obstack, 'I');
6745 else if (TYPE_MODE (type) == DImode)
6746 obstack_1grow (&util_obstack, 'Q');
6749 else
6750 /* Signed integer types. */
6752 if (TYPE_MODE (type) == QImode)
6753 obstack_1grow (&util_obstack, 'c');
6754 else if (TYPE_MODE (type) == HImode)
6755 obstack_1grow (&util_obstack, 's');
6756 else if (TYPE_MODE (type) == SImode)
6758 if (type == long_integer_type_node)
6759 obstack_1grow (&util_obstack, 'l');
6760 else
6761 obstack_1grow (&util_obstack, 'i');
6764 else if (TYPE_MODE (type) == DImode)
6765 obstack_1grow (&util_obstack, 'q');
6769 else if (code == REAL_TYPE)
6771 /* Floating point types. */
6773 if (TYPE_MODE (type) == SFmode)
6774 obstack_1grow (&util_obstack, 'f');
6775 else if (TYPE_MODE (type) == DFmode
6776 || TYPE_MODE (type) == TFmode)
6777 obstack_1grow (&util_obstack, 'd');
6780 else if (code == VOID_TYPE)
6781 obstack_1grow (&util_obstack, 'v');
6783 else if (code == ARRAY_TYPE)
6784 encode_array (type, curtype, format);
6786 else if (code == POINTER_TYPE)
6787 encode_pointer (type, curtype, format);
6789 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6790 encode_aggregate (type, curtype, format);
6792 else if (code == FUNCTION_TYPE) /* '?' */
6793 obstack_1grow (&util_obstack, '?');
6796 static void
6797 encode_complete_bitfield (int position, tree type, int size)
6799 enum tree_code code = TREE_CODE (type);
6800 char buffer[40];
6801 char charType = '?';
6803 if (code == INTEGER_TYPE)
6805 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
6806 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
6808 /* Unsigned integer types. */
6810 if (TYPE_MODE (type) == QImode)
6811 charType = 'C';
6812 else if (TYPE_MODE (type) == HImode)
6813 charType = 'S';
6814 else if (TYPE_MODE (type) == SImode)
6816 if (type == long_unsigned_type_node)
6817 charType = 'L';
6818 else
6819 charType = 'I';
6821 else if (TYPE_MODE (type) == DImode)
6822 charType = 'Q';
6825 else
6826 /* Signed integer types. */
6828 if (TYPE_MODE (type) == QImode)
6829 charType = 'c';
6830 else if (TYPE_MODE (type) == HImode)
6831 charType = 's';
6832 else if (TYPE_MODE (type) == SImode)
6834 if (type == long_integer_type_node)
6835 charType = 'l';
6836 else
6837 charType = 'i';
6840 else if (TYPE_MODE (type) == DImode)
6841 charType = 'q';
6845 else
6846 abort ();
6848 sprintf (buffer, "b%d%c%d", position, charType, size);
6849 obstack_grow (&util_obstack, buffer, strlen (buffer));
6852 static void
6853 encode_field_decl (field_decl, curtype, format)
6854 tree field_decl;
6855 int curtype;
6856 int format;
6858 tree type;
6860 type = TREE_TYPE (field_decl);
6862 /* If this field is obviously a bitfield, or is a bitfield that has been
6863 clobbered to look like a ordinary integer mode, go ahead and generate
6864 the bitfield typing information. */
6865 if (flag_next_runtime)
6867 if (DECL_BIT_FIELD (field_decl))
6868 encode_bitfield (TREE_INT_CST_LOW (DECL_SIZE (field_decl)));
6869 else
6870 encode_type (TREE_TYPE (field_decl), curtype, format);
6872 else
6874 if (DECL_BIT_FIELD (field_decl))
6875 encode_complete_bitfield (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)),
6876 DECL_BIT_FIELD_TYPE (field_decl),
6877 TREE_INT_CST_LOW (DECL_SIZE (field_decl)));
6878 else
6879 encode_type (TREE_TYPE (field_decl), curtype, format);
6883 static tree
6884 expr_last (complex_expr)
6885 tree complex_expr;
6887 tree next;
6889 if (complex_expr)
6890 while ((next = TREE_OPERAND (complex_expr, 0)))
6891 complex_expr = next;
6893 return complex_expr;
6896 /* The selector of the current method,
6897 or NULL if we aren't compiling a method. */
6899 tree
6900 maybe_objc_method_name (decl)
6901 tree decl ATTRIBUTE_UNUSED;
6903 if (method_context)
6904 return METHOD_SEL_NAME (method_context);
6905 else
6906 return 0;
6909 /* Transform a method definition into a function definition as follows:
6910 - synthesize the first two arguments, "self" and "_cmd". */
6912 void
6913 start_method_def (method)
6914 tree method;
6916 tree decl_specs;
6918 /* Required to implement _msgSuper. */
6919 method_context = method;
6920 UOBJC_SUPER_decl = NULL_TREE;
6922 /* Must be called BEFORE start_function. */
6923 pushlevel (0);
6925 /* Generate prototype declarations for arguments..."new-style". */
6927 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6928 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6929 else
6930 /* Really a `struct objc_class *'. However, we allow people to
6931 assign to self, which changes its type midstream. */
6932 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6934 push_parm_decl (build_tree_list
6935 (build_tree_list (decl_specs,
6936 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6937 build_tree_list (unused_list, NULL_TREE)));
6939 #ifdef OBJC_INT_SELECTORS
6940 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
6941 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
6942 push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
6943 build_tree_list (unused_list, NULL_TREE)));
6944 #else /* not OBJC_INT_SELECTORS */
6945 decl_specs = build_tree_list (NULL_TREE,
6946 xref_tag (RECORD_TYPE,
6947 get_identifier (TAG_SELECTOR)));
6948 push_parm_decl (build_tree_list
6949 (build_tree_list (decl_specs,
6950 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6951 build_tree_list (unused_list, NULL_TREE)));
6952 #endif /* not OBJC_INT_SELECTORS */
6954 /* Generate argument declarations if a keyword_decl. */
6955 if (METHOD_SEL_ARGS (method))
6957 tree arglist = METHOD_SEL_ARGS (method);
6960 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6961 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6963 if (arg_decl)
6965 tree last_expr = expr_last (arg_decl);
6967 /* Unite the abstract decl with its name. */
6968 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6969 push_parm_decl (build_tree_list
6970 (build_tree_list (arg_spec, arg_decl),
6971 build_tree_list (NULL_TREE, NULL_TREE)));
6973 /* Unhook: restore the abstract declarator. */
6974 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6977 else
6978 push_parm_decl (build_tree_list
6979 (build_tree_list (arg_spec,
6980 KEYWORD_ARG_NAME (arglist)),
6981 build_tree_list (NULL_TREE, NULL_TREE)));
6983 arglist = TREE_CHAIN (arglist);
6985 while (arglist);
6988 if (METHOD_ADD_ARGS (method) > (tree)1)
6990 /* We have a variable length selector - in "prototype" format. */
6991 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
6992 while (akey)
6994 /* This must be done prior to calling pushdecl. pushdecl is
6995 going to change our chain on us. */
6996 tree nextkey = TREE_CHAIN (akey);
6997 pushdecl (akey);
6998 akey = nextkey;
7003 static void
7004 warn_with_method (message, mtype, method)
7005 const char *message;
7006 int mtype;
7007 tree method;
7009 if (count_error (1) == 0)
7010 return;
7012 report_error_function (DECL_SOURCE_FILE (method));
7014 fprintf (stderr, "%s:%d: warning: ",
7015 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
7016 bzero (errbuf, BUFSIZE);
7017 fprintf (stderr, "%s `%c%s'\n",
7018 message, mtype, gen_method_decl (method, errbuf));
7021 /* Return 1 if METHOD is consistent with PROTO. */
7023 static int
7024 comp_method_with_proto (method, proto)
7025 tree method, proto;
7027 static tree function_type = 0;
7029 /* Create a function_type node once. */
7030 if (!function_type)
7031 function_type = make_node (FUNCTION_TYPE);
7033 /* Install argument types - normally set by build_function_type. */
7034 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
7036 /* install return type */
7037 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
7039 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
7042 /* Return 1 if PROTO1 is consistent with PROTO2. */
7044 static int
7045 comp_proto_with_proto (proto1, proto2)
7046 tree proto1, proto2;
7048 static tree function_type1 = 0, function_type2 = 0;
7050 /* Create a couple function_type node's once. */
7051 if (!function_type1)
7053 function_type1 = make_node (FUNCTION_TYPE);
7054 function_type2 = make_node (FUNCTION_TYPE);
7057 /* Install argument types; normally set by build_function_type. */
7058 TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0);
7059 TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0);
7061 /* Install return type. */
7062 TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1));
7063 TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2));
7065 return comptypes (function_type1, function_type2);
7068 /* - Generate an identifier for the function. the format is "_n_cls",
7069 where 1 <= n <= nMethods, and cls is the name the implementation we
7070 are processing.
7071 - Install the return type from the method declaration.
7072 - If we have a prototype, check for type consistency. */
7074 static void
7075 really_start_method (method, parmlist)
7076 tree method, parmlist;
7078 tree sc_spec, ret_spec, ret_decl, decl_specs;
7079 tree method_decl, method_id;
7080 const char *sel_name, *class_name, *cat_name;
7081 char *buf;
7083 /* Synth the storage class & assemble the return type. */
7084 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7085 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7086 decl_specs = chainon (sc_spec, ret_spec);
7088 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7089 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
7090 cat_name = ((TREE_CODE (implementation_context)
7091 == CLASS_IMPLEMENTATION_TYPE)
7092 ? NULL
7093 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
7094 method_slot++;
7096 /* Make sure this is big enough for any plausible method label. */
7097 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7098 + (cat_name ? strlen (cat_name) : 0));
7100 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7101 class_name, cat_name, sel_name, method_slot);
7103 method_id = get_identifier (buf);
7105 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7107 /* Check the declarator portion of the return type for the method. */
7108 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7110 /* Unite the complex decl (specified in the abstract decl) with the
7111 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7112 tree save_expr = expr_last (ret_decl);
7114 TREE_OPERAND (save_expr, 0) = method_decl;
7115 method_decl = ret_decl;
7117 /* Fool the parser into thinking it is starting a function. */
7118 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE);
7120 /* Unhook: this has the effect of restoring the abstract declarator. */
7121 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7124 else
7126 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7128 /* Fool the parser into thinking it is starting a function. */
7129 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE);
7131 /* Unhook: this has the effect of restoring the abstract declarator. */
7132 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7135 METHOD_DEFINITION (method) = current_function_decl;
7137 if (implementation_template != implementation_context)
7139 tree proto;
7141 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7142 proto = lookup_instance_method_static (implementation_template,
7143 METHOD_SEL_NAME (method));
7144 else
7145 proto = lookup_class_method_static (implementation_template,
7146 METHOD_SEL_NAME (method));
7148 if (proto && ! comp_method_with_proto (method, proto))
7150 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7152 warn_with_method ("conflicting types for", type, method);
7153 warn_with_method ("previous declaration of", type, proto);
7158 /* The following routine is always called...this "architecture" is to
7159 accommodate "old-style" variable length selectors.
7161 - a:a b:b // prototype ; id c; id d; // old-style. */
7163 void
7164 continue_method_def ()
7166 tree parmlist;
7168 if (METHOD_ADD_ARGS (method_context) == (tree)1)
7169 /* We have a `, ...' immediately following the selector. */
7170 parmlist = get_parm_info (0);
7171 else
7172 parmlist = get_parm_info (1); /* place a `void_at_end' */
7174 /* Set self_decl from the first argument...this global is used by
7175 build_ivar_reference calling build_indirect_ref. */
7176 self_decl = TREE_PURPOSE (parmlist);
7178 poplevel (0, 0, 0);
7179 really_start_method (method_context, parmlist);
7180 store_parm_decls ();
7183 /* Called by the parser, from the `pushlevel' production. */
7185 void
7186 add_objc_decls ()
7188 if (!UOBJC_SUPER_decl)
7190 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7191 build_tree_list (NULL_TREE,
7192 objc_super_template),
7193 0, NULL_TREE, NULL_TREE);
7195 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7197 /* This prevents `unused variable' warnings when compiling with -Wall. */
7198 TREE_USED (UOBJC_SUPER_decl) = 1;
7199 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7203 /* _n_Method (id self, SEL sel, ...)
7205 struct objc_super _S;
7206 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7207 } */
7209 tree
7210 get_super_receiver ()
7212 if (method_context)
7214 tree super_expr, super_expr_list;
7216 /* Set receiver to self. */
7217 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7218 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7219 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7221 /* Set class to begin searching. */
7222 super_expr = build_component_ref (UOBJC_SUPER_decl,
7223 get_identifier ("class"));
7225 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7227 /* [_cls, __cls]Super are "pre-built" in
7228 synth_forward_declarations. */
7230 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7231 ((TREE_CODE (method_context)
7232 == INSTANCE_METHOD_DECL)
7233 ? ucls_super_ref
7234 : uucls_super_ref));
7237 else
7238 /* We have a category. */
7240 tree super_name = CLASS_SUPER_NAME (implementation_template);
7241 tree super_class;
7243 if (!super_name)
7245 error ("no super class declared in interface for `%s'",
7246 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7247 return error_mark_node;
7250 if (flag_next_runtime)
7252 super_class = get_class_reference (super_name);
7253 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
7254 super_class
7255 = build_component_ref (build_indirect_ref (super_class, "->"),
7256 get_identifier ("isa"));
7258 else
7260 add_class_reference (super_name);
7261 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
7262 ? objc_get_class_decl : objc_get_meta_class_decl);
7263 assemble_external (super_class);
7264 super_class
7265 = build_function_call
7266 (super_class,
7267 build_tree_list
7268 (NULL_TREE,
7269 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7270 IDENTIFIER_POINTER (super_name))));
7273 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7274 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7277 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7279 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7280 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7282 return build_compound_expr (super_expr_list);
7284 else
7286 error ("[super ...] must appear in a method context");
7287 return error_mark_node;
7291 static tree
7292 encode_method_def (func_decl)
7293 tree func_decl;
7295 tree parms;
7296 int stack_size;
7297 int max_parm_end = 0;
7298 char buffer[40];
7299 tree result;
7301 /* Return type. */
7302 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7303 obstack_object_size (&util_obstack),
7304 OBJC_ENCODE_INLINE_DEFS);
7306 /* Stack size. */
7307 for (parms = DECL_ARGUMENTS (func_decl); parms;
7308 parms = TREE_CHAIN (parms))
7310 int parm_end = (forwarding_offset (parms)
7311 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms)))
7312 / BITS_PER_UNIT));
7314 if (!offset_is_register && parm_end > max_parm_end)
7315 max_parm_end = parm_end;
7318 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7320 sprintf (buffer, "%d", stack_size);
7321 obstack_grow (&util_obstack, buffer, strlen (buffer));
7323 /* Argument types. */
7324 for (parms = DECL_ARGUMENTS (func_decl); parms;
7325 parms = TREE_CHAIN (parms))
7327 /* Type. */
7328 encode_type (TREE_TYPE (parms),
7329 obstack_object_size (&util_obstack),
7330 OBJC_ENCODE_INLINE_DEFS);
7332 /* Compute offset. */
7333 sprintf (buffer, "%d", forwarding_offset (parms));
7335 /* Indicate register. */
7336 if (offset_is_register)
7337 obstack_1grow (&util_obstack, '+');
7339 obstack_grow (&util_obstack, buffer, strlen (buffer));
7342 obstack_1grow (&util_obstack, 0);
7343 result = get_identifier (obstack_finish (&util_obstack));
7344 obstack_free (&util_obstack, util_firstobj);
7345 return result;
7348 void
7349 finish_method_def ()
7351 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
7353 finish_function (0);
7355 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7356 since the optimizer may find "may be used before set" errors. */
7357 method_context = NULL_TREE;
7360 #if 0
7362 lang_report_error_function (decl)
7363 tree decl;
7365 if (method_context)
7367 fprintf (stderr, "In method `%s'\n",
7368 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
7369 return 1;
7372 else
7373 return 0;
7375 #endif
7377 static int
7378 is_complex_decl (type)
7379 tree type;
7381 return (TREE_CODE (type) == ARRAY_TYPE
7382 || TREE_CODE (type) == FUNCTION_TYPE
7383 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7387 /* Code to convert a decl node into text for a declaration in C. */
7389 static char tmpbuf[256];
7391 static void
7392 adorn_decl (decl, str)
7393 tree decl;
7394 char *str;
7396 enum tree_code code = TREE_CODE (decl);
7398 if (code == ARRAY_REF)
7400 tree an_int_cst = TREE_OPERAND (decl, 1);
7402 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7403 sprintf (str + strlen (str), "[%ld]",
7404 (long) TREE_INT_CST_LOW (an_int_cst));
7405 else
7406 strcat (str, "[]");
7409 else if (code == ARRAY_TYPE)
7411 tree an_int_cst = TYPE_SIZE (decl);
7412 tree array_of = TREE_TYPE (decl);
7414 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7415 sprintf (str + strlen (str), "[%ld]",
7416 (long) (TREE_INT_CST_LOW (an_int_cst)
7417 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7418 else
7419 strcat (str, "[]");
7422 else if (code == CALL_EXPR)
7424 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7426 strcat (str, "(");
7427 while (chain)
7429 gen_declaration (chain, str);
7430 chain = TREE_CHAIN (chain);
7431 if (chain)
7432 strcat (str, ", ");
7434 strcat (str, ")");
7437 else if (code == FUNCTION_TYPE)
7439 tree chain = TYPE_ARG_TYPES (decl);
7441 strcat (str, "(");
7442 while (chain && TREE_VALUE (chain) != void_type_node)
7444 gen_declaration (TREE_VALUE (chain), str);
7445 chain = TREE_CHAIN (chain);
7446 if (chain && TREE_VALUE (chain) != void_type_node)
7447 strcat (str, ", ");
7449 strcat (str, ")");
7452 else if (code == INDIRECT_REF)
7454 strcpy (tmpbuf, "*");
7455 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7457 tree chain;
7459 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7460 chain;
7461 chain = TREE_CHAIN (chain))
7463 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7465 strcat (tmpbuf, " ");
7466 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7469 if (str[0])
7470 strcat (tmpbuf, " ");
7472 strcat (tmpbuf, str);
7473 strcpy (str, tmpbuf);
7476 else if (code == POINTER_TYPE)
7478 strcpy (tmpbuf, "*");
7479 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7481 if (TREE_READONLY (decl))
7482 strcat (tmpbuf, " const");
7483 if (TYPE_VOLATILE (decl))
7484 strcat (tmpbuf, " volatile");
7485 if (str[0])
7486 strcat (tmpbuf, " ");
7488 strcat (tmpbuf, str);
7489 strcpy (str, tmpbuf);
7493 static char *
7494 gen_declarator (decl, buf, name)
7495 tree decl;
7496 char *buf;
7497 const char *name;
7499 if (decl)
7501 enum tree_code code = TREE_CODE (decl);
7502 char *str;
7503 tree op;
7504 int wrap = 0;
7506 switch (code)
7508 case ARRAY_REF:
7509 case INDIRECT_REF:
7510 case CALL_EXPR:
7511 op = TREE_OPERAND (decl, 0);
7513 /* We have a pointer to a function or array...(*)(), (*)[] */
7514 if ((code == ARRAY_REF || code == CALL_EXPR)
7515 && op && TREE_CODE (op) == INDIRECT_REF)
7516 wrap = 1;
7518 str = gen_declarator (op, buf, name);
7520 if (wrap)
7522 strcpy (tmpbuf, "(");
7523 strcat (tmpbuf, str);
7524 strcat (tmpbuf, ")");
7525 strcpy (str, tmpbuf);
7528 adorn_decl (decl, str);
7529 break;
7531 case ARRAY_TYPE:
7532 case FUNCTION_TYPE:
7533 case POINTER_TYPE:
7534 strcpy (buf, name);
7535 str = buf;
7537 /* This clause is done iteratively rather than recursively. */
7540 op = (is_complex_decl (TREE_TYPE (decl))
7541 ? TREE_TYPE (decl) : NULL_TREE);
7543 adorn_decl (decl, str);
7545 /* We have a pointer to a function or array...(*)(), (*)[] */
7546 if (code == POINTER_TYPE
7547 && op && (TREE_CODE (op) == FUNCTION_TYPE
7548 || TREE_CODE (op) == ARRAY_TYPE))
7550 strcpy (tmpbuf, "(");
7551 strcat (tmpbuf, str);
7552 strcat (tmpbuf, ")");
7553 strcpy (str, tmpbuf);
7556 decl = (is_complex_decl (TREE_TYPE (decl))
7557 ? TREE_TYPE (decl) : NULL_TREE);
7560 while (decl && (code = TREE_CODE (decl)))
7563 break;
7565 case IDENTIFIER_NODE:
7566 /* Will only happen if we are processing a "raw" expr-decl. */
7567 strcpy (buf, IDENTIFIER_POINTER (decl));
7568 return buf;
7570 default:
7571 abort ();
7574 return str;
7577 else
7578 /* We have an abstract declarator or a _DECL node. */
7580 strcpy (buf, name);
7581 return buf;
7585 static void
7586 gen_declspecs (declspecs, buf, raw)
7587 tree declspecs;
7588 char *buf;
7589 int raw;
7591 if (raw)
7593 tree chain;
7595 for (chain = nreverse (copy_list (declspecs));
7596 chain; chain = TREE_CHAIN (chain))
7598 tree aspec = TREE_VALUE (chain);
7600 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7601 strcat (buf, IDENTIFIER_POINTER (aspec));
7602 else if (TREE_CODE (aspec) == RECORD_TYPE)
7604 if (TYPE_NAME (aspec))
7606 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7608 if (! TREE_STATIC_TEMPLATE (aspec))
7609 strcat (buf, "struct ");
7610 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7612 /* NEW!!! */
7613 if (protocol_list)
7615 tree chain = protocol_list;
7617 strcat (buf, " <");
7618 while (chain)
7620 strcat (buf,
7621 IDENTIFIER_POINTER
7622 (PROTOCOL_NAME (TREE_VALUE (chain))));
7623 chain = TREE_CHAIN (chain);
7624 if (chain)
7625 strcat (buf, ", ");
7627 strcat (buf, ">");
7631 else
7632 strcat (buf, "untagged struct");
7635 else if (TREE_CODE (aspec) == UNION_TYPE)
7637 if (TYPE_NAME (aspec))
7639 if (! TREE_STATIC_TEMPLATE (aspec))
7640 strcat (buf, "union ");
7641 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7643 else
7644 strcat (buf, "untagged union");
7647 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7649 if (TYPE_NAME (aspec))
7651 if (! TREE_STATIC_TEMPLATE (aspec))
7652 strcat (buf, "enum ");
7653 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7655 else
7656 strcat (buf, "untagged enum");
7659 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7660 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7662 else if (IS_ID (aspec))
7664 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7666 strcat (buf, "id");
7667 if (protocol_list)
7669 tree chain = protocol_list;
7671 strcat (buf, " <");
7672 while (chain)
7674 strcat (buf,
7675 IDENTIFIER_POINTER
7676 (PROTOCOL_NAME (TREE_VALUE (chain))));
7677 chain = TREE_CHAIN (chain);
7678 if (chain)
7679 strcat (buf, ", ");
7681 strcat (buf, ">");
7684 if (TREE_CHAIN (chain))
7685 strcat (buf, " ");
7688 else
7690 /* Type qualifiers. */
7691 if (TREE_READONLY (declspecs))
7692 strcat (buf, "const ");
7693 if (TYPE_VOLATILE (declspecs))
7694 strcat (buf, "volatile ");
7696 switch (TREE_CODE (declspecs))
7698 /* Type specifiers. */
7700 case INTEGER_TYPE:
7701 declspecs = TYPE_MAIN_VARIANT (declspecs);
7703 /* Signed integer types. */
7705 if (declspecs == short_integer_type_node)
7706 strcat (buf, "short int ");
7707 else if (declspecs == integer_type_node)
7708 strcat (buf, "int ");
7709 else if (declspecs == long_integer_type_node)
7710 strcat (buf, "long int ");
7711 else if (declspecs == long_long_integer_type_node)
7712 strcat (buf, "long long int ");
7713 else if (declspecs == signed_char_type_node
7714 || declspecs == char_type_node)
7715 strcat (buf, "char ");
7717 /* Unsigned integer types. */
7719 else if (declspecs == short_unsigned_type_node)
7720 strcat (buf, "unsigned short ");
7721 else if (declspecs == unsigned_type_node)
7722 strcat (buf, "unsigned int ");
7723 else if (declspecs == long_unsigned_type_node)
7724 strcat (buf, "unsigned long ");
7725 else if (declspecs == long_long_unsigned_type_node)
7726 strcat (buf, "unsigned long long ");
7727 else if (declspecs == unsigned_char_type_node)
7728 strcat (buf, "unsigned char ");
7729 break;
7731 case REAL_TYPE:
7732 declspecs = TYPE_MAIN_VARIANT (declspecs);
7734 if (declspecs == float_type_node)
7735 strcat (buf, "float ");
7736 else if (declspecs == double_type_node)
7737 strcat (buf, "double ");
7738 else if (declspecs == long_double_type_node)
7739 strcat (buf, "long double ");
7740 break;
7742 case RECORD_TYPE:
7743 if (TYPE_NAME (declspecs)
7744 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7746 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7748 if (! TREE_STATIC_TEMPLATE (declspecs))
7749 strcat (buf, "struct ");
7750 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7752 if (protocol_list)
7754 tree chain = protocol_list;
7756 strcat (buf, " <");
7757 while (chain)
7759 strcat (buf,
7760 IDENTIFIER_POINTER
7761 (PROTOCOL_NAME (TREE_VALUE (chain))));
7762 chain = TREE_CHAIN (chain);
7763 if (chain)
7764 strcat (buf, ", ");
7766 strcat (buf, ">");
7770 else
7771 strcat (buf, "untagged struct");
7773 strcat (buf, " ");
7774 break;
7776 case UNION_TYPE:
7777 if (TYPE_NAME (declspecs)
7778 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7780 strcat (buf, "union ");
7781 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7782 strcat (buf, " ");
7785 else
7786 strcat (buf, "untagged union ");
7787 break;
7789 case ENUMERAL_TYPE:
7790 if (TYPE_NAME (declspecs)
7791 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7793 strcat (buf, "enum ");
7794 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7795 strcat (buf, " ");
7798 else
7799 strcat (buf, "untagged enum ");
7800 break;
7802 case VOID_TYPE:
7803 strcat (buf, "void ");
7804 break;
7806 case POINTER_TYPE:
7808 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7810 strcat (buf, "id");
7811 if (protocol_list)
7813 tree chain = protocol_list;
7815 strcat (buf, " <");
7816 while (chain)
7818 strcat (buf,
7819 IDENTIFIER_POINTER
7820 (PROTOCOL_NAME (TREE_VALUE (chain))));
7821 chain = TREE_CHAIN (chain);
7822 if (chain)
7823 strcat (buf, ", ");
7826 strcat (buf, ">");
7829 break;
7831 default:
7832 break;
7837 static char *
7838 gen_declaration (atype_or_adecl, buf)
7839 tree atype_or_adecl;
7840 char *buf;
7842 char declbuf[256];
7844 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7846 tree declspecs; /* "identifier_node", "record_type" */
7847 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7849 /* We have a "raw", abstract declarator (typename). */
7850 declarator = TREE_VALUE (atype_or_adecl);
7851 declspecs = TREE_PURPOSE (atype_or_adecl);
7853 gen_declspecs (declspecs, buf, 1);
7854 if (declarator)
7856 strcat (buf, " ");
7857 strcat (buf, gen_declarator (declarator, declbuf, ""));
7861 else
7863 tree atype;
7864 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7865 tree declarator; /* "array_type", "function_type", "pointer_type". */
7867 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7868 || TREE_CODE (atype_or_adecl) == PARM_DECL
7869 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7870 atype = TREE_TYPE (atype_or_adecl);
7871 else
7872 /* Assume we have a *_type node. */
7873 atype = atype_or_adecl;
7875 if (is_complex_decl (atype))
7877 tree chain;
7879 /* Get the declaration specifier; it is at the end of the list. */
7880 declarator = chain = atype;
7882 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7883 while (is_complex_decl (chain));
7884 declspecs = chain;
7887 else
7889 declspecs = atype;
7890 declarator = NULL_TREE;
7893 gen_declspecs (declspecs, buf, 0);
7895 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7896 || TREE_CODE (atype_or_adecl) == PARM_DECL
7897 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7899 const char *decl_name =
7900 (DECL_NAME (atype_or_adecl)
7901 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7903 if (declarator)
7905 strcat (buf, " ");
7906 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7909 else if (decl_name[0])
7911 strcat (buf, " ");
7912 strcat (buf, decl_name);
7915 else if (declarator)
7917 strcat (buf, " ");
7918 strcat (buf, gen_declarator (declarator, declbuf, ""));
7922 return buf;
7925 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7927 static char *
7928 gen_method_decl (method, buf)
7929 tree method;
7930 char *buf;
7932 tree chain;
7934 if (RAW_TYPESPEC (method) != objc_object_reference)
7936 strcpy (buf, "(");
7937 gen_declaration (TREE_TYPE (method), buf);
7938 strcat (buf, ")");
7941 chain = METHOD_SEL_ARGS (method);
7942 if (chain)
7944 /* We have a chain of keyword_decls. */
7947 if (KEYWORD_KEY_NAME (chain))
7948 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7950 strcat (buf, ":");
7951 if (RAW_TYPESPEC (chain) != objc_object_reference)
7953 strcat (buf, "(");
7954 gen_declaration (TREE_TYPE (chain), buf);
7955 strcat (buf, ")");
7958 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7959 if ((chain = TREE_CHAIN (chain)))
7960 strcat (buf, " ");
7962 while (chain);
7964 if (METHOD_ADD_ARGS (method) == (tree)1)
7965 strcat (buf, ", ...");
7966 else if (METHOD_ADD_ARGS (method))
7968 /* We have a tree list node as generate by get_parm_info. */
7969 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7971 /* Know we have a chain of parm_decls. */
7972 while (chain)
7974 strcat (buf, ", ");
7975 gen_declaration (chain, buf);
7976 chain = TREE_CHAIN (chain);
7981 else
7982 /* We have a unary selector. */
7983 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7985 return buf;
7988 /* Debug info. */
7990 static void
7991 dump_interface (fp, chain)
7992 FILE *fp;
7993 tree chain;
7995 char *buf = (char *)xmalloc (256);
7996 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7997 tree ivar_decls = CLASS_RAW_IVARS (chain);
7998 tree nst_methods = CLASS_NST_METHODS (chain);
7999 tree cls_methods = CLASS_CLS_METHODS (chain);
8001 fprintf (fp, "\n@interface %s", my_name);
8003 if (CLASS_SUPER_NAME (chain))
8005 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8006 fprintf (fp, " : %s\n", super_name);
8008 else
8009 fprintf (fp, "\n");
8011 if (ivar_decls)
8013 fprintf (fp, "{\n");
8016 bzero (buf, 256);
8017 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8018 ivar_decls = TREE_CHAIN (ivar_decls);
8020 while (ivar_decls);
8021 fprintf (fp, "}\n");
8024 while (nst_methods)
8026 bzero (buf, 256);
8027 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8028 nst_methods = TREE_CHAIN (nst_methods);
8031 while (cls_methods)
8033 bzero (buf, 256);
8034 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8035 cls_methods = TREE_CHAIN (cls_methods);
8037 fprintf (fp, "\n@end");
8040 /* Demangle function for Objective-C */
8041 static const char *
8042 objc_demangle (mangled)
8043 const char *mangled;
8045 char *demangled, *cp;
8047 if (mangled[0] == '_' &&
8048 (mangled[1] == 'i' || mangled[1] == 'c') &&
8049 mangled[2] == '_')
8051 cp = demangled = xmalloc(strlen(mangled) + 2);
8052 if (mangled[1] == 'i')
8053 *cp++ = '-'; /* for instance method */
8054 else
8055 *cp++ = '+'; /* for class method */
8056 *cp++ = '['; /* opening left brace */
8057 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8058 while (*cp && *cp == '_')
8059 cp++; /* skip any initial underbars in class name */
8060 cp = strchr(cp, '_'); /* find first non-initial underbar */
8061 if (cp == NULL)
8063 free(demangled); /* not mangled name */
8064 return mangled;
8066 if (cp[1] == '_') /* easy case: no category name */
8068 *cp++ = ' '; /* replace two '_' with one ' ' */
8069 strcpy(cp, mangled + (cp - demangled) + 2);
8071 else
8073 *cp++ = '('; /* less easy case: category name */
8074 cp = strchr(cp, '_');
8075 if (cp == 0)
8077 free(demangled); /* not mangled name */
8078 return mangled;
8080 *cp++ = ')';
8081 *cp++ = ' '; /* overwriting 1st char of method name... */
8082 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8084 while (*cp && *cp == '_')
8085 cp++; /* skip any initial underbars in method name */
8086 for (; *cp; cp++)
8087 if (*cp == '_')
8088 *cp = ':'; /* replace remaining '_' with ':' */
8089 *cp++ = ']'; /* closing right brace */
8090 *cp++ = 0; /* string terminator */
8091 return demangled;
8093 else
8094 return mangled; /* not an objc mangled name */
8097 static const char *
8098 objc_printable_name (decl, kind)
8099 tree decl;
8100 int kind ATTRIBUTE_UNUSED;
8102 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8105 static void
8106 init_objc ()
8108 /* Add the special tree codes of Objective C to the tables. */
8110 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8112 gcc_obstack_init (&util_obstack);
8113 util_firstobj = (char *) obstack_finish (&util_obstack);
8115 memcpy (tree_code_type + (int) LAST_CODE,
8116 objc_tree_code_type,
8117 (int) LAST_OBJC_TREE_CODE - (int) LAST_CODE);
8118 memcpy (tree_code_length + (int) LAST_CODE,
8119 objc_tree_code_length,
8120 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) * sizeof (int)));
8121 memcpy (tree_code_name + (int) LAST_CODE,
8122 objc_tree_code_name,
8123 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) * sizeof (char *)));
8125 errbuf = (char *)xmalloc (BUFSIZE);
8126 hash_init ();
8127 synth_module_prologue ();
8129 /* Change the default error function */
8130 decl_printable_name = objc_printable_name;
8133 static void
8134 finish_objc ()
8136 struct imp_entry *impent;
8137 tree chain;
8138 /* The internally generated initializers appear to have missing braces.
8139 Don't warn about this. */
8140 int save_warn_missing_braces = warn_missing_braces;
8141 warn_missing_braces = 0;
8143 generate_forward_declaration_to_string_table ();
8145 #ifdef OBJC_PROLOGUE
8146 OBJC_PROLOGUE;
8147 #endif
8149 /* Process the static instances here because initialization of objc_symtab
8150 depends on them. */
8151 if (objc_static_instances)
8152 generate_static_references ();
8154 if (implementation_context || class_names_chain
8155 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8156 generate_objc_symtab_decl ();
8158 for (impent = imp_list; impent; impent = impent->next)
8160 implementation_context = impent->imp_context;
8161 implementation_template = impent->imp_template;
8163 UOBJC_CLASS_decl = impent->class_decl;
8164 UOBJC_METACLASS_decl = impent->meta_decl;
8166 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8168 /* all of the following reference the string pool... */
8169 generate_ivar_lists ();
8170 generate_dispatch_tables ();
8171 generate_shared_structures ();
8173 else
8175 generate_dispatch_tables ();
8176 generate_category (implementation_context);
8180 /* If we are using an array of selectors, we must always
8181 finish up the array decl even if no selectors were used. */
8182 if (! flag_next_runtime || sel_ref_chain)
8183 build_selector_translation_table ();
8185 if (protocol_chain)
8186 generate_protocols ();
8188 if (implementation_context || class_names_chain || objc_static_instances
8189 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8191 /* Arrange for Objc data structures to be initialized at run time. */
8192 const char *init_name = build_module_descriptor ();
8193 if (init_name)
8194 assemble_constructor (init_name);
8197 /* Dump the class references. This forces the appropriate classes
8198 to be linked into the executable image, preserving unix archive
8199 semantics. This can be removed when we move to a more dynamically
8200 linked environment. */
8202 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8204 handle_class_ref (chain);
8205 if (TREE_PURPOSE (chain))
8206 generate_classref_translation_entry (chain);
8209 for (impent = imp_list; impent; impent = impent->next)
8210 handle_impent (impent);
8212 /* Dump the string table last. */
8214 generate_strings ();
8216 if (flag_gen_declaration)
8218 add_class (implementation_context);
8219 dump_interface (gen_declaration_file, implementation_context);
8222 if (warn_selector)
8224 int slot;
8225 hash hsh;
8227 /* Run through the selector hash tables and print a warning for any
8228 selector which has multiple methods. */
8230 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8231 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8232 if (hsh->list)
8234 tree meth = hsh->key;
8235 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8236 ? '-' : '+');
8237 attr loop;
8239 warning ("potential selector conflict for method `%s'",
8240 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8241 warn_with_method ("found", type, meth);
8242 for (loop = hsh->list; loop; loop = loop->next)
8243 warn_with_method ("found", type, loop->value);
8246 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8247 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8248 if (hsh->list)
8250 tree meth = hsh->key;
8251 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8252 ? '-' : '+');
8253 attr loop;
8255 warning ("potential selector conflict for method `%s'",
8256 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8257 warn_with_method ("found", type, meth);
8258 for (loop = hsh->list; loop; loop = loop->next)
8259 warn_with_method ("found", type, loop->value);
8263 warn_missing_braces = save_warn_missing_braces;
8266 /* Subroutines of finish_objc. */
8268 static void
8269 generate_classref_translation_entry (chain)
8270 tree chain;
8272 tree expr, name, decl_specs, decl, sc_spec;
8273 tree type;
8275 type = TREE_TYPE (TREE_PURPOSE (chain));
8277 expr = add_objc_string (TREE_VALUE (chain), class_names);
8278 expr = build_c_cast (type, expr); /* cast! */
8280 name = DECL_NAME (TREE_PURPOSE (chain));
8282 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8284 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8285 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8287 /* The decl that is returned from start_decl is the one that we
8288 forward declared in build_class_reference. */
8289 decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
8290 finish_decl (decl, expr, NULL_TREE);
8291 return;
8294 static void
8295 handle_class_ref (chain)
8296 tree chain;
8298 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8299 if (! flag_next_runtime)
8301 tree decl;
8302 char *string = (char *) alloca (strlen (name) + 30);
8303 tree exp;
8305 sprintf (string, "%sobjc_class_name_%s",
8306 (flag_next_runtime ? "." : "__"), name);
8308 /* Make a decl for this name, so we can use its address in a tree. */
8309 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8310 DECL_EXTERNAL (decl) = 1;
8311 TREE_PUBLIC (decl) = 1;
8313 pushdecl (decl);
8314 rest_of_decl_compilation (decl, 0, 0, 0);
8316 /* Make following constant read-only (why not)? */
8317 readonly_data_section ();
8319 exp = build1 (ADDR_EXPR, string_type_node, decl);
8321 /* Align the section properly. */
8322 assemble_constant_align (exp);
8324 /* Inform the assembler about this new external thing. */
8325 assemble_external (decl);
8327 /* Output a constant to reference this address. */
8328 output_constant (exp, int_size_in_bytes (string_type_node));
8330 else
8332 /* This overreliance on our assembler (i.e. lack of portability)
8333 should be dealt with at some point. The GNU strategy (above)
8334 won't work either, but it is a start. */
8335 char *string = (char *) alloca (strlen (name) + 30);
8336 sprintf (string, ".reference .objc_class_name_%s", name);
8337 assemble_asm (my_build_string (strlen (string) + 1, string));
8341 static void
8342 handle_impent (impent)
8343 struct imp_entry *impent;
8345 implementation_context = impent->imp_context;
8346 implementation_template = impent->imp_template;
8348 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8350 const char *class_name =
8351 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8352 char *string = (char *) alloca (strlen (class_name) + 30);
8354 if (flag_next_runtime)
8356 /* Grossly unportable.
8357 People should know better than to assume
8358 such things about assembler syntax! */
8359 sprintf (string, ".objc_class_name_%s=0", class_name);
8360 assemble_asm (my_build_string (strlen (string) + 1, string));
8362 sprintf (string, ".globl .objc_class_name_%s", class_name);
8363 assemble_asm (my_build_string (strlen (string) + 1, string));
8366 else
8368 sprintf (string, "%sobjc_class_name_%s",
8369 (flag_next_runtime ? "." : "__"), class_name);
8370 assemble_global (string);
8371 assemble_label (string);
8375 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8377 const char *class_name =
8378 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8379 const char *class_super_name =
8380 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8381 char *string = (char *) alloca (strlen (class_name)
8382 + strlen (class_super_name) + 30);
8384 /* Do the same for categories. Even though no references to these
8385 symbols are generated automatically by the compiler, it gives
8386 you a handle to pull them into an archive by hand. */
8387 if (flag_next_runtime)
8389 /* Grossly unportable. */
8390 sprintf (string, ".objc_category_name_%s_%s=0",
8391 class_name, class_super_name);
8392 assemble_asm (my_build_string (strlen (string) + 1, string));
8394 sprintf (string, ".globl .objc_category_name_%s_%s",
8395 class_name, class_super_name);
8396 assemble_asm (my_build_string (strlen (string) + 1, string));
8399 else
8401 sprintf (string, "%sobjc_category_name_%s_%s",
8402 (flag_next_runtime ? "." : "__"),
8403 class_name, class_super_name);
8404 assemble_global (string);
8405 assemble_label (string);
8410 #ifdef DEBUG
8412 static void
8413 objc_debug (fp)
8414 FILE *fp;
8416 char *buf = (char *)xmalloc (256);
8418 { /* dump function prototypes */
8419 tree loop = UOBJC_MODULES_decl;
8421 fprintf (fp, "\n\nfunction prototypes:\n");
8422 while (loop)
8424 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
8426 /* We have a function definition: generate prototype. */
8427 bzero (errbuf, BUFSIZE);
8428 gen_declaration (loop, errbuf);
8429 fprintf (fp, "%s;\n", errbuf);
8431 loop = TREE_CHAIN (loop);
8435 /* Dump global chains. */
8436 tree loop;
8437 int i, index = 0, offset = 0;
8438 hash hashlist;
8440 for (i = 0; i < SIZEHASHTABLE; i++)
8442 if (hashlist = nst_method_hash_list[i])
8444 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
8447 bzero (buf, 256);
8448 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8449 hashlist = hashlist->next;
8451 while (hashlist);
8455 for (i = 0; i < SIZEHASHTABLE; i++)
8457 if (hashlist = cls_method_hash_list[i])
8459 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
8462 bzero (buf, 256);
8463 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8464 hashlist = hashlist->next;
8466 while (hashlist);
8470 fprintf (fp, "\nsel_refdef_chain:\n");
8471 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
8473 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
8474 IDENTIFIER_POINTER (TREE_VALUE (loop)));
8475 index++;
8476 /* add one for the '\0' character */
8477 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
8480 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
8483 #endif
8485 void
8486 print_lang_statistics ()