1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000, 2001 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));
151 static void objc_post_options PARAMS ((void));
152 static void objc_init PARAMS ((void));
154 /* Code generation. */
156 static void synth_module_prologue PARAMS ((void));
157 static tree build_constructor PARAMS ((tree, tree));
158 static const char *build_module_descriptor PARAMS ((void));
159 static tree init_module_descriptor PARAMS ((tree));
160 static tree build_objc_method_call PARAMS ((int, tree, tree,
162 static void generate_strings PARAMS ((void));
163 static tree get_proto_encoding PARAMS ((tree));
164 static void build_selector_translation_table PARAMS ((void));
165 static tree build_ivar_chain PARAMS ((tree, int));
167 static tree objc_add_static_instance PARAMS ((tree, tree));
169 static tree build_ivar_template PARAMS ((void));
170 static tree build_method_template PARAMS ((void));
171 static tree build_private_template PARAMS ((tree));
172 static void build_class_template PARAMS ((void));
173 static void build_selector_template PARAMS ((void));
174 static void build_category_template PARAMS ((void));
175 static tree build_super_template PARAMS ((void));
176 static tree build_category_initializer PARAMS ((tree, tree, tree,
178 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
181 static void synth_forward_declarations PARAMS ((void));
182 static void generate_ivar_lists PARAMS ((void));
183 static void generate_dispatch_tables PARAMS ((void));
184 static void generate_shared_structures PARAMS ((void));
185 static tree generate_protocol_list PARAMS ((tree));
186 static void generate_forward_declaration_to_string_table PARAMS ((void));
187 static void build_protocol_reference PARAMS ((tree));
190 static tree init_selector PARAMS ((int));
192 static tree build_keyword_selector PARAMS ((tree));
193 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
195 static void generate_static_references PARAMS ((void));
196 static int check_methods_accessible PARAMS ((tree, tree,
198 static void encode_aggregate_within PARAMS ((tree, int, int,
200 static const char *objc_demangle PARAMS ((const char *));
201 static const char *objc_printable_name PARAMS ((tree, int));
202 static void objc_expand_function_end PARAMS ((void));
204 /* Misc. bookkeeping */
206 typedef struct hashed_entry *hash;
207 typedef struct hashed_attribute *attr;
209 struct hashed_attribute
221 static void hash_init PARAMS ((void));
222 static void hash_enter PARAMS ((hash *, tree));
223 static hash hash_lookup PARAMS ((hash *, tree));
224 static void hash_add_attr PARAMS ((hash, tree));
225 static tree lookup_method PARAMS ((tree, tree));
226 static tree lookup_instance_method_static PARAMS ((tree, tree));
227 static tree lookup_class_method_static PARAMS ((tree, tree));
228 static tree add_class PARAMS ((tree));
229 static void add_category PARAMS ((tree, tree));
233 class_names, /* class, category, protocol, module names */
234 meth_var_names, /* method and variable names */
235 meth_var_types /* method and variable type descriptors */
238 static tree add_objc_string PARAMS ((tree,
239 enum string_section));
240 static tree get_objc_string_decl PARAMS ((tree,
241 enum string_section));
242 static tree build_objc_string_decl PARAMS ((enum string_section));
243 static tree build_selector_reference_decl PARAMS ((void));
245 /* Protocol additions. */
247 static tree add_protocol PARAMS ((tree));
248 static tree lookup_protocol PARAMS ((tree));
249 static tree lookup_and_install_protocols PARAMS ((tree));
253 static void encode_type_qualifiers PARAMS ((tree));
254 static void encode_pointer PARAMS ((tree, int, int));
255 static void encode_array PARAMS ((tree, int, int));
256 static void encode_aggregate PARAMS ((tree, int, int));
257 static void encode_bitfield PARAMS ((int));
258 static void encode_type PARAMS ((tree, int, int));
259 static void encode_field_decl PARAMS ((tree, int, int));
261 static void really_start_method PARAMS ((tree, tree));
262 static int comp_method_with_proto PARAMS ((tree, tree));
263 static int comp_proto_with_proto PARAMS ((tree, tree));
264 static tree get_arg_type_list PARAMS ((tree, int, int));
265 static tree expr_last PARAMS ((tree));
267 /* Utilities for debugging and error diagnostics. */
269 static void warn_with_method PARAMS ((const char *, int, tree));
270 static void error_with_ivar PARAMS ((const char *, tree, tree));
271 static char *gen_method_decl PARAMS ((tree, char *));
272 static char *gen_declaration PARAMS ((tree, char *));
273 static char *gen_declarator PARAMS ((tree, char *,
275 static int is_complex_decl PARAMS ((tree));
276 static void adorn_decl PARAMS ((tree, char *));
277 static void dump_interface PARAMS ((FILE *, tree));
279 /* Everything else. */
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 /* Each front end provides its own. */
632 struct lang_hooks lang_hooks = {objc_init,
633 NULL, /* objc_finish */
636 /* Post-switch processing. */
640 cpp_post_options (parse_in);
643 /* Some platforms pass small structures through registers versus through
644 an invisible pointer. Determine at what size structure is the
645 transition point between the two possibilities. */
648 generate_struct_by_value_array ()
651 tree field_decl, field_decl_chain;
653 int aggregate_in_mem[32];
656 /* Presumbaly no platform passes 32 byte structures in a register. */
657 for (i = 1; i < 32; i++)
661 /* Create an unnamed struct that has `i' character components */
662 type = start_struct (RECORD_TYPE, NULL_TREE);
664 strcpy (buffer, "c1");
665 field_decl = create_builtin_decl (FIELD_DECL,
668 field_decl_chain = field_decl;
670 for (j = 1; j < i; j++)
672 sprintf (buffer, "c%d", j + 1);
673 field_decl = create_builtin_decl (FIELD_DECL,
676 chainon (field_decl_chain, field_decl);
678 finish_struct (type, field_decl_chain, NULL_TREE);
680 aggregate_in_mem[i] = aggregate_value_p (type);
681 if (!aggregate_in_mem[i])
685 /* We found some structures that are returned in registers instead of memory
686 so output the necessary data. */
689 for (i = 31; i >= 0; i--)
690 if (!aggregate_in_mem[i])
692 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
694 /* The first member of the structure is always 0 because we don't handle
695 structures with 0 members */
696 printf ("static int struct_forward_array[] = {\n 0");
698 for (j = 1; j <= i; j++)
699 printf (", %d", aggregate_in_mem[j]);
709 parse_in = cpp_create_reader (CLK_OBJC);
710 c_language = clk_objective_c;
716 /* Force the line number back to 0; check_newline will have
717 raised it to 1, which will make the builtin functions appear
718 not to be built in. */
721 c_common_lang_init ();
723 /* If gen_declaration desired, open the output file. */
724 if (flag_gen_declaration)
726 register char * const dumpname = concat (dumpname, ".decl", NULL);
727 gen_declaration_file = fopen (dumpname, "w");
728 if (gen_declaration_file == 0)
729 pfatal_with_name (dumpname);
733 if (flag_next_runtime)
735 TAG_GETCLASS = "objc_getClass";
736 TAG_GETMETACLASS = "objc_getMetaClass";
737 TAG_MSGSEND = "objc_msgSend";
738 TAG_MSGSENDSUPER = "objc_msgSendSuper";
739 TAG_EXECCLASS = "__objc_execClass";
743 TAG_GETCLASS = "objc_get_class";
744 TAG_GETMETACLASS = "objc_get_meta_class";
745 TAG_MSGSEND = "objc_msg_lookup";
746 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
747 TAG_EXECCLASS = "__objc_exec_class";
748 flag_typed_selectors = 1;
751 objc_ellipsis_node = make_node (ERROR_MARK);
755 if (print_struct_values)
756 generate_struct_by_value_array ();
758 objc_act_parse_init ();
765 finish_objc (); /* Objective-C finalization */
767 if (gen_declaration_file)
768 fclose (gen_declaration_file);
778 lang_decode_option (argc, argv)
782 const char *p = argv[0];
784 if (!strcmp (p, "-gen-decls"))
785 flag_gen_declaration = 1;
786 else if (!strcmp (p, "-Wselector"))
788 else if (!strcmp (p, "-Wno-selector"))
790 else if (!strcmp (p, "-Wprotocol"))
791 flag_warn_protocol = 1;
792 else if (!strcmp (p, "-Wno-protocol"))
793 flag_warn_protocol = 0;
794 else if (!strcmp (p, "-fgnu-runtime"))
795 flag_next_runtime = 0;
796 else if (!strcmp (p, "-fno-next-runtime"))
797 flag_next_runtime = 0;
798 else if (!strcmp (p, "-fno-gnu-runtime"))
799 flag_next_runtime = 1;
800 else if (!strcmp (p, "-fnext-runtime"))
801 flag_next_runtime = 1;
802 else if (!strcmp (p, "-print-objc-runtime-info"))
803 print_struct_values = 1;
804 #define CSTSTRCLASS "-fconstant-string-class="
805 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
806 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
807 error ("no class name specified as argument to -fconstant-string-class");
808 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
812 return c_decode_option (argc, argv);
817 /* used by print-tree.c */
820 lang_print_xnode (file, node, indent)
821 FILE *file ATTRIBUTE_UNUSED;
822 tree node ATTRIBUTE_UNUSED;
823 int indent ATTRIBUTE_UNUSED;
829 define_decl (declarator, declspecs)
833 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
834 finish_decl (decl, NULL_TREE, NULL_TREE);
838 /* Return 1 if LHS and RHS are compatible types for assignment or
839 various other operations. Return 0 if they are incompatible, and
840 return -1 if we choose to not decide. When the operation is
841 REFLEXIVE, check for compatibility in either direction.
843 For statically typed objects, an assignment of the form `a' = `b'
847 `a' and `b' are the same class type, or
848 `a' and `b' are of class types A and B such that B is a descendant of A. */
851 maybe_objc_comptypes (lhs, rhs, reflexive)
855 return objc_comptypes (lhs, rhs, reflexive);
859 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
867 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
869 p = TREE_VALUE (rproto);
871 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
873 if ((fnd = lookup_method (class_meth
874 ? PROTOCOL_CLS_METHODS (p)
875 : PROTOCOL_NST_METHODS (p), sel_name)))
877 else if (PROTOCOL_LIST (p))
878 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
879 sel_name, class_meth);
883 ; /* An identifier...if we could not find a protocol. */
894 lookup_protocol_in_reflist (rproto_list, lproto)
900 /* Make sure the protocol is support by the object on the rhs. */
901 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
904 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
906 p = TREE_VALUE (rproto);
908 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
913 else if (PROTOCOL_LIST (p))
914 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
923 ; /* An identifier...if we could not find a protocol. */
929 /* Return 1 if LHS and RHS are compatible types for assignment
930 or various other operations. Return 0 if they are incompatible,
931 and return -1 if we choose to not decide. When the operation
932 is REFLEXIVE, check for compatibility in either direction. */
935 objc_comptypes (lhs, rhs, reflexive)
940 /* New clause for protocols. */
942 if (TREE_CODE (lhs) == POINTER_TYPE
943 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
944 && TREE_CODE (rhs) == POINTER_TYPE
945 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
947 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
948 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
952 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
953 tree rproto, rproto_list;
958 rproto_list = TYPE_PROTOCOL_LIST (rhs);
960 /* Make sure the protocol is supported by the object
962 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
964 p = TREE_VALUE (lproto);
965 rproto = lookup_protocol_in_reflist (rproto_list, p);
968 warning ("object does not conform to the `%s' protocol",
969 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
972 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
974 tree rname = TYPE_NAME (TREE_TYPE (rhs));
977 /* Make sure the protocol is supported by the object
979 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
981 p = TREE_VALUE (lproto);
983 rinter = lookup_interface (rname);
985 while (rinter && !rproto)
989 rproto_list = CLASS_PROTOCOL_LIST (rinter);
990 rproto = lookup_protocol_in_reflist (rproto_list, p);
992 /* Check for protocols adopted by categories. */
993 cat = CLASS_CATEGORY_LIST (rinter);
994 while (cat && !rproto)
996 rproto_list = CLASS_PROTOCOL_LIST (cat);
997 rproto = lookup_protocol_in_reflist (rproto_list, p);
999 cat = CLASS_CATEGORY_LIST (cat);
1002 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
1006 warning ("class `%s' does not implement the `%s' protocol",
1007 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
1008 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1012 /* May change...based on whether there was any mismatch */
1015 else if (rhs_is_proto)
1016 /* Lhs is not a protocol...warn if it is statically typed */
1017 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
1020 /* Defer to comptypes .*/
1024 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
1025 ; /* Fall thru. This is the case we have been handling all along */
1027 /* Defer to comptypes. */
1030 /* `id' = `<class> *', `<class> *' = `id' */
1032 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
1033 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
1036 /* `id' = `Class', `Class' = `id' */
1038 else if ((TYPE_NAME (lhs) == objc_object_id
1039 && TYPE_NAME (rhs) == objc_class_id)
1040 || (TYPE_NAME (lhs) == objc_class_id
1041 && TYPE_NAME (rhs) == objc_object_id))
1044 /* `<class> *' = `<class> *' */
1046 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1048 tree lname = TYPE_NAME (lhs);
1049 tree rname = TYPE_NAME (rhs);
1055 /* If the left hand side is a super class of the right hand side,
1057 for (inter = lookup_interface (rname); inter;
1058 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1059 if (lname == CLASS_SUPER_NAME (inter))
1062 /* Allow the reverse when reflexive. */
1064 for (inter = lookup_interface (lname); inter;
1065 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1066 if (rname == CLASS_SUPER_NAME (inter))
1072 /* Defer to comptypes. */
1076 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1079 objc_check_decl (decl)
1082 tree type = TREE_TYPE (decl);
1084 if (TREE_CODE (type) == RECORD_TYPE
1085 && TREE_STATIC_TEMPLATE (type)
1086 && type != constant_string_type)
1088 error_with_decl (decl, "`%s' cannot be statically allocated");
1089 fatal ("statically allocated objects not supported");
1094 maybe_objc_check_decl (decl)
1097 objc_check_decl (decl);
1100 /* Implement static typing. At this point, we know we have an interface. */
1103 get_static_reference (interface, protocols)
1107 tree type = xref_tag (RECORD_TYPE, interface);
1111 tree t, m = TYPE_MAIN_VARIANT (type);
1113 t = copy_node (type);
1114 TYPE_BINFO (t) = make_tree_vec (2);
1116 /* Add this type to the chain of variants of TYPE. */
1117 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1118 TYPE_NEXT_VARIANT (m) = t;
1120 /* Look up protocols and install in lang specific list. */
1121 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1123 /* This forces a new pointer type to be created later
1124 (in build_pointer_type)...so that the new template
1125 we just created will actually be used...what a hack! */
1126 if (TYPE_POINTER_TO (t))
1127 TYPE_POINTER_TO (t) = 0;
1136 get_object_reference (protocols)
1139 tree type_decl = lookup_name (objc_id_id);
1142 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
1144 type = TREE_TYPE (type_decl);
1145 if (TYPE_MAIN_VARIANT (type) != id_type)
1146 warning ("Unexpected type for `id' (%s)",
1147 gen_declaration (type, errbuf));
1150 fatal ("Undefined type `id', please import <objc/objc.h>");
1152 /* This clause creates a new pointer type that is qualified with
1153 the protocol specification...this info is used later to do more
1154 elaborate type checking. */
1158 tree t, m = TYPE_MAIN_VARIANT (type);
1160 t = copy_node (type);
1161 TYPE_BINFO (t) = make_tree_vec (2);
1163 /* Add this type to the chain of variants of TYPE. */
1164 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1165 TYPE_NEXT_VARIANT (m) = t;
1167 /* Look up protocols...and install in lang specific list */
1168 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1170 /* This forces a new pointer type to be created later
1171 (in build_pointer_type)...so that the new template
1172 we just created will actually be used...what a hack! */
1173 if (TYPE_POINTER_TO (t))
1174 TYPE_POINTER_TO (t) = NULL;
1182 lookup_and_install_protocols (protocols)
1187 tree return_value = protocols;
1189 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1191 tree ident = TREE_VALUE (proto);
1192 tree p = lookup_protocol (ident);
1196 error ("Cannot find protocol declaration for `%s'",
1197 IDENTIFIER_POINTER (ident));
1199 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1201 return_value = TREE_CHAIN (proto);
1205 /* Replace identifier with actual protocol node. */
1206 TREE_VALUE (proto) = p;
1211 return return_value;
1214 /* Create and push a decl for a built-in external variable or field NAME.
1216 TYPE is its data type. */
1219 create_builtin_decl (code, type, name)
1220 enum tree_code code;
1224 tree decl = build_decl (code, get_identifier (name), type);
1226 if (code == VAR_DECL)
1228 TREE_STATIC (decl) = 1;
1229 make_decl_rtl (decl, 0, 1);
1233 DECL_ARTIFICIAL (decl) = 1;
1237 /* Purpose: "play" parser, creating/installing representations
1238 of the declarations that are required by Objective-C.
1242 type_spec--------->sc_spec
1243 (tree_list) (tree_list)
1246 identifier_node identifier_node */
1249 synth_module_prologue ()
1254 /* Defined in `objc.h' */
1255 objc_object_id = get_identifier (TAG_OBJECT);
1257 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1259 id_type = build_pointer_type (objc_object_reference);
1261 objc_id_id = get_identifier (TYPE_ID);
1262 objc_class_id = get_identifier (TAG_CLASS);
1264 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1265 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1266 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1268 /* Declare type of selector-objects that represent an operation name. */
1270 #ifdef OBJC_INT_SELECTORS
1271 /* `unsigned int' */
1272 selector_type = unsigned_type_node;
1274 /* `struct objc_selector *' */
1276 = build_pointer_type (xref_tag (RECORD_TYPE,
1277 get_identifier (TAG_SELECTOR)));
1278 #endif /* not OBJC_INT_SELECTORS */
1280 /* Forward declare type, or else the prototype for msgSendSuper will
1283 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1284 get_identifier (TAG_SUPER)));
1287 /* id objc_msgSend (id, SEL, ...); */
1290 = build_function_type (id_type,
1291 tree_cons (NULL_TREE, id_type,
1292 tree_cons (NULL_TREE, selector_type,
1295 if (! flag_next_runtime)
1297 umsg_decl = build_decl (FUNCTION_DECL,
1298 get_identifier (TAG_MSGSEND), temp_type);
1299 DECL_EXTERNAL (umsg_decl) = 1;
1300 TREE_PUBLIC (umsg_decl) = 1;
1301 DECL_INLINE (umsg_decl) = 1;
1302 DECL_ARTIFICIAL (umsg_decl) = 1;
1304 if (flag_traditional && TAG_MSGSEND[0] != '_')
1305 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1307 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1308 pushdecl (umsg_decl);
1311 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1313 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1316 = build_function_type (id_type,
1317 tree_cons (NULL_TREE, super_p,
1318 tree_cons (NULL_TREE, selector_type,
1321 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1322 temp_type, 0, NOT_BUILT_IN, 0);
1324 /* id objc_getClass (const char *); */
1326 temp_type = build_function_type (id_type,
1327 tree_cons (NULL_TREE,
1328 const_string_type_node,
1329 tree_cons (NULL_TREE, void_type_node,
1333 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1335 /* id objc_getMetaClass (const char *); */
1337 objc_get_meta_class_decl
1338 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1340 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1342 if (! flag_next_runtime)
1344 if (flag_typed_selectors)
1346 /* Suppress outputting debug symbols, because
1347 dbxout_init hasn'r been called yet. */
1348 enum debug_info_type save_write_symbols = write_symbols;
1349 write_symbols = NO_DEBUG;
1351 build_selector_template ();
1352 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1354 write_symbols = save_write_symbols;
1357 temp_type = build_array_type (selector_type, NULL_TREE);
1359 layout_type (temp_type);
1360 UOBJC_SELECTOR_TABLE_decl
1361 = create_builtin_decl (VAR_DECL, temp_type,
1362 "_OBJC_SELECTOR_TABLE");
1364 /* Avoid warning when not sending messages. */
1365 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1368 generate_forward_declaration_to_string_table ();
1370 /* Forward declare constant_string_id and constant_string_type. */
1371 if (!constant_string_class_name)
1372 constant_string_class_name = STRING_OBJECT_CLASS_NAME;
1374 constant_string_id = get_identifier (constant_string_class_name);
1375 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1378 /* Custom build_string which sets TREE_TYPE! */
1381 my_build_string (len, str)
1386 tree a_string = build_string (len, str);
1388 /* Some code from combine_strings, which is local to c-parse.y. */
1389 if (TREE_TYPE (a_string) == int_array_type_node)
1392 TREE_TYPE (a_string)
1393 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1394 build_index_type (build_int_2 (len - 1, 0)));
1396 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1397 TREE_STATIC (a_string) = 1;
1402 /* Given a chain of STRING_CST's, build a static instance of
1403 NXConstanString which points at the concatenation of those strings.
1404 We place the string object in the __string_objects section of the
1405 __OBJC segment. The Objective-C runtime will initialize the isa
1406 pointers of the string objects to point at the NXConstandString class
1410 build_objc_string_object (strings)
1413 tree string, initlist, constructor;
1416 if (lookup_interface (constant_string_id) == NULL_TREE)
1418 error ("Cannot find interface declaration for `%s'",
1419 IDENTIFIER_POINTER (constant_string_id));
1420 return error_mark_node;
1423 add_class_reference (constant_string_id);
1425 string = combine_strings (strings);
1426 TREE_SET_CODE (string, STRING_CST);
1427 length = TREE_STRING_LENGTH (string) - 1;
1429 /* & ((NXConstantString) {0, string, length}) */
1431 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1433 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1435 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1436 constructor = build_constructor (constant_string_type, nreverse (initlist));
1438 if (!flag_next_runtime)
1441 = objc_add_static_instance (constructor, constant_string_type);
1444 return (build_unary_op (ADDR_EXPR, constructor, 1));
1447 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1450 objc_add_static_instance (constructor, class_decl)
1451 tree constructor, class_decl;
1453 static int num_static_inst;
1457 /* Find the list of static instances for the CLASS_DECL. Create one if
1459 for (chain = &objc_static_instances;
1460 *chain && TREE_VALUE (*chain) != class_decl;
1461 chain = &TREE_CHAIN (*chain));
1464 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1465 add_objc_string (TYPE_NAME (class_decl), class_names);
1468 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1469 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1470 DECL_COMMON (decl) = 1;
1471 TREE_STATIC (decl) = 1;
1472 DECL_ARTIFICIAL (decl) = 1;
1473 pushdecl_top_level (decl);
1474 rest_of_decl_compilation (decl, 0, 1, 0);
1476 /* Do this here so it gets output later instead of possibly
1477 inside something else we are writing. */
1478 DECL_INITIAL (decl) = constructor;
1480 /* Add the DECL to the head of this CLASS' list. */
1481 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1486 /* Build a static constant CONSTRUCTOR
1487 with type TYPE and elements ELTS. */
1490 build_constructor (type, elts)
1493 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1495 TREE_CONSTANT (constructor) = 1;
1496 TREE_STATIC (constructor) = 1;
1497 TREE_READONLY (constructor) = 1;
1502 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1504 /* Predefine the following data type:
1512 void *defs[cls_def_cnt + cat_def_cnt];
1516 build_objc_symtab_template ()
1518 tree field_decl, field_decl_chain, index;
1520 objc_symtab_template
1521 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1523 /* long sel_ref_cnt; */
1525 field_decl = create_builtin_decl (FIELD_DECL,
1526 long_integer_type_node,
1528 field_decl_chain = field_decl;
1532 field_decl = create_builtin_decl (FIELD_DECL,
1533 build_pointer_type (selector_type),
1535 chainon (field_decl_chain, field_decl);
1537 /* short cls_def_cnt; */
1539 field_decl = create_builtin_decl (FIELD_DECL,
1540 short_integer_type_node,
1542 chainon (field_decl_chain, field_decl);
1544 /* short cat_def_cnt; */
1546 field_decl = create_builtin_decl (FIELD_DECL,
1547 short_integer_type_node,
1549 chainon (field_decl_chain, field_decl);
1551 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1553 if (!flag_next_runtime)
1554 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1556 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1557 imp_count == 0 && cat_count == 0
1559 field_decl = create_builtin_decl (FIELD_DECL,
1560 build_array_type (ptr_type_node, index),
1562 chainon (field_decl_chain, field_decl);
1564 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1567 /* Create the initial value for the `defs' field of _objc_symtab.
1568 This is a CONSTRUCTOR. */
1571 init_def_list (type)
1574 tree expr, initlist = NULL_TREE;
1575 struct imp_entry *impent;
1578 for (impent = imp_list; impent; impent = impent->next)
1580 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1582 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1583 initlist = tree_cons (NULL_TREE, expr, initlist);
1588 for (impent = imp_list; impent; impent = impent->next)
1590 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1592 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1593 initlist = tree_cons (NULL_TREE, expr, initlist);
1597 if (!flag_next_runtime)
1599 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1602 if (static_instances_decl)
1603 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1605 expr = build_int_2 (0, 0);
1607 initlist = tree_cons (NULL_TREE, expr, initlist);
1610 return build_constructor (type, nreverse (initlist));
1613 /* Construct the initial value for all of _objc_symtab. */
1616 init_objc_symtab (type)
1621 /* sel_ref_cnt = { ..., 5, ... } */
1623 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1625 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1627 if (flag_next_runtime || ! sel_ref_chain)
1628 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1630 initlist = tree_cons (NULL_TREE,
1631 build_unary_op (ADDR_EXPR,
1632 UOBJC_SELECTOR_TABLE_decl, 1),
1635 /* cls_def_cnt = { ..., 5, ... } */
1637 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1639 /* cat_def_cnt = { ..., 5, ... } */
1641 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1643 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1645 if (imp_count || cat_count || static_instances_decl)
1648 tree field = TYPE_FIELDS (type);
1649 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1651 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1655 return build_constructor (type, nreverse (initlist));
1658 /* Push forward-declarations of all the categories
1659 so that init_def_list can use them in a CONSTRUCTOR. */
1662 forward_declare_categories ()
1664 struct imp_entry *impent;
1665 tree sav = implementation_context;
1667 for (impent = imp_list; impent; impent = impent->next)
1669 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1671 /* Set an invisible arg to synth_id_with_class_suffix. */
1672 implementation_context = impent->imp_context;
1674 = create_builtin_decl (VAR_DECL, objc_category_template,
1675 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1678 implementation_context = sav;
1681 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1682 and initialized appropriately. */
1685 generate_objc_symtab_decl ()
1689 if (!objc_category_template)
1690 build_category_template ();
1692 /* forward declare categories */
1694 forward_declare_categories ();
1696 if (!objc_symtab_template)
1697 build_objc_symtab_template ();
1699 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1701 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1702 tree_cons (NULL_TREE,
1703 objc_symtab_template, sc_spec),
1705 NULL_TREE, NULL_TREE);
1707 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1708 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1709 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1710 finish_decl (UOBJC_SYMBOLS_decl,
1711 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1716 init_module_descriptor (type)
1719 tree initlist, expr;
1721 /* version = { 1, ... } */
1723 expr = build_int_2 (OBJC_VERSION, 0);
1724 initlist = build_tree_list (NULL_TREE, expr);
1726 /* size = { ..., sizeof (struct objc_module), ... } */
1728 expr = size_in_bytes (objc_module_template);
1729 initlist = tree_cons (NULL_TREE, expr, initlist);
1731 /* name = { ..., "foo.m", ... } */
1733 expr = add_objc_string (get_identifier (input_filename), class_names);
1734 initlist = tree_cons (NULL_TREE, expr, initlist);
1736 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1738 if (UOBJC_SYMBOLS_decl)
1739 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1741 expr = build_int_2 (0, 0);
1742 initlist = tree_cons (NULL_TREE, expr, initlist);
1744 return build_constructor (type, nreverse (initlist));
1747 /* Write out the data structures to describe Objective C classes defined.
1748 If appropriate, compile and output a setup function to initialize them.
1749 Return a string which is the name of a function to call to initialize
1750 the Objective C data structures for this file (and perhaps for other files
1753 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1756 build_module_descriptor ()
1758 tree decl_specs, field_decl, field_decl_chain;
1760 objc_module_template
1761 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1765 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1766 field_decl = get_identifier ("version");
1768 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1769 field_decl_chain = field_decl;
1773 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1774 field_decl = get_identifier ("size");
1776 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1777 chainon (field_decl_chain, field_decl);
1781 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1782 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1784 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1785 chainon (field_decl_chain, field_decl);
1787 /* struct objc_symtab *symtab; */
1789 decl_specs = get_identifier (UTAG_SYMTAB);
1790 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1791 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1793 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1794 chainon (field_decl_chain, field_decl);
1796 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1798 /* Create an instance of "objc_module". */
1800 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1801 build_tree_list (NULL_TREE,
1802 ridpointers[(int) RID_STATIC]));
1804 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1805 decl_specs, 1, NULL_TREE, NULL_TREE);
1807 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1808 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1809 finish_decl (UOBJC_MODULES_decl,
1810 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1813 /* Mark the decl to avoid "defined but not used" warning. */
1814 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1816 /* Generate a constructor call for the module descriptor.
1817 This code was generated by reading the grammar rules
1818 of c-parse.in; Therefore, it may not be the most efficient
1819 way of generating the requisite code. */
1821 if (flag_next_runtime)
1825 tree parms, function_decl, decelerator, void_list_node_1;
1827 tree init_function_name = get_file_function_name ('I');
1829 /* Declare void __objc_execClass (void *); */
1831 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1833 = build_function_type (void_type_node,
1834 tree_cons (NULL_TREE, ptr_type_node,
1836 function_decl = build_decl (FUNCTION_DECL,
1837 get_identifier (TAG_EXECCLASS),
1839 DECL_EXTERNAL (function_decl) = 1;
1840 DECL_ARTIFICIAL (function_decl) = 1;
1841 TREE_PUBLIC (function_decl) = 1;
1843 pushdecl (function_decl);
1844 rest_of_decl_compilation (function_decl, 0, 0, 0);
1847 = build_tree_list (NULL_TREE,
1848 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1849 decelerator = build_function_call (function_decl, parms);
1851 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1853 start_function (void_list_node_1,
1854 build_parse_node (CALL_EXPR, init_function_name,
1855 /* This has the format of the output
1856 of get_parm_info. */
1857 tree_cons (NULL_TREE, NULL_TREE,
1860 NULL_TREE, NULL_TREE);
1861 #if 0 /* This should be turned back on later
1862 for the systems where collect is not needed. */
1863 /* Make these functions nonglobal
1864 so each file can use the same name. */
1865 TREE_PUBLIC (current_function_decl) = 0;
1867 TREE_USED (current_function_decl) = 1;
1868 store_parm_decls ();
1870 assemble_external (function_decl);
1871 c_expand_expr_stmt (decelerator);
1873 TREE_PUBLIC (current_function_decl) = 1;
1875 function_decl = current_function_decl;
1876 finish_function (0);
1878 /* Return the name of the constructor function. */
1879 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1883 /* extern const char _OBJC_STRINGS[]; */
1886 generate_forward_declaration_to_string_table ()
1888 tree sc_spec, decl_specs, expr_decl;
1890 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1891 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1894 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1896 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1899 /* Return the DECL of the string IDENT in the SECTION. */
1902 get_objc_string_decl (ident, section)
1904 enum string_section section;
1908 if (section == class_names)
1909 chain = class_names_chain;
1910 else if (section == meth_var_names)
1911 chain = meth_var_names_chain;
1912 else if (section == meth_var_types)
1913 chain = meth_var_types_chain;
1917 for (; chain != 0; chain = TREE_VALUE (chain))
1918 if (TREE_VALUE (chain) == ident)
1919 return (TREE_PURPOSE (chain));
1925 /* Output references to all statically allocated objects. Return the DECL
1926 for the array built. */
1929 generate_static_references ()
1931 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1932 tree class_name, class, decl, initlist;
1933 tree cl_chain, in_chain, type;
1934 int num_inst, num_class;
1937 if (flag_next_runtime)
1940 for (cl_chain = objc_static_instances, num_class = 0;
1941 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1943 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1944 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1946 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1947 ident = get_identifier (buf);
1949 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1950 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1951 build_tree_list (NULL_TREE,
1952 ridpointers[(int) RID_STATIC]));
1953 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1954 DECL_CONTEXT (decl) = 0;
1955 DECL_ARTIFICIAL (decl) = 1;
1957 /* Output {class_name, ...}. */
1958 class = TREE_VALUE (cl_chain);
1959 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1960 initlist = build_tree_list (NULL_TREE,
1961 build_unary_op (ADDR_EXPR, class_name, 1));
1963 /* Output {..., instance, ...}. */
1964 for (in_chain = TREE_PURPOSE (cl_chain);
1965 in_chain; in_chain = TREE_CHAIN (in_chain))
1967 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1968 initlist = tree_cons (NULL_TREE, expr, initlist);
1971 /* Output {..., NULL}. */
1972 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1974 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1975 finish_decl (decl, expr, NULL_TREE);
1976 TREE_USED (decl) = 1;
1978 type = build_array_type (build_pointer_type (void_type_node), 0);
1979 decl = build_decl (VAR_DECL, ident, type);
1980 make_decl_rtl (decl, 0, 1);
1981 TREE_USED (decl) = 1;
1983 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
1986 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
1987 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
1988 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1989 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1990 build_tree_list (NULL_TREE,
1991 ridpointers[(int) RID_STATIC]));
1992 static_instances_decl
1993 = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1994 TREE_USED (static_instances_decl) = 1;
1995 DECL_CONTEXT (static_instances_decl) = 0;
1996 DECL_ARTIFICIAL (static_instances_decl) = 1;
1997 expr = build_constructor (TREE_TYPE (static_instances_decl),
1999 finish_decl (static_instances_decl, expr, NULL_TREE);
2002 /* Output all strings. */
2007 tree sc_spec, decl_specs, expr_decl;
2008 tree chain, string_expr;
2011 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2013 string = TREE_VALUE (chain);
2014 decl = TREE_PURPOSE (chain);
2016 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2017 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2018 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2019 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2020 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2021 IDENTIFIER_POINTER (string));
2022 finish_decl (decl, string_expr, NULL_TREE);
2025 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2027 string = TREE_VALUE (chain);
2028 decl = TREE_PURPOSE (chain);
2030 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2031 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2032 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2033 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2034 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2035 IDENTIFIER_POINTER (string));
2036 finish_decl (decl, string_expr, NULL_TREE);
2039 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2041 string = TREE_VALUE (chain);
2042 decl = TREE_PURPOSE (chain);
2044 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2045 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2046 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2047 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2048 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2049 IDENTIFIER_POINTER (string));
2050 finish_decl (decl, string_expr, NULL_TREE);
2055 build_selector_reference_decl ()
2061 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
2063 ident = get_identifier (buf);
2065 decl = build_decl (VAR_DECL, ident, selector_type);
2066 DECL_EXTERNAL (decl) = 1;
2067 TREE_PUBLIC (decl) = 1;
2068 TREE_USED (decl) = 1;
2069 TREE_READONLY (decl) = 1;
2070 DECL_ARTIFICIAL (decl) = 1;
2071 DECL_CONTEXT (decl) = 0;
2073 make_decl_rtl (decl, 0, 1);
2074 pushdecl_top_level (decl);
2079 /* Just a handy wrapper for add_objc_string. */
2082 build_selector (ident)
2085 tree expr = add_objc_string (ident, meth_var_names);
2086 if (flag_typed_selectors)
2089 return build_c_cast (selector_type, expr); /* cast! */
2092 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2093 The cast stops the compiler from issuing the following message:
2094 grok.m: warning: initialization of non-const * pointer from const *
2095 grok.m: warning: initialization between incompatible pointer types. */
2099 build_msg_pool_reference (offset)
2102 tree expr = build_int_2 (offset, 0);
2105 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
2106 expr = build_unary_op (ADDR_EXPR, expr, 0);
2108 cast = build_tree_list (build_tree_list (NULL_TREE,
2109 ridpointers[(int) RID_CHAR]),
2110 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
2111 TREE_TYPE (expr) = groktypename (cast);
2116 init_selector (offset)
2119 tree expr = build_msg_pool_reference (offset);
2120 TREE_TYPE (expr) = selector_type;
2126 build_selector_translation_table ()
2128 tree sc_spec, decl_specs;
2129 tree chain, initlist = NULL_TREE;
2131 tree decl = NULL_TREE, var_decl, name;
2133 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2137 expr = build_selector (TREE_VALUE (chain));
2139 if (flag_next_runtime)
2141 name = DECL_NAME (TREE_PURPOSE (chain));
2143 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2145 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2146 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2150 /* The `decl' that is returned from start_decl is the one that we
2151 forward declared in `build_selector_reference' */
2152 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2155 /* add one for the '\0' character */
2156 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2158 if (flag_next_runtime)
2159 finish_decl (decl, expr, NULL_TREE);
2162 if (flag_typed_selectors)
2164 tree eltlist = NULL_TREE;
2165 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2166 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2167 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2168 expr = build_constructor (objc_selector_template,
2169 nreverse (eltlist));
2171 initlist = tree_cons (NULL_TREE, expr, initlist);
2176 if (! flag_next_runtime)
2178 /* Cause the variable and its initial value to be actually output. */
2179 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2180 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2181 /* NULL terminate the list and fix the decl for output. */
2182 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2183 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2184 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2185 nreverse (initlist));
2186 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2187 current_function_decl = NULL_TREE;
2192 get_proto_encoding (proto)
2200 if (! METHOD_ENCODING (proto))
2202 tmp_decl = build_tmp_function_decl ();
2203 hack_method_prototype (proto, tmp_decl);
2204 encoding = encode_method_prototype (proto, tmp_decl);
2205 METHOD_ENCODING (proto) = encoding;
2208 encoding = METHOD_ENCODING (proto);
2210 return add_objc_string (encoding, meth_var_types);
2213 return build_int_2 (0, 0);
2216 /* sel_ref_chain is a list whose "value" fields will be instances of
2217 identifier_node that represent the selector. */
2220 build_typed_selector_reference (ident, proto)
2223 tree *chain = &sel_ref_chain;
2229 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2230 goto return_at_index;
2233 chain = &TREE_CHAIN (*chain);
2236 *chain = tree_cons (proto, ident, NULL_TREE);
2239 expr = build_unary_op (ADDR_EXPR,
2240 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2241 build_int_2 (index, 0)),
2243 return build_c_cast (selector_type, expr);
2247 build_selector_reference (ident)
2250 tree *chain = &sel_ref_chain;
2256 if (TREE_VALUE (*chain) == ident)
2257 return (flag_next_runtime
2258 ? TREE_PURPOSE (*chain)
2259 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2260 build_int_2 (index, 0)));
2263 chain = &TREE_CHAIN (*chain);
2266 expr = build_selector_reference_decl ();
2268 *chain = tree_cons (expr, ident, NULL_TREE);
2270 return (flag_next_runtime
2272 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2273 build_int_2 (index, 0)));
2277 build_class_reference_decl ()
2283 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2285 ident = get_identifier (buf);
2287 decl = build_decl (VAR_DECL, ident, objc_class_type);
2288 DECL_EXTERNAL (decl) = 1;
2289 TREE_PUBLIC (decl) = 1;
2290 TREE_USED (decl) = 1;
2291 TREE_READONLY (decl) = 1;
2292 DECL_CONTEXT (decl) = 0;
2293 DECL_ARTIFICIAL (decl) = 1;
2295 make_decl_rtl (decl, 0, 1);
2296 pushdecl_top_level (decl);
2301 /* Create a class reference, but don't create a variable to reference
2305 add_class_reference (ident)
2310 if ((chain = cls_ref_chain))
2315 if (ident == TREE_VALUE (chain))
2319 chain = TREE_CHAIN (chain);
2323 /* Append to the end of the list */
2324 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2327 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2330 /* Get a class reference, creating it if necessary. Also create the
2331 reference variable. */
2334 get_class_reference (ident)
2337 if (flag_next_runtime)
2342 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2343 if (TREE_VALUE (*chain) == ident)
2345 if (! TREE_PURPOSE (*chain))
2346 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2348 return TREE_PURPOSE (*chain);
2351 decl = build_class_reference_decl ();
2352 *chain = tree_cons (decl, ident, NULL_TREE);
2359 add_class_reference (ident);
2361 params = build_tree_list (NULL_TREE,
2362 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2363 IDENTIFIER_POINTER (ident)));
2365 assemble_external (objc_get_class_decl);
2366 return build_function_call (objc_get_class_decl, params);
2370 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2371 of identifier_node that represent the selector. It returns the
2372 offset of the selector from the beginning of the _OBJC_STRINGS
2373 pool. This offset is typically used by init_selector during code
2376 For each string section we have a chain which maps identifier nodes
2377 to decls for the strings. */
2380 add_objc_string (ident, section)
2382 enum string_section section;
2386 if (section == class_names)
2387 chain = &class_names_chain;
2388 else if (section == meth_var_names)
2389 chain = &meth_var_names_chain;
2390 else if (section == meth_var_types)
2391 chain = &meth_var_types_chain;
2397 if (TREE_VALUE (*chain) == ident)
2398 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2400 chain = &TREE_CHAIN (*chain);
2403 decl = build_objc_string_decl (section);
2405 *chain = tree_cons (decl, ident, NULL_TREE);
2407 return build_unary_op (ADDR_EXPR, decl, 1);
2411 build_objc_string_decl (section)
2412 enum string_section section;
2416 static int class_names_idx = 0;
2417 static int meth_var_names_idx = 0;
2418 static int meth_var_types_idx = 0;
2420 if (section == class_names)
2421 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2422 else if (section == meth_var_names)
2423 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2424 else if (section == meth_var_types)
2425 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2427 ident = get_identifier (buf);
2429 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2430 DECL_EXTERNAL (decl) = 1;
2431 TREE_PUBLIC (decl) = 1;
2432 TREE_USED (decl) = 1;
2433 TREE_READONLY (decl) = 1;
2434 TREE_CONSTANT (decl) = 1;
2435 DECL_CONTEXT (decl) = 0;
2436 DECL_ARTIFICIAL (decl) = 1;
2438 make_decl_rtl (decl, 0, 1);
2439 pushdecl_top_level (decl);
2446 objc_declare_alias (alias_ident, class_ident)
2450 if (is_class_name (class_ident) != class_ident)
2451 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2452 else if (is_class_name (alias_ident))
2453 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2455 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2459 objc_declare_class (ident_list)
2464 for (list = ident_list; list; list = TREE_CHAIN (list))
2466 tree ident = TREE_VALUE (list);
2469 if ((decl = lookup_name (ident)))
2471 error ("`%s' redeclared as different kind of symbol",
2472 IDENTIFIER_POINTER (ident));
2473 error_with_decl (decl, "previous declaration of `%s'");
2476 if (! is_class_name (ident))
2478 tree record = xref_tag (RECORD_TYPE, ident);
2479 TREE_STATIC_TEMPLATE (record) = 1;
2480 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2486 is_class_name (ident)
2491 if (lookup_interface (ident))
2494 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2496 if (ident == TREE_VALUE (chain))
2500 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2502 if (ident == TREE_VALUE (chain))
2503 return TREE_PURPOSE (chain);
2510 lookup_interface (ident)
2515 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2517 if (ident == CLASS_NAME (chain))
2524 objc_copy_list (list, head)
2528 tree newlist = NULL_TREE, tail = NULL_TREE;
2532 tail = copy_node (list);
2534 /* The following statement fixes a bug when inheriting instance
2535 variables that are declared to be bitfields. finish_struct
2536 expects to find the width of the bitfield in DECL_INITIAL. */
2537 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2538 DECL_INITIAL (tail) = DECL_SIZE (tail);
2540 newlist = chainon (newlist, tail);
2541 list = TREE_CHAIN (list);
2548 /* Used by: build_private_template, get_class_ivars, and
2549 continue_class. COPY is 1 when called from @defs. In this case
2550 copy all fields. Otherwise don't copy leaf ivars since we rely on
2551 them being side-effected exactly once by finish_struct. */
2554 build_ivar_chain (interface, copy)
2558 tree my_name, super_name, ivar_chain;
2560 my_name = CLASS_NAME (interface);
2561 super_name = CLASS_SUPER_NAME (interface);
2563 /* Possibly copy leaf ivars. */
2565 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2567 ivar_chain = CLASS_IVARS (interface);
2572 tree super_interface = lookup_interface (super_name);
2574 if (!super_interface)
2576 /* fatal did not work with 2 args...should fix */
2577 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2578 IDENTIFIER_POINTER (super_name),
2579 IDENTIFIER_POINTER (my_name));
2580 exit (FATAL_EXIT_CODE);
2583 if (super_interface == interface)
2585 fatal ("Circular inheritance in interface declaration for `%s'",
2586 IDENTIFIER_POINTER (super_name));
2589 interface = super_interface;
2590 my_name = CLASS_NAME (interface);
2591 super_name = CLASS_SUPER_NAME (interface);
2593 op1 = CLASS_IVARS (interface);
2596 tree head, tail = objc_copy_list (op1, &head);
2598 /* Prepend super class ivars...make a copy of the list, we
2599 do not want to alter the original. */
2600 TREE_CHAIN (tail) = ivar_chain;
2607 /* struct <classname> {
2608 struct objc_class *isa;
2613 build_private_template (class)
2618 if (CLASS_STATIC_TEMPLATE (class))
2620 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2621 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2625 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2627 ivar_context = build_ivar_chain (class, 0);
2629 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2631 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2633 /* mark this record as class template - for class type checking */
2634 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2638 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2640 build1 (INDIRECT_REF, NULL_TREE,
2643 return ivar_context;
2646 /* Begin code generation for protocols... */
2648 /* struct objc_protocol {
2649 char *protocol_name;
2650 struct objc_protocol **protocol_list;
2651 struct objc_method_desc *instance_methods;
2652 struct objc_method_desc *class_methods;
2656 build_protocol_template ()
2658 tree decl_specs, field_decl, field_decl_chain;
2661 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2663 /* struct objc_class *isa; */
2665 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2666 get_identifier (UTAG_CLASS)));
2667 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2669 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2670 field_decl_chain = field_decl;
2672 /* char *protocol_name; */
2674 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2676 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2678 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2679 chainon (field_decl_chain, field_decl);
2681 /* struct objc_protocol **protocol_list; */
2683 decl_specs = build_tree_list (NULL_TREE, template);
2685 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2686 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2688 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2689 chainon (field_decl_chain, field_decl);
2691 /* struct objc_method_list *instance_methods; */
2694 = build_tree_list (NULL_TREE,
2695 xref_tag (RECORD_TYPE,
2696 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2698 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2700 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2701 chainon (field_decl_chain, field_decl);
2703 /* struct objc_method_list *class_methods; */
2706 = build_tree_list (NULL_TREE,
2707 xref_tag (RECORD_TYPE,
2708 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2710 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2712 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2713 chainon (field_decl_chain, field_decl);
2715 return finish_struct (template, field_decl_chain, NULL_TREE);
2719 build_descriptor_table_initializer (type, entries)
2723 tree initlist = NULL_TREE;
2727 tree eltlist = NULL_TREE;
2730 = tree_cons (NULL_TREE,
2731 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2733 = tree_cons (NULL_TREE,
2734 add_objc_string (METHOD_ENCODING (entries),
2739 = tree_cons (NULL_TREE,
2740 build_constructor (type, nreverse (eltlist)), initlist);
2742 entries = TREE_CHAIN (entries);
2746 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2749 /* struct objc_method_prototype_list {
2751 struct objc_method_prototype {
2758 build_method_prototype_list_template (list_type, size)
2762 tree objc_ivar_list_record;
2763 tree decl_specs, field_decl, field_decl_chain;
2765 /* Generate an unnamed struct definition. */
2767 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2769 /* int method_count; */
2771 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2772 field_decl = get_identifier ("method_count");
2775 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2776 field_decl_chain = field_decl;
2778 /* struct objc_method method_list[]; */
2780 decl_specs = build_tree_list (NULL_TREE, list_type);
2781 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2782 build_int_2 (size, 0));
2785 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2786 chainon (field_decl_chain, field_decl);
2788 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2790 return objc_ivar_list_record;
2794 build_method_prototype_template ()
2797 tree decl_specs, field_decl, field_decl_chain;
2800 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2802 #ifdef OBJC_INT_SELECTORS
2803 /* unsigned int _cmd; */
2805 = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2806 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2807 field_decl = get_identifier ("_cmd");
2808 #else /* OBJC_INT_SELECTORS */
2809 /* struct objc_selector *_cmd; */
2810 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2811 get_identifier (TAG_SELECTOR)), NULL_TREE);
2812 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2813 #endif /* OBJC_INT_SELECTORS */
2816 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2817 field_decl_chain = field_decl;
2819 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2821 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2823 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2824 chainon (field_decl_chain, field_decl);
2826 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2828 return proto_record;
2831 /* True if last call to forwarding_offset yielded a register offset. */
2832 static int offset_is_register;
2835 forwarding_offset (parm)
2838 int offset_in_bytes;
2840 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2842 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2844 /* ??? Here we assume that the parm address is indexed
2845 off the frame pointer or arg pointer.
2846 If that is not true, we produce meaningless results,
2847 but do not crash. */
2848 if (GET_CODE (addr) == PLUS
2849 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2850 offset_in_bytes = INTVAL (XEXP (addr, 1));
2852 offset_in_bytes = 0;
2854 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2855 offset_is_register = 0;
2857 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2859 int regno = REGNO (DECL_INCOMING_RTL (parm));
2860 offset_in_bytes = apply_args_register_offset (regno);
2861 offset_is_register = 1;
2866 /* This is the case where the parm is passed as an int or double
2867 and it is converted to a char, short or float and stored back
2868 in the parmlist. In this case, describe the parm
2869 with the variable's declared type, and adjust the address
2870 if the least significant bytes (which we are using) are not
2872 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2873 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2874 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2876 return offset_in_bytes;
2880 encode_method_prototype (method_decl, func_decl)
2887 HOST_WIDE_INT max_parm_end = 0;
2891 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2892 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2895 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2896 obstack_object_size (&util_obstack),
2897 OBJC_ENCODE_INLINE_DEFS);
2900 for (parms = DECL_ARGUMENTS (func_decl); parms;
2901 parms = TREE_CHAIN (parms))
2903 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2904 + int_size_in_bytes (TREE_TYPE (parms)));
2906 if (!offset_is_register && max_parm_end < parm_end)
2907 max_parm_end = parm_end;
2910 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2912 sprintf (buf, "%d", stack_size);
2913 obstack_grow (&util_obstack, buf, strlen (buf));
2915 user_args = METHOD_SEL_ARGS (method_decl);
2917 /* Argument types. */
2918 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2919 parms = TREE_CHAIN (parms), i++)
2921 /* Process argument qualifiers for user supplied arguments. */
2924 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2925 user_args = TREE_CHAIN (user_args);
2929 encode_type (TREE_TYPE (parms),
2930 obstack_object_size (&util_obstack),
2931 OBJC_ENCODE_INLINE_DEFS);
2933 /* Compute offset. */
2934 sprintf (buf, "%d", forwarding_offset (parms));
2936 /* Indicate register. */
2937 if (offset_is_register)
2938 obstack_1grow (&util_obstack, '+');
2940 obstack_grow (&util_obstack, buf, strlen (buf));
2943 obstack_1grow (&util_obstack, '\0');
2944 result = get_identifier (obstack_finish (&util_obstack));
2945 obstack_free (&util_obstack, util_firstobj);
2950 generate_descriptor_table (type, name, size, list, proto)
2957 tree sc_spec, decl_specs, decl, initlist;
2959 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2960 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2962 decl = start_decl (synth_id_with_class_suffix (name, proto),
2963 decl_specs, 1, NULL_TREE, NULL_TREE);
2965 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2966 initlist = tree_cons (NULL_TREE, list, initlist);
2968 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2975 generate_method_descriptors (protocol) /* generate_dispatch_tables */
2978 static tree objc_method_prototype_template;
2979 tree initlist, chain, method_list_template;
2980 tree cast, variable_length_type;
2983 if (!objc_method_prototype_template)
2985 objc_method_prototype_template = build_method_prototype_template ();
2986 ggc_add_tree_root (&objc_method_prototype_template, 1);
2989 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2990 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
2992 variable_length_type = groktypename (cast);
2994 chain = PROTOCOL_CLS_METHODS (protocol);
2997 size = list_length (chain);
2999 method_list_template
3000 = build_method_prototype_list_template (objc_method_prototype_template,
3004 = build_descriptor_table_initializer (objc_method_prototype_template,
3007 UOBJC_CLASS_METHODS_decl
3008 = generate_descriptor_table (method_list_template,
3009 "_OBJC_PROTOCOL_CLASS_METHODS",
3010 size, initlist, protocol);
3011 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3014 UOBJC_CLASS_METHODS_decl = 0;
3016 chain = PROTOCOL_NST_METHODS (protocol);
3019 size = list_length (chain);
3021 method_list_template
3022 = build_method_prototype_list_template (objc_method_prototype_template,
3025 = build_descriptor_table_initializer (objc_method_prototype_template,
3028 UOBJC_INSTANCE_METHODS_decl
3029 = generate_descriptor_table (method_list_template,
3030 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3031 size, initlist, protocol);
3032 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3035 UOBJC_INSTANCE_METHODS_decl = 0;
3039 build_tmp_function_decl ()
3041 tree decl_specs, expr_decl, parms;
3045 /* struct objc_object *objc_xxx (id, SEL, ...); */
3047 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3048 push_parm_decl (build_tree_list
3049 (build_tree_list (decl_specs,
3050 build1 (INDIRECT_REF, NULL_TREE,
3052 build_tree_list (NULL_TREE, NULL_TREE)));
3054 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3055 get_identifier (TAG_SELECTOR)));
3056 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
3058 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
3059 build_tree_list (NULL_TREE, NULL_TREE)));
3060 parms = get_parm_info (0);
3063 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3064 sprintf (buffer, "__objc_tmp_%x", xxx++);
3065 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
3066 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
3068 return define_decl (expr_decl, decl_specs);
3072 hack_method_prototype (nst_methods, tmp_decl)
3079 /* Hack to avoid problem with static typing of self arg. */
3080 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
3081 start_method_def (nst_methods);
3082 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
3084 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
3085 parms = get_parm_info (0); /* we have a `, ...' */
3087 parms = get_parm_info (1); /* place a `void_at_end' */
3089 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3091 /* Usually called from store_parm_decls -> init_function_start. */
3093 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
3094 current_function_decl = tmp_decl;
3097 /* Code taken from start_function. */
3098 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3099 /* Promote the value to int before returning it. */
3100 if (TREE_CODE (restype) == INTEGER_TYPE
3101 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3102 restype = integer_type_node;
3103 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3106 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3107 DECL_CONTEXT (parm) = tmp_decl;
3109 init_function_start (tmp_decl, "objc-act", 0);
3111 /* Typically called from expand_function_start for function definitions. */
3112 assign_parms (tmp_decl);
3114 /* install return type */
3115 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3120 generate_protocol_references (plist)
3125 /* Forward declare protocols referenced. */
3126 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3128 tree proto = TREE_VALUE (lproto);
3130 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3131 && PROTOCOL_NAME (proto))
3133 if (! PROTOCOL_FORWARD_DECL (proto))
3134 build_protocol_reference (proto);
3136 if (PROTOCOL_LIST (proto))
3137 generate_protocol_references (PROTOCOL_LIST (proto));
3143 generate_protocols ()
3145 tree p, tmp_decl, encoding;
3146 tree sc_spec, decl_specs, decl;
3147 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3150 tmp_decl = build_tmp_function_decl ();
3152 if (! objc_protocol_template)
3153 objc_protocol_template = build_protocol_template ();
3155 /* If a protocol was directly referenced, pull in indirect references. */
3156 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3157 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3158 generate_protocol_references (PROTOCOL_LIST (p));
3160 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3162 tree nst_methods = PROTOCOL_NST_METHODS (p);
3163 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3165 /* If protocol wasn't referenced, don't generate any code. */
3166 if (! PROTOCOL_FORWARD_DECL (p))
3169 /* Make sure we link in the Protocol class. */
3170 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3174 if (! METHOD_ENCODING (nst_methods))
3176 hack_method_prototype (nst_methods, tmp_decl);
3177 encoding = encode_method_prototype (nst_methods, tmp_decl);
3178 METHOD_ENCODING (nst_methods) = encoding;
3180 nst_methods = TREE_CHAIN (nst_methods);
3185 if (! METHOD_ENCODING (cls_methods))
3187 hack_method_prototype (cls_methods, tmp_decl);
3188 encoding = encode_method_prototype (cls_methods, tmp_decl);
3189 METHOD_ENCODING (cls_methods) = encoding;
3192 cls_methods = TREE_CHAIN (cls_methods);
3194 generate_method_descriptors (p);
3196 if (PROTOCOL_LIST (p))
3197 refs_decl = generate_protocol_list (p);
3201 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3203 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3205 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3207 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3208 decl_specs, 1, NULL_TREE, NULL_TREE);
3210 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3216 (build_tree_list (build_tree_list (NULL_TREE,
3217 objc_protocol_template),
3218 build1 (INDIRECT_REF, NULL_TREE,
3219 build1 (INDIRECT_REF, NULL_TREE,
3222 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3223 TREE_TYPE (refs_expr) = cast_type2;
3226 refs_expr = build_int_2 (0, 0);
3228 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3229 by generate_method_descriptors, which is called above. */
3230 initlist = build_protocol_initializer (TREE_TYPE (decl),
3231 protocol_name_expr, refs_expr,
3232 UOBJC_INSTANCE_METHODS_decl,
3233 UOBJC_CLASS_METHODS_decl);
3234 finish_decl (decl, initlist, NULL_TREE);
3236 /* Mark the decl as used to avoid "defined but not used" warning. */
3237 TREE_USED (decl) = 1;
3242 build_protocol_initializer (type, protocol_name, protocol_list,
3243 instance_methods, class_methods)
3247 tree instance_methods;
3250 tree initlist = NULL_TREE, expr;
3253 cast_type = groktypename
3255 (build_tree_list (NULL_TREE,
3256 xref_tag (RECORD_TYPE,
3257 get_identifier (UTAG_CLASS))),
3258 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3260 /* Filling the "isa" in with one allows the runtime system to
3261 detect that the version change...should remove before final release. */
3263 expr = build_int_2 (PROTOCOL_VERSION, 0);
3264 TREE_TYPE (expr) = cast_type;
3265 initlist = tree_cons (NULL_TREE, expr, initlist);
3266 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3267 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3269 if (!instance_methods)
3270 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3273 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3274 initlist = tree_cons (NULL_TREE, expr, initlist);
3278 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3281 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3282 initlist = tree_cons (NULL_TREE, expr, initlist);
3285 return build_constructor (type, nreverse (initlist));
3288 /* struct objc_category {
3289 char *category_name;
3291 struct objc_method_list *instance_methods;
3292 struct objc_method_list *class_methods;
3293 struct objc_protocol_list *protocols;
3297 build_category_template ()
3299 tree decl_specs, field_decl, field_decl_chain;
3301 objc_category_template = start_struct (RECORD_TYPE,
3302 get_identifier (UTAG_CATEGORY));
3303 /* char *category_name; */
3305 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3307 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3309 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3310 field_decl_chain = field_decl;
3312 /* char *class_name; */
3314 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3315 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3317 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3318 chainon (field_decl_chain, field_decl);
3320 /* struct objc_method_list *instance_methods; */
3322 decl_specs = build_tree_list (NULL_TREE,
3323 xref_tag (RECORD_TYPE,
3324 get_identifier (UTAG_METHOD_LIST)));
3326 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3328 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3329 chainon (field_decl_chain, field_decl);
3331 /* struct objc_method_list *class_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 ("class_methods"));
3339 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3340 chainon (field_decl_chain, field_decl);
3342 /* struct objc_protocol **protocol_list; */
3344 decl_specs = build_tree_list (NULL_TREE,
3345 xref_tag (RECORD_TYPE,
3346 get_identifier (UTAG_PROTOCOL)));
3348 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3349 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3351 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3352 chainon (field_decl_chain, field_decl);
3354 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3357 /* struct objc_selector {
3363 build_selector_template ()
3366 tree decl_specs, field_decl, field_decl_chain;
3368 objc_selector_template
3369 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3373 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3374 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3376 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3377 field_decl_chain = field_decl;
3379 /* char *sel_type; */
3381 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3382 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3384 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3385 chainon (field_decl_chain, field_decl);
3387 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3390 /* struct objc_class {
3391 struct objc_class *isa;
3392 struct objc_class *super_class;
3397 struct objc_ivar_list *ivars;
3398 struct objc_method_list *methods;
3399 if (flag_next_runtime)
3400 struct objc_cache *cache;
3402 struct sarray *dtable;
3403 struct objc_class *subclass_list;
3404 struct objc_class *sibling_class;
3406 struct objc_protocol_list *protocols;
3407 void *gc_object_type;
3411 build_class_template ()
3413 tree decl_specs, field_decl, field_decl_chain;
3416 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3418 /* struct objc_class *isa; */
3420 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3421 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3423 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3424 field_decl_chain = field_decl;
3426 /* struct objc_class *super_class; */
3428 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3430 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3432 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3433 chainon (field_decl_chain, field_decl);
3437 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3438 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3440 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3441 chainon (field_decl_chain, field_decl);
3445 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3446 field_decl = get_identifier ("version");
3448 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3449 chainon (field_decl_chain, field_decl);
3453 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3454 field_decl = get_identifier ("info");
3456 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3457 chainon (field_decl_chain, field_decl);
3459 /* long instance_size; */
3461 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3462 field_decl = get_identifier ("instance_size");
3464 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3465 chainon (field_decl_chain, field_decl);
3467 /* struct objc_ivar_list *ivars; */
3469 decl_specs = build_tree_list (NULL_TREE,
3470 xref_tag (RECORD_TYPE,
3471 get_identifier (UTAG_IVAR_LIST)));
3472 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3474 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3475 chainon (field_decl_chain, field_decl);
3477 /* struct objc_method_list *methods; */
3479 decl_specs = build_tree_list (NULL_TREE,
3480 xref_tag (RECORD_TYPE,
3481 get_identifier (UTAG_METHOD_LIST)));
3482 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3484 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3485 chainon (field_decl_chain, field_decl);
3487 if (flag_next_runtime)
3489 /* struct objc_cache *cache; */
3491 decl_specs = build_tree_list (NULL_TREE,
3492 xref_tag (RECORD_TYPE,
3493 get_identifier ("objc_cache")));
3494 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3495 field_decl = grokfield (input_filename, lineno, field_decl,
3496 decl_specs, NULL_TREE);
3497 chainon (field_decl_chain, field_decl);
3501 /* struct sarray *dtable; */
3503 decl_specs = build_tree_list (NULL_TREE,
3504 xref_tag (RECORD_TYPE,
3505 get_identifier ("sarray")));
3506 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3507 field_decl = grokfield (input_filename, lineno, field_decl,
3508 decl_specs, NULL_TREE);
3509 chainon (field_decl_chain, field_decl);
3511 /* struct objc_class *subclass_list; */
3513 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3515 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3516 field_decl = grokfield (input_filename, lineno, field_decl,
3517 decl_specs, NULL_TREE);
3518 chainon (field_decl_chain, field_decl);
3520 /* struct objc_class *sibling_class; */
3522 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3524 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3525 field_decl = grokfield (input_filename, lineno, field_decl,
3526 decl_specs, NULL_TREE);
3527 chainon (field_decl_chain, field_decl);
3530 /* struct objc_protocol **protocol_list; */
3532 decl_specs = build_tree_list (NULL_TREE,
3533 xref_tag (RECORD_TYPE,
3534 get_identifier (UTAG_PROTOCOL)));
3536 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3538 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3539 field_decl = grokfield (input_filename, lineno, field_decl,
3540 decl_specs, NULL_TREE);
3541 chainon (field_decl_chain, field_decl);
3545 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3546 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3548 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3549 chainon (field_decl_chain, field_decl);
3551 /* void *gc_object_type; */
3553 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3554 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3556 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3557 chainon (field_decl_chain, field_decl);
3559 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3562 /* Generate appropriate forward declarations for an implementation. */
3565 synth_forward_declarations ()
3567 tree sc_spec, decl_specs, an_id;
3569 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3571 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3573 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3574 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3575 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3576 TREE_USED (UOBJC_CLASS_decl) = 1;
3577 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3579 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3581 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3582 implementation_context);
3584 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3585 TREE_USED (UOBJC_METACLASS_decl) = 1;
3586 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3588 /* Pre-build the following entities - for speed/convenience. */
3590 an_id = get_identifier ("super_class");
3591 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3592 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3596 error_with_ivar (message, decl, rawdecl)
3597 const char *message;
3603 report_error_function (DECL_SOURCE_FILE (decl));
3605 fprintf (stderr, "%s:%d: ",
3606 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3607 memset (errbuf, 0, BUFSIZE);
3608 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3611 #define USERTYPE(t) \
3612 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3613 || TREE_CODE (t) == ENUMERAL_TYPE)
3616 check_ivars (inter, imp)
3620 tree intdecls = CLASS_IVARS (inter);
3621 tree impdecls = CLASS_IVARS (imp);
3622 tree rawintdecls = CLASS_RAW_IVARS (inter);
3623 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3629 if (intdecls == 0 && impdecls == 0)
3631 if (intdecls == 0 || impdecls == 0)
3633 error ("inconsistent instance variable specification");
3637 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3639 if (!comptypes (t1, t2))
3641 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3643 error_with_ivar ("conflicting instance variable type",
3644 impdecls, rawimpdecls);
3645 error_with_ivar ("previous declaration of",
3646 intdecls, rawintdecls);
3648 else /* both the type and the name don't match */
3650 error ("inconsistent instance variable specification");
3655 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3657 error_with_ivar ("conflicting instance variable name",
3658 impdecls, rawimpdecls);
3659 error_with_ivar ("previous declaration of",
3660 intdecls, rawintdecls);
3663 intdecls = TREE_CHAIN (intdecls);
3664 impdecls = TREE_CHAIN (impdecls);
3665 rawintdecls = TREE_CHAIN (rawintdecls);
3666 rawimpdecls = TREE_CHAIN (rawimpdecls);
3670 /* Set super_type to the data type node for struct objc_super *,
3671 first defining struct objc_super itself.
3672 This needs to be done just once per compilation. */
3675 build_super_template ()
3677 tree record, decl_specs, field_decl, field_decl_chain;
3679 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3681 /* struct objc_object *self; */
3683 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3684 field_decl = get_identifier ("self");
3685 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3686 field_decl = grokfield (input_filename, lineno,
3687 field_decl, decl_specs, NULL_TREE);
3688 field_decl_chain = field_decl;
3690 /* struct objc_class *class; */
3692 decl_specs = get_identifier (UTAG_CLASS);
3693 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3694 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3696 field_decl = grokfield (input_filename, lineno,
3697 field_decl, decl_specs, NULL_TREE);
3698 chainon (field_decl_chain, field_decl);
3700 finish_struct (record, field_decl_chain, NULL_TREE);
3702 /* `struct objc_super *' */
3703 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3705 build1 (INDIRECT_REF,
3706 NULL_TREE, NULL_TREE)));
3710 /* struct objc_ivar {
3717 build_ivar_template ()
3719 tree objc_ivar_id, objc_ivar_record;
3720 tree decl_specs, field_decl, field_decl_chain;
3722 objc_ivar_id = get_identifier (UTAG_IVAR);
3723 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3725 /* char *ivar_name; */
3727 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3728 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3730 field_decl = grokfield (input_filename, lineno, field_decl,
3731 decl_specs, NULL_TREE);
3732 field_decl_chain = field_decl;
3734 /* char *ivar_type; */
3736 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3737 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3739 field_decl = grokfield (input_filename, lineno, field_decl,
3740 decl_specs, NULL_TREE);
3741 chainon (field_decl_chain, field_decl);
3743 /* int ivar_offset; */
3745 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3746 field_decl = get_identifier ("ivar_offset");
3748 field_decl = grokfield (input_filename, lineno, field_decl,
3749 decl_specs, NULL_TREE);
3750 chainon (field_decl_chain, field_decl);
3752 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3754 return objc_ivar_record;
3759 struct objc_ivar ivar_list[ivar_count];
3763 build_ivar_list_template (list_type, size)
3767 tree objc_ivar_list_record;
3768 tree decl_specs, field_decl, field_decl_chain;
3770 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3772 /* int ivar_count; */
3774 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3775 field_decl = get_identifier ("ivar_count");
3777 field_decl = grokfield (input_filename, lineno, field_decl,
3778 decl_specs, NULL_TREE);
3779 field_decl_chain = field_decl;
3781 /* struct objc_ivar ivar_list[]; */
3783 decl_specs = build_tree_list (NULL_TREE, list_type);
3784 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3785 build_int_2 (size, 0));
3787 field_decl = grokfield (input_filename, lineno,
3788 field_decl, decl_specs, NULL_TREE);
3789 chainon (field_decl_chain, field_decl);
3791 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3793 return objc_ivar_list_record;
3799 struct objc_method method_list[method_count];
3803 build_method_list_template (list_type, size)
3807 tree objc_ivar_list_record;
3808 tree decl_specs, field_decl, field_decl_chain;
3810 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3812 /* int method_next; */
3817 xref_tag (RECORD_TYPE,
3818 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3820 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3821 field_decl = grokfield (input_filename, lineno, field_decl,
3822 decl_specs, NULL_TREE);
3823 field_decl_chain = field_decl;
3825 /* int method_count; */
3827 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3828 field_decl = get_identifier ("method_count");
3830 field_decl = grokfield (input_filename, lineno,
3831 field_decl, decl_specs, NULL_TREE);
3832 chainon (field_decl_chain, field_decl);
3834 /* struct objc_method method_list[]; */
3836 decl_specs = build_tree_list (NULL_TREE, list_type);
3837 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3838 build_int_2 (size, 0));
3840 field_decl = grokfield (input_filename, lineno,
3841 field_decl, decl_specs, NULL_TREE);
3842 chainon (field_decl_chain, field_decl);
3844 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3846 return objc_ivar_list_record;
3850 build_ivar_list_initializer (type, field_decl)
3854 tree initlist = NULL_TREE;
3858 tree ivar = NULL_TREE;
3861 if (DECL_NAME (field_decl))
3862 ivar = tree_cons (NULL_TREE,
3863 add_objc_string (DECL_NAME (field_decl),
3867 /* Unnamed bit-field ivar (yuck). */
3868 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3871 encode_field_decl (field_decl,
3872 obstack_object_size (&util_obstack),
3873 OBJC_ENCODE_DONT_INLINE_DEFS);
3875 /* Null terminate string. */
3876 obstack_1grow (&util_obstack, 0);
3880 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3883 obstack_free (&util_obstack, util_firstobj);
3886 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3887 initlist = tree_cons (NULL_TREE,
3888 build_constructor (type, nreverse (ivar)),
3891 field_decl = TREE_CHAIN (field_decl);
3895 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3899 generate_ivars_list (type, name, size, list)
3905 tree sc_spec, decl_specs, decl, initlist;
3907 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3908 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3910 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3911 decl_specs, 1, NULL_TREE, NULL_TREE);
3913 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3914 initlist = tree_cons (NULL_TREE, list, initlist);
3917 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3924 generate_ivar_lists ()
3926 tree initlist, ivar_list_template, chain;
3927 tree cast, variable_length_type;
3930 generating_instance_variables = 1;
3932 if (!objc_ivar_template)
3933 objc_ivar_template = build_ivar_template ();
3937 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3938 get_identifier (UTAG_IVAR_LIST))),
3940 variable_length_type = groktypename (cast);
3942 /* Only generate class variables for the root of the inheritance
3943 hierarchy since these will be the same for every class. */
3945 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3946 && (chain = TYPE_FIELDS (objc_class_template)))
3948 size = list_length (chain);
3950 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3951 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3953 UOBJC_CLASS_VARIABLES_decl
3954 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3956 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3959 UOBJC_CLASS_VARIABLES_decl = 0;
3961 chain = CLASS_IVARS (implementation_template);
3964 size = list_length (chain);
3965 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3966 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3968 UOBJC_INSTANCE_VARIABLES_decl
3969 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3971 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3974 UOBJC_INSTANCE_VARIABLES_decl = 0;
3976 generating_instance_variables = 0;
3980 build_dispatch_table_initializer (type, entries)
3984 tree initlist = NULL_TREE;
3988 tree elemlist = NULL_TREE;
3990 elemlist = tree_cons (NULL_TREE,
3991 build_selector (METHOD_SEL_NAME (entries)),
3994 elemlist = tree_cons (NULL_TREE,
3995 add_objc_string (METHOD_ENCODING (entries),
3999 elemlist = tree_cons (NULL_TREE,
4000 build_unary_op (ADDR_EXPR,
4001 METHOD_DEFINITION (entries), 1),
4004 initlist = tree_cons (NULL_TREE,
4005 build_constructor (type, nreverse (elemlist)),
4008 entries = TREE_CHAIN (entries);
4012 return build_constructor (build_array_type (type, 0), nreverse (initlist));
4015 /* To accomplish method prototyping without generating all kinds of
4016 inane warnings, the definition of the dispatch table entries were
4019 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4021 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4024 build_method_template ()
4027 tree decl_specs, field_decl, field_decl_chain;
4029 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4031 #ifdef OBJC_INT_SELECTORS
4032 /* unsigned int _cmd; */
4033 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
4035 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
4036 field_decl = get_identifier ("_cmd");
4037 #else /* not OBJC_INT_SELECTORS */
4038 /* struct objc_selector *_cmd; */
4039 decl_specs = tree_cons (NULL_TREE,
4040 xref_tag (RECORD_TYPE,
4041 get_identifier (TAG_SELECTOR)),
4043 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4044 #endif /* not OBJC_INT_SELECTORS */
4046 field_decl = grokfield (input_filename, lineno, field_decl,
4047 decl_specs, NULL_TREE);
4048 field_decl_chain = field_decl;
4050 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4051 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4052 get_identifier ("method_types"));
4053 field_decl = grokfield (input_filename, lineno, field_decl,
4054 decl_specs, NULL_TREE);
4055 chainon (field_decl_chain, field_decl);
4059 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4060 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4061 field_decl = grokfield (input_filename, lineno, field_decl,
4062 decl_specs, NULL_TREE);
4063 chainon (field_decl_chain, field_decl);
4065 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4072 generate_dispatch_table (type, name, size, list)
4078 tree sc_spec, decl_specs, decl, initlist;
4080 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4081 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4083 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
4084 decl_specs, 1, NULL_TREE, NULL_TREE);
4086 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4087 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4088 initlist = tree_cons (NULL_TREE, list, initlist);
4091 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4098 generate_dispatch_tables ()
4100 tree initlist, chain, method_list_template;
4101 tree cast, variable_length_type;
4104 if (!objc_method_template)
4105 objc_method_template = build_method_template ();
4109 (build_tree_list (NULL_TREE,
4110 xref_tag (RECORD_TYPE,
4111 get_identifier (UTAG_METHOD_LIST))),
4114 variable_length_type = groktypename (cast);
4116 chain = CLASS_CLS_METHODS (implementation_context);
4119 size = list_length (chain);
4121 method_list_template
4122 = build_method_list_template (objc_method_template, size);
4124 = build_dispatch_table_initializer (objc_method_template, chain);
4126 UOBJC_CLASS_METHODS_decl
4127 = generate_dispatch_table (method_list_template,
4128 ((TREE_CODE (implementation_context)
4129 == CLASS_IMPLEMENTATION_TYPE)
4130 ? "_OBJC_CLASS_METHODS"
4131 : "_OBJC_CATEGORY_CLASS_METHODS"),
4133 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4136 UOBJC_CLASS_METHODS_decl = 0;
4138 chain = CLASS_NST_METHODS (implementation_context);
4141 size = list_length (chain);
4143 method_list_template
4144 = build_method_list_template (objc_method_template, size);
4146 = build_dispatch_table_initializer (objc_method_template, chain);
4148 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4149 UOBJC_INSTANCE_METHODS_decl
4150 = generate_dispatch_table (method_list_template,
4151 "_OBJC_INSTANCE_METHODS",
4154 /* We have a category. */
4155 UOBJC_INSTANCE_METHODS_decl
4156 = generate_dispatch_table (method_list_template,
4157 "_OBJC_CATEGORY_INSTANCE_METHODS",
4159 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4162 UOBJC_INSTANCE_METHODS_decl = 0;
4166 generate_protocol_list (i_or_p)
4169 tree initlist, decl_specs, sc_spec;
4170 tree refs_decl, expr_decl, lproto, e, plist;
4174 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4175 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4176 plist = CLASS_PROTOCOL_LIST (i_or_p);
4177 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4178 plist = PROTOCOL_LIST (i_or_p);
4182 cast_type = groktypename
4184 (build_tree_list (NULL_TREE,
4185 xref_tag (RECORD_TYPE,
4186 get_identifier (UTAG_PROTOCOL))),
4187 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4190 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4191 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4192 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4195 /* Build initializer. */
4196 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4198 e = build_int_2 (size, 0);
4199 TREE_TYPE (e) = cast_type;
4200 initlist = tree_cons (NULL_TREE, e, initlist);
4202 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4204 tree pval = TREE_VALUE (lproto);
4206 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4207 && PROTOCOL_FORWARD_DECL (pval))
4209 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4210 initlist = tree_cons (NULL_TREE, e, initlist);
4214 /* static struct objc_protocol *refs[n]; */
4216 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4217 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4218 get_identifier (UTAG_PROTOCOL)),
4221 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4222 expr_decl = build_nt (ARRAY_REF,
4223 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4225 build_int_2 (size + 2, 0));
4226 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4227 expr_decl = build_nt (ARRAY_REF,
4228 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4230 build_int_2 (size + 2, 0));
4231 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4233 = build_nt (ARRAY_REF,
4234 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4236 build_int_2 (size + 2, 0));
4240 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4242 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
4244 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4245 nreverse (initlist)),
4252 build_category_initializer (type, cat_name, class_name,
4253 instance_methods, class_methods, protocol_list)
4257 tree instance_methods;
4261 tree initlist = NULL_TREE, expr;
4263 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4264 initlist = tree_cons (NULL_TREE, class_name, initlist);
4266 if (!instance_methods)
4267 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4270 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4271 initlist = tree_cons (NULL_TREE, expr, initlist);
4274 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4277 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4278 initlist = tree_cons (NULL_TREE, expr, initlist);
4281 /* protocol_list = */
4283 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4286 tree cast_type2 = groktypename
4288 (build_tree_list (NULL_TREE,
4289 xref_tag (RECORD_TYPE,
4290 get_identifier (UTAG_PROTOCOL))),
4291 build1 (INDIRECT_REF, NULL_TREE,
4292 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4294 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4295 TREE_TYPE (expr) = cast_type2;
4296 initlist = tree_cons (NULL_TREE, expr, initlist);
4299 return build_constructor (type, nreverse (initlist));
4302 /* struct objc_class {
4303 struct objc_class *isa;
4304 struct objc_class *super_class;
4309 struct objc_ivar_list *ivars;
4310 struct objc_method_list *methods;
4311 if (flag_next_runtime)
4312 struct objc_cache *cache;
4314 struct sarray *dtable;
4315 struct objc_class *subclass_list;
4316 struct objc_class *sibling_class;
4318 struct objc_protocol_list *protocols;
4319 void *gc_object_type;
4323 build_shared_structure_initializer (type, isa, super, name, size, status,
4324 dispatch_table, ivar_list, protocol_list)
4331 tree dispatch_table;
4335 tree initlist = NULL_TREE, expr;
4338 initlist = tree_cons (NULL_TREE, isa, initlist);
4341 initlist = tree_cons (NULL_TREE, super, initlist);
4344 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4347 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4350 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4352 /* instance_size = */
4353 initlist = tree_cons (NULL_TREE, size, initlist);
4355 /* objc_ivar_list = */
4357 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4360 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4361 initlist = tree_cons (NULL_TREE, expr, initlist);
4364 /* objc_method_list = */
4365 if (!dispatch_table)
4366 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4369 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4370 initlist = tree_cons (NULL_TREE, expr, initlist);
4373 if (flag_next_runtime)
4374 /* method_cache = */
4375 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4379 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4381 /* subclass_list = */
4382 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4384 /* sibling_class = */
4385 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4388 /* protocol_list = */
4389 if (! protocol_list)
4390 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4396 (build_tree_list (NULL_TREE,
4397 xref_tag (RECORD_TYPE,
4398 get_identifier (UTAG_PROTOCOL))),
4399 build1 (INDIRECT_REF, NULL_TREE,
4400 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4402 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4403 TREE_TYPE (expr) = cast_type2;
4404 initlist = tree_cons (NULL_TREE, expr, initlist);
4407 /* gc_object_type = NULL */
4408 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4410 return build_constructor (type, nreverse (initlist));
4413 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4416 generate_category (cat)
4419 tree sc_spec, decl_specs, decl;
4420 tree initlist, cat_name_expr, class_name_expr;
4421 tree protocol_decl, category;
4423 add_class_reference (CLASS_NAME (cat));
4424 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4426 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4428 category = CLASS_CATEGORY_LIST (implementation_template);
4430 /* find the category interface from the class it is associated with */
4433 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4435 category = CLASS_CATEGORY_LIST (category);
4438 if (category && CLASS_PROTOCOL_LIST (category))
4440 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4441 protocol_decl = generate_protocol_list (category);
4446 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4447 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4449 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4450 implementation_context),
4451 decl_specs, 1, NULL_TREE, NULL_TREE);
4453 initlist = build_category_initializer (TREE_TYPE (decl),
4454 cat_name_expr, class_name_expr,
4455 UOBJC_INSTANCE_METHODS_decl,
4456 UOBJC_CLASS_METHODS_decl,
4459 TREE_USED (decl) = 1;
4460 finish_decl (decl, initlist, NULL_TREE);
4463 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4464 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4467 generate_shared_structures ()
4469 tree sc_spec, decl_specs, decl;
4470 tree name_expr, super_expr, root_expr;
4471 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4472 tree cast_type, initlist, protocol_decl;
4474 my_super_id = CLASS_SUPER_NAME (implementation_template);
4477 add_class_reference (my_super_id);
4479 /* Compute "my_root_id" - this is required for code generation.
4480 the "isa" for all meta class structures points to the root of
4481 the inheritance hierarchy (e.g. "__Object")... */
4482 my_root_id = my_super_id;
4485 tree my_root_int = lookup_interface (my_root_id);
4487 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4488 my_root_id = CLASS_SUPER_NAME (my_root_int);
4495 /* No super class. */
4496 my_root_id = CLASS_NAME (implementation_template);
4499 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4500 objc_class_template),
4501 build1 (INDIRECT_REF,
4502 NULL_TREE, NULL_TREE)));
4504 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4507 /* Install class `isa' and `super' pointers at runtime. */
4510 super_expr = add_objc_string (my_super_id, class_names);
4511 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4514 super_expr = build_int_2 (0, 0);
4516 root_expr = add_objc_string (my_root_id, class_names);
4517 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4519 if (CLASS_PROTOCOL_LIST (implementation_template))
4521 generate_protocol_references
4522 (CLASS_PROTOCOL_LIST (implementation_template));
4523 protocol_decl = generate_protocol_list (implementation_template);
4528 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4530 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4531 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4533 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4534 NULL_TREE, NULL_TREE);
4537 = build_shared_structure_initializer
4539 root_expr, super_expr, name_expr,
4540 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4542 UOBJC_CLASS_METHODS_decl,
4543 UOBJC_CLASS_VARIABLES_decl,
4546 finish_decl (decl, initlist, NULL_TREE);
4548 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4550 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4551 NULL_TREE, NULL_TREE);
4554 = build_shared_structure_initializer
4556 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4557 super_expr, name_expr,
4558 convert (integer_type_node,
4559 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4560 (implementation_template))),
4562 UOBJC_INSTANCE_METHODS_decl,
4563 UOBJC_INSTANCE_VARIABLES_decl,
4566 finish_decl (decl, initlist, NULL_TREE);
4570 synth_id_with_class_suffix (preamble, ctxt)
4571 const char *preamble;
4575 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4576 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4578 const char *class_name
4579 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4580 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4581 sprintf (string, "%s_%s", preamble,
4582 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4584 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4585 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4587 /* We have a category. */
4588 const char *class_name
4589 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4590 const char *class_super_name
4591 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4592 string = (char *) alloca (strlen (preamble)
4593 + strlen (class_name)
4594 + strlen (class_super_name)
4596 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4598 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4600 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4602 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4603 sprintf (string, "%s_%s", preamble, protocol_name);
4608 return get_identifier (string);
4612 is_objc_type_qualifier (node)
4615 return (TREE_CODE (node) == IDENTIFIER_NODE
4616 && (node == ridpointers [(int) RID_CONST]
4617 || node == ridpointers [(int) RID_VOLATILE]
4618 || node == ridpointers [(int) RID_IN]
4619 || node == ridpointers [(int) RID_OUT]
4620 || node == ridpointers [(int) RID_INOUT]
4621 || node == ridpointers [(int) RID_BYCOPY]
4622 || node == ridpointers [(int) RID_BYREF]
4623 || node == ridpointers [(int) RID_ONEWAY]));
4626 /* If type is empty or only type qualifiers are present, add default
4627 type of id (otherwise grokdeclarator will default to int). */
4630 adjust_type_for_id_default (type)
4633 tree declspecs, chain;
4636 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4637 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4639 declspecs = TREE_PURPOSE (type);
4641 /* Determine if a typespec is present. */
4642 for (chain = declspecs;
4644 chain = TREE_CHAIN (chain))
4646 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4650 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4652 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4657 selector ':' '(' typename ')' identifier
4660 Transform an Objective-C keyword argument into
4661 the C equivalent parameter declarator.
4663 In: key_name, an "identifier_node" (optional).
4664 arg_type, a "tree_list" (optional).
4665 arg_name, an "identifier_node".
4667 Note: It would be really nice to strongly type the preceding
4668 arguments in the function prototype; however, then I
4669 could not use the "accessor" macros defined in "tree.h".
4671 Out: an instance of "keyword_decl". */
4674 build_keyword_decl (key_name, arg_type, arg_name)
4681 /* If no type is specified, default to "id". */
4682 arg_type = adjust_type_for_id_default (arg_type);
4684 keyword_decl = make_node (KEYWORD_DECL);
4686 TREE_TYPE (keyword_decl) = arg_type;
4687 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4688 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4690 return keyword_decl;
4693 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4696 build_keyword_selector (selector)
4700 tree key_chain, key_name;
4703 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4705 if (TREE_CODE (selector) == KEYWORD_DECL)
4706 key_name = KEYWORD_KEY_NAME (key_chain);
4707 else if (TREE_CODE (selector) == TREE_LIST)
4708 key_name = TREE_PURPOSE (key_chain);
4713 len += IDENTIFIER_LENGTH (key_name) + 1;
4715 /* Just a ':' arg. */
4719 buf = (char *)alloca (len + 1);
4720 memset (buf, 0, len + 1);
4722 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4724 if (TREE_CODE (selector) == KEYWORD_DECL)
4725 key_name = KEYWORD_KEY_NAME (key_chain);
4726 else if (TREE_CODE (selector) == TREE_LIST)
4727 key_name = TREE_PURPOSE (key_chain);
4732 strcat (buf, IDENTIFIER_POINTER (key_name));
4736 return get_identifier (buf);
4739 /* Used for declarations and definitions. */
4742 build_method_decl (code, ret_type, selector, add_args)
4743 enum tree_code code;
4750 /* If no type is specified, default to "id". */
4751 ret_type = adjust_type_for_id_default (ret_type);
4753 method_decl = make_node (code);
4754 TREE_TYPE (method_decl) = ret_type;
4756 /* If we have a keyword selector, create an identifier_node that
4757 represents the full selector name (`:' included)... */
4758 if (TREE_CODE (selector) == KEYWORD_DECL)
4760 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4761 METHOD_SEL_ARGS (method_decl) = selector;
4762 METHOD_ADD_ARGS (method_decl) = add_args;
4766 METHOD_SEL_NAME (method_decl) = selector;
4767 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4768 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4774 #define METHOD_DEF 0
4775 #define METHOD_REF 1
4777 /* Used by `build_message_expr' and `comp_method_types'. Return an
4778 argument list for method METH. CONTEXT is either METHOD_DEF or
4779 METHOD_REF, saying whether we are trying to define a method or call
4780 one. SUPERFLAG says this is for a send to super; this makes a
4781 difference for the NeXT calling sequence in which the lookup and
4782 the method call are done together. */
4785 get_arg_type_list (meth, context, superflag)
4792 /* Receiver type. */
4793 if (flag_next_runtime && superflag)
4794 arglist = build_tree_list (NULL_TREE, super_type);
4795 else if (context == METHOD_DEF)
4796 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4798 arglist = build_tree_list (NULL_TREE, id_type);
4800 /* Selector type - will eventually change to `int'. */
4801 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4803 /* Build a list of argument types. */
4804 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4806 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4807 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4810 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4811 /* We have a `, ...' immediately following the selector,
4812 finalize the arglist...simulate get_parm_info (0). */
4814 else if (METHOD_ADD_ARGS (meth))
4816 /* we have a variable length selector */
4817 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4818 chainon (arglist, add_arg_list);
4821 /* finalize the arglist...simulate get_parm_info (1) */
4822 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4828 check_duplicates (hsh)
4831 tree meth = NULL_TREE;
4839 /* We have two methods with the same name and different types. */
4841 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4843 warning ("multiple declarations for method `%s'",
4844 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4846 warn_with_method ("using", type, meth);
4847 for (loop = hsh->list; loop; loop = loop->next)
4848 warn_with_method ("also found", type, loop->value);
4854 /* If RECEIVER is a class reference, return the identifier node for the
4855 referenced class. RECEIVER is created by get_class_reference, so we
4856 check the exact form created depending on which runtimes are used. */
4859 receiver_is_class_object (receiver)
4862 tree chain, exp, arg;
4863 if (flag_next_runtime)
4865 /* The receiver is a variable created by build_class_reference_decl. */
4866 if (TREE_CODE (receiver) == VAR_DECL
4867 && TREE_TYPE (receiver) == objc_class_type)
4868 /* Look up the identifier. */
4869 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4870 if (TREE_PURPOSE (chain) == receiver)
4871 return TREE_VALUE (chain);
4875 /* The receiver is a function call that returns an id. Check if
4876 it is a call to objc_getClass, if so, pick up the class name. */
4877 if ((exp = TREE_OPERAND (receiver, 0))
4878 && TREE_CODE (exp) == ADDR_EXPR
4879 && (exp = TREE_OPERAND (exp, 0))
4880 && TREE_CODE (exp) == FUNCTION_DECL
4881 && exp == objc_get_class_decl
4882 /* we have a call to objc_getClass! */
4883 && (arg = TREE_OPERAND (receiver, 1))
4884 && TREE_CODE (arg) == TREE_LIST
4885 && (arg = TREE_VALUE (arg)))
4888 if (TREE_CODE (arg) == ADDR_EXPR
4889 && (arg = TREE_OPERAND (arg, 0))
4890 && TREE_CODE (arg) == STRING_CST)
4891 /* Finally, we have the class name. */
4892 return get_identifier (TREE_STRING_POINTER (arg));
4898 /* If we are currently building a message expr, this holds
4899 the identifier of the selector of the message. This is
4900 used when printing warnings about argument mismatches. */
4902 static tree building_objc_message_expr = 0;
4905 maybe_building_objc_message_expr ()
4907 return building_objc_message_expr;
4910 /* Construct an expression for sending a message.
4911 MESS has the object to send to in TREE_PURPOSE
4912 and the argument list (including selector) in TREE_VALUE.
4914 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4915 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4918 build_message_expr (mess)
4921 tree receiver = TREE_PURPOSE (mess);
4922 tree selector, self_object;
4923 tree rtype, sel_name;
4924 tree args = TREE_VALUE (mess);
4925 tree method_params = NULL_TREE;
4926 tree method_prototype = NULL_TREE;
4928 int statically_typed = 0, statically_allocated = 0;
4929 tree class_ident = 0;
4931 /* 1 if this is sending to the superclass. */
4934 if (TREE_CODE (receiver) == ERROR_MARK)
4935 return error_mark_node;
4937 /* Determine receiver type. */
4938 rtype = TREE_TYPE (receiver);
4939 super = IS_SUPER (rtype);
4943 if (TREE_STATIC_TEMPLATE (rtype))
4944 statically_allocated = 1;
4945 else if (TREE_CODE (rtype) == POINTER_TYPE
4946 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4947 statically_typed = 1;
4948 else if ((flag_next_runtime
4949 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4950 && (class_ident = receiver_is_class_object (receiver)))
4952 else if (! IS_ID (rtype)
4953 /* Allow any type that matches objc_class_type. */
4954 && ! comptypes (rtype, objc_class_type))
4956 memset (errbuf, 0, BUFSIZE);
4957 warning ("invalid receiver type `%s'",
4958 gen_declaration (rtype, errbuf));
4961 if (statically_allocated)
4962 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4964 /* Don't evaluate the receiver twice. */
4965 receiver = save_expr (receiver);
4966 self_object = receiver;
4969 /* If sending to `super', use current self as the object. */
4970 self_object = self_decl;
4972 /* Obtain the full selector name. */
4974 if (TREE_CODE (args) == IDENTIFIER_NODE)
4975 /* A unary selector. */
4977 else if (TREE_CODE (args) == TREE_LIST)
4978 sel_name = build_keyword_selector (args);
4982 /* Build the parameter list to give to the method. */
4984 method_params = NULL_TREE;
4985 if (TREE_CODE (args) == TREE_LIST)
4987 tree chain = args, prev = NULL_TREE;
4989 /* We have a keyword selector--check for comma expressions. */
4992 tree element = TREE_VALUE (chain);
4994 /* We have a comma expression, must collapse... */
4995 if (TREE_CODE (element) == TREE_LIST)
4998 TREE_CHAIN (prev) = element;
5003 chain = TREE_CHAIN (chain);
5005 method_params = args;
5008 /* Determine operation return type. */
5010 if (IS_SUPER (rtype))
5014 if (CLASS_SUPER_NAME (implementation_template))
5017 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5019 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
5020 method_prototype = lookup_instance_method_static (iface, sel_name);
5022 method_prototype = lookup_class_method_static (iface, sel_name);
5024 if (iface && !method_prototype)
5025 warning ("`%s' does not respond to `%s'",
5026 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
5027 IDENTIFIER_POINTER (sel_name));
5031 error ("no super class declared in interface for `%s'",
5032 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5033 return error_mark_node;
5037 else if (statically_allocated)
5039 tree ctype = TREE_TYPE (rtype);
5040 tree iface = lookup_interface (TYPE_NAME (rtype));
5043 method_prototype = lookup_instance_method_static (iface, sel_name);
5045 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5047 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5050 if (!method_prototype)
5051 warning ("`%s' does not respond to `%s'",
5052 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5053 IDENTIFIER_POINTER (sel_name));
5055 else if (statically_typed)
5057 tree ctype = TREE_TYPE (rtype);
5059 /* `self' is now statically_typed. All methods should be visible
5060 within the context of the implementation. */
5061 if (implementation_context
5062 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
5065 = lookup_instance_method_static (implementation_template,
5068 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5070 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5073 if (! method_prototype
5074 && implementation_template != implementation_context)
5075 /* The method is not published in the interface. Check
5078 = lookup_method (CLASS_NST_METHODS (implementation_context),
5085 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5086 method_prototype = lookup_instance_method_static (iface, sel_name);
5088 if (! method_prototype)
5090 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5093 = lookup_method_in_protocol_list (protocol_list,
5098 if (!method_prototype)
5099 warning ("`%s' does not respond to `%s'",
5100 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5101 IDENTIFIER_POINTER (sel_name));
5103 else if (class_ident)
5105 if (implementation_context
5106 && CLASS_NAME (implementation_context) == class_ident)
5109 = lookup_class_method_static (implementation_template, sel_name);
5111 if (!method_prototype
5112 && implementation_template != implementation_context)
5113 /* The method is not published in the interface. Check
5116 = lookup_method (CLASS_CLS_METHODS (implementation_context),
5123 if ((iface = lookup_interface (class_ident)))
5124 method_prototype = lookup_class_method_static (iface, sel_name);
5127 if (!method_prototype)
5129 warning ("cannot find class (factory) method.");
5130 warning ("return type for `%s' defaults to id",
5131 IDENTIFIER_POINTER (sel_name));
5134 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5136 /* An anonymous object that has been qualified with a protocol. */
5138 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5140 method_prototype = lookup_method_in_protocol_list (protocol_list,
5143 if (!method_prototype)
5147 warning ("method `%s' not implemented by protocol.",
5148 IDENTIFIER_POINTER (sel_name));
5150 /* Try and find the method signature in the global pools. */
5152 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5153 hsh = hash_lookup (cls_method_hash_list, sel_name);
5155 if (!(method_prototype = check_duplicates (hsh)))
5156 warning ("return type defaults to id");
5163 /* We think we have an instance...loophole: extern id Object; */
5164 hsh = hash_lookup (nst_method_hash_list, sel_name);
5166 /* For various loopholes, like sending messages to self in a
5168 hsh = hash_lookup (cls_method_hash_list, sel_name);
5170 method_prototype = check_duplicates (hsh);
5171 if (!method_prototype)
5173 warning ("cannot find method.");
5174 warning ("return type for `%s' defaults to id",
5175 IDENTIFIER_POINTER (sel_name));
5179 /* Save the selector name for printing error messages. */
5180 building_objc_message_expr = sel_name;
5182 /* Build the parameters list for looking up the method.
5183 These are the object itself and the selector. */
5185 if (flag_typed_selectors)
5186 selector = build_typed_selector_reference (sel_name, method_prototype);
5188 selector = build_selector_reference (sel_name);
5190 retval = build_objc_method_call (super, method_prototype,
5191 receiver, self_object,
5192 selector, method_params);
5194 building_objc_message_expr = 0;
5199 /* Build a tree expression to send OBJECT the operation SELECTOR,
5200 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5201 assuming the method has prototype METHOD_PROTOTYPE.
5202 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5203 Use METHOD_PARAMS as list of args to pass to the method.
5204 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5207 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5208 selector, method_params)
5210 tree method_prototype, lookup_object, object, selector, method_params;
5212 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5213 tree rcv_p = (super_flag
5214 ? build_pointer_type (xref_tag (RECORD_TYPE,
5215 get_identifier (TAG_SUPER)))
5218 if (flag_next_runtime)
5220 if (! method_prototype)
5222 method_params = tree_cons (NULL_TREE, lookup_object,
5223 tree_cons (NULL_TREE, selector,
5225 assemble_external (sender);
5226 return build_function_call (sender, method_params);
5230 /* This is a real kludge, but it is used only for the Next.
5231 Clobber the data type of SENDER temporarily to accept
5232 all the arguments for this operation, and to return
5233 whatever this operation returns. */
5234 tree arglist = NULL_TREE;
5237 /* Save the proper contents of SENDER's data type. */
5238 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5239 tree savret = TREE_TYPE (TREE_TYPE (sender));
5241 /* Install this method's argument types. */
5242 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5244 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5246 /* Install this method's return type. */
5247 TREE_TYPE (TREE_TYPE (sender))
5248 = groktypename (TREE_TYPE (method_prototype));
5250 /* Call SENDER with all the parameters. This will do type
5251 checking using the arg types for this method. */
5252 method_params = tree_cons (NULL_TREE, lookup_object,
5253 tree_cons (NULL_TREE, selector,
5255 assemble_external (sender);
5256 retval = build_function_call (sender, method_params);
5258 /* Restore SENDER's return/argument types. */
5259 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5260 TREE_TYPE (TREE_TYPE (sender)) = savret;
5266 /* This is the portable way.
5267 First call the lookup function to get a pointer to the method,
5268 then cast the pointer, then call it with the method arguments. */
5271 /* Avoid trouble since we may evaluate each of these twice. */
5272 object = save_expr (object);
5273 selector = save_expr (selector);
5275 lookup_object = build_c_cast (rcv_p, lookup_object);
5277 assemble_external (sender);
5279 = build_function_call (sender,
5280 tree_cons (NULL_TREE, lookup_object,
5281 tree_cons (NULL_TREE, selector,
5284 /* If we have a method prototype, construct the data type this
5285 method needs, and cast what we got from SENDER into a pointer
5287 if (method_prototype)
5289 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5291 tree valtype = groktypename (TREE_TYPE (method_prototype));
5292 tree fake_function_type = build_function_type (valtype, arglist);
5293 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5297 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5299 /* Pass the object to the method. */
5300 assemble_external (method);
5301 return build_function_call (method,
5302 tree_cons (NULL_TREE, object,
5303 tree_cons (NULL_TREE, selector,
5309 build_protocol_reference (p)
5312 tree decl, ident, ptype;
5314 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5316 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5318 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5319 objc_protocol_template),
5322 if (IDENTIFIER_GLOBAL_VALUE (ident))
5323 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5326 decl = build_decl (VAR_DECL, ident, ptype);
5327 DECL_EXTERNAL (decl) = 1;
5328 TREE_PUBLIC (decl) = 1;
5329 TREE_USED (decl) = 1;
5330 DECL_ARTIFICIAL (decl) = 1;
5332 make_decl_rtl (decl, 0, 1);
5333 pushdecl_top_level (decl);
5336 PROTOCOL_FORWARD_DECL (p) = decl;
5340 build_protocol_expr (protoname)
5344 tree p = lookup_protocol (protoname);
5348 error ("Cannot find protocol declaration for `%s'",
5349 IDENTIFIER_POINTER (protoname));
5350 return error_mark_node;
5353 if (!PROTOCOL_FORWARD_DECL (p))
5354 build_protocol_reference (p);
5356 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5358 TREE_TYPE (expr) = protocol_type;
5364 build_selector_expr (selnamelist)
5369 /* Obtain the full selector name. */
5370 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5371 /* A unary selector. */
5372 selname = selnamelist;
5373 else if (TREE_CODE (selnamelist) == TREE_LIST)
5374 selname = build_keyword_selector (selnamelist);
5378 if (flag_typed_selectors)
5379 return build_typed_selector_reference (selname, 0);
5381 return build_selector_reference (selname);
5385 build_encode_expr (type)
5391 encode_type (type, obstack_object_size (&util_obstack),
5392 OBJC_ENCODE_INLINE_DEFS);
5393 obstack_1grow (&util_obstack, 0); /* null terminate string */
5394 string = obstack_finish (&util_obstack);
5396 /* Synthesize a string that represents the encoded struct/union. */
5397 result = my_build_string (strlen (string) + 1, string);
5398 obstack_free (&util_obstack, util_firstobj);
5403 build_ivar_reference (id)
5406 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
5408 /* Historically, a class method that produced objects (factory
5409 method) would assign `self' to the instance that it
5410 allocated. This would effectively turn the class method into
5411 an instance method. Following this assignment, the instance
5412 variables could be accessed. That practice, while safe,
5413 violates the simple rule that a class method should not refer
5414 to an instance variable. It's better to catch the cases
5415 where this is done unknowingly than to support the above
5417 warning ("instance variable `%s' accessed in class method",
5418 IDENTIFIER_POINTER (id));
5419 TREE_TYPE (self_decl) = instance_type; /* cast */
5422 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5425 #define HASH_ALLOC_LIST_SIZE 170
5426 #define ATTR_ALLOC_LIST_SIZE 170
5427 #define SIZEHASHTABLE 257
5430 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5435 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5436 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5438 if (!nst_method_hash_list || !cls_method_hash_list)
5439 perror ("unable to allocate space in objc-tree.c");
5444 for (i = 0; i < SIZEHASHTABLE; i++)
5446 nst_method_hash_list[i] = 0;
5447 cls_method_hash_list[i] = 0;
5453 hash_enter (hashlist, method)
5457 static hash hash_alloc_list = 0;
5458 static int hash_alloc_index = 0;
5460 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5462 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5464 hash_alloc_index = 0;
5465 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5466 * HASH_ALLOC_LIST_SIZE);
5467 if (! hash_alloc_list)
5468 perror ("unable to allocate in objc-tree.c");
5470 obj = &hash_alloc_list[hash_alloc_index++];
5472 obj->next = hashlist[slot];
5475 hashlist[slot] = obj; /* append to front */
5479 hash_lookup (hashlist, sel_name)
5485 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5489 if (sel_name == METHOD_SEL_NAME (target->key))
5492 target = target->next;
5498 hash_add_attr (entry, value)
5502 static attr attr_alloc_list = 0;
5503 static int attr_alloc_index = 0;
5506 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5508 attr_alloc_index = 0;
5509 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5510 * ATTR_ALLOC_LIST_SIZE);
5511 if (! attr_alloc_list)
5512 perror ("unable to allocate in objc-tree.c");
5514 obj = &attr_alloc_list[attr_alloc_index++];
5515 obj->next = entry->list;
5518 entry->list = obj; /* append to front */
5522 lookup_method (mchain, method)
5528 if (TREE_CODE (method) == IDENTIFIER_NODE)
5531 key = METHOD_SEL_NAME (method);
5535 if (METHOD_SEL_NAME (mchain) == key)
5537 mchain = TREE_CHAIN (mchain);
5543 lookup_instance_method_static (interface, ident)
5547 tree inter = interface;
5548 tree chain = CLASS_NST_METHODS (inter);
5549 tree meth = NULL_TREE;
5553 if ((meth = lookup_method (chain, ident)))
5556 if (CLASS_CATEGORY_LIST (inter))
5558 tree category = CLASS_CATEGORY_LIST (inter);
5559 chain = CLASS_NST_METHODS (category);
5563 if ((meth = lookup_method (chain, ident)))
5566 /* Check for instance methods in protocols in categories. */
5567 if (CLASS_PROTOCOL_LIST (category))
5569 if ((meth = (lookup_method_in_protocol_list
5570 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5574 if ((category = CLASS_CATEGORY_LIST (category)))
5575 chain = CLASS_NST_METHODS (category);
5580 if (CLASS_PROTOCOL_LIST (inter))
5582 if ((meth = (lookup_method_in_protocol_list
5583 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5587 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5588 chain = CLASS_NST_METHODS (inter);
5596 lookup_class_method_static (interface, ident)
5600 tree inter = interface;
5601 tree chain = CLASS_CLS_METHODS (inter);
5602 tree meth = NULL_TREE;
5603 tree root_inter = NULL_TREE;
5607 if ((meth = lookup_method (chain, ident)))
5610 if (CLASS_CATEGORY_LIST (inter))
5612 tree category = CLASS_CATEGORY_LIST (inter);
5613 chain = CLASS_CLS_METHODS (category);
5617 if ((meth = lookup_method (chain, ident)))
5620 /* Check for class methods in protocols in categories. */
5621 if (CLASS_PROTOCOL_LIST (category))
5623 if ((meth = (lookup_method_in_protocol_list
5624 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5628 if ((category = CLASS_CATEGORY_LIST (category)))
5629 chain = CLASS_CLS_METHODS (category);
5634 /* Check for class methods in protocols. */
5635 if (CLASS_PROTOCOL_LIST (inter))
5637 if ((meth = (lookup_method_in_protocol_list
5638 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5643 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5644 chain = CLASS_CLS_METHODS (inter);
5648 /* Simulate wrap around. */
5649 return lookup_instance_method_static (root_inter, ident);
5653 add_class_method (class, method)
5660 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5662 /* put method on list in reverse order */
5663 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5664 CLASS_CLS_METHODS (class) = method;
5668 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5669 error ("duplicate definition of class method `%s'.",
5670 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5673 /* Check types; if different, complain. */
5674 if (!comp_proto_with_proto (method, mth))
5675 error ("duplicate declaration of class method `%s'.",
5676 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5680 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5682 /* Install on a global chain. */
5683 hash_enter (cls_method_hash_list, method);
5687 /* Check types; if different, add to a list. */
5688 if (!comp_proto_with_proto (method, hsh->key))
5689 hash_add_attr (hsh, method);
5695 add_instance_method (class, method)
5702 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5704 /* Put method on list in reverse order. */
5705 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5706 CLASS_NST_METHODS (class) = method;
5710 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5711 error ("duplicate definition of instance method `%s'.",
5712 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5715 /* Check types; if different, complain. */
5716 if (!comp_proto_with_proto (method, mth))
5717 error ("duplicate declaration of instance method `%s'.",
5718 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5722 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5724 /* Install on a global chain. */
5725 hash_enter (nst_method_hash_list, method);
5729 /* Check types; if different, add to a list. */
5730 if (!comp_proto_with_proto (method, hsh->key))
5731 hash_add_attr (hsh, method);
5740 /* Put interfaces on list in reverse order. */
5741 TREE_CHAIN (class) = interface_chain;
5742 interface_chain = class;
5743 return interface_chain;
5747 add_category (class, category)
5751 /* Put categories on list in reverse order. */
5752 tree cat = CLASS_CATEGORY_LIST (class);
5756 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5757 warning ("duplicate interface declaration for category `%s(%s)'",
5758 IDENTIFIER_POINTER (CLASS_NAME (class)),
5759 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5760 cat = CLASS_CATEGORY_LIST (cat);
5763 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5764 CLASS_CATEGORY_LIST (class) = category;
5767 /* Called after parsing each instance variable declaration. Necessary to
5768 preserve typedefs and implement public/private...
5770 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5773 add_instance_variable (class, public, declarator, declspecs, width)
5780 tree field_decl, raw_decl;
5782 raw_decl = build_tree_list (declspecs, declarator);
5784 if (CLASS_RAW_IVARS (class))
5785 chainon (CLASS_RAW_IVARS (class), raw_decl);
5787 CLASS_RAW_IVARS (class) = raw_decl;
5789 field_decl = grokfield (input_filename, lineno,
5790 declarator, declspecs, width);
5792 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5796 TREE_PUBLIC (field_decl) = 0;
5797 TREE_PRIVATE (field_decl) = 0;
5798 TREE_PROTECTED (field_decl) = 1;
5802 TREE_PUBLIC (field_decl) = 1;
5803 TREE_PRIVATE (field_decl) = 0;
5804 TREE_PROTECTED (field_decl) = 0;
5808 TREE_PUBLIC (field_decl) = 0;
5809 TREE_PRIVATE (field_decl) = 1;
5810 TREE_PROTECTED (field_decl) = 0;
5815 if (CLASS_IVARS (class))
5816 chainon (CLASS_IVARS (class), field_decl);
5818 CLASS_IVARS (class) = field_decl;
5824 is_ivar (decl_chain, ident)
5828 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5829 if (DECL_NAME (decl_chain) == ident)
5834 /* True if the ivar is private and we are not in its implementation. */
5840 if (TREE_PRIVATE (decl)
5841 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5843 error ("instance variable `%s' is declared private",
5844 IDENTIFIER_POINTER (DECL_NAME (decl)));
5851 /* We have an instance variable reference;, check to see if it is public. */
5854 is_public (expr, identifier)
5858 tree basetype = TREE_TYPE (expr);
5859 enum tree_code code = TREE_CODE (basetype);
5862 if (code == RECORD_TYPE)
5864 if (TREE_STATIC_TEMPLATE (basetype))
5866 if (!lookup_interface (TYPE_NAME (basetype)))
5868 error ("Cannot find interface declaration for `%s'",
5869 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5873 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5875 if (TREE_PUBLIC (decl))
5878 /* Important difference between the Stepstone translator:
5879 all instance variables should be public within the context
5880 of the implementation. */
5881 if (implementation_context
5882 && (((TREE_CODE (implementation_context)
5883 == CLASS_IMPLEMENTATION_TYPE)
5884 || (TREE_CODE (implementation_context)
5885 == CATEGORY_IMPLEMENTATION_TYPE))
5886 && (CLASS_NAME (implementation_context)
5887 == TYPE_NAME (basetype))))
5888 return ! is_private (decl);
5890 error ("instance variable `%s' is declared %s",
5891 IDENTIFIER_POINTER (identifier),
5892 TREE_PRIVATE (decl) ? "private" : "protected");
5897 else if (implementation_context && (basetype == objc_object_reference))
5899 TREE_TYPE (expr) = uprivate_record;
5900 warning ("static access to object of type `id'");
5907 /* Implement @defs (<classname>) within struct bodies. */
5910 get_class_ivars (interface)
5913 return build_ivar_chain (interface, 1);
5916 /* Make sure all entries in CHAIN are also in LIST. */
5919 check_methods (chain, list, mtype)
5928 if (!lookup_method (list, chain))
5932 if (TREE_CODE (implementation_context)
5933 == CLASS_IMPLEMENTATION_TYPE)
5934 warning ("incomplete implementation of class `%s'",
5935 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5936 else if (TREE_CODE (implementation_context)
5937 == CATEGORY_IMPLEMENTATION_TYPE)
5938 warning ("incomplete implementation of category `%s'",
5939 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5943 warning ("method definition for `%c%s' not found",
5944 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5947 chain = TREE_CHAIN (chain);
5954 conforms_to_protocol (class, protocol)
5960 tree p = CLASS_PROTOCOL_LIST (class);
5962 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
5967 tree super = (CLASS_SUPER_NAME (class)
5968 ? lookup_interface (CLASS_SUPER_NAME (class))
5970 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
5975 protocol = TREE_CHAIN (protocol);
5981 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5982 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5985 check_methods_accessible (chain, context, mtype)
5992 tree base_context = context;
5996 context = base_context;
6000 list = CLASS_CLS_METHODS (context);
6002 list = CLASS_NST_METHODS (context);
6004 if (lookup_method (list, chain))
6007 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6008 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6009 context = (CLASS_SUPER_NAME (context)
6010 ? lookup_interface (CLASS_SUPER_NAME (context))
6013 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6014 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6015 context = (CLASS_NAME (context)
6016 ? lookup_interface (CLASS_NAME (context))
6022 if (context == NULL_TREE)
6026 if (TREE_CODE (implementation_context)
6027 == CLASS_IMPLEMENTATION_TYPE)
6028 warning ("incomplete implementation of class `%s'",
6030 (CLASS_NAME (implementation_context)));
6031 else if (TREE_CODE (implementation_context)
6032 == CATEGORY_IMPLEMENTATION_TYPE)
6033 warning ("incomplete implementation of category `%s'",
6035 (CLASS_SUPER_NAME (implementation_context)));
6038 warning ("method definition for `%c%s' not found",
6039 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6042 chain = TREE_CHAIN (chain); /* next method... */
6048 check_protocols (proto_list, type, name)
6053 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6055 tree p = TREE_VALUE (proto_list);
6057 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6061 /* Ensure that all protocols have bodies. */
6062 if (flag_warn_protocol) {
6063 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6064 CLASS_CLS_METHODS (implementation_context),
6066 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6067 CLASS_NST_METHODS (implementation_context),
6070 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6071 implementation_context,
6073 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6074 implementation_context,
6079 warning ("%s `%s' does not fully implement the `%s' protocol",
6080 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6085 ; /* An identifier if we could not find a protocol. */
6088 /* Check protocols recursively. */
6089 if (PROTOCOL_LIST (p))
6092 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6093 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
6094 check_protocols (PROTOCOL_LIST (p), type, name);
6099 /* Make sure that the class CLASS_NAME is defined
6100 CODE says which kind of thing CLASS_NAME ought to be.
6101 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6102 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6105 start_class (code, class_name, super_name, protocol_list)
6106 enum tree_code code;
6113 class = make_node (code);
6114 TYPE_BINFO (class) = make_tree_vec (5);
6116 CLASS_NAME (class) = class_name;
6117 CLASS_SUPER_NAME (class) = super_name;
6118 CLASS_CLS_METHODS (class) = NULL_TREE;
6120 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6122 error ("`%s' redeclared as different kind of symbol",
6123 IDENTIFIER_POINTER (class_name));
6124 error_with_decl (decl, "previous declaration of `%s'");
6127 if (code == CLASS_IMPLEMENTATION_TYPE)
6130 static tree implemented_classes = 0;
6131 tree chain = implemented_classes;
6132 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6133 if (TREE_VALUE (chain) == class_name)
6135 error ("reimplementation of class `%s'",
6136 IDENTIFIER_POINTER (class_name));
6137 return error_mark_node;
6139 implemented_classes = tree_cons (NULL_TREE, class_name,
6140 implemented_classes);
6143 /* Pre-build the following entities - for speed/convenience. */
6145 self_id = get_identifier ("self");
6147 ucmd_id = get_identifier ("_cmd");
6150 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6151 if (!objc_super_template)
6152 objc_super_template = build_super_template ();
6154 /* Reset for multiple classes per file. */
6157 implementation_context = class;
6159 /* Lookup the interface for this implementation. */
6161 if (!(implementation_template = lookup_interface (class_name)))
6163 warning ("Cannot find interface declaration for `%s'",
6164 IDENTIFIER_POINTER (class_name));
6165 add_class (implementation_template = implementation_context);
6168 /* If a super class has been specified in the implementation,
6169 insure it conforms to the one specified in the interface. */
6172 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6174 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6176 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6177 error ("conflicting super class name `%s'",
6178 IDENTIFIER_POINTER (super_name));
6179 error ("previous declaration of `%s'", name);
6182 else if (! super_name)
6184 CLASS_SUPER_NAME (implementation_context)
6185 = CLASS_SUPER_NAME (implementation_template);
6189 else if (code == CLASS_INTERFACE_TYPE)
6191 if (lookup_interface (class_name))
6192 warning ("duplicate interface declaration for class `%s'",
6193 IDENTIFIER_POINTER (class_name));
6198 CLASS_PROTOCOL_LIST (class)
6199 = lookup_and_install_protocols (protocol_list);
6202 else if (code == CATEGORY_INTERFACE_TYPE)
6204 tree class_category_is_assoc_with;
6206 /* For a category, class_name is really the name of the class that
6207 the following set of methods will be associated with. We must
6208 find the interface so that can derive the objects template. */
6210 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6212 error ("Cannot find interface declaration for `%s'",
6213 IDENTIFIER_POINTER (class_name));
6214 exit (FATAL_EXIT_CODE);
6217 add_category (class_category_is_assoc_with, class);
6220 CLASS_PROTOCOL_LIST (class)
6221 = lookup_and_install_protocols (protocol_list);
6224 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6226 /* Pre-build the following entities for speed/convenience. */
6228 self_id = get_identifier ("self");
6230 ucmd_id = get_identifier ("_cmd");
6233 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6234 if (!objc_super_template)
6235 objc_super_template = build_super_template ();
6237 /* Reset for multiple classes per file. */
6240 implementation_context = class;
6242 /* For a category, class_name is really the name of the class that
6243 the following set of methods will be associated with. We must
6244 find the interface so that can derive the objects template. */
6246 if (!(implementation_template = lookup_interface (class_name)))
6248 error ("Cannot find interface declaration for `%s'",
6249 IDENTIFIER_POINTER (class_name));
6250 exit (FATAL_EXIT_CODE);
6257 continue_class (class)
6260 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6261 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6263 struct imp_entry *imp_entry;
6266 /* Check consistency of the instance variables. */
6268 if (CLASS_IVARS (class))
6269 check_ivars (implementation_template, class);
6271 /* code generation */
6273 ivar_context = build_private_template (implementation_template);
6275 if (!objc_class_template)
6276 build_class_template ();
6279 = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
6280 perror ("unable to allocate in objc-tree.c");
6282 imp_entry->next = imp_list;
6283 imp_entry->imp_context = class;
6284 imp_entry->imp_template = implementation_template;
6286 synth_forward_declarations ();
6287 imp_entry->class_decl = UOBJC_CLASS_decl;
6288 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6290 /* Append to front and increment count. */
6291 imp_list = imp_entry;
6292 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6297 return ivar_context;
6300 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6302 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6304 if (!TYPE_FIELDS (record))
6306 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6307 CLASS_STATIC_TEMPLATE (class) = record;
6309 /* Mark this record as a class template for static typing. */
6310 TREE_STATIC_TEMPLATE (record) = 1;
6317 return error_mark_node;
6320 /* This is called once we see the "@end" in an interface/implementation. */
6323 finish_class (class)
6326 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6328 /* All code generation is done in finish_objc. */
6330 if (implementation_template != implementation_context)
6332 /* Ensure that all method listed in the interface contain bodies. */
6333 check_methods (CLASS_CLS_METHODS (implementation_template),
6334 CLASS_CLS_METHODS (implementation_context), '+');
6335 check_methods (CLASS_NST_METHODS (implementation_template),
6336 CLASS_NST_METHODS (implementation_context), '-');
6338 if (CLASS_PROTOCOL_LIST (implementation_template))
6339 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6341 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
6345 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6347 tree category = CLASS_CATEGORY_LIST (implementation_template);
6349 /* Find the category interface from the class it is associated with. */
6352 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6354 category = CLASS_CATEGORY_LIST (category);
6359 /* Ensure all method listed in the interface contain bodies. */
6360 check_methods (CLASS_CLS_METHODS (category),
6361 CLASS_CLS_METHODS (implementation_context), '+');
6362 check_methods (CLASS_NST_METHODS (category),
6363 CLASS_NST_METHODS (implementation_context), '-');
6365 if (CLASS_PROTOCOL_LIST (category))
6366 check_protocols (CLASS_PROTOCOL_LIST (category),
6368 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6372 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6375 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6376 char *string = (char *) alloca (strlen (class_name) + 3);
6378 /* extern struct objc_object *_<my_name>; */
6380 sprintf (string, "_%s", class_name);
6382 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6383 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6384 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6390 add_protocol (protocol)
6393 /* Put protocol on list in reverse order. */
6394 TREE_CHAIN (protocol) = protocol_chain;
6395 protocol_chain = protocol;
6396 return protocol_chain;
6400 lookup_protocol (ident)
6405 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6407 if (ident == PROTOCOL_NAME (chain))
6415 start_protocol (code, name, list)
6416 enum tree_code code;
6422 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6423 if (!objc_protocol_template)
6424 objc_protocol_template = build_protocol_template ();
6426 protocol = make_node (code);
6427 TYPE_BINFO (protocol) = make_tree_vec (2);
6429 PROTOCOL_NAME (protocol) = name;
6430 PROTOCOL_LIST (protocol) = list;
6432 lookup_and_install_protocols (list);
6434 if (lookup_protocol (name))
6435 warning ("duplicate declaration for protocol `%s'",
6436 IDENTIFIER_POINTER (name));
6438 add_protocol (protocol);
6440 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6446 finish_protocol (protocol)
6447 tree protocol ATTRIBUTE_UNUSED;
6452 /* "Encode" a data type into a string, which grows in util_obstack.
6453 ??? What is the FORMAT? Someone please document this! */
6456 encode_type_qualifiers (declspecs)
6461 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6463 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6464 obstack_1grow (&util_obstack, 'r');
6465 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6466 obstack_1grow (&util_obstack, 'n');
6467 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6468 obstack_1grow (&util_obstack, 'N');
6469 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6470 obstack_1grow (&util_obstack, 'o');
6471 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6472 obstack_1grow (&util_obstack, 'O');
6473 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6474 obstack_1grow (&util_obstack, 'R');
6475 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6476 obstack_1grow (&util_obstack, 'V');
6480 /* Encode a pointer type. */
6483 encode_pointer (type, curtype, format)
6488 tree pointer_to = TREE_TYPE (type);
6490 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6492 if (TYPE_NAME (pointer_to)
6493 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6495 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6497 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6499 obstack_1grow (&util_obstack, '@');
6502 else if (TREE_STATIC_TEMPLATE (pointer_to))
6504 if (generating_instance_variables)
6506 obstack_1grow (&util_obstack, '@');
6507 obstack_1grow (&util_obstack, '"');
6508 obstack_grow (&util_obstack, name, strlen (name));
6509 obstack_1grow (&util_obstack, '"');
6514 obstack_1grow (&util_obstack, '@');
6518 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6520 obstack_1grow (&util_obstack, '#');
6523 #ifndef OBJC_INT_SELECTORS
6524 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6526 obstack_1grow (&util_obstack, ':');
6529 #endif /* OBJC_INT_SELECTORS */
6532 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6533 && TYPE_MODE (pointer_to) == QImode)
6535 obstack_1grow (&util_obstack, '*');
6539 /* We have a type that does not get special treatment. */
6541 /* NeXT extension */
6542 obstack_1grow (&util_obstack, '^');
6543 encode_type (pointer_to, curtype, format);
6547 encode_array (type, curtype, format)
6552 tree an_int_cst = TYPE_SIZE (type);
6553 tree array_of = TREE_TYPE (type);
6556 /* An incomplete array is treated like a pointer. */
6557 if (an_int_cst == NULL)
6559 encode_pointer (type, curtype, format);
6563 sprintf (buffer, "[%ld",
6564 (long) (TREE_INT_CST_LOW (an_int_cst)
6565 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6567 obstack_grow (&util_obstack, buffer, strlen (buffer));
6568 encode_type (array_of, curtype, format);
6569 obstack_1grow (&util_obstack, ']');
6574 encode_aggregate_within (type, curtype, format, left, right)
6581 if (obstack_object_size (&util_obstack) > 0
6582 && *(obstack_next_free (&util_obstack) - 1) == '^')
6584 tree name = TYPE_NAME (type);
6586 /* we have a reference; this is a NeXT extension. */
6588 if (obstack_object_size (&util_obstack) - curtype == 1
6589 && format == OBJC_ENCODE_INLINE_DEFS)
6591 /* Output format of struct for first level only. */
6592 tree fields = TYPE_FIELDS (type);
6594 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6596 obstack_1grow (&util_obstack, left);
6597 obstack_grow (&util_obstack,
6598 IDENTIFIER_POINTER (name),
6599 strlen (IDENTIFIER_POINTER (name)));
6600 obstack_1grow (&util_obstack, '=');
6604 obstack_1grow (&util_obstack, left);
6605 obstack_grow (&util_obstack, "?=", 2);
6608 for ( ; fields; fields = TREE_CHAIN (fields))
6609 encode_field_decl (fields, curtype, format);
6611 obstack_1grow (&util_obstack, right);
6614 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6616 obstack_1grow (&util_obstack, left);
6617 obstack_grow (&util_obstack,
6618 IDENTIFIER_POINTER (name),
6619 strlen (IDENTIFIER_POINTER (name)));
6620 obstack_1grow (&util_obstack, right);
6625 /* We have an untagged structure or a typedef. */
6626 obstack_1grow (&util_obstack, left);
6627 obstack_1grow (&util_obstack, '?');
6628 obstack_1grow (&util_obstack, right);
6634 tree name = TYPE_NAME (type);
6635 tree fields = TYPE_FIELDS (type);
6637 if (format == OBJC_ENCODE_INLINE_DEFS
6638 || generating_instance_variables)
6640 obstack_1grow (&util_obstack, left);
6641 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6642 obstack_grow (&util_obstack,
6643 IDENTIFIER_POINTER (name),
6644 strlen (IDENTIFIER_POINTER (name)));
6646 obstack_1grow (&util_obstack, '?');
6648 obstack_1grow (&util_obstack, '=');
6650 for (; fields; fields = TREE_CHAIN (fields))
6652 if (generating_instance_variables)
6654 tree fname = DECL_NAME (fields);
6656 obstack_1grow (&util_obstack, '"');
6657 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6659 obstack_grow (&util_obstack,
6660 IDENTIFIER_POINTER (fname),
6661 strlen (IDENTIFIER_POINTER (fname)));
6664 obstack_1grow (&util_obstack, '"');
6667 encode_field_decl (fields, curtype, format);
6670 obstack_1grow (&util_obstack, right);
6675 obstack_1grow (&util_obstack, left);
6676 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6677 obstack_grow (&util_obstack,
6678 IDENTIFIER_POINTER (name),
6679 strlen (IDENTIFIER_POINTER (name)));
6681 /* We have an untagged structure or a typedef. */
6682 obstack_1grow (&util_obstack, '?');
6684 obstack_1grow (&util_obstack, right);
6690 encode_aggregate (type, curtype, format)
6695 enum tree_code code = TREE_CODE (type);
6701 encode_aggregate_within(type, curtype, format, '{', '}');
6706 encode_aggregate_within(type, curtype, format, '(', ')');
6711 obstack_1grow (&util_obstack, 'i');
6719 /* Support bitfields. The current version of Objective-C does not support
6720 them. The string will consist of one or more "b:n"'s where n is an
6721 integer describing the width of the bitfield. Currently, classes in
6722 the kit implement a method "-(char *)describeBitfieldStruct:" that
6723 simulates this. If they do not implement this method, the archiver
6724 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6725 according to the GNU compiler. After looking at the "kit", it appears
6726 that all classes currently rely on this default behavior, rather than
6727 hand generating this string (which is tedious). */
6730 encode_bitfield (width)
6734 sprintf (buffer, "b%d", width);
6735 obstack_grow (&util_obstack, buffer, strlen (buffer));
6738 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6741 encode_type (type, curtype, format)
6746 enum tree_code code = TREE_CODE (type);
6748 if (code == INTEGER_TYPE)
6750 if (integer_zerop (TYPE_MIN_VALUE (type)))
6752 /* Unsigned integer types. */
6754 if (TYPE_MODE (type) == QImode)
6755 obstack_1grow (&util_obstack, 'C');
6756 else if (TYPE_MODE (type) == HImode)
6757 obstack_1grow (&util_obstack, 'S');
6758 else if (TYPE_MODE (type) == SImode)
6760 if (type == long_unsigned_type_node)
6761 obstack_1grow (&util_obstack, 'L');
6763 obstack_1grow (&util_obstack, 'I');
6765 else if (TYPE_MODE (type) == DImode)
6766 obstack_1grow (&util_obstack, 'Q');
6770 /* Signed integer types. */
6772 if (TYPE_MODE (type) == QImode)
6773 obstack_1grow (&util_obstack, 'c');
6774 else if (TYPE_MODE (type) == HImode)
6775 obstack_1grow (&util_obstack, 's');
6776 else if (TYPE_MODE (type) == SImode)
6778 if (type == long_integer_type_node)
6779 obstack_1grow (&util_obstack, 'l');
6781 obstack_1grow (&util_obstack, 'i');
6784 else if (TYPE_MODE (type) == DImode)
6785 obstack_1grow (&util_obstack, 'q');
6789 else if (code == REAL_TYPE)
6791 /* Floating point types. */
6793 if (TYPE_MODE (type) == SFmode)
6794 obstack_1grow (&util_obstack, 'f');
6795 else if (TYPE_MODE (type) == DFmode
6796 || TYPE_MODE (type) == TFmode)
6797 obstack_1grow (&util_obstack, 'd');
6800 else if (code == VOID_TYPE)
6801 obstack_1grow (&util_obstack, 'v');
6803 else if (code == ARRAY_TYPE)
6804 encode_array (type, curtype, format);
6806 else if (code == POINTER_TYPE)
6807 encode_pointer (type, curtype, format);
6809 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6810 encode_aggregate (type, curtype, format);
6812 else if (code == FUNCTION_TYPE) /* '?' */
6813 obstack_1grow (&util_obstack, '?');
6817 encode_complete_bitfield (int position, tree type, int size)
6819 enum tree_code code = TREE_CODE (type);
6821 char charType = '?';
6823 if (code == INTEGER_TYPE)
6825 if (integer_zerop (TYPE_MIN_VALUE (type)))
6827 /* Unsigned integer types. */
6829 if (TYPE_MODE (type) == QImode)
6831 else if (TYPE_MODE (type) == HImode)
6833 else if (TYPE_MODE (type) == SImode)
6835 if (type == long_unsigned_type_node)
6840 else if (TYPE_MODE (type) == DImode)
6845 /* Signed integer types. */
6847 if (TYPE_MODE (type) == QImode)
6849 else if (TYPE_MODE (type) == HImode)
6851 else if (TYPE_MODE (type) == SImode)
6853 if (type == long_integer_type_node)
6859 else if (TYPE_MODE (type) == DImode)
6867 sprintf (buffer, "b%d%c%d", position, charType, size);
6868 obstack_grow (&util_obstack, buffer, strlen (buffer));
6872 encode_field_decl (field_decl, curtype, format)
6879 type = TREE_TYPE (field_decl);
6881 /* If this field is obviously a bitfield, or is a bitfield that has been
6882 clobbered to look like a ordinary integer mode, go ahead and generate
6883 the bitfield typing information. */
6884 if (flag_next_runtime)
6886 if (DECL_BIT_FIELD (field_decl))
6887 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6889 encode_type (TREE_TYPE (field_decl), curtype, format);
6893 if (DECL_BIT_FIELD (field_decl))
6894 encode_complete_bitfield (int_bit_position (field_decl),
6895 DECL_BIT_FIELD_TYPE (field_decl),
6896 tree_low_cst (DECL_SIZE (field_decl), 1));
6898 encode_type (TREE_TYPE (field_decl), curtype, format);
6903 expr_last (complex_expr)
6909 while ((next = TREE_OPERAND (complex_expr, 0)))
6910 complex_expr = next;
6912 return complex_expr;
6915 /* The selector of the current method,
6916 or NULL if we aren't compiling a method. */
6919 maybe_objc_method_name (decl)
6920 tree decl ATTRIBUTE_UNUSED;
6923 return METHOD_SEL_NAME (method_context);
6928 /* Transform a method definition into a function definition as follows:
6929 - synthesize the first two arguments, "self" and "_cmd". */
6932 start_method_def (method)
6937 /* Required to implement _msgSuper. */
6938 method_context = method;
6939 UOBJC_SUPER_decl = NULL_TREE;
6941 /* Must be called BEFORE start_function. */
6944 /* Generate prototype declarations for arguments..."new-style". */
6946 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6947 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6949 /* Really a `struct objc_class *'. However, we allow people to
6950 assign to self, which changes its type midstream. */
6951 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6953 push_parm_decl (build_tree_list
6954 (build_tree_list (decl_specs,
6955 build1 (INDIRECT_REF, NULL_TREE, self_id)),
6956 build_tree_list (unused_list, NULL_TREE)));
6958 #ifdef OBJC_INT_SELECTORS
6959 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
6960 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
6961 push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
6962 build_tree_list (unused_list, NULL_TREE)));
6963 #else /* not OBJC_INT_SELECTORS */
6964 decl_specs = build_tree_list (NULL_TREE,
6965 xref_tag (RECORD_TYPE,
6966 get_identifier (TAG_SELECTOR)));
6967 push_parm_decl (build_tree_list
6968 (build_tree_list (decl_specs,
6969 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
6970 build_tree_list (unused_list, NULL_TREE)));
6971 #endif /* not OBJC_INT_SELECTORS */
6973 /* Generate argument declarations if a keyword_decl. */
6974 if (METHOD_SEL_ARGS (method))
6976 tree arglist = METHOD_SEL_ARGS (method);
6979 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
6980 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
6984 tree last_expr = expr_last (arg_decl);
6986 /* Unite the abstract decl with its name. */
6987 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
6988 push_parm_decl (build_tree_list
6989 (build_tree_list (arg_spec, arg_decl),
6990 build_tree_list (NULL_TREE, NULL_TREE)));
6992 /* Unhook: restore the abstract declarator. */
6993 TREE_OPERAND (last_expr, 0) = NULL_TREE;
6997 push_parm_decl (build_tree_list
6998 (build_tree_list (arg_spec,
6999 KEYWORD_ARG_NAME (arglist)),
7000 build_tree_list (NULL_TREE, NULL_TREE)));
7002 arglist = TREE_CHAIN (arglist);
7007 if (METHOD_ADD_ARGS (method) != NULL_TREE
7008 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7010 /* We have a variable length selector - in "prototype" format. */
7011 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7014 /* This must be done prior to calling pushdecl. pushdecl is
7015 going to change our chain on us. */
7016 tree nextkey = TREE_CHAIN (akey);
7024 warn_with_method (message, mtype, method)
7025 const char *message;
7029 if (count_error (1) == 0)
7032 report_error_function (DECL_SOURCE_FILE (method));
7034 fprintf (stderr, "%s:%d: warning: ",
7035 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
7036 memset (errbuf, 0, BUFSIZE);
7037 fprintf (stderr, "%s `%c%s'\n",
7038 message, mtype, gen_method_decl (method, errbuf));
7041 /* Return 1 if METHOD is consistent with PROTO. */
7044 comp_method_with_proto (method, proto)
7047 static tree function_type = 0;
7049 /* Create a function_type node once. */
7052 function_type = make_node (FUNCTION_TYPE);
7053 ggc_add_tree_root (&function_type, 1);
7056 /* Install argument types - normally set by build_function_type. */
7057 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
7059 /* install return type */
7060 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
7062 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
7065 /* Return 1 if PROTO1 is consistent with PROTO2. */
7068 comp_proto_with_proto (proto0, proto1)
7069 tree proto0, proto1;
7071 static tree function_type[2];
7073 /* Create a couple function_type node's once. */
7074 if (!function_type[0])
7076 function_type[0] = make_node (FUNCTION_TYPE);
7077 function_type[1] = make_node (FUNCTION_TYPE);
7078 ggc_add_tree_root (function_type, 2);
7081 /* Install argument types; normally set by build_function_type. */
7082 TYPE_ARG_TYPES (function_type[0]) = get_arg_type_list (proto0, METHOD_REF, 0);
7083 TYPE_ARG_TYPES (function_type[1]) = get_arg_type_list (proto1, METHOD_REF, 0);
7085 /* Install return type. */
7086 TREE_TYPE (function_type[0]) = groktypename (TREE_TYPE (proto0));
7087 TREE_TYPE (function_type[1]) = groktypename (TREE_TYPE (proto1));
7089 return comptypes (function_type[0], function_type[1]);
7092 /* - Generate an identifier for the function. the format is "_n_cls",
7093 where 1 <= n <= nMethods, and cls is the name the implementation we
7095 - Install the return type from the method declaration.
7096 - If we have a prototype, check for type consistency. */
7099 really_start_method (method, parmlist)
7100 tree method, parmlist;
7102 tree sc_spec, ret_spec, ret_decl, decl_specs;
7103 tree method_decl, method_id;
7104 const char *sel_name, *class_name, *cat_name;
7107 /* Synth the storage class & assemble the return type. */
7108 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7109 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7110 decl_specs = chainon (sc_spec, ret_spec);
7112 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7113 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
7114 cat_name = ((TREE_CODE (implementation_context)
7115 == CLASS_IMPLEMENTATION_TYPE)
7117 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
7120 /* Make sure this is big enough for any plausible method label. */
7121 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7122 + (cat_name ? strlen (cat_name) : 0));
7124 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7125 class_name, cat_name, sel_name, method_slot);
7127 method_id = get_identifier (buf);
7129 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7131 /* Check the declarator portion of the return type for the method. */
7132 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7134 /* Unite the complex decl (specified in the abstract decl) with the
7135 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7136 tree save_expr = expr_last (ret_decl);
7138 TREE_OPERAND (save_expr, 0) = method_decl;
7139 method_decl = ret_decl;
7141 /* Fool the parser into thinking it is starting a function. */
7142 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE);
7144 /* Unhook: this has the effect of restoring the abstract declarator. */
7145 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7150 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7152 /* Fool the parser into thinking it is starting a function. */
7153 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE);
7155 /* Unhook: this has the effect of restoring the abstract declarator. */
7156 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7159 METHOD_DEFINITION (method) = current_function_decl;
7161 if (implementation_template != implementation_context)
7165 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7166 proto = lookup_instance_method_static (implementation_template,
7167 METHOD_SEL_NAME (method));
7169 proto = lookup_class_method_static (implementation_template,
7170 METHOD_SEL_NAME (method));
7172 if (proto && ! comp_method_with_proto (method, proto))
7174 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7176 warn_with_method ("conflicting types for", type, method);
7177 warn_with_method ("previous declaration of", type, proto);
7182 /* The following routine is always called...this "architecture" is to
7183 accommodate "old-style" variable length selectors.
7185 - a:a b:b // prototype ; id c; id d; // old-style. */
7188 continue_method_def ()
7192 if (METHOD_ADD_ARGS (method_context) == objc_ellipsis_node)
7193 /* We have a `, ...' immediately following the selector. */
7194 parmlist = get_parm_info (0);
7196 parmlist = get_parm_info (1); /* place a `void_at_end' */
7198 /* Set self_decl from the first argument...this global is used by
7199 build_ivar_reference calling build_indirect_ref. */
7200 self_decl = TREE_PURPOSE (parmlist);
7203 really_start_method (method_context, parmlist);
7204 store_parm_decls ();
7207 /* Called by the parser, from the `pushlevel' production. */
7212 if (!UOBJC_SUPER_decl)
7214 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7215 build_tree_list (NULL_TREE,
7216 objc_super_template),
7217 0, NULL_TREE, NULL_TREE);
7219 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7221 /* This prevents `unused variable' warnings when compiling with -Wall. */
7222 TREE_USED (UOBJC_SUPER_decl) = 1;
7223 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7227 /* _n_Method (id self, SEL sel, ...)
7229 struct objc_super _S;
7230 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7234 get_super_receiver ()
7238 tree super_expr, super_expr_list;
7240 /* Set receiver to self. */
7241 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7242 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7243 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7245 /* Set class to begin searching. */
7246 super_expr = build_component_ref (UOBJC_SUPER_decl,
7247 get_identifier ("class"));
7249 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7251 /* [_cls, __cls]Super are "pre-built" in
7252 synth_forward_declarations. */
7254 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7255 ((TREE_CODE (method_context)
7256 == INSTANCE_METHOD_DECL)
7258 : uucls_super_ref));
7262 /* We have a category. */
7264 tree super_name = CLASS_SUPER_NAME (implementation_template);
7269 error ("no super class declared in interface for `%s'",
7270 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7271 return error_mark_node;
7274 if (flag_next_runtime)
7276 super_class = get_class_reference (super_name);
7277 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
7279 = build_component_ref (build_indirect_ref (super_class, "->"),
7280 get_identifier ("isa"));
7284 add_class_reference (super_name);
7285 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
7286 ? objc_get_class_decl : objc_get_meta_class_decl);
7287 assemble_external (super_class);
7289 = build_function_call
7293 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7294 IDENTIFIER_POINTER (super_name))));
7297 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7298 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7301 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7303 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7304 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7306 return build_compound_expr (super_expr_list);
7310 error ("[super ...] must appear in a method context");
7311 return error_mark_node;
7316 encode_method_def (func_decl)
7321 HOST_WIDE_INT max_parm_end = 0;
7326 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7327 obstack_object_size (&util_obstack),
7328 OBJC_ENCODE_INLINE_DEFS);
7331 for (parms = DECL_ARGUMENTS (func_decl); parms;
7332 parms = TREE_CHAIN (parms))
7334 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7335 + int_size_in_bytes (TREE_TYPE (parms)));
7337 if (! offset_is_register && parm_end > max_parm_end)
7338 max_parm_end = parm_end;
7341 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7343 sprintf (buffer, "%d", stack_size);
7344 obstack_grow (&util_obstack, buffer, strlen (buffer));
7346 /* Argument types. */
7347 for (parms = DECL_ARGUMENTS (func_decl); parms;
7348 parms = TREE_CHAIN (parms))
7351 encode_type (TREE_TYPE (parms),
7352 obstack_object_size (&util_obstack),
7353 OBJC_ENCODE_INLINE_DEFS);
7355 /* Compute offset. */
7356 sprintf (buffer, "%d", forwarding_offset (parms));
7358 /* Indicate register. */
7359 if (offset_is_register)
7360 obstack_1grow (&util_obstack, '+');
7362 obstack_grow (&util_obstack, buffer, strlen (buffer));
7365 obstack_1grow (&util_obstack, 0);
7366 result = get_identifier (obstack_finish (&util_obstack));
7367 obstack_free (&util_obstack, util_firstobj);
7372 objc_expand_function_end ()
7374 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
7378 finish_method_def ()
7380 lang_expand_function_end = objc_expand_function_end;
7381 finish_function (0);
7382 lang_expand_function_end = NULL;
7384 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7385 since the optimizer may find "may be used before set" errors. */
7386 method_context = NULL_TREE;
7391 lang_report_error_function (decl)
7396 fprintf (stderr, "In method `%s'\n",
7397 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
7407 is_complex_decl (type)
7410 return (TREE_CODE (type) == ARRAY_TYPE
7411 || TREE_CODE (type) == FUNCTION_TYPE
7412 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7416 /* Code to convert a decl node into text for a declaration in C. */
7418 static char tmpbuf[256];
7421 adorn_decl (decl, str)
7425 enum tree_code code = TREE_CODE (decl);
7427 if (code == ARRAY_REF)
7429 tree an_int_cst = TREE_OPERAND (decl, 1);
7431 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7432 sprintf (str + strlen (str), "[%ld]",
7433 (long) TREE_INT_CST_LOW (an_int_cst));
7438 else if (code == ARRAY_TYPE)
7440 tree an_int_cst = TYPE_SIZE (decl);
7441 tree array_of = TREE_TYPE (decl);
7443 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7444 sprintf (str + strlen (str), "[%ld]",
7445 (long) (TREE_INT_CST_LOW (an_int_cst)
7446 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7451 else if (code == CALL_EXPR)
7453 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7458 gen_declaration (chain, str);
7459 chain = TREE_CHAIN (chain);
7466 else if (code == FUNCTION_TYPE)
7468 tree chain = TYPE_ARG_TYPES (decl);
7471 while (chain && TREE_VALUE (chain) != void_type_node)
7473 gen_declaration (TREE_VALUE (chain), str);
7474 chain = TREE_CHAIN (chain);
7475 if (chain && TREE_VALUE (chain) != void_type_node)
7481 else if (code == INDIRECT_REF)
7483 strcpy (tmpbuf, "*");
7484 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7488 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7490 chain = TREE_CHAIN (chain))
7492 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7494 strcat (tmpbuf, " ");
7495 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7499 strcat (tmpbuf, " ");
7501 strcat (tmpbuf, str);
7502 strcpy (str, tmpbuf);
7505 else if (code == POINTER_TYPE)
7507 strcpy (tmpbuf, "*");
7508 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7510 if (TREE_READONLY (decl))
7511 strcat (tmpbuf, " const");
7512 if (TYPE_VOLATILE (decl))
7513 strcat (tmpbuf, " volatile");
7515 strcat (tmpbuf, " ");
7517 strcat (tmpbuf, str);
7518 strcpy (str, tmpbuf);
7523 gen_declarator (decl, buf, name)
7530 enum tree_code code = TREE_CODE (decl);
7540 op = TREE_OPERAND (decl, 0);
7542 /* We have a pointer to a function or array...(*)(), (*)[] */
7543 if ((code == ARRAY_REF || code == CALL_EXPR)
7544 && op && TREE_CODE (op) == INDIRECT_REF)
7547 str = gen_declarator (op, buf, name);
7551 strcpy (tmpbuf, "(");
7552 strcat (tmpbuf, str);
7553 strcat (tmpbuf, ")");
7554 strcpy (str, tmpbuf);
7557 adorn_decl (decl, str);
7566 /* This clause is done iteratively rather than recursively. */
7569 op = (is_complex_decl (TREE_TYPE (decl))
7570 ? TREE_TYPE (decl) : NULL_TREE);
7572 adorn_decl (decl, str);
7574 /* We have a pointer to a function or array...(*)(), (*)[] */
7575 if (code == POINTER_TYPE
7576 && op && (TREE_CODE (op) == FUNCTION_TYPE
7577 || TREE_CODE (op) == ARRAY_TYPE))
7579 strcpy (tmpbuf, "(");
7580 strcat (tmpbuf, str);
7581 strcat (tmpbuf, ")");
7582 strcpy (str, tmpbuf);
7585 decl = (is_complex_decl (TREE_TYPE (decl))
7586 ? TREE_TYPE (decl) : NULL_TREE);
7589 while (decl && (code = TREE_CODE (decl)))
7594 case IDENTIFIER_NODE:
7595 /* Will only happen if we are processing a "raw" expr-decl. */
7596 strcpy (buf, IDENTIFIER_POINTER (decl));
7607 /* We have an abstract declarator or a _DECL node. */
7615 gen_declspecs (declspecs, buf, raw)
7624 for (chain = nreverse (copy_list (declspecs));
7625 chain; chain = TREE_CHAIN (chain))
7627 tree aspec = TREE_VALUE (chain);
7629 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7630 strcat (buf, IDENTIFIER_POINTER (aspec));
7631 else if (TREE_CODE (aspec) == RECORD_TYPE)
7633 if (TYPE_NAME (aspec))
7635 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7637 if (! TREE_STATIC_TEMPLATE (aspec))
7638 strcat (buf, "struct ");
7639 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7644 tree chain = protocol_list;
7651 (PROTOCOL_NAME (TREE_VALUE (chain))));
7652 chain = TREE_CHAIN (chain);
7661 strcat (buf, "untagged struct");
7664 else if (TREE_CODE (aspec) == UNION_TYPE)
7666 if (TYPE_NAME (aspec))
7668 if (! TREE_STATIC_TEMPLATE (aspec))
7669 strcat (buf, "union ");
7670 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7673 strcat (buf, "untagged union");
7676 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7678 if (TYPE_NAME (aspec))
7680 if (! TREE_STATIC_TEMPLATE (aspec))
7681 strcat (buf, "enum ");
7682 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7685 strcat (buf, "untagged enum");
7688 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7689 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7691 else if (IS_ID (aspec))
7693 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7698 tree chain = protocol_list;
7705 (PROTOCOL_NAME (TREE_VALUE (chain))));
7706 chain = TREE_CHAIN (chain);
7713 if (TREE_CHAIN (chain))
7719 /* Type qualifiers. */
7720 if (TREE_READONLY (declspecs))
7721 strcat (buf, "const ");
7722 if (TYPE_VOLATILE (declspecs))
7723 strcat (buf, "volatile ");
7725 switch (TREE_CODE (declspecs))
7727 /* Type specifiers. */
7730 declspecs = TYPE_MAIN_VARIANT (declspecs);
7732 /* Signed integer types. */
7734 if (declspecs == short_integer_type_node)
7735 strcat (buf, "short int ");
7736 else if (declspecs == integer_type_node)
7737 strcat (buf, "int ");
7738 else if (declspecs == long_integer_type_node)
7739 strcat (buf, "long int ");
7740 else if (declspecs == long_long_integer_type_node)
7741 strcat (buf, "long long int ");
7742 else if (declspecs == signed_char_type_node
7743 || declspecs == char_type_node)
7744 strcat (buf, "char ");
7746 /* Unsigned integer types. */
7748 else if (declspecs == short_unsigned_type_node)
7749 strcat (buf, "unsigned short ");
7750 else if (declspecs == unsigned_type_node)
7751 strcat (buf, "unsigned int ");
7752 else if (declspecs == long_unsigned_type_node)
7753 strcat (buf, "unsigned long ");
7754 else if (declspecs == long_long_unsigned_type_node)
7755 strcat (buf, "unsigned long long ");
7756 else if (declspecs == unsigned_char_type_node)
7757 strcat (buf, "unsigned char ");
7761 declspecs = TYPE_MAIN_VARIANT (declspecs);
7763 if (declspecs == float_type_node)
7764 strcat (buf, "float ");
7765 else if (declspecs == double_type_node)
7766 strcat (buf, "double ");
7767 else if (declspecs == long_double_type_node)
7768 strcat (buf, "long double ");
7772 if (TYPE_NAME (declspecs)
7773 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7775 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7777 if (! TREE_STATIC_TEMPLATE (declspecs))
7778 strcat (buf, "struct ");
7779 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7783 tree chain = protocol_list;
7790 (PROTOCOL_NAME (TREE_VALUE (chain))));
7791 chain = TREE_CHAIN (chain);
7800 strcat (buf, "untagged struct");
7806 if (TYPE_NAME (declspecs)
7807 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7809 strcat (buf, "union ");
7810 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7815 strcat (buf, "untagged union ");
7819 if (TYPE_NAME (declspecs)
7820 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7822 strcat (buf, "enum ");
7823 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7828 strcat (buf, "untagged enum ");
7832 strcat (buf, "void ");
7837 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7842 tree chain = protocol_list;
7849 (PROTOCOL_NAME (TREE_VALUE (chain))));
7850 chain = TREE_CHAIN (chain);
7867 gen_declaration (atype_or_adecl, buf)
7868 tree atype_or_adecl;
7873 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7875 tree declspecs; /* "identifier_node", "record_type" */
7876 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7878 /* We have a "raw", abstract declarator (typename). */
7879 declarator = TREE_VALUE (atype_or_adecl);
7880 declspecs = TREE_PURPOSE (atype_or_adecl);
7882 gen_declspecs (declspecs, buf, 1);
7886 strcat (buf, gen_declarator (declarator, declbuf, ""));
7893 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7894 tree declarator; /* "array_type", "function_type", "pointer_type". */
7896 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7897 || TREE_CODE (atype_or_adecl) == PARM_DECL
7898 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7899 atype = TREE_TYPE (atype_or_adecl);
7901 /* Assume we have a *_type node. */
7902 atype = atype_or_adecl;
7904 if (is_complex_decl (atype))
7908 /* Get the declaration specifier; it is at the end of the list. */
7909 declarator = chain = atype;
7911 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7912 while (is_complex_decl (chain));
7919 declarator = NULL_TREE;
7922 gen_declspecs (declspecs, buf, 0);
7924 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7925 || TREE_CODE (atype_or_adecl) == PARM_DECL
7926 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7928 const char *decl_name =
7929 (DECL_NAME (atype_or_adecl)
7930 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7935 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7938 else if (decl_name[0])
7941 strcat (buf, decl_name);
7944 else if (declarator)
7947 strcat (buf, gen_declarator (declarator, declbuf, ""));
7954 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7957 gen_method_decl (method, buf)
7963 if (RAW_TYPESPEC (method) != objc_object_reference)
7966 gen_declaration (TREE_TYPE (method), buf);
7970 chain = METHOD_SEL_ARGS (method);
7973 /* We have a chain of keyword_decls. */
7976 if (KEYWORD_KEY_NAME (chain))
7977 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7980 if (RAW_TYPESPEC (chain) != objc_object_reference)
7983 gen_declaration (TREE_TYPE (chain), buf);
7987 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7988 if ((chain = TREE_CHAIN (chain)))
7993 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
7994 strcat (buf, ", ...");
7995 else if (METHOD_ADD_ARGS (method))
7997 /* We have a tree list node as generate by get_parm_info. */
7998 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8000 /* Know we have a chain of parm_decls. */
8004 gen_declaration (chain, buf);
8005 chain = TREE_CHAIN (chain);
8011 /* We have a unary selector. */
8012 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8020 dump_interface (fp, chain)
8024 char *buf = (char *)xmalloc (256);
8025 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8026 tree ivar_decls = CLASS_RAW_IVARS (chain);
8027 tree nst_methods = CLASS_NST_METHODS (chain);
8028 tree cls_methods = CLASS_CLS_METHODS (chain);
8030 fprintf (fp, "\n@interface %s", my_name);
8032 if (CLASS_SUPER_NAME (chain))
8034 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8035 fprintf (fp, " : %s\n", super_name);
8042 fprintf (fp, "{\n");
8045 memset (buf, 0, 256);
8046 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8047 ivar_decls = TREE_CHAIN (ivar_decls);
8050 fprintf (fp, "}\n");
8055 memset (buf, 0, 256);
8056 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8057 nst_methods = TREE_CHAIN (nst_methods);
8062 memset (buf, 0, 256);
8063 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8064 cls_methods = TREE_CHAIN (cls_methods);
8066 fprintf (fp, "\n@end");
8069 /* Demangle function for Objective-C */
8071 objc_demangle (mangled)
8072 const char *mangled;
8074 char *demangled, *cp;
8076 if (mangled[0] == '_' &&
8077 (mangled[1] == 'i' || mangled[1] == 'c') &&
8080 cp = demangled = xmalloc(strlen(mangled) + 2);
8081 if (mangled[1] == 'i')
8082 *cp++ = '-'; /* for instance method */
8084 *cp++ = '+'; /* for class method */
8085 *cp++ = '['; /* opening left brace */
8086 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8087 while (*cp && *cp == '_')
8088 cp++; /* skip any initial underbars in class name */
8089 cp = strchr(cp, '_'); /* find first non-initial underbar */
8092 free(demangled); /* not mangled name */
8095 if (cp[1] == '_') /* easy case: no category name */
8097 *cp++ = ' '; /* replace two '_' with one ' ' */
8098 strcpy(cp, mangled + (cp - demangled) + 2);
8102 *cp++ = '('; /* less easy case: category name */
8103 cp = strchr(cp, '_');
8106 free(demangled); /* not mangled name */
8110 *cp++ = ' '; /* overwriting 1st char of method name... */
8111 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8113 while (*cp && *cp == '_')
8114 cp++; /* skip any initial underbars in method name */
8117 *cp = ':'; /* replace remaining '_' with ':' */
8118 *cp++ = ']'; /* closing right brace */
8119 *cp++ = 0; /* string terminator */
8123 return mangled; /* not an objc mangled name */
8127 objc_printable_name (decl, kind)
8129 int kind ATTRIBUTE_UNUSED;
8131 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8137 /* Add the special tree codes of Objective C to the tables. */
8139 #define LAST_CODE LAST_C_TREE_CODE
8141 gcc_obstack_init (&util_obstack);
8142 util_firstobj = (char *) obstack_finish (&util_obstack);
8144 memcpy (tree_code_type + (int) LAST_CODE,
8145 objc_tree_code_type,
8146 (int) LAST_OBJC_TREE_CODE - (int) LAST_CODE);
8147 memcpy (tree_code_length + (int) LAST_CODE,
8148 objc_tree_code_length,
8149 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) * sizeof (int)));
8150 memcpy (tree_code_name + (int) LAST_CODE,
8151 objc_tree_code_name,
8152 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) * sizeof (char *)));
8154 errbuf = (char *)xmalloc (BUFSIZE);
8156 synth_module_prologue ();
8158 /* Change the default error function */
8159 decl_printable_name = objc_printable_name;
8160 lang_expand_expr = c_expand_expr;
8161 lang_expand_decl_stmt = c_expand_decl_stmt;
8167 struct imp_entry *impent;
8169 /* The internally generated initializers appear to have missing braces.
8170 Don't warn about this. */
8171 int save_warn_missing_braces = warn_missing_braces;
8172 warn_missing_braces = 0;
8174 generate_forward_declaration_to_string_table ();
8176 #ifdef OBJC_PROLOGUE
8180 /* Process the static instances here because initialization of objc_symtab
8182 if (objc_static_instances)
8183 generate_static_references ();
8185 if (implementation_context || class_names_chain
8186 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8187 generate_objc_symtab_decl ();
8189 for (impent = imp_list; impent; impent = impent->next)
8191 implementation_context = impent->imp_context;
8192 implementation_template = impent->imp_template;
8194 UOBJC_CLASS_decl = impent->class_decl;
8195 UOBJC_METACLASS_decl = impent->meta_decl;
8197 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8199 /* all of the following reference the string pool... */
8200 generate_ivar_lists ();
8201 generate_dispatch_tables ();
8202 generate_shared_structures ();
8206 generate_dispatch_tables ();
8207 generate_category (implementation_context);
8211 /* If we are using an array of selectors, we must always
8212 finish up the array decl even if no selectors were used. */
8213 if (! flag_next_runtime || sel_ref_chain)
8214 build_selector_translation_table ();
8217 generate_protocols ();
8219 if (implementation_context || class_names_chain || objc_static_instances
8220 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8222 /* Arrange for Objc data structures to be initialized at run time. */
8223 const char *init_name = build_module_descriptor ();
8225 assemble_constructor (init_name);
8228 /* Dump the class references. This forces the appropriate classes
8229 to be linked into the executable image, preserving unix archive
8230 semantics. This can be removed when we move to a more dynamically
8231 linked environment. */
8233 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8235 handle_class_ref (chain);
8236 if (TREE_PURPOSE (chain))
8237 generate_classref_translation_entry (chain);
8240 for (impent = imp_list; impent; impent = impent->next)
8241 handle_impent (impent);
8243 /* Dump the string table last. */
8245 generate_strings ();
8247 if (flag_gen_declaration)
8249 add_class (implementation_context);
8250 dump_interface (gen_declaration_file, implementation_context);
8258 /* Run through the selector hash tables and print a warning for any
8259 selector which has multiple methods. */
8261 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8262 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8265 tree meth = hsh->key;
8266 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8270 warning ("potential selector conflict for method `%s'",
8271 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8272 warn_with_method ("found", type, meth);
8273 for (loop = hsh->list; loop; loop = loop->next)
8274 warn_with_method ("found", type, loop->value);
8277 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8278 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8281 tree meth = hsh->key;
8282 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8286 warning ("potential selector conflict for method `%s'",
8287 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8288 warn_with_method ("found", type, meth);
8289 for (loop = hsh->list; loop; loop = loop->next)
8290 warn_with_method ("found", type, loop->value);
8294 warn_missing_braces = save_warn_missing_braces;
8297 /* Subroutines of finish_objc. */
8300 generate_classref_translation_entry (chain)
8303 tree expr, name, decl_specs, decl, sc_spec;
8306 type = TREE_TYPE (TREE_PURPOSE (chain));
8308 expr = add_objc_string (TREE_VALUE (chain), class_names);
8309 expr = build_c_cast (type, expr); /* cast! */
8311 name = DECL_NAME (TREE_PURPOSE (chain));
8313 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8315 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8316 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8318 /* The decl that is returned from start_decl is the one that we
8319 forward declared in build_class_reference. */
8320 decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
8321 finish_decl (decl, expr, NULL_TREE);
8326 handle_class_ref (chain)
8329 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8330 if (! flag_next_runtime)
8333 char *string = (char *) alloca (strlen (name) + 30);
8336 sprintf (string, "%sobjc_class_name_%s",
8337 (flag_next_runtime ? "." : "__"), name);
8339 /* Make a decl for this name, so we can use its address in a tree. */
8340 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8341 DECL_EXTERNAL (decl) = 1;
8342 TREE_PUBLIC (decl) = 1;
8345 rest_of_decl_compilation (decl, 0, 0, 0);
8347 /* Make following constant read-only (why not)? */
8348 readonly_data_section ();
8350 exp = build1 (ADDR_EXPR, string_type_node, decl);
8352 /* Align the section properly. */
8353 assemble_constant_align (exp);
8355 /* Inform the assembler about this new external thing. */
8356 assemble_external (decl);
8358 /* Output a constant to reference this address. */
8359 output_constant (exp, int_size_in_bytes (string_type_node));
8363 /* This overreliance on our assembler (i.e. lack of portability)
8364 should be dealt with at some point. The GNU strategy (above)
8365 won't work either, but it is a start. */
8366 char *string = (char *) alloca (strlen (name) + 30);
8367 sprintf (string, ".reference .objc_class_name_%s", name);
8368 assemble_asm (my_build_string (strlen (string) + 1, string));
8373 handle_impent (impent)
8374 struct imp_entry *impent;
8376 implementation_context = impent->imp_context;
8377 implementation_template = impent->imp_template;
8379 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8381 const char *class_name =
8382 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8383 char *string = (char *) alloca (strlen (class_name) + 30);
8385 if (flag_next_runtime)
8387 /* Grossly unportable.
8388 People should know better than to assume
8389 such things about assembler syntax! */
8390 sprintf (string, ".objc_class_name_%s=0", class_name);
8391 assemble_asm (my_build_string (strlen (string) + 1, string));
8393 sprintf (string, ".globl .objc_class_name_%s", class_name);
8394 assemble_asm (my_build_string (strlen (string) + 1, string));
8399 sprintf (string, "%sobjc_class_name_%s",
8400 (flag_next_runtime ? "." : "__"), class_name);
8401 assemble_global (string);
8402 assemble_label (string);
8406 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8408 const char *class_name =
8409 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8410 const char *class_super_name =
8411 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8412 char *string = (char *) alloca (strlen (class_name)
8413 + strlen (class_super_name) + 30);
8415 /* Do the same for categories. Even though no references to these
8416 symbols are generated automatically by the compiler, it gives
8417 you a handle to pull them into an archive by hand. */
8418 if (flag_next_runtime)
8420 /* Grossly unportable. */
8421 sprintf (string, ".objc_category_name_%s_%s=0",
8422 class_name, class_super_name);
8423 assemble_asm (my_build_string (strlen (string) + 1, string));
8425 sprintf (string, ".globl .objc_category_name_%s_%s",
8426 class_name, class_super_name);
8427 assemble_asm (my_build_string (strlen (string) + 1, string));
8432 sprintf (string, "%sobjc_category_name_%s_%s",
8433 (flag_next_runtime ? "." : "__"),
8434 class_name, class_super_name);
8435 assemble_global (string);
8436 assemble_label (string);
8447 char *buf = (char *)xmalloc (256);
8449 { /* dump function prototypes */
8450 tree loop = UOBJC_MODULES_decl;
8452 fprintf (fp, "\n\nfunction prototypes:\n");
8455 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
8457 /* We have a function definition: generate prototype. */
8458 memset (errbuf, 0, BUFSIZE);
8459 gen_declaration (loop, errbuf);
8460 fprintf (fp, "%s;\n", errbuf);
8462 loop = TREE_CHAIN (loop);
8466 /* Dump global chains. */
8468 int i, index = 0, offset = 0;
8471 for (i = 0; i < SIZEHASHTABLE; i++)
8473 if (hashlist = nst_method_hash_list[i])
8475 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
8478 memset (buf, 0, 256);
8479 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8480 hashlist = hashlist->next;
8486 for (i = 0; i < SIZEHASHTABLE; i++)
8488 if (hashlist = cls_method_hash_list[i])
8490 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
8493 memset (buf, 0, 256);
8494 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8495 hashlist = hashlist->next;
8501 fprintf (fp, "\nsel_refdef_chain:\n");
8502 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
8504 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
8505 IDENTIFIER_POINTER (TREE_VALUE (loop)));
8507 /* add one for the '\0' character */
8508 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
8511 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
8517 print_lang_statistics ()
8522 ggc_mark_imp_list (arg)
8525 struct imp_entry *impent;
8527 for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
8529 ggc_mark_tree (impent->imp_context);
8530 ggc_mark_tree (impent->imp_template);
8531 ggc_mark_tree (impent->class_decl);
8532 ggc_mark_tree (impent->meta_decl);
8537 ggc_mark_hash_table (arg)
8540 hash *hash_table = *(hash **)arg;
8545 if (hash_table == NULL)
8547 for (i = 0; i < SIZEHASHTABLE; i++)
8548 for (hst = hash_table [i]; hst; hst = hst->next)
8550 ggc_mark_tree (hst->key);
8551 for (list = hst->list; list; list = list->next)
8552 ggc_mark_tree (list->value);
8556 /* Add GC roots for variables local to this file. */
8558 objc_act_parse_init ()
8560 ggc_add_tree_root (&objc_ellipsis_node, 1);
8561 ggc_add_tree_root (objc_global_trees, OCTI_MAX);
8562 ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
8563 ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
8564 ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
8567 /* Look up ID as an instance variable. */
8569 lookup_objc_ivar (id)
8574 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8575 /* we have a message to super */
8576 return get_super_receiver ();
8577 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8579 if (is_private (decl))
8580 return error_mark_node;
8582 return build_ivar_reference (id);
8588 /* Parser callbacks. */
8590 forget_protocol_qualifiers ()
8592 C_IS_RESERVED_WORD (ridpointers[(int) RID_IN]) = 0;
8593 C_IS_RESERVED_WORD (ridpointers[(int) RID_OUT]) = 0;
8594 C_IS_RESERVED_WORD (ridpointers[(int) RID_INOUT]) = 0;
8595 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYCOPY]) = 0;
8596 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYREF]) = 0;
8597 C_IS_RESERVED_WORD (ridpointers[(int) RID_ONEWAY]) = 0;
8601 remember_protocol_qualifiers ()
8603 C_IS_RESERVED_WORD (ridpointers[(int) RID_IN]) = 1;
8604 C_IS_RESERVED_WORD (ridpointers[(int) RID_OUT]) = 1;
8605 C_IS_RESERVED_WORD (ridpointers[(int) RID_INOUT]) = 1;
8606 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYCOPY]) = 1;
8607 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYREF]) = 1;
8608 C_IS_RESERVED_WORD (ridpointers[(int) RID_ONEWAY]) = 1;