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)
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
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 */
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
87 /* Define the special tree codes that we use. */
89 /* Table indexed by tree code giving a string containing a character
90 classifying the tree code. Possibilities are
91 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
95 static const char objc_tree_code_type[] = {
97 #include "objc-tree.def"
101 /* Table indexed by tree code giving number of expression
102 operands beyond the fixed part of the node structure.
103 Not used for types or decls. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
107 static const int objc_tree_code_length[] = {
109 #include "objc-tree.def"
113 /* Names of tree components.
114 Used for printing out the tree and error messages. */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
117 static const char * const objc_tree_code_name[] = {
119 #include "objc-tree.def"
123 /* Set up for use of obstacks. */
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
130 /* This obstack is used to accumulate the encoding of a data type. */
131 static struct obstack util_obstack;
132 /* This points to the beginning of obstack contents,
133 so we can free the whole contents. */
136 /* for encode_method_def */
139 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
140 #define PROTOCOL_VERSION 2
142 #define OBJC_ENCODE_INLINE_DEFS 0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
145 /*** Private Interface (procedures) ***/
147 /* Used by compile_file. */
149 static void init_objc PARAMS ((void));
150 static void finish_objc PARAMS ((void));
152 /* Code generation. */
154 static void synth_module_prologue PARAMS ((void));
155 static tree build_constructor PARAMS ((tree, tree));
156 static const char *build_module_descriptor PARAMS ((void));
157 static tree init_module_descriptor PARAMS ((tree));
158 static tree build_objc_method_call PARAMS ((int, tree, tree,
160 static void generate_strings PARAMS ((void));
161 static tree get_proto_encoding PARAMS ((tree));
162 static void build_selector_translation_table PARAMS ((void));
163 static tree build_ivar_chain PARAMS ((tree, int));
165 static tree objc_add_static_instance PARAMS ((tree, tree));
167 static tree build_ivar_template PARAMS ((void));
168 static tree build_method_template PARAMS ((void));
169 static tree build_private_template PARAMS ((tree));
170 static void build_class_template PARAMS ((void));
171 static void build_selector_template PARAMS ((void));
172 static void build_category_template PARAMS ((void));
173 static tree build_super_template PARAMS ((void));
174 static tree build_category_initializer PARAMS ((tree, tree, tree,
176 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
179 static void synth_forward_declarations PARAMS ((void));
180 static void generate_ivar_lists PARAMS ((void));
181 static void generate_dispatch_tables PARAMS ((void));
182 static void generate_shared_structures PARAMS ((void));
183 static tree generate_protocol_list PARAMS ((tree));
184 static void generate_forward_declaration_to_string_table PARAMS ((void));
185 static void build_protocol_reference PARAMS ((tree));
188 static tree init_selector PARAMS ((int));
190 static tree build_keyword_selector PARAMS ((tree));
191 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
193 static void generate_static_references PARAMS ((void));
194 static int check_methods_accessible PARAMS ((tree, tree,
196 static void encode_aggregate_within PARAMS ((tree, int, int,
198 static const char *objc_demangle PARAMS ((const char *));
199 static const char *objc_printable_name PARAMS ((tree, int));
200 static void objc_expand_function_end PARAMS ((void));
202 /* Misc. bookkeeping */
204 typedef struct hashed_entry *hash;
205 typedef struct hashed_attribute *attr;
207 struct hashed_attribute
219 static void hash_init PARAMS ((void));
220 static void hash_enter PARAMS ((hash *, tree));
221 static hash hash_lookup PARAMS ((hash *, tree));
222 static void hash_add_attr PARAMS ((hash, tree));
223 static tree lookup_method PARAMS ((tree, tree));
224 static tree lookup_instance_method_static PARAMS ((tree, tree));
225 static tree lookup_class_method_static PARAMS ((tree, tree));
226 static tree add_class PARAMS ((tree));
227 static void add_category PARAMS ((tree, tree));
231 class_names, /* class, category, protocol, module names */
232 meth_var_names, /* method and variable names */
233 meth_var_types /* method and variable type descriptors */
236 static tree add_objc_string PARAMS ((tree,
237 enum string_section));
238 static tree get_objc_string_decl PARAMS ((tree,
239 enum string_section));
240 static tree build_objc_string_decl PARAMS ((enum string_section));
241 static tree build_selector_reference_decl PARAMS ((void));
243 /* Protocol additions. */
245 static tree add_protocol PARAMS ((tree));
246 static tree lookup_protocol PARAMS ((tree));
247 static tree lookup_and_install_protocols PARAMS ((tree));
251 static void encode_type_qualifiers PARAMS ((tree));
252 static void encode_pointer PARAMS ((tree, int, int));
253 static void encode_array PARAMS ((tree, int, int));
254 static void encode_aggregate PARAMS ((tree, int, int));
255 static void encode_bitfield PARAMS ((int));
256 static void encode_type PARAMS ((tree, int, int));
257 static void encode_field_decl PARAMS ((tree, int, int));
259 static void really_start_method PARAMS ((tree, tree));
260 static int comp_method_with_proto PARAMS ((tree, tree));
261 static int comp_proto_with_proto PARAMS ((tree, tree));
262 static tree get_arg_type_list PARAMS ((tree, int, int));
263 static tree expr_last PARAMS ((tree));
265 /* Utilities for debugging and error diagnostics. */
267 static void warn_with_method PARAMS ((const char *, int, tree));
268 static void error_with_ivar PARAMS ((const char *, tree, tree));
269 static char *gen_method_decl PARAMS ((tree, char *));
270 static char *gen_declaration PARAMS ((tree, char *));
271 static char *gen_declarator PARAMS ((tree, char *,
273 static int is_complex_decl PARAMS ((tree));
274 static void adorn_decl PARAMS ((tree, char *));
275 static void dump_interface PARAMS ((FILE *, tree));
277 /* Everything else. */
279 static void objc_fatal PARAMS ((void))
281 static tree define_decl PARAMS ((tree, tree));
282 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
283 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
284 static tree create_builtin_decl PARAMS ((enum tree_code,
285 tree, const char *));
286 static tree my_build_string PARAMS ((int, const char *));
287 static void build_objc_symtab_template PARAMS ((void));
288 static tree init_def_list PARAMS ((tree));
289 static tree init_objc_symtab PARAMS ((tree));
290 static void forward_declare_categories PARAMS ((void));
291 static void generate_objc_symtab_decl PARAMS ((void));
292 static tree build_selector PARAMS ((tree));
294 static tree build_msg_pool_reference PARAMS ((int));
296 static tree build_typed_selector_reference PARAMS ((tree, tree));
297 static tree build_selector_reference PARAMS ((tree));
298 static tree build_class_reference_decl PARAMS ((void));
299 static void add_class_reference PARAMS ((tree));
300 static tree objc_copy_list PARAMS ((tree, tree *));
301 static tree build_protocol_template PARAMS ((void));
302 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
303 static tree build_method_prototype_list_template PARAMS ((tree, int));
304 static tree build_method_prototype_template PARAMS ((void));
305 static int forwarding_offset PARAMS ((tree));
306 static tree encode_method_prototype PARAMS ((tree, tree));
307 static tree generate_descriptor_table PARAMS ((tree, const char *,
309 static void generate_method_descriptors PARAMS ((tree));
310 static tree build_tmp_function_decl PARAMS ((void));
311 static void hack_method_prototype PARAMS ((tree, tree));
312 static void generate_protocol_references PARAMS ((tree));
313 static void generate_protocols PARAMS ((void));
314 static void check_ivars PARAMS ((tree, tree));
315 static tree build_ivar_list_template PARAMS ((tree, int));
316 static tree build_method_list_template PARAMS ((tree, int));
317 static tree build_ivar_list_initializer PARAMS ((tree, tree));
318 static tree generate_ivars_list PARAMS ((tree, const char *,
320 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
321 static tree generate_dispatch_table PARAMS ((tree, const char *,
323 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
324 tree, int, tree, tree,
326 static void generate_category PARAMS ((tree));
327 static int is_objc_type_qualifier PARAMS ((tree));
328 static tree adjust_type_for_id_default PARAMS ((tree));
329 static tree check_duplicates PARAMS ((hash));
330 static tree receiver_is_class_object PARAMS ((tree));
331 static int check_methods PARAMS ((tree, tree, int));
332 static int conforms_to_protocol PARAMS ((tree, tree));
333 static void check_protocols PARAMS ((tree, const char *,
335 static tree encode_method_def PARAMS ((tree));
336 static void gen_declspecs PARAMS ((tree, char *, int));
337 static void generate_classref_translation_entry PARAMS ((tree));
338 static void handle_class_ref PARAMS ((tree));
339 static void generate_struct_by_value_array PARAMS ((void))
341 static void objc_act_parse_init PARAMS ((void));
342 static void ggc_mark_imp_list PARAMS ((void *));
343 static void ggc_mark_hash_table PARAMS ((void *));
345 /*** Private Interface (data) ***/
347 /* Reserved tag definitions. */
350 #define TAG_OBJECT "objc_object"
351 #define TAG_CLASS "objc_class"
352 #define TAG_SUPER "objc_super"
353 #define TAG_SELECTOR "objc_selector"
355 #define UTAG_CLASS "_objc_class"
356 #define UTAG_IVAR "_objc_ivar"
357 #define UTAG_IVAR_LIST "_objc_ivar_list"
358 #define UTAG_METHOD "_objc_method"
359 #define UTAG_METHOD_LIST "_objc_method_list"
360 #define UTAG_CATEGORY "_objc_category"
361 #define UTAG_MODULE "_objc_module"
362 #define UTAG_STATICS "_objc_statics"
363 #define UTAG_SYMTAB "_objc_symtab"
364 #define UTAG_SUPER "_objc_super"
365 #define UTAG_SELECTOR "_objc_selector"
367 #define UTAG_PROTOCOL "_objc_protocol"
368 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
369 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
370 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
372 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
373 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
375 static const char *constant_string_class_name = NULL;
377 static const char *TAG_GETCLASS;
378 static const char *TAG_GETMETACLASS;
379 static const char *TAG_MSGSEND;
380 static const char *TAG_MSGSENDSUPER;
381 static const char *TAG_EXECCLASS;
383 /* Set by `continue_class' and checked by `is_public'. */
385 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
386 #define TYPED_OBJECT(type) \
387 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
389 tree objc_ellipsis_node;
394 OCTI_STATIC_NST_DECL,
400 OCTI_UMSG_SUPER_DECL,
402 OCTI_GET_MCLASS_DECL,
416 OCTI_CLS_NAMES_CHAIN,
417 OCTI_METH_VAR_NAMES_CHAIN,
418 OCTI_METH_VAR_TYPES_CHAIN,
440 OCTI_UUCLS_SUPER_REF,
458 static tree objc_global_trees[OCTI_MAX];
460 /* List of classes with list of their static instances. */
461 #define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
463 /* The declaration of the array administrating the static instances. */
464 #define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
466 /* Some commonly used instances of "identifier_node". */
468 #define self_id objc_global_trees[OCTI_SELF_ID]
469 #define ucmd_id objc_global_trees[OCTI_UCMD_ID]
470 #define unused_list objc_global_trees[OCTI_UNUSED_LIST]
472 #define self_decl objc_global_trees[OCTI_SELF_DECL]
473 #define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
474 #define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
475 #define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
476 #define objc_get_meta_class_decl \
477 objc_global_trees[OCTI_GET_MCLASS_DECL]
479 #define super_type objc_global_trees[OCTI_SUPER_TYPE]
480 #define selector_type objc_global_trees[OCTI_SEL_TYPE]
481 #define id_type objc_global_trees[OCTI_ID_TYPE]
482 #define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
483 #define instance_type objc_global_trees[OCTI_NST_TYPE]
484 #define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
486 /* Type checking macros. */
488 #define IS_ID(TYPE) \
489 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
490 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
491 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
492 #define IS_SUPER(TYPE) \
493 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
495 #define class_chain objc_global_trees[OCTI_CLS_CHAIN]
496 #define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
497 #define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
498 #define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
500 /* Chains to manage selectors that are referenced and defined in the
503 #define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
504 #define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
506 /* Chains to manage uniquing of strings. */
508 #define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
509 #define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
510 #define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
512 /* Hash tables to manage the global pool of method prototypes. */
514 static hash *nst_method_hash_list = 0;
515 static hash *cls_method_hash_list = 0;
517 /* Backend data declarations. */
519 #define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
520 #define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
521 #define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
522 #define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
523 #define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
524 #define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
525 #define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
526 #define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
527 #define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
528 #define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
530 /* The following are used when compiling a class implementation.
531 implementation_template will normally be an interface, however if
532 none exists this will be equal to implementation_context...it is
533 set in start_class. */
535 #define implementation_context objc_global_trees[OCTI_IMPL_CTX]
536 #define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
540 struct imp_entry *next;
543 tree class_decl; /* _OBJC_CLASS_<my_name>; */
544 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
547 static void handle_impent PARAMS ((struct imp_entry *));
549 static struct imp_entry *imp_list = 0;
550 static int imp_count = 0; /* `@implementation' */
551 static int cat_count = 0; /* `@category' */
553 #define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
554 #define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
555 #define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
556 #define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
557 #define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
558 #define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
559 #define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
561 #define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
562 #define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
563 #define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
564 #define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
565 #define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
566 #define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
568 #define objc_object_id objc_global_trees[OCTI_OBJ_ID]
569 #define objc_class_id objc_global_trees[OCTI_CLS_ID]
570 #define objc_id_id objc_global_trees[OCTI_ID_ID]
571 #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
572 #define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
573 #define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
575 #define method_context objc_global_trees[OCTI_METH_CTX]
576 static int method_slot = 0; /* Used by start_method_def, */
580 static char *errbuf; /* Buffer for error diagnostics */
582 /* Data imported from tree.c. */
584 extern enum debug_info_type write_symbols;
586 /* Data imported from toplev.c. */
588 extern const char *dump_base_name;
590 /* Generate code for GNU or NeXT runtime environment. */
592 #ifdef NEXT_OBJC_RUNTIME
593 int flag_next_runtime = 1;
595 int flag_next_runtime = 0;
598 int flag_typed_selectors;
600 /* Open and close the file for outputting class declarations, if requested. */
602 int flag_gen_declaration = 0;
604 FILE *gen_declaration_file;
606 /* Warn if multiple methods are seen for the same selector, but with
607 different argument types. */
609 int warn_selector = 0;
611 /* Warn if methods required by a protocol are not implemented in the
612 class adopting it. When turned off, methods inherited to that
613 class are also considered implemented */
615 int flag_warn_protocol = 1;
617 /* Tells "encode_pointer/encode_aggregate" whether we are generating
618 type descriptors for instance variables (as opposed to methods).
619 Type descriptors for instance variables contain more information
620 than methods (for static typing and embedded structures). This
621 was added to support features being planned for dbkit2. */
623 static int generating_instance_variables = 0;
625 /* Tells the compiler that this is a special run. Do not perform
626 any compiling, instead we are to test some platform dependent
627 features and output a C header file with appropriate definitions. */
629 static int print_struct_values = 0;
631 /* Some platforms pass small structures through registers versus through
632 an invisible pointer. Determine at what size structure is the
633 transition point between the two possibilities. */
636 generate_struct_by_value_array ()
639 tree field_decl, field_decl_chain;
641 int aggregate_in_mem[32];
644 /* Presumbaly no platform passes 32 byte structures in a register. */
645 for (i = 1; i < 32; i++)
649 /* Create an unnamed struct that has `i' character components */
650 type = start_struct (RECORD_TYPE, NULL_TREE);
652 strcpy (buffer, "c1");
653 field_decl = create_builtin_decl (FIELD_DECL,
656 field_decl_chain = field_decl;
658 for (j = 1; j < i; j++)
660 sprintf (buffer, "c%d", j + 1);
661 field_decl = create_builtin_decl (FIELD_DECL,
664 chainon (field_decl_chain, field_decl);
666 finish_struct (type, field_decl_chain, NULL_TREE);
668 aggregate_in_mem[i] = aggregate_value_p (type);
669 if (!aggregate_in_mem[i])
673 /* We found some structures that are returned in registers instead of memory
674 so output the necessary data. */
677 for (i = 31; i >= 0; i--)
678 if (!aggregate_in_mem[i])
680 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
682 /* The first member of the structure is always 0 because we don't handle
683 structures with 0 members */
684 printf ("static int struct_forward_array[] = {\n 0");
686 for (j = 1; j <= i; j++)
687 printf (", %d", aggregate_in_mem[j]);
697 parse_in = cpp_create_reader (CLK_OBJC);
698 c_language = clk_objective_c;
704 /* Force the line number back to 0; check_newline will have
705 raised it to 1, which will make the builtin functions appear
706 not to be built in. */
709 /* If gen_declaration desired, open the output file. */
710 if (flag_gen_declaration)
712 register char * const dumpname = concat (dumpname, ".decl", NULL);
713 gen_declaration_file = fopen (dumpname, "w");
714 if (gen_declaration_file == 0)
715 pfatal_with_name (dumpname);
719 if (flag_next_runtime)
721 TAG_GETCLASS = "objc_getClass";
722 TAG_GETMETACLASS = "objc_getMetaClass";
723 TAG_MSGSEND = "objc_msgSend";
724 TAG_MSGSENDSUPER = "objc_msgSendSuper";
725 TAG_EXECCLASS = "__objc_execClass";
729 TAG_GETCLASS = "objc_get_class";
730 TAG_GETMETACLASS = "objc_get_meta_class";
731 TAG_MSGSEND = "objc_msg_lookup";
732 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
733 TAG_EXECCLASS = "__objc_exec_class";
734 flag_typed_selectors = 1;
737 objc_ellipsis_node = make_node (ERROR_MARK);
739 if (doing_objc_thang)
742 if (print_struct_values)
743 generate_struct_by_value_array ();
745 objc_act_parse_init ();
752 fatal ("Objective-C text in C source file");
758 if (doing_objc_thang)
759 finish_objc (); /* Objective-C finalization */
761 if (gen_declaration_file)
762 fclose (gen_declaration_file);
777 lang_decode_option (argc, argv)
781 const char *p = argv[0];
783 if (!strcmp (p, "-gen-decls"))
784 flag_gen_declaration = 1;
785 else if (!strcmp (p, "-Wselector"))
787 else if (!strcmp (p, "-Wno-selector"))
789 else if (!strcmp (p, "-Wprotocol"))
790 flag_warn_protocol = 1;
791 else if (!strcmp (p, "-Wno-protocol"))
792 flag_warn_protocol = 0;
793 else if (!strcmp (p, "-fgnu-runtime"))
794 flag_next_runtime = 0;
795 else if (!strcmp (p, "-fno-next-runtime"))
796 flag_next_runtime = 0;
797 else if (!strcmp (p, "-fno-gnu-runtime"))
798 flag_next_runtime = 1;
799 else if (!strcmp (p, "-fnext-runtime"))
800 flag_next_runtime = 1;
801 else if (!strcmp (p, "-print-objc-runtime-info"))
802 print_struct_values = 1;
803 #define CSTSTRCLASS "-fconstant-string-class="
804 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
805 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
806 error ("no class name specified as argument to -fconstant-string-class");
807 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
811 return c_decode_option (argc, argv);
816 /* used by print-tree.c */
819 lang_print_xnode (file, node, indent)
820 FILE *file ATTRIBUTE_UNUSED;
821 tree node ATTRIBUTE_UNUSED;
822 int indent ATTRIBUTE_UNUSED;
828 define_decl (declarator, declspecs)
832 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
833 finish_decl (decl, NULL_TREE, NULL_TREE);
837 /* Return 1 if LHS and RHS are compatible types for assignment or
838 various other operations. Return 0 if they are incompatible, and
839 return -1 if we choose to not decide. When the operation is
840 REFLEXIVE, check for compatibility in either direction.
842 For statically typed objects, an assignment of the form `a' = `b'
846 `a' and `b' are the same class type, or
847 `a' and `b' are of class types A and B such that B is a descendant of A. */
850 maybe_objc_comptypes (lhs, rhs, reflexive)
854 if (doing_objc_thang)
855 return objc_comptypes (lhs, rhs, reflexive);
860 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
868 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
870 p = TREE_VALUE (rproto);
872 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
874 if ((fnd = lookup_method (class_meth
875 ? PROTOCOL_CLS_METHODS (p)
876 : PROTOCOL_NST_METHODS (p), sel_name)))
878 else if (PROTOCOL_LIST (p))
879 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
880 sel_name, class_meth);
884 ; /* An identifier...if we could not find a protocol. */
895 lookup_protocol_in_reflist (rproto_list, lproto)
901 /* Make sure the protocol is support by the object on the rhs. */
902 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
905 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
907 p = TREE_VALUE (rproto);
909 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
914 else if (PROTOCOL_LIST (p))
915 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
924 ; /* An identifier...if we could not find a protocol. */
930 /* Return 1 if LHS and RHS are compatible types for assignment
931 or various other operations. Return 0 if they are incompatible,
932 and return -1 if we choose to not decide. When the operation
933 is REFLEXIVE, check for compatibility in either direction. */
936 objc_comptypes (lhs, rhs, reflexive)
941 /* New clause for protocols. */
943 if (TREE_CODE (lhs) == POINTER_TYPE
944 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
945 && TREE_CODE (rhs) == POINTER_TYPE
946 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
948 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
949 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
953 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
954 tree rproto, rproto_list;
959 rproto_list = TYPE_PROTOCOL_LIST (rhs);
961 /* Make sure the protocol is supported by the object
963 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
965 p = TREE_VALUE (lproto);
966 rproto = lookup_protocol_in_reflist (rproto_list, p);
969 warning ("object does not conform to the `%s' protocol",
970 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
973 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
975 tree rname = TYPE_NAME (TREE_TYPE (rhs));
978 /* Make sure the protocol is supported by the object
980 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
982 p = TREE_VALUE (lproto);
984 rinter = lookup_interface (rname);
986 while (rinter && !rproto)
990 rproto_list = CLASS_PROTOCOL_LIST (rinter);
991 rproto = lookup_protocol_in_reflist (rproto_list, p);
993 /* Check for protocols adopted by categories. */
994 cat = CLASS_CATEGORY_LIST (rinter);
995 while (cat && !rproto)
997 rproto_list = CLASS_PROTOCOL_LIST (cat);
998 rproto = lookup_protocol_in_reflist (rproto_list, p);
1000 cat = CLASS_CATEGORY_LIST (cat);
1003 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
1007 warning ("class `%s' does not implement the `%s' protocol",
1008 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
1009 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1013 /* May change...based on whether there was any mismatch */
1016 else if (rhs_is_proto)
1017 /* Lhs is not a protocol...warn if it is statically typed */
1018 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
1021 /* Defer to comptypes .*/
1025 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
1026 ; /* Fall thru. This is the case we have been handling all along */
1028 /* Defer to comptypes. */
1031 /* `id' = `<class> *', `<class> *' = `id' */
1033 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
1034 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
1037 /* `id' = `Class', `Class' = `id' */
1039 else if ((TYPE_NAME (lhs) == objc_object_id
1040 && TYPE_NAME (rhs) == objc_class_id)
1041 || (TYPE_NAME (lhs) == objc_class_id
1042 && TYPE_NAME (rhs) == objc_object_id))
1045 /* `<class> *' = `<class> *' */
1047 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1049 tree lname = TYPE_NAME (lhs);
1050 tree rname = TYPE_NAME (rhs);
1056 /* If the left hand side is a super class of the right hand side,
1058 for (inter = lookup_interface (rname); inter;
1059 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1060 if (lname == CLASS_SUPER_NAME (inter))
1063 /* Allow the reverse when reflexive. */
1065 for (inter = lookup_interface (lname); inter;
1066 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1067 if (rname == CLASS_SUPER_NAME (inter))
1073 /* Defer to comptypes. */
1077 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1080 objc_check_decl (decl)
1083 tree type = TREE_TYPE (decl);
1085 if (TREE_CODE (type) == RECORD_TYPE
1086 && TREE_STATIC_TEMPLATE (type)
1087 && type != constant_string_type)
1089 error_with_decl (decl, "`%s' cannot be statically allocated");
1090 fatal ("statically allocated objects not supported");
1095 maybe_objc_check_decl (decl)
1098 if (doing_objc_thang)
1099 objc_check_decl (decl);
1102 /* Implement static typing. At this point, we know we have an interface. */
1105 get_static_reference (interface, protocols)
1109 tree type = xref_tag (RECORD_TYPE, interface);
1113 tree t, m = TYPE_MAIN_VARIANT (type);
1115 t = copy_node (type);
1116 TYPE_BINFO (t) = make_tree_vec (2);
1118 /* Add this type to the chain of variants of TYPE. */
1119 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1120 TYPE_NEXT_VARIANT (m) = t;
1122 /* Look up protocols and install in lang specific list. */
1123 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1125 /* This forces a new pointer type to be created later
1126 (in build_pointer_type)...so that the new template
1127 we just created will actually be used...what a hack! */
1128 if (TYPE_POINTER_TO (t))
1129 TYPE_POINTER_TO (t) = 0;
1138 get_object_reference (protocols)
1141 tree type_decl = lookup_name (objc_id_id);
1144 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
1146 type = TREE_TYPE (type_decl);
1147 if (TYPE_MAIN_VARIANT (type) != id_type)
1148 warning ("Unexpected type for `id' (%s)",
1149 gen_declaration (type, errbuf));
1152 fatal ("Undefined type `id', please import <objc/objc.h>");
1154 /* This clause creates a new pointer type that is qualified with
1155 the protocol specification...this info is used later to do more
1156 elaborate type checking. */
1160 tree t, m = TYPE_MAIN_VARIANT (type);
1162 t = copy_node (type);
1163 TYPE_BINFO (t) = make_tree_vec (2);
1165 /* Add this type to the chain of variants of TYPE. */
1166 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1167 TYPE_NEXT_VARIANT (m) = t;
1169 /* Look up protocols...and install in lang specific list */
1170 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1172 /* This forces a new pointer type to be created later
1173 (in build_pointer_type)...so that the new template
1174 we just created will actually be used...what a hack! */
1175 if (TYPE_POINTER_TO (t))
1176 TYPE_POINTER_TO (t) = NULL;
1184 lookup_and_install_protocols (protocols)
1189 tree return_value = protocols;
1191 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1193 tree ident = TREE_VALUE (proto);
1194 tree p = lookup_protocol (ident);
1198 error ("Cannot find protocol declaration for `%s'",
1199 IDENTIFIER_POINTER (ident));
1201 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1203 return_value = TREE_CHAIN (proto);
1207 /* Replace identifier with actual protocol node. */
1208 TREE_VALUE (proto) = p;
1213 return return_value;
1216 /* Create and push a decl for a built-in external variable or field NAME.
1218 TYPE is its data type. */
1221 create_builtin_decl (code, type, name)
1222 enum tree_code code;
1226 tree decl = build_decl (code, get_identifier (name), type);
1228 if (code == VAR_DECL)
1230 TREE_STATIC (decl) = 1;
1231 make_decl_rtl (decl, 0, 1);
1235 DECL_ARTIFICIAL (decl) = 1;
1239 /* Purpose: "play" parser, creating/installing representations
1240 of the declarations that are required by Objective-C.
1244 type_spec--------->sc_spec
1245 (tree_list) (tree_list)
1248 identifier_node identifier_node */
1251 synth_module_prologue ()
1256 /* Defined in `objc.h' */
1257 objc_object_id = get_identifier (TAG_OBJECT);
1259 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1261 id_type = build_pointer_type (objc_object_reference);
1263 objc_id_id = get_identifier (TYPE_ID);
1264 objc_class_id = get_identifier (TAG_CLASS);
1266 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1267 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1268 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1270 /* Declare type of selector-objects that represent an operation name. */
1272 #ifdef OBJC_INT_SELECTORS
1273 /* `unsigned int' */
1274 selector_type = unsigned_type_node;
1276 /* `struct objc_selector *' */
1278 = build_pointer_type (xref_tag (RECORD_TYPE,
1279 get_identifier (TAG_SELECTOR)));
1280 #endif /* not OBJC_INT_SELECTORS */
1282 /* Forward declare type, or else the prototype for msgSendSuper will
1285 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1286 get_identifier (TAG_SUPER)));
1289 /* id objc_msgSend (id, SEL, ...); */
1292 = build_function_type (id_type,
1293 tree_cons (NULL_TREE, id_type,
1294 tree_cons (NULL_TREE, selector_type,
1297 if (! flag_next_runtime)
1299 umsg_decl = build_decl (FUNCTION_DECL,
1300 get_identifier (TAG_MSGSEND), temp_type);
1301 DECL_EXTERNAL (umsg_decl) = 1;
1302 TREE_PUBLIC (umsg_decl) = 1;
1303 DECL_INLINE (umsg_decl) = 1;
1304 DECL_ARTIFICIAL (umsg_decl) = 1;
1306 if (flag_traditional && TAG_MSGSEND[0] != '_')
1307 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1309 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1310 pushdecl (umsg_decl);
1313 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1315 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1318 = build_function_type (id_type,
1319 tree_cons (NULL_TREE, super_p,
1320 tree_cons (NULL_TREE, selector_type,
1323 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1324 temp_type, 0, NOT_BUILT_IN, 0);
1326 /* id objc_getClass (const char *); */
1328 temp_type = build_function_type (id_type,
1329 tree_cons (NULL_TREE,
1330 const_string_type_node,
1331 tree_cons (NULL_TREE, void_type_node,
1335 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1337 /* id objc_getMetaClass (const char *); */
1339 objc_get_meta_class_decl
1340 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1342 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1344 if (! flag_next_runtime)
1346 if (flag_typed_selectors)
1348 /* Suppress outputting debug symbols, because
1349 dbxout_init hasn'r been called yet. */
1350 enum debug_info_type save_write_symbols = write_symbols;
1351 write_symbols = NO_DEBUG;
1353 build_selector_template ();
1354 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1356 write_symbols = save_write_symbols;
1359 temp_type = build_array_type (selector_type, NULL_TREE);
1361 layout_type (temp_type);
1362 UOBJC_SELECTOR_TABLE_decl
1363 = create_builtin_decl (VAR_DECL, temp_type,
1364 "_OBJC_SELECTOR_TABLE");
1366 /* Avoid warning when not sending messages. */
1367 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1370 generate_forward_declaration_to_string_table ();
1372 /* Forward declare constant_string_id and constant_string_type. */
1373 if (!constant_string_class_name)
1374 constant_string_class_name = STRING_OBJECT_CLASS_NAME;
1376 constant_string_id = get_identifier (constant_string_class_name);
1377 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1380 /* Custom build_string which sets TREE_TYPE! */
1383 my_build_string (len, str)
1388 tree a_string = build_string (len, str);
1390 /* Some code from combine_strings, which is local to c-parse.y. */
1391 if (TREE_TYPE (a_string) == int_array_type_node)
1394 TREE_TYPE (a_string)
1395 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1396 build_index_type (build_int_2 (len - 1, 0)));
1398 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1399 TREE_STATIC (a_string) = 1;
1404 /* Given a chain of STRING_CST's, build a static instance of
1405 NXConstanString which points at the concatenation of those strings.
1406 We place the string object in the __string_objects section of the
1407 __OBJC segment. The Objective-C runtime will initialize the isa
1408 pointers of the string objects to point at the NXConstandString class
1412 build_objc_string_object (strings)
1415 tree string, initlist, constructor;
1418 if (!doing_objc_thang)
1421 if (lookup_interface (constant_string_id) == NULL_TREE)
1423 error ("Cannot find interface declaration for `%s'",
1424 IDENTIFIER_POINTER (constant_string_id));
1425 return error_mark_node;
1428 add_class_reference (constant_string_id);
1430 string = combine_strings (strings);
1431 TREE_SET_CODE (string, STRING_CST);
1432 length = TREE_STRING_LENGTH (string) - 1;
1434 /* & ((NXConstantString) {0, string, length}) */
1436 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1438 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1440 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1441 constructor = build_constructor (constant_string_type, nreverse (initlist));
1443 if (!flag_next_runtime)
1446 = objc_add_static_instance (constructor, constant_string_type);
1449 return (build_unary_op (ADDR_EXPR, constructor, 1));
1452 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1455 objc_add_static_instance (constructor, class_decl)
1456 tree constructor, class_decl;
1458 static int num_static_inst;
1462 /* Find the list of static instances for the CLASS_DECL. Create one if
1464 for (chain = &objc_static_instances;
1465 *chain && TREE_VALUE (*chain) != class_decl;
1466 chain = &TREE_CHAIN (*chain));
1469 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1470 add_objc_string (TYPE_NAME (class_decl), class_names);
1473 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1474 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1475 DECL_COMMON (decl) = 1;
1476 TREE_STATIC (decl) = 1;
1477 DECL_ARTIFICIAL (decl) = 1;
1478 pushdecl_top_level (decl);
1479 rest_of_decl_compilation (decl, 0, 1, 0);
1481 /* Do this here so it gets output later instead of possibly
1482 inside something else we are writing. */
1483 DECL_INITIAL (decl) = constructor;
1485 /* Add the DECL to the head of this CLASS' list. */
1486 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1491 /* Build a static constant CONSTRUCTOR
1492 with type TYPE and elements ELTS. */
1495 build_constructor (type, elts)
1498 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1500 TREE_CONSTANT (constructor) = 1;
1501 TREE_STATIC (constructor) = 1;
1502 TREE_READONLY (constructor) = 1;
1507 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1509 /* Predefine the following data type:
1517 void *defs[cls_def_cnt + cat_def_cnt];
1521 build_objc_symtab_template ()
1523 tree field_decl, field_decl_chain, index;
1525 objc_symtab_template
1526 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1528 /* long sel_ref_cnt; */
1530 field_decl = create_builtin_decl (FIELD_DECL,
1531 long_integer_type_node,
1533 field_decl_chain = field_decl;
1537 field_decl = create_builtin_decl (FIELD_DECL,
1538 build_pointer_type (selector_type),
1540 chainon (field_decl_chain, field_decl);
1542 /* short cls_def_cnt; */
1544 field_decl = create_builtin_decl (FIELD_DECL,
1545 short_integer_type_node,
1547 chainon (field_decl_chain, field_decl);
1549 /* short cat_def_cnt; */
1551 field_decl = create_builtin_decl (FIELD_DECL,
1552 short_integer_type_node,
1554 chainon (field_decl_chain, field_decl);
1556 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1558 if (!flag_next_runtime)
1559 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1561 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1562 imp_count == 0 && cat_count == 0
1564 field_decl = create_builtin_decl (FIELD_DECL,
1565 build_array_type (ptr_type_node, index),
1567 chainon (field_decl_chain, field_decl);
1569 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1572 /* Create the initial value for the `defs' field of _objc_symtab.
1573 This is a CONSTRUCTOR. */
1576 init_def_list (type)
1579 tree expr, initlist = NULL_TREE;
1580 struct imp_entry *impent;
1583 for (impent = imp_list; impent; impent = impent->next)
1585 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1587 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1588 initlist = tree_cons (NULL_TREE, expr, initlist);
1593 for (impent = imp_list; impent; impent = impent->next)
1595 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1597 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1598 initlist = tree_cons (NULL_TREE, expr, initlist);
1602 if (!flag_next_runtime)
1604 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1607 if (static_instances_decl)
1608 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1610 expr = build_int_2 (0, 0);
1612 initlist = tree_cons (NULL_TREE, expr, initlist);
1615 return build_constructor (type, nreverse (initlist));
1618 /* Construct the initial value for all of _objc_symtab. */
1621 init_objc_symtab (type)
1626 /* sel_ref_cnt = { ..., 5, ... } */
1628 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1630 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1632 if (flag_next_runtime || ! sel_ref_chain)
1633 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1635 initlist = tree_cons (NULL_TREE,
1636 build_unary_op (ADDR_EXPR,
1637 UOBJC_SELECTOR_TABLE_decl, 1),
1640 /* cls_def_cnt = { ..., 5, ... } */
1642 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1644 /* cat_def_cnt = { ..., 5, ... } */
1646 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1648 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1650 if (imp_count || cat_count || static_instances_decl)
1653 tree field = TYPE_FIELDS (type);
1654 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1656 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1660 return build_constructor (type, nreverse (initlist));
1663 /* Push forward-declarations of all the categories
1664 so that init_def_list can use them in a CONSTRUCTOR. */
1667 forward_declare_categories ()
1669 struct imp_entry *impent;
1670 tree sav = implementation_context;
1672 for (impent = imp_list; impent; impent = impent->next)
1674 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1676 /* Set an invisible arg to synth_id_with_class_suffix. */
1677 implementation_context = impent->imp_context;
1679 = create_builtin_decl (VAR_DECL, objc_category_template,
1680 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1683 implementation_context = sav;
1686 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1687 and initialized appropriately. */
1690 generate_objc_symtab_decl ()
1694 if (!objc_category_template)
1695 build_category_template ();
1697 /* forward declare categories */
1699 forward_declare_categories ();
1701 if (!objc_symtab_template)
1702 build_objc_symtab_template ();
1704 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1706 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1707 tree_cons (NULL_TREE,
1708 objc_symtab_template, sc_spec),
1710 NULL_TREE, NULL_TREE);
1712 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1713 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1714 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1715 finish_decl (UOBJC_SYMBOLS_decl,
1716 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1721 init_module_descriptor (type)
1724 tree initlist, expr;
1726 /* version = { 1, ... } */
1728 expr = build_int_2 (OBJC_VERSION, 0);
1729 initlist = build_tree_list (NULL_TREE, expr);
1731 /* size = { ..., sizeof (struct objc_module), ... } */
1733 expr = size_in_bytes (objc_module_template);
1734 initlist = tree_cons (NULL_TREE, expr, initlist);
1736 /* name = { ..., "foo.m", ... } */
1738 expr = add_objc_string (get_identifier (input_filename), class_names);
1739 initlist = tree_cons (NULL_TREE, expr, initlist);
1741 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1743 if (UOBJC_SYMBOLS_decl)
1744 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1746 expr = build_int_2 (0, 0);
1747 initlist = tree_cons (NULL_TREE, expr, initlist);
1749 return build_constructor (type, nreverse (initlist));
1752 /* Write out the data structures to describe Objective C classes defined.
1753 If appropriate, compile and output a setup function to initialize them.
1754 Return a string which is the name of a function to call to initialize
1755 the Objective C data structures for this file (and perhaps for other files
1758 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1761 build_module_descriptor ()
1763 tree decl_specs, field_decl, field_decl_chain;
1765 objc_module_template
1766 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1770 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1771 field_decl = get_identifier ("version");
1773 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1774 field_decl_chain = field_decl;
1778 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1779 field_decl = get_identifier ("size");
1781 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1782 chainon (field_decl_chain, field_decl);
1786 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1787 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1789 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1790 chainon (field_decl_chain, field_decl);
1792 /* struct objc_symtab *symtab; */
1794 decl_specs = get_identifier (UTAG_SYMTAB);
1795 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1796 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1798 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1799 chainon (field_decl_chain, field_decl);
1801 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1803 /* Create an instance of "objc_module". */
1805 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1806 build_tree_list (NULL_TREE,
1807 ridpointers[(int) RID_STATIC]));
1809 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1810 decl_specs, 1, NULL_TREE, NULL_TREE);
1812 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1813 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1814 finish_decl (UOBJC_MODULES_decl,
1815 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1818 /* Mark the decl to avoid "defined but not used" warning. */
1819 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1821 /* Generate a constructor call for the module descriptor.
1822 This code was generated by reading the grammar rules
1823 of c-parse.in; Therefore, it may not be the most efficient
1824 way of generating the requisite code. */
1826 if (flag_next_runtime)
1830 tree parms, function_decl, decelerator, void_list_node_1;
1832 tree init_function_name = get_file_function_name ('I');
1834 /* Declare void __objc_execClass (void *); */
1836 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1838 = build_function_type (void_type_node,
1839 tree_cons (NULL_TREE, ptr_type_node,
1841 function_decl = build_decl (FUNCTION_DECL,
1842 get_identifier (TAG_EXECCLASS),
1844 DECL_EXTERNAL (function_decl) = 1;
1845 DECL_ARTIFICIAL (function_decl) = 1;
1846 TREE_PUBLIC (function_decl) = 1;
1848 pushdecl (function_decl);
1849 rest_of_decl_compilation (function_decl, 0, 0, 0);
1852 = build_tree_list (NULL_TREE,
1853 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1854 decelerator = build_function_call (function_decl, parms);
1856 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1858 start_function (void_list_node_1,
1859 build_parse_node (CALL_EXPR, init_function_name,
1860 /* This has the format of the output
1861 of get_parm_info. */
1862 tree_cons (NULL_TREE, NULL_TREE,
1865 NULL_TREE, NULL_TREE);
1866 #if 0 /* This should be turned back on later
1867 for the systems where collect is not needed. */
1868 /* Make these functions nonglobal
1869 so each file can use the same name. */
1870 TREE_PUBLIC (current_function_decl) = 0;
1872 TREE_USED (current_function_decl) = 1;
1873 store_parm_decls ();
1875 assemble_external (function_decl);
1876 c_expand_expr_stmt (decelerator);
1878 TREE_PUBLIC (current_function_decl) = 1;
1880 function_decl = current_function_decl;
1881 finish_function (0);
1883 /* Return the name of the constructor function. */
1884 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1888 /* extern const char _OBJC_STRINGS[]; */
1891 generate_forward_declaration_to_string_table ()
1893 tree sc_spec, decl_specs, expr_decl;
1895 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1896 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1899 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1901 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1904 /* Return the DECL of the string IDENT in the SECTION. */
1907 get_objc_string_decl (ident, section)
1909 enum string_section section;
1913 if (section == class_names)
1914 chain = class_names_chain;
1915 else if (section == meth_var_names)
1916 chain = meth_var_names_chain;
1917 else if (section == meth_var_types)
1918 chain = meth_var_types_chain;
1922 for (; chain != 0; chain = TREE_VALUE (chain))
1923 if (TREE_VALUE (chain) == ident)
1924 return (TREE_PURPOSE (chain));
1930 /* Output references to all statically allocated objects. Return the DECL
1931 for the array built. */
1934 generate_static_references ()
1936 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1937 tree class_name, class, decl, initlist;
1938 tree cl_chain, in_chain, type;
1939 int num_inst, num_class;
1942 if (flag_next_runtime)
1945 for (cl_chain = objc_static_instances, num_class = 0;
1946 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1948 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1949 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1951 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1952 ident = get_identifier (buf);
1954 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1955 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1956 build_tree_list (NULL_TREE,
1957 ridpointers[(int) RID_STATIC]));
1958 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1959 DECL_CONTEXT (decl) = 0;
1960 DECL_ARTIFICIAL (decl) = 1;
1962 /* Output {class_name, ...}. */
1963 class = TREE_VALUE (cl_chain);
1964 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1965 initlist = build_tree_list (NULL_TREE,
1966 build_unary_op (ADDR_EXPR, class_name, 1));
1968 /* Output {..., instance, ...}. */
1969 for (in_chain = TREE_PURPOSE (cl_chain);
1970 in_chain; in_chain = TREE_CHAIN (in_chain))
1972 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1973 initlist = tree_cons (NULL_TREE, expr, initlist);
1976 /* Output {..., NULL}. */
1977 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1979 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1980 finish_decl (decl, expr, NULL_TREE);
1981 TREE_USED (decl) = 1;
1983 type = build_array_type (build_pointer_type (void_type_node), 0);
1984 decl = build_decl (VAR_DECL, ident, type);
1985 make_decl_rtl (decl, 0, 1);
1986 TREE_USED (decl) = 1;
1988 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1991 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1992 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1993 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1994 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1995 build_tree_list (NULL_TREE,
1996 ridpointers[(int) RID_STATIC]));
1997 static_instances_decl
1998 = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1999 TREE_USED (static_instances_decl) = 1;
2000 DECL_CONTEXT (static_instances_decl) = 0;
2001 DECL_ARTIFICIAL (static_instances_decl) = 1;
2002 expr = build_constructor (TREE_TYPE (static_instances_decl),
2004 finish_decl (static_instances_decl, expr, NULL_TREE);
2007 /* Output all strings. */
2012 tree sc_spec, decl_specs, expr_decl;
2013 tree chain, string_expr;
2016 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2018 string = TREE_VALUE (chain);
2019 decl = TREE_PURPOSE (chain);
2021 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2022 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2023 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2024 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2025 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2026 IDENTIFIER_POINTER (string));
2027 finish_decl (decl, string_expr, NULL_TREE);
2030 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2032 string = TREE_VALUE (chain);
2033 decl = TREE_PURPOSE (chain);
2035 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2036 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2037 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2038 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2039 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2040 IDENTIFIER_POINTER (string));
2041 finish_decl (decl, string_expr, NULL_TREE);
2044 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2046 string = TREE_VALUE (chain);
2047 decl = TREE_PURPOSE (chain);
2049 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2050 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2051 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2052 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2053 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2054 IDENTIFIER_POINTER (string));
2055 finish_decl (decl, string_expr, NULL_TREE);
2060 build_selector_reference_decl ()
2066 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
2068 ident = get_identifier (buf);
2070 decl = build_decl (VAR_DECL, ident, selector_type);
2071 DECL_EXTERNAL (decl) = 1;
2072 TREE_PUBLIC (decl) = 1;
2073 TREE_USED (decl) = 1;
2074 TREE_READONLY (decl) = 1;
2075 DECL_ARTIFICIAL (decl) = 1;
2076 DECL_CONTEXT (decl) = 0;
2078 make_decl_rtl (decl, 0, 1);
2079 pushdecl_top_level (decl);
2084 /* Just a handy wrapper for add_objc_string. */
2087 build_selector (ident)
2090 tree expr = add_objc_string (ident, meth_var_names);
2091 if (flag_typed_selectors)
2094 return build_c_cast (selector_type, expr); /* cast! */
2097 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2098 The cast stops the compiler from issuing the following message:
2099 grok.m: warning: initialization of non-const * pointer from const *
2100 grok.m: warning: initialization between incompatible pointer types. */
2104 build_msg_pool_reference (offset)
2107 tree expr = build_int_2 (offset, 0);
2110 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
2111 expr = build_unary_op (ADDR_EXPR, expr, 0);
2113 cast = build_tree_list (build_tree_list (NULL_TREE,
2114 ridpointers[(int) RID_CHAR]),
2115 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
2116 TREE_TYPE (expr) = groktypename (cast);
2121 init_selector (offset)
2124 tree expr = build_msg_pool_reference (offset);
2125 TREE_TYPE (expr) = selector_type;
2131 build_selector_translation_table ()
2133 tree sc_spec, decl_specs;
2134 tree chain, initlist = NULL_TREE;
2136 tree decl = NULL_TREE, var_decl, name;
2138 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2142 expr = build_selector (TREE_VALUE (chain));
2144 if (flag_next_runtime)
2146 name = DECL_NAME (TREE_PURPOSE (chain));
2148 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2150 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2151 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2155 /* The `decl' that is returned from start_decl is the one that we
2156 forward declared in `build_selector_reference' */
2157 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2160 /* add one for the '\0' character */
2161 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2163 if (flag_next_runtime)
2164 finish_decl (decl, expr, NULL_TREE);
2167 if (flag_typed_selectors)
2169 tree eltlist = NULL_TREE;
2170 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2171 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2172 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2173 expr = build_constructor (objc_selector_template,
2174 nreverse (eltlist));
2176 initlist = tree_cons (NULL_TREE, expr, initlist);
2181 if (! flag_next_runtime)
2183 /* Cause the variable and its initial value to be actually output. */
2184 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2185 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2186 /* NULL terminate the list and fix the decl for output. */
2187 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2188 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2189 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2190 nreverse (initlist));
2191 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2192 current_function_decl = NULL_TREE;
2197 get_proto_encoding (proto)
2205 if (! METHOD_ENCODING (proto))
2207 tmp_decl = build_tmp_function_decl ();
2208 hack_method_prototype (proto, tmp_decl);
2209 encoding = encode_method_prototype (proto, tmp_decl);
2210 METHOD_ENCODING (proto) = encoding;
2213 encoding = METHOD_ENCODING (proto);
2215 return add_objc_string (encoding, meth_var_types);
2218 return build_int_2 (0, 0);
2221 /* sel_ref_chain is a list whose "value" fields will be instances of
2222 identifier_node that represent the selector. */
2225 build_typed_selector_reference (ident, proto)
2228 tree *chain = &sel_ref_chain;
2234 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2235 goto return_at_index;
2238 chain = &TREE_CHAIN (*chain);
2241 *chain = tree_cons (proto, ident, NULL_TREE);
2244 expr = build_unary_op (ADDR_EXPR,
2245 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2246 build_int_2 (index, 0)),
2248 return build_c_cast (selector_type, expr);
2252 build_selector_reference (ident)
2255 tree *chain = &sel_ref_chain;
2261 if (TREE_VALUE (*chain) == ident)
2262 return (flag_next_runtime
2263 ? TREE_PURPOSE (*chain)
2264 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2265 build_int_2 (index, 0)));
2268 chain = &TREE_CHAIN (*chain);
2271 expr = build_selector_reference_decl ();
2273 *chain = tree_cons (expr, ident, NULL_TREE);
2275 return (flag_next_runtime
2277 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2278 build_int_2 (index, 0)));
2282 build_class_reference_decl ()
2288 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2290 ident = get_identifier (buf);
2292 decl = build_decl (VAR_DECL, ident, objc_class_type);
2293 DECL_EXTERNAL (decl) = 1;
2294 TREE_PUBLIC (decl) = 1;
2295 TREE_USED (decl) = 1;
2296 TREE_READONLY (decl) = 1;
2297 DECL_CONTEXT (decl) = 0;
2298 DECL_ARTIFICIAL (decl) = 1;
2300 make_decl_rtl (decl, 0, 1);
2301 pushdecl_top_level (decl);
2306 /* Create a class reference, but don't create a variable to reference
2310 add_class_reference (ident)
2315 if ((chain = cls_ref_chain))
2320 if (ident == TREE_VALUE (chain))
2324 chain = TREE_CHAIN (chain);
2328 /* Append to the end of the list */
2329 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2332 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2335 /* Get a class reference, creating it if necessary. Also create the
2336 reference variable. */
2339 get_class_reference (ident)
2342 if (flag_next_runtime)
2347 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2348 if (TREE_VALUE (*chain) == ident)
2350 if (! TREE_PURPOSE (*chain))
2351 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2353 return TREE_PURPOSE (*chain);
2356 decl = build_class_reference_decl ();
2357 *chain = tree_cons (decl, ident, NULL_TREE);
2364 add_class_reference (ident);
2366 params = build_tree_list (NULL_TREE,
2367 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2368 IDENTIFIER_POINTER (ident)));
2370 assemble_external (objc_get_class_decl);
2371 return build_function_call (objc_get_class_decl, params);
2375 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2376 of identifier_node that represent the selector. It returns the
2377 offset of the selector from the beginning of the _OBJC_STRINGS
2378 pool. This offset is typically used by init_selector during code
2381 For each string section we have a chain which maps identifier nodes
2382 to decls for the strings. */
2385 add_objc_string (ident, section)
2387 enum string_section section;
2391 if (section == class_names)
2392 chain = &class_names_chain;
2393 else if (section == meth_var_names)
2394 chain = &meth_var_names_chain;
2395 else if (section == meth_var_types)
2396 chain = &meth_var_types_chain;
2402 if (TREE_VALUE (*chain) == ident)
2403 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2405 chain = &TREE_CHAIN (*chain);
2408 decl = build_objc_string_decl (section);
2410 *chain = tree_cons (decl, ident, NULL_TREE);
2412 return build_unary_op (ADDR_EXPR, decl, 1);
2416 build_objc_string_decl (section)
2417 enum string_section section;
2421 static int class_names_idx = 0;
2422 static int meth_var_names_idx = 0;
2423 static int meth_var_types_idx = 0;
2425 if (section == class_names)
2426 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2427 else if (section == meth_var_names)
2428 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2429 else if (section == meth_var_types)
2430 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2432 ident = get_identifier (buf);
2434 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2435 DECL_EXTERNAL (decl) = 1;
2436 TREE_PUBLIC (decl) = 1;
2437 TREE_USED (decl) = 1;
2438 TREE_READONLY (decl) = 1;
2439 TREE_CONSTANT (decl) = 1;
2440 DECL_CONTEXT (decl) = 0;
2441 DECL_ARTIFICIAL (decl) = 1;
2443 make_decl_rtl (decl, 0, 1);
2444 pushdecl_top_level (decl);
2451 objc_declare_alias (alias_ident, class_ident)
2455 if (!doing_objc_thang)
2458 if (is_class_name (class_ident) != class_ident)
2459 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2460 else if (is_class_name (alias_ident))
2461 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2463 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2467 objc_declare_class (ident_list)
2472 if (!doing_objc_thang)
2475 for (list = ident_list; list; list = TREE_CHAIN (list))
2477 tree ident = TREE_VALUE (list);
2480 if ((decl = lookup_name (ident)))
2482 error ("`%s' redeclared as different kind of symbol",
2483 IDENTIFIER_POINTER (ident));
2484 error_with_decl (decl, "previous declaration of `%s'");
2487 if (! is_class_name (ident))
2489 tree record = xref_tag (RECORD_TYPE, ident);
2490 TREE_STATIC_TEMPLATE (record) = 1;
2491 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2497 is_class_name (ident)
2502 if (lookup_interface (ident))
2505 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2507 if (ident == TREE_VALUE (chain))
2511 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2513 if (ident == TREE_VALUE (chain))
2514 return TREE_PURPOSE (chain);
2521 lookup_interface (ident)
2526 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2528 if (ident == CLASS_NAME (chain))
2535 objc_copy_list (list, head)
2539 tree newlist = NULL_TREE, tail = NULL_TREE;
2543 tail = copy_node (list);
2545 /* The following statement fixes a bug when inheriting instance
2546 variables that are declared to be bitfields. finish_struct
2547 expects to find the width of the bitfield in DECL_INITIAL. */
2548 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2549 DECL_INITIAL (tail) = DECL_SIZE (tail);
2551 newlist = chainon (newlist, tail);
2552 list = TREE_CHAIN (list);
2559 /* Used by: build_private_template, get_class_ivars, and
2560 continue_class. COPY is 1 when called from @defs. In this case
2561 copy all fields. Otherwise don't copy leaf ivars since we rely on
2562 them being side-effected exactly once by finish_struct. */
2565 build_ivar_chain (interface, copy)
2569 tree my_name, super_name, ivar_chain;
2571 my_name = CLASS_NAME (interface);
2572 super_name = CLASS_SUPER_NAME (interface);
2574 /* Possibly copy leaf ivars. */
2576 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2578 ivar_chain = CLASS_IVARS (interface);
2583 tree super_interface = lookup_interface (super_name);
2585 if (!super_interface)
2587 /* fatal did not work with 2 args...should fix */
2588 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2589 IDENTIFIER_POINTER (super_name),
2590 IDENTIFIER_POINTER (my_name));
2591 exit (FATAL_EXIT_CODE);
2594 if (super_interface == interface)
2596 fatal ("Circular inheritance in interface declaration for `%s'",
2597 IDENTIFIER_POINTER (super_name));
2600 interface = super_interface;
2601 my_name = CLASS_NAME (interface);
2602 super_name = CLASS_SUPER_NAME (interface);
2604 op1 = CLASS_IVARS (interface);
2607 tree head, tail = objc_copy_list (op1, &head);
2609 /* Prepend super class ivars...make a copy of the list, we
2610 do not want to alter the original. */
2611 TREE_CHAIN (tail) = ivar_chain;
2618 /* struct <classname> {
2619 struct objc_class *isa;
2624 build_private_template (class)
2629 if (CLASS_STATIC_TEMPLATE (class))
2631 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2632 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2636 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2638 ivar_context = build_ivar_chain (class, 0);
2640 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2642 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2644 /* mark this record as class template - for class type checking */
2645 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2649 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2651 build1 (INDIRECT_REF, NULL_TREE,
2654 return ivar_context;
2657 /* Begin code generation for protocols... */
2659 /* struct objc_protocol {
2660 char *protocol_name;
2661 struct objc_protocol **protocol_list;
2662 struct objc_method_desc *instance_methods;
2663 struct objc_method_desc *class_methods;
2667 build_protocol_template ()
2669 tree decl_specs, field_decl, field_decl_chain;
2672 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2674 /* struct objc_class *isa; */
2676 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2677 get_identifier (UTAG_CLASS)));
2678 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2680 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2681 field_decl_chain = field_decl;
2683 /* char *protocol_name; */
2685 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2687 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2689 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2690 chainon (field_decl_chain, field_decl);
2692 /* struct objc_protocol **protocol_list; */
2694 decl_specs = build_tree_list (NULL_TREE, template);
2696 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2697 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2699 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2700 chainon (field_decl_chain, field_decl);
2702 /* struct objc_method_list *instance_methods; */
2705 = build_tree_list (NULL_TREE,
2706 xref_tag (RECORD_TYPE,
2707 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2709 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2711 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2712 chainon (field_decl_chain, field_decl);
2714 /* struct objc_method_list *class_methods; */
2717 = build_tree_list (NULL_TREE,
2718 xref_tag (RECORD_TYPE,
2719 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2721 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2723 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2724 chainon (field_decl_chain, field_decl);
2726 return finish_struct (template, field_decl_chain, NULL_TREE);
2730 build_descriptor_table_initializer (type, entries)
2734 tree initlist = NULL_TREE;
2738 tree eltlist = NULL_TREE;
2741 = tree_cons (NULL_TREE,
2742 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2744 = tree_cons (NULL_TREE,
2745 add_objc_string (METHOD_ENCODING (entries),
2750 = tree_cons (NULL_TREE,
2751 build_constructor (type, nreverse (eltlist)), initlist);
2753 entries = TREE_CHAIN (entries);
2757 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2760 /* struct objc_method_prototype_list {
2762 struct objc_method_prototype {
2769 build_method_prototype_list_template (list_type, size)
2773 tree objc_ivar_list_record;
2774 tree decl_specs, field_decl, field_decl_chain;
2776 /* Generate an unnamed struct definition. */
2778 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2780 /* int method_count; */
2782 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2783 field_decl = get_identifier ("method_count");
2786 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2787 field_decl_chain = field_decl;
2789 /* struct objc_method method_list[]; */
2791 decl_specs = build_tree_list (NULL_TREE, list_type);
2792 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2793 build_int_2 (size, 0));
2796 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2797 chainon (field_decl_chain, field_decl);
2799 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2801 return objc_ivar_list_record;
2805 build_method_prototype_template ()
2808 tree decl_specs, field_decl, field_decl_chain;
2811 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2813 #ifdef OBJC_INT_SELECTORS
2814 /* unsigned int _cmd; */
2816 = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2817 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2818 field_decl = get_identifier ("_cmd");
2819 #else /* OBJC_INT_SELECTORS */
2820 /* struct objc_selector *_cmd; */
2821 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2822 get_identifier (TAG_SELECTOR)), NULL_TREE);
2823 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2824 #endif /* OBJC_INT_SELECTORS */
2827 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2828 field_decl_chain = field_decl;
2830 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2832 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2834 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2835 chainon (field_decl_chain, field_decl);
2837 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2839 return proto_record;
2842 /* True if last call to forwarding_offset yielded a register offset. */
2843 static int offset_is_register;
2846 forwarding_offset (parm)
2849 int offset_in_bytes;
2851 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2853 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2855 /* ??? Here we assume that the parm address is indexed
2856 off the frame pointer or arg pointer.
2857 If that is not true, we produce meaningless results,
2858 but do not crash. */
2859 if (GET_CODE (addr) == PLUS
2860 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2861 offset_in_bytes = INTVAL (XEXP (addr, 1));
2863 offset_in_bytes = 0;
2865 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2866 offset_is_register = 0;
2868 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2870 int regno = REGNO (DECL_INCOMING_RTL (parm));
2871 offset_in_bytes = apply_args_register_offset (regno);
2872 offset_is_register = 1;
2877 /* This is the case where the parm is passed as an int or double
2878 and it is converted to a char, short or float and stored back
2879 in the parmlist. In this case, describe the parm
2880 with the variable's declared type, and adjust the address
2881 if the least significant bytes (which we are using) are not
2883 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2884 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2885 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2887 return offset_in_bytes;
2891 encode_method_prototype (method_decl, func_decl)
2898 HOST_WIDE_INT max_parm_end = 0;
2902 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2903 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2906 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2907 obstack_object_size (&util_obstack),
2908 OBJC_ENCODE_INLINE_DEFS);
2911 for (parms = DECL_ARGUMENTS (func_decl); parms;
2912 parms = TREE_CHAIN (parms))
2914 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2915 + int_size_in_bytes (TREE_TYPE (parms)));
2917 if (!offset_is_register && max_parm_end < parm_end)
2918 max_parm_end = parm_end;
2921 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2923 sprintf (buf, "%d", stack_size);
2924 obstack_grow (&util_obstack, buf, strlen (buf));
2926 user_args = METHOD_SEL_ARGS (method_decl);
2928 /* Argument types. */
2929 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2930 parms = TREE_CHAIN (parms), i++)
2932 /* Process argument qualifiers for user supplied arguments. */
2935 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2936 user_args = TREE_CHAIN (user_args);
2940 encode_type (TREE_TYPE (parms),
2941 obstack_object_size (&util_obstack),
2942 OBJC_ENCODE_INLINE_DEFS);
2944 /* Compute offset. */
2945 sprintf (buf, "%d", forwarding_offset (parms));
2947 /* Indicate register. */
2948 if (offset_is_register)
2949 obstack_1grow (&util_obstack, '+');
2951 obstack_grow (&util_obstack, buf, strlen (buf));
2954 obstack_1grow (&util_obstack, '\0');
2955 result = get_identifier (obstack_finish (&util_obstack));
2956 obstack_free (&util_obstack, util_firstobj);
2961 generate_descriptor_table (type, name, size, list, proto)
2968 tree sc_spec, decl_specs, decl, initlist;
2970 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2971 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2973 decl = start_decl (synth_id_with_class_suffix (name, proto),
2974 decl_specs, 1, NULL_TREE, NULL_TREE);
2976 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2977 initlist = tree_cons (NULL_TREE, list, initlist);
2979 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2986 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2989 static tree objc_method_prototype_template;
2990 tree initlist, chain, method_list_template;
2991 tree cast, variable_length_type;
2994 if (!objc_method_prototype_template)
2996 objc_method_prototype_template = build_method_prototype_template ();
2997 ggc_add_tree_root (&objc_method_prototype_template, 1);
3000 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3001 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3003 variable_length_type = groktypename (cast);
3005 chain = PROTOCOL_CLS_METHODS (protocol);
3008 size = list_length (chain);
3010 method_list_template
3011 = build_method_prototype_list_template (objc_method_prototype_template,
3015 = build_descriptor_table_initializer (objc_method_prototype_template,
3018 UOBJC_CLASS_METHODS_decl
3019 = generate_descriptor_table (method_list_template,
3020 "_OBJC_PROTOCOL_CLASS_METHODS",
3021 size, initlist, protocol);
3022 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3025 UOBJC_CLASS_METHODS_decl = 0;
3027 chain = PROTOCOL_NST_METHODS (protocol);
3030 size = list_length (chain);
3032 method_list_template
3033 = build_method_prototype_list_template (objc_method_prototype_template,
3036 = build_descriptor_table_initializer (objc_method_prototype_template,
3039 UOBJC_INSTANCE_METHODS_decl
3040 = generate_descriptor_table (method_list_template,
3041 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3042 size, initlist, protocol);
3043 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3046 UOBJC_INSTANCE_METHODS_decl = 0;
3050 build_tmp_function_decl ()
3052 tree decl_specs, expr_decl, parms;
3056 /* struct objc_object *objc_xxx (id, SEL, ...); */
3058 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3059 push_parm_decl (build_tree_list
3060 (build_tree_list (decl_specs,
3061 build1 (INDIRECT_REF, NULL_TREE,
3063 build_tree_list (NULL_TREE, NULL_TREE)));
3065 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3066 get_identifier (TAG_SELECTOR)));
3067 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
3069 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
3070 build_tree_list (NULL_TREE, NULL_TREE)));
3071 parms = get_parm_info (0);
3074 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3075 sprintf (buffer, "__objc_tmp_%x", xxx++);
3076 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
3077 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
3079 return define_decl (expr_decl, decl_specs);
3083 hack_method_prototype (nst_methods, tmp_decl)
3090 /* Hack to avoid problem with static typing of self arg. */
3091 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
3092 start_method_def (nst_methods);
3093 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
3095 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
3096 parms = get_parm_info (0); /* we have a `, ...' */
3098 parms = get_parm_info (1); /* place a `void_at_end' */
3100 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3102 /* Usually called from store_parm_decls -> init_function_start. */
3104 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
3105 current_function_decl = tmp_decl;
3108 /* Code taken from start_function. */
3109 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3110 /* Promote the value to int before returning it. */
3111 if (TREE_CODE (restype) == INTEGER_TYPE
3112 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3113 restype = integer_type_node;
3114 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3117 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3118 DECL_CONTEXT (parm) = tmp_decl;
3120 init_function_start (tmp_decl, "objc-act", 0);
3122 /* Typically called from expand_function_start for function definitions. */
3123 assign_parms (tmp_decl);
3125 /* install return type */
3126 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3131 generate_protocol_references (plist)
3136 /* Forward declare protocols referenced. */
3137 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3139 tree proto = TREE_VALUE (lproto);
3141 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3142 && PROTOCOL_NAME (proto))
3144 if (! PROTOCOL_FORWARD_DECL (proto))
3145 build_protocol_reference (proto);
3147 if (PROTOCOL_LIST (proto))
3148 generate_protocol_references (PROTOCOL_LIST (proto));
3154 generate_protocols ()
3156 tree p, tmp_decl, encoding;
3157 tree sc_spec, decl_specs, decl;
3158 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3161 tmp_decl = build_tmp_function_decl ();
3163 if (! objc_protocol_template)
3164 objc_protocol_template = build_protocol_template ();
3166 /* If a protocol was directly referenced, pull in indirect references. */
3167 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3168 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3169 generate_protocol_references (PROTOCOL_LIST (p));
3171 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3173 tree nst_methods = PROTOCOL_NST_METHODS (p);
3174 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3176 /* If protocol wasn't referenced, don't generate any code. */
3177 if (! PROTOCOL_FORWARD_DECL (p))
3180 /* Make sure we link in the Protocol class. */
3181 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3185 if (! METHOD_ENCODING (nst_methods))
3187 hack_method_prototype (nst_methods, tmp_decl);
3188 encoding = encode_method_prototype (nst_methods, tmp_decl);
3189 METHOD_ENCODING (nst_methods) = encoding;
3191 nst_methods = TREE_CHAIN (nst_methods);
3196 if (! METHOD_ENCODING (cls_methods))
3198 hack_method_prototype (cls_methods, tmp_decl);
3199 encoding = encode_method_prototype (cls_methods, tmp_decl);
3200 METHOD_ENCODING (cls_methods) = encoding;
3203 cls_methods = TREE_CHAIN (cls_methods);
3205 generate_method_descriptors (p);
3207 if (PROTOCOL_LIST (p))
3208 refs_decl = generate_protocol_list (p);
3212 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3214 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3216 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3218 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3219 decl_specs, 1, NULL_TREE, NULL_TREE);
3221 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3227 (build_tree_list (build_tree_list (NULL_TREE,
3228 objc_protocol_template),
3229 build1 (INDIRECT_REF, NULL_TREE,
3230 build1 (INDIRECT_REF, NULL_TREE,
3233 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3234 TREE_TYPE (refs_expr) = cast_type2;
3237 refs_expr = build_int_2 (0, 0);
3239 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3240 by generate_method_descriptors, which is called above. */
3241 initlist = build_protocol_initializer (TREE_TYPE (decl),
3242 protocol_name_expr, refs_expr,
3243 UOBJC_INSTANCE_METHODS_decl,
3244 UOBJC_CLASS_METHODS_decl);
3245 finish_decl (decl, initlist, NULL_TREE);
3247 /* Mark the decl as used to avoid "defined but not used" warning. */
3248 TREE_USED (decl) = 1;
3253 build_protocol_initializer (type, protocol_name, protocol_list,
3254 instance_methods, class_methods)
3258 tree instance_methods;
3261 tree initlist = NULL_TREE, expr;
3264 cast_type = groktypename
3266 (build_tree_list (NULL_TREE,
3267 xref_tag (RECORD_TYPE,
3268 get_identifier (UTAG_CLASS))),
3269 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3271 /* Filling the "isa" in with one allows the runtime system to
3272 detect that the version change...should remove before final release. */
3274 expr = build_int_2 (PROTOCOL_VERSION, 0);
3275 TREE_TYPE (expr) = cast_type;
3276 initlist = tree_cons (NULL_TREE, expr, initlist);
3277 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3278 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3280 if (!instance_methods)
3281 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3284 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3285 initlist = tree_cons (NULL_TREE, expr, initlist);
3289 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3292 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3293 initlist = tree_cons (NULL_TREE, expr, initlist);
3296 return build_constructor (type, nreverse (initlist));
3299 /* struct objc_category {
3300 char *category_name;
3302 struct objc_method_list *instance_methods;
3303 struct objc_method_list *class_methods;
3304 struct objc_protocol_list *protocols;
3308 build_category_template ()
3310 tree decl_specs, field_decl, field_decl_chain;
3312 objc_category_template = start_struct (RECORD_TYPE,
3313 get_identifier (UTAG_CATEGORY));
3314 /* char *category_name; */
3316 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3318 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3320 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3321 field_decl_chain = field_decl;
3323 /* char *class_name; */
3325 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3326 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3328 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3329 chainon (field_decl_chain, field_decl);
3331 /* struct objc_method_list *instance_methods; */
3333 decl_specs = build_tree_list (NULL_TREE,
3334 xref_tag (RECORD_TYPE,
3335 get_identifier (UTAG_METHOD_LIST)));
3337 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3339 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3340 chainon (field_decl_chain, field_decl);
3342 /* struct objc_method_list *class_methods; */
3344 decl_specs = build_tree_list (NULL_TREE,
3345 xref_tag (RECORD_TYPE,
3346 get_identifier (UTAG_METHOD_LIST)));
3348 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3350 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3351 chainon (field_decl_chain, field_decl);
3353 /* struct objc_protocol **protocol_list; */
3355 decl_specs = build_tree_list (NULL_TREE,
3356 xref_tag (RECORD_TYPE,
3357 get_identifier (UTAG_PROTOCOL)));
3359 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3360 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3362 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3363 chainon (field_decl_chain, field_decl);
3365 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3368 /* struct objc_selector {
3374 build_selector_template ()
3377 tree decl_specs, field_decl, field_decl_chain;
3379 objc_selector_template
3380 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3384 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3385 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3387 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3388 field_decl_chain = field_decl;
3390 /* char *sel_type; */
3392 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3393 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3395 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3396 chainon (field_decl_chain, field_decl);
3398 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3401 /* struct objc_class {
3402 struct objc_class *isa;
3403 struct objc_class *super_class;
3408 struct objc_ivar_list *ivars;
3409 struct objc_method_list *methods;
3410 if (flag_next_runtime)
3411 struct objc_cache *cache;
3413 struct sarray *dtable;
3414 struct objc_class *subclass_list;
3415 struct objc_class *sibling_class;
3417 struct objc_protocol_list *protocols;
3418 void *gc_object_type;
3422 build_class_template ()
3424 tree decl_specs, field_decl, field_decl_chain;
3427 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3429 /* struct objc_class *isa; */
3431 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3432 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3434 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3435 field_decl_chain = field_decl;
3437 /* struct objc_class *super_class; */
3439 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3441 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3443 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3444 chainon (field_decl_chain, field_decl);
3448 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3449 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3451 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3452 chainon (field_decl_chain, field_decl);
3456 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3457 field_decl = get_identifier ("version");
3459 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3460 chainon (field_decl_chain, field_decl);
3464 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3465 field_decl = get_identifier ("info");
3467 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3468 chainon (field_decl_chain, field_decl);
3470 /* long instance_size; */
3472 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3473 field_decl = get_identifier ("instance_size");
3475 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3476 chainon (field_decl_chain, field_decl);
3478 /* struct objc_ivar_list *ivars; */
3480 decl_specs = build_tree_list (NULL_TREE,
3481 xref_tag (RECORD_TYPE,
3482 get_identifier (UTAG_IVAR_LIST)));
3483 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3485 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3486 chainon (field_decl_chain, field_decl);
3488 /* struct objc_method_list *methods; */
3490 decl_specs = build_tree_list (NULL_TREE,
3491 xref_tag (RECORD_TYPE,
3492 get_identifier (UTAG_METHOD_LIST)));
3493 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3495 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3496 chainon (field_decl_chain, field_decl);
3498 if (flag_next_runtime)
3500 /* struct objc_cache *cache; */
3502 decl_specs = build_tree_list (NULL_TREE,
3503 xref_tag (RECORD_TYPE,
3504 get_identifier ("objc_cache")));
3505 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3506 field_decl = grokfield (input_filename, lineno, field_decl,
3507 decl_specs, NULL_TREE);
3508 chainon (field_decl_chain, field_decl);
3512 /* struct sarray *dtable; */
3514 decl_specs = build_tree_list (NULL_TREE,
3515 xref_tag (RECORD_TYPE,
3516 get_identifier ("sarray")));
3517 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3518 field_decl = grokfield (input_filename, lineno, field_decl,
3519 decl_specs, NULL_TREE);
3520 chainon (field_decl_chain, field_decl);
3522 /* struct objc_class *subclass_list; */
3524 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3526 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3527 field_decl = grokfield (input_filename, lineno, field_decl,
3528 decl_specs, NULL_TREE);
3529 chainon (field_decl_chain, field_decl);
3531 /* struct objc_class *sibling_class; */
3533 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3535 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3536 field_decl = grokfield (input_filename, lineno, field_decl,
3537 decl_specs, NULL_TREE);
3538 chainon (field_decl_chain, field_decl);
3541 /* struct objc_protocol **protocol_list; */
3543 decl_specs = build_tree_list (NULL_TREE,
3544 xref_tag (RECORD_TYPE,
3545 get_identifier (UTAG_PROTOCOL)));
3547 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3549 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3550 field_decl = grokfield (input_filename, lineno, field_decl,
3551 decl_specs, NULL_TREE);
3552 chainon (field_decl_chain, field_decl);