1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
40 - OBJC_INT_SELECTORS */
61 extern cpp_reader parse_in;
64 /* This is the default way of generating a method name. */
65 /* I am not sure it is really correct.
66 Perhaps there's a danger that it will make name conflicts
67 if method names contain underscores. -- rms. */
68 #ifndef OBJC_GEN_METHOD_LABEL
69 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
72 sprintf ((BUF), "_%s_%s_%s_%s", \
73 ((IS_INST) ? "i" : "c"), \
75 ((CAT_NAME)? (CAT_NAME) : ""), \
77 for (temp = (BUF); *temp; temp++) \
78 if (*temp == ':') *temp = '_'; \
82 /* These need specifying. */
83 #ifndef OBJC_FORWARDING_STACK_OFFSET
84 #define OBJC_FORWARDING_STACK_OFFSET 0
87 #ifndef OBJC_FORWARDING_MIN_OFFSET
88 #define OBJC_FORWARDING_MIN_OFFSET 0
91 /* Define the special tree codes that we use. */
93 /* Table indexed by tree code giving a string containing a character
94 classifying the tree code. Possibilities are
95 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
97 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
99 static const char objc_tree_code_type[] = {
101 #include "objc-tree.def"
105 /* Table indexed by tree code giving number of expression
106 operands beyond the fixed part of the node structure.
107 Not used for types or decls. */
109 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
111 static const int objc_tree_code_length[] = {
113 #include "objc-tree.def"
117 /* Names of tree components.
118 Used for printing out the tree and error messages. */
119 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
121 static const char * const objc_tree_code_name[] = {
123 #include "objc-tree.def"
127 /* Set up for use of obstacks. */
131 #define obstack_chunk_alloc xmalloc
132 #define obstack_chunk_free free
134 /* This obstack is used to accumulate the encoding of a data type. */
135 static struct obstack util_obstack;
136 /* This points to the beginning of obstack contents,
137 so we can free the whole contents. */
140 /* for encode_method_def */
143 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
144 #define PROTOCOL_VERSION 2
146 #define OBJC_ENCODE_INLINE_DEFS 0
147 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
149 /*** Private Interface (procedures) ***/
151 /* Used by compile_file. */
153 static void init_objc PARAMS ((void));
154 static void finish_objc PARAMS ((void));
156 /* Code generation. */
158 static void synth_module_prologue PARAMS ((void));
159 static tree build_constructor PARAMS ((tree, tree));
160 static const char *build_module_descriptor PARAMS ((void));
161 static tree init_module_descriptor PARAMS ((tree));
162 static tree build_objc_method_call PARAMS ((int, tree, tree,
164 static void generate_strings PARAMS ((void));
165 static tree get_proto_encoding PARAMS ((tree));
166 static void build_selector_translation_table PARAMS ((void));
167 static tree build_ivar_chain PARAMS ((tree, int));
169 static tree objc_add_static_instance PARAMS ((tree, tree));
171 static tree build_ivar_template PARAMS ((void));
172 static tree build_method_template PARAMS ((void));
173 static tree build_private_template PARAMS ((tree));
174 static void build_class_template PARAMS ((void));
175 static void build_selector_template PARAMS ((void));
176 static void build_category_template PARAMS ((void));
177 static tree build_super_template PARAMS ((void));
178 static tree build_category_initializer PARAMS ((tree, tree, tree,
180 static tree build_protocol_initializer PARAMS ((tree, tree, tree,
183 static void synth_forward_declarations PARAMS ((void));
184 static void generate_ivar_lists PARAMS ((void));
185 static void generate_dispatch_tables PARAMS ((void));
186 static void generate_shared_structures PARAMS ((void));
187 static tree generate_protocol_list PARAMS ((tree));
188 static void generate_forward_declaration_to_string_table PARAMS ((void));
189 static void build_protocol_reference PARAMS ((tree));
192 static tree init_selector PARAMS ((int));
194 static tree build_keyword_selector PARAMS ((tree));
195 static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
197 static void generate_static_references PARAMS ((void));
198 static int check_methods_accessible PARAMS ((tree, tree,
200 static void encode_aggregate_within PARAMS ((tree, int, int,
202 static const char *objc_demangle PARAMS ((const char *));
203 static const char *objc_printable_name PARAMS ((tree, int));
204 static void objc_expand_function_end PARAMS ((void));
206 /* Misc. bookkeeping */
208 typedef struct hashed_entry *hash;
209 typedef struct hashed_attribute *attr;
211 struct hashed_attribute
223 static void hash_init PARAMS ((void));
224 static void hash_enter PARAMS ((hash *, tree));
225 static hash hash_lookup PARAMS ((hash *, tree));
226 static void hash_add_attr PARAMS ((hash, tree));
227 static tree lookup_method PARAMS ((tree, tree));
228 static tree lookup_instance_method_static PARAMS ((tree, tree));
229 static tree lookup_class_method_static PARAMS ((tree, tree));
230 static tree add_class PARAMS ((tree));
231 static void add_category PARAMS ((tree, tree));
235 class_names, /* class, category, protocol, module names */
236 meth_var_names, /* method and variable names */
237 meth_var_types /* method and variable type descriptors */
240 static tree add_objc_string PARAMS ((tree,
241 enum string_section));
242 static tree get_objc_string_decl PARAMS ((tree,
243 enum string_section));
244 static tree build_objc_string_decl PARAMS ((enum string_section));
245 static tree build_selector_reference_decl PARAMS ((void));
247 /* Protocol additions. */
249 static tree add_protocol PARAMS ((tree));
250 static tree lookup_protocol PARAMS ((tree));
251 static tree lookup_and_install_protocols PARAMS ((tree));
255 static void encode_type_qualifiers PARAMS ((tree));
256 static void encode_pointer PARAMS ((tree, int, int));
257 static void encode_array PARAMS ((tree, int, int));
258 static void encode_aggregate PARAMS ((tree, int, int));
259 static void encode_bitfield PARAMS ((int));
260 static void encode_type PARAMS ((tree, int, int));
261 static void encode_field_decl PARAMS ((tree, int, int));
263 static void really_start_method PARAMS ((tree, tree));
264 static int comp_method_with_proto PARAMS ((tree, tree));
265 static int comp_proto_with_proto PARAMS ((tree, tree));
266 static tree get_arg_type_list PARAMS ((tree, int, int));
267 static tree expr_last PARAMS ((tree));
269 /* Utilities for debugging and error diagnostics. */
271 static void warn_with_method PARAMS ((const char *, int, tree));
272 static void error_with_ivar PARAMS ((const char *, tree, tree));
273 static char *gen_method_decl PARAMS ((tree, char *));
274 static char *gen_declaration PARAMS ((tree, char *));
275 static char *gen_declarator PARAMS ((tree, char *,
277 static int is_complex_decl PARAMS ((tree));
278 static void adorn_decl PARAMS ((tree, char *));
279 static void dump_interface PARAMS ((FILE *, tree));
281 /* Everything else. */
283 static void objc_fatal PARAMS ((void))
285 static tree define_decl PARAMS ((tree, tree));
286 static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
287 static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
288 static tree create_builtin_decl PARAMS ((enum tree_code,
289 tree, const char *));
290 static tree my_build_string PARAMS ((int, const char *));
291 static void build_objc_symtab_template PARAMS ((void));
292 static tree init_def_list PARAMS ((tree));
293 static tree init_objc_symtab PARAMS ((tree));
294 static void forward_declare_categories PARAMS ((void));
295 static void generate_objc_symtab_decl PARAMS ((void));
296 static tree build_selector PARAMS ((tree));
298 static tree build_msg_pool_reference PARAMS ((int));
300 static tree build_typed_selector_reference PARAMS ((tree, tree));
301 static tree build_selector_reference PARAMS ((tree));
302 static tree build_class_reference_decl PARAMS ((void));
303 static void add_class_reference PARAMS ((tree));
304 static tree objc_copy_list PARAMS ((tree, tree *));
305 static tree build_protocol_template PARAMS ((void));
306 static tree build_descriptor_table_initializer PARAMS ((tree, tree));
307 static tree build_method_prototype_list_template PARAMS ((tree, int));
308 static tree build_method_prototype_template PARAMS ((void));
309 static int forwarding_offset PARAMS ((tree));
310 static tree encode_method_prototype PARAMS ((tree, tree));
311 static tree generate_descriptor_table PARAMS ((tree, const char *,
313 static void generate_method_descriptors PARAMS ((tree));
314 static tree build_tmp_function_decl PARAMS ((void));
315 static void hack_method_prototype PARAMS ((tree, tree));
316 static void generate_protocol_references PARAMS ((tree));
317 static void generate_protocols PARAMS ((void));
318 static void check_ivars PARAMS ((tree, tree));
319 static tree build_ivar_list_template PARAMS ((tree, int));
320 static tree build_method_list_template PARAMS ((tree, int));
321 static tree build_ivar_list_initializer PARAMS ((tree, tree));
322 static tree generate_ivars_list PARAMS ((tree, const char *,
324 static tree build_dispatch_table_initializer PARAMS ((tree, tree));
325 static tree generate_dispatch_table PARAMS ((tree, const char *,
327 static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
328 tree, int, tree, tree,
330 static void generate_category PARAMS ((tree));
331 static int is_objc_type_qualifier PARAMS ((tree));
332 static tree adjust_type_for_id_default PARAMS ((tree));
333 static tree check_duplicates PARAMS ((hash));
334 static tree receiver_is_class_object PARAMS ((tree));
335 static int check_methods PARAMS ((tree, tree, int));
336 static int conforms_to_protocol PARAMS ((tree, tree));
337 static void check_protocols PARAMS ((tree, const char *,
339 static tree encode_method_def PARAMS ((tree));
340 static void gen_declspecs PARAMS ((tree, char *, int));
341 static void generate_classref_translation_entry PARAMS ((tree));
342 static void handle_class_ref PARAMS ((tree));
343 static void generate_struct_by_value_array PARAMS ((void))
345 static void objc_act_parse_init PARAMS ((void));
346 static void ggc_mark_imp_list PARAMS ((void *));
347 static void ggc_mark_hash_table PARAMS ((void *));
349 /*** Private Interface (data) ***/
351 /* Reserved tag definitions. */
354 #define TAG_OBJECT "objc_object"
355 #define TAG_CLASS "objc_class"
356 #define TAG_SUPER "objc_super"
357 #define TAG_SELECTOR "objc_selector"
359 #define UTAG_CLASS "_objc_class"
360 #define UTAG_IVAR "_objc_ivar"
361 #define UTAG_IVAR_LIST "_objc_ivar_list"
362 #define UTAG_METHOD "_objc_method"
363 #define UTAG_METHOD_LIST "_objc_method_list"
364 #define UTAG_CATEGORY "_objc_category"
365 #define UTAG_MODULE "_objc_module"
366 #define UTAG_STATICS "_objc_statics"
367 #define UTAG_SYMTAB "_objc_symtab"
368 #define UTAG_SUPER "_objc_super"
369 #define UTAG_SELECTOR "_objc_selector"
371 #define UTAG_PROTOCOL "_objc_protocol"
372 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
373 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
374 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
376 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
377 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
379 static const char *constant_string_class_name = NULL;
381 static const char *TAG_GETCLASS;
382 static const char *TAG_GETMETACLASS;
383 static const char *TAG_MSGSEND;
384 static const char *TAG_MSGSENDSUPER;
385 static const char *TAG_EXECCLASS;
387 /* Set by `continue_class' and checked by `is_public'. */
389 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
390 #define TYPED_OBJECT(type) \
391 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
393 tree objc_ellipsis_node;
398 OCTI_STATIC_NST_DECL,
404 OCTI_UMSG_SUPER_DECL,
406 OCTI_GET_MCLASS_DECL,
420 OCTI_CLS_NAMES_CHAIN,
421 OCTI_METH_VAR_NAMES_CHAIN,
422 OCTI_METH_VAR_TYPES_CHAIN,
444 OCTI_UUCLS_SUPER_REF,
462 static tree objc_global_trees[OCTI_MAX];
464 /* List of classes with list of their static instances. */
465 #define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
467 /* The declaration of the array administrating the static instances. */
468 #define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
470 /* Some commonly used instances of "identifier_node". */
472 #define self_id objc_global_trees[OCTI_SELF_ID]
473 #define ucmd_id objc_global_trees[OCTI_UCMD_ID]
474 #define unused_list objc_global_trees[OCTI_UNUSED_LIST]
476 #define self_decl objc_global_trees[OCTI_SELF_DECL]
477 #define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
478 #define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
479 #define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
480 #define objc_get_meta_class_decl \
481 objc_global_trees[OCTI_GET_MCLASS_DECL]
483 #define super_type objc_global_trees[OCTI_SUPER_TYPE]
484 #define selector_type objc_global_trees[OCTI_SEL_TYPE]
485 #define id_type objc_global_trees[OCTI_ID_TYPE]
486 #define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
487 #define instance_type objc_global_trees[OCTI_NST_TYPE]
488 #define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
490 /* Type checking macros. */
492 #define IS_ID(TYPE) \
493 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
494 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
495 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
496 #define IS_SUPER(TYPE) \
497 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
499 #define class_chain objc_global_trees[OCTI_CLS_CHAIN]
500 #define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
501 #define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
502 #define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
504 /* Chains to manage selectors that are referenced and defined in the
507 #define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
508 #define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
510 /* Chains to manage uniquing of strings. */
512 #define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
513 #define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
514 #define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
516 /* Hash tables to manage the global pool of method prototypes. */
518 static hash *nst_method_hash_list = 0;
519 static hash *cls_method_hash_list = 0;
521 /* Backend data declarations. */
523 #define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
524 #define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
525 #define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
526 #define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
527 #define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
528 #define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
529 #define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
530 #define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
531 #define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
532 #define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
534 /* The following are used when compiling a class implementation.
535 implementation_template will normally be an interface, however if
536 none exists this will be equal to implementation_context...it is
537 set in start_class. */
539 #define implementation_context objc_global_trees[OCTI_IMPL_CTX]
540 #define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
544 struct imp_entry *next;
547 tree class_decl; /* _OBJC_CLASS_<my_name>; */
548 tree meta_decl; /* _OBJC_METACLASS_<my_name>; */
551 static void handle_impent PARAMS ((struct imp_entry *));
553 static struct imp_entry *imp_list = 0;
554 static int imp_count = 0; /* `@implementation' */
555 static int cat_count = 0; /* `@category' */
557 #define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
558 #define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
559 #define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
560 #define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
561 #define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
562 #define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
563 #define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
565 #define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
566 #define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
567 #define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
568 #define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
569 #define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
570 #define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
572 #define objc_object_id objc_global_trees[OCTI_OBJ_ID]
573 #define objc_class_id objc_global_trees[OCTI_CLS_ID]
574 #define objc_id_id objc_global_trees[OCTI_ID_ID]
575 #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
576 #define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
577 #define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
579 #define method_context objc_global_trees[OCTI_METH_CTX]
580 static int method_slot = 0; /* Used by start_method_def, */
584 static char *errbuf; /* Buffer for error diagnostics */
586 /* Data imported from tree.c. */
588 extern enum debug_info_type write_symbols;
590 /* Data imported from toplev.c. */
592 extern const char *dump_base_name;
594 /* Generate code for GNU or NeXT runtime environment. */
596 #ifdef NEXT_OBJC_RUNTIME
597 int flag_next_runtime = 1;
599 int flag_next_runtime = 0;
602 int flag_typed_selectors;
604 /* Open and close the file for outputting class declarations, if requested. */
606 int flag_gen_declaration = 0;
608 FILE *gen_declaration_file;
610 /* Warn if multiple methods are seen for the same selector, but with
611 different argument types. */
613 int warn_selector = 0;
615 /* Warn if methods required by a protocol are not implemented in the
616 class adopting it. When turned off, methods inherited to that
617 class are also considered implemented */
619 int flag_warn_protocol = 1;
621 /* Tells "encode_pointer/encode_aggregate" whether we are generating
622 type descriptors for instance variables (as opposed to methods).
623 Type descriptors for instance variables contain more information
624 than methods (for static typing and embedded structures). This
625 was added to support features being planned for dbkit2. */
627 static int generating_instance_variables = 0;
629 /* Tells the compiler that this is a special run. Do not perform
630 any compiling, instead we are to test some platform dependent
631 features and output a C header file with appropriate definitions. */
633 static int print_struct_values = 0;
635 /* Some platforms pass small structures through registers versus through
636 an invisible pointer. Determine at what size structure is the
637 transition point between the two possibilities. */
640 generate_struct_by_value_array ()
643 tree field_decl, field_decl_chain;
645 int aggregate_in_mem[32];
648 /* Presumbaly no platform passes 32 byte structures in a register. */
649 for (i = 1; i < 32; i++)
653 /* Create an unnamed struct that has `i' character components */
654 type = start_struct (RECORD_TYPE, NULL_TREE);
656 strcpy (buffer, "c1");
657 field_decl = create_builtin_decl (FIELD_DECL,
660 field_decl_chain = field_decl;
662 for (j = 1; j < i; j++)
664 sprintf (buffer, "c%d", j + 1);
665 field_decl = create_builtin_decl (FIELD_DECL,
668 chainon (field_decl_chain, field_decl);
670 finish_struct (type, field_decl_chain, NULL_TREE);
672 aggregate_in_mem[i] = aggregate_value_p (type);
673 if (!aggregate_in_mem[i])
677 /* We found some structures that are returned in registers instead of memory
678 so output the necessary data. */
681 for (i = 31; i >= 0; i--)
682 if (!aggregate_in_mem[i])
684 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
686 /* The first member of the structure is always 0 because we don't handle
687 structures with 0 members */
688 printf ("static int struct_forward_array[] = {\n 0");
690 for (j = 1; j <= i; j++)
691 printf (", %d", aggregate_in_mem[j]);
703 cpp_reader_init (&parse_in, CLK_GNUC89);
711 /* The beginning of the file is a new line; check for #.
712 With luck, we discover the real source file's name from that
713 and put it in input_filename. */
714 ungetc (check_newline (), finput);
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 /* If gen_declaration desired, open the output file. */
722 if (flag_gen_declaration)
724 register char * const dumpname = concat (dumpname, ".decl", NULL);
725 gen_declaration_file = fopen (dumpname, "w");
726 if (gen_declaration_file == 0)
727 pfatal_with_name (dumpname);
731 if (flag_next_runtime)
733 TAG_GETCLASS = "objc_getClass";
734 TAG_GETMETACLASS = "objc_getMetaClass";
735 TAG_MSGSEND = "objc_msgSend";
736 TAG_MSGSENDSUPER = "objc_msgSendSuper";
737 TAG_EXECCLASS = "__objc_execClass";
741 TAG_GETCLASS = "objc_get_class";
742 TAG_GETMETACLASS = "objc_get_meta_class";
743 TAG_MSGSEND = "objc_msg_lookup";
744 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
745 TAG_EXECCLASS = "__objc_exec_class";
746 flag_typed_selectors = 1;
749 objc_ellipsis_node = make_node (ERROR_MARK);
751 if (doing_objc_thang)
754 if (print_struct_values)
755 generate_struct_by_value_array ();
757 objc_act_parse_init ();
764 fatal ("Objective-C text in C source file");
770 if (doing_objc_thang)
771 finish_objc (); /* Objective-C finalization */
773 if (gen_declaration_file)
774 fclose (gen_declaration_file);
789 lang_decode_option (argc, argv)
793 const char *p = argv[0];
795 if (!strcmp (p, "-gen-decls"))
796 flag_gen_declaration = 1;
797 else if (!strcmp (p, "-Wselector"))
799 else if (!strcmp (p, "-Wno-selector"))
801 else if (!strcmp (p, "-Wprotocol"))
802 flag_warn_protocol = 1;
803 else if (!strcmp (p, "-Wno-protocol"))
804 flag_warn_protocol = 0;
805 else if (!strcmp (p, "-fgnu-runtime"))
806 flag_next_runtime = 0;
807 else if (!strcmp (p, "-fno-next-runtime"))
808 flag_next_runtime = 0;
809 else if (!strcmp (p, "-fno-gnu-runtime"))
810 flag_next_runtime = 1;
811 else if (!strcmp (p, "-fnext-runtime"))
812 flag_next_runtime = 1;
813 else if (!strcmp (p, "-print-objc-runtime-info"))
814 print_struct_values = 1;
815 #define CSTSTRCLASS "-fconstant-string-class="
816 else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) {
817 if (strlen (argv[0]) <= strlen (CSTSTRCLASS))
818 error ("no class name specified as argument to -fconstant-string-class");
819 constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1);
823 return c_decode_option (argc, argv);
828 /* used by print-tree.c */
831 lang_print_xnode (file, node, indent)
832 FILE *file ATTRIBUTE_UNUSED;
833 tree node ATTRIBUTE_UNUSED;
834 int indent ATTRIBUTE_UNUSED;
840 define_decl (declarator, declspecs)
844 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE);
845 finish_decl (decl, NULL_TREE, NULL_TREE);
849 /* Return 1 if LHS and RHS are compatible types for assignment or
850 various other operations. Return 0 if they are incompatible, and
851 return -1 if we choose to not decide. When the operation is
852 REFLEXIVE, check for compatibility in either direction.
854 For statically typed objects, an assignment of the form `a' = `b'
858 `a' and `b' are the same class type, or
859 `a' and `b' are of class types A and B such that B is a descendant of A. */
862 maybe_objc_comptypes (lhs, rhs, reflexive)
866 if (doing_objc_thang)
867 return objc_comptypes (lhs, rhs, reflexive);
872 lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
880 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
882 p = TREE_VALUE (rproto);
884 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
886 if ((fnd = lookup_method (class_meth
887 ? PROTOCOL_CLS_METHODS (p)
888 : PROTOCOL_NST_METHODS (p), sel_name)))
890 else if (PROTOCOL_LIST (p))
891 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
892 sel_name, class_meth);
896 ; /* An identifier...if we could not find a protocol. */
907 lookup_protocol_in_reflist (rproto_list, lproto)
913 /* Make sure the protocol is support by the object on the rhs. */
914 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
917 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
919 p = TREE_VALUE (rproto);
921 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
926 else if (PROTOCOL_LIST (p))
927 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
936 ; /* An identifier...if we could not find a protocol. */
942 /* Return 1 if LHS and RHS are compatible types for assignment
943 or various other operations. Return 0 if they are incompatible,
944 and return -1 if we choose to not decide. When the operation
945 is REFLEXIVE, check for compatibility in either direction. */
948 objc_comptypes (lhs, rhs, reflexive)
953 /* New clause for protocols. */
955 if (TREE_CODE (lhs) == POINTER_TYPE
956 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
957 && TREE_CODE (rhs) == POINTER_TYPE
958 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
960 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
961 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
965 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
966 tree rproto, rproto_list;
971 rproto_list = TYPE_PROTOCOL_LIST (rhs);
973 /* Make sure the protocol is supported by the object
975 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
977 p = TREE_VALUE (lproto);
978 rproto = lookup_protocol_in_reflist (rproto_list, p);
981 warning ("object does not conform to the `%s' protocol",
982 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
985 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
987 tree rname = TYPE_NAME (TREE_TYPE (rhs));
990 /* Make sure the protocol is supported by the object
992 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
994 p = TREE_VALUE (lproto);
996 rinter = lookup_interface (rname);
998 while (rinter && !rproto)
1002 rproto_list = CLASS_PROTOCOL_LIST (rinter);
1003 rproto = lookup_protocol_in_reflist (rproto_list, p);
1005 /* Check for protocols adopted by categories. */
1006 cat = CLASS_CATEGORY_LIST (rinter);
1007 while (cat && !rproto)
1009 rproto_list = CLASS_PROTOCOL_LIST (cat);
1010 rproto = lookup_protocol_in_reflist (rproto_list, p);
1012 cat = CLASS_CATEGORY_LIST (cat);
1015 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
1019 warning ("class `%s' does not implement the `%s' protocol",
1020 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
1021 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1025 /* May change...based on whether there was any mismatch */
1028 else if (rhs_is_proto)
1029 /* Lhs is not a protocol...warn if it is statically typed */
1030 return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0);
1033 /* Defer to comptypes .*/
1037 else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE)
1038 ; /* Fall thru. This is the case we have been handling all along */
1040 /* Defer to comptypes. */
1043 /* `id' = `<class> *', `<class> *' = `id' */
1045 if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
1046 || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
1049 /* `id' = `Class', `Class' = `id' */
1051 else if ((TYPE_NAME (lhs) == objc_object_id
1052 && TYPE_NAME (rhs) == objc_class_id)
1053 || (TYPE_NAME (lhs) == objc_class_id
1054 && TYPE_NAME (rhs) == objc_object_id))
1057 /* `<class> *' = `<class> *' */
1059 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1061 tree lname = TYPE_NAME (lhs);
1062 tree rname = TYPE_NAME (rhs);
1068 /* If the left hand side is a super class of the right hand side,
1070 for (inter = lookup_interface (rname); inter;
1071 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1072 if (lname == CLASS_SUPER_NAME (inter))
1075 /* Allow the reverse when reflexive. */
1077 for (inter = lookup_interface (lname); inter;
1078 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1079 if (rname == CLASS_SUPER_NAME (inter))
1085 /* Defer to comptypes. */
1089 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1092 objc_check_decl (decl)
1095 tree type = TREE_TYPE (decl);
1097 if (TREE_CODE (type) == RECORD_TYPE
1098 && TREE_STATIC_TEMPLATE (type)
1099 && type != constant_string_type)
1101 error_with_decl (decl, "`%s' cannot be statically allocated");
1102 fatal ("statically allocated objects not supported");
1107 maybe_objc_check_decl (decl)
1110 if (doing_objc_thang)
1111 objc_check_decl (decl);
1114 /* Implement static typing. At this point, we know we have an interface. */
1117 get_static_reference (interface, protocols)
1121 tree type = xref_tag (RECORD_TYPE, interface);
1125 tree t, m = TYPE_MAIN_VARIANT (type);
1127 t = copy_node (type);
1128 TYPE_BINFO (t) = make_tree_vec (2);
1130 /* Add this type to the chain of variants of TYPE. */
1131 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1132 TYPE_NEXT_VARIANT (m) = t;
1134 /* Look up protocols and install in lang specific list. */
1135 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1137 /* This forces a new pointer type to be created later
1138 (in build_pointer_type)...so that the new template
1139 we just created will actually be used...what a hack! */
1140 if (TYPE_POINTER_TO (t))
1141 TYPE_POINTER_TO (t) = 0;
1150 get_object_reference (protocols)
1153 tree type_decl = lookup_name (objc_id_id);
1156 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
1158 type = TREE_TYPE (type_decl);
1159 if (TYPE_MAIN_VARIANT (type) != id_type)
1160 warning ("Unexpected type for `id' (%s)",
1161 gen_declaration (type, errbuf));
1164 fatal ("Undefined type `id', please import <objc/objc.h>");
1166 /* This clause creates a new pointer type that is qualified with
1167 the protocol specification...this info is used later to do more
1168 elaborate type checking. */
1172 tree t, m = TYPE_MAIN_VARIANT (type);
1174 t = copy_node (type);
1175 TYPE_BINFO (t) = make_tree_vec (2);
1177 /* Add this type to the chain of variants of TYPE. */
1178 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1179 TYPE_NEXT_VARIANT (m) = t;
1181 /* Look up protocols...and install in lang specific list */
1182 TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
1184 /* This forces a new pointer type to be created later
1185 (in build_pointer_type)...so that the new template
1186 we just created will actually be used...what a hack! */
1187 if (TYPE_POINTER_TO (t))
1188 TYPE_POINTER_TO (t) = NULL;
1196 lookup_and_install_protocols (protocols)
1201 tree return_value = protocols;
1203 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1205 tree ident = TREE_VALUE (proto);
1206 tree p = lookup_protocol (ident);
1210 error ("Cannot find protocol declaration for `%s'",
1211 IDENTIFIER_POINTER (ident));
1213 TREE_CHAIN (prev) = TREE_CHAIN (proto);
1215 return_value = TREE_CHAIN (proto);
1219 /* Replace identifier with actual protocol node. */
1220 TREE_VALUE (proto) = p;
1225 return return_value;
1228 /* Create and push a decl for a built-in external variable or field NAME.
1230 TYPE is its data type. */
1233 create_builtin_decl (code, type, name)
1234 enum tree_code code;
1238 tree decl = build_decl (code, get_identifier (name), type);
1240 if (code == VAR_DECL)
1242 TREE_STATIC (decl) = 1;
1243 make_decl_rtl (decl, 0, 1);
1247 DECL_ARTIFICIAL (decl) = 1;
1251 /* Purpose: "play" parser, creating/installing representations
1252 of the declarations that are required by Objective-C.
1256 type_spec--------->sc_spec
1257 (tree_list) (tree_list)
1260 identifier_node identifier_node */
1263 synth_module_prologue ()
1268 /* Defined in `objc.h' */
1269 objc_object_id = get_identifier (TAG_OBJECT);
1271 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1273 id_type = build_pointer_type (objc_object_reference);
1275 objc_id_id = get_identifier (TYPE_ID);
1276 objc_class_id = get_identifier (TAG_CLASS);
1278 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1279 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1280 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
1282 /* Declare type of selector-objects that represent an operation name. */
1284 #ifdef OBJC_INT_SELECTORS
1285 /* `unsigned int' */
1286 selector_type = unsigned_type_node;
1288 /* `struct objc_selector *' */
1290 = build_pointer_type (xref_tag (RECORD_TYPE,
1291 get_identifier (TAG_SELECTOR)));
1292 #endif /* not OBJC_INT_SELECTORS */
1294 /* Forward declare type, or else the prototype for msgSendSuper will
1297 super_p = build_pointer_type (xref_tag (RECORD_TYPE,
1298 get_identifier (TAG_SUPER)));
1301 /* id objc_msgSend (id, SEL, ...); */
1304 = build_function_type (id_type,
1305 tree_cons (NULL_TREE, id_type,
1306 tree_cons (NULL_TREE, selector_type,
1309 if (! flag_next_runtime)
1311 umsg_decl = build_decl (FUNCTION_DECL,
1312 get_identifier (TAG_MSGSEND), temp_type);
1313 DECL_EXTERNAL (umsg_decl) = 1;
1314 TREE_PUBLIC (umsg_decl) = 1;
1315 DECL_INLINE (umsg_decl) = 1;
1316 DECL_ARTIFICIAL (umsg_decl) = 1;
1318 if (flag_traditional && TAG_MSGSEND[0] != '_')
1319 DECL_BUILT_IN_NONANSI (umsg_decl) = 1;
1321 make_decl_rtl (umsg_decl, NULL_PTR, 1);
1322 pushdecl (umsg_decl);
1325 umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0);
1327 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1330 = build_function_type (id_type,
1331 tree_cons (NULL_TREE, super_p,
1332 tree_cons (NULL_TREE, selector_type,
1335 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1336 temp_type, 0, NOT_BUILT_IN, 0);
1338 /* id objc_getClass (const char *); */
1340 temp_type = build_function_type (id_type,
1341 tree_cons (NULL_TREE,
1342 const_string_type_node,
1343 tree_cons (NULL_TREE, void_type_node,
1347 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0);
1349 /* id objc_getMetaClass (const char *); */
1351 objc_get_meta_class_decl
1352 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0);
1354 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1356 if (! flag_next_runtime)
1358 if (flag_typed_selectors)
1360 /* Suppress outputting debug symbols, because
1361 dbxout_init hasn'r been called yet. */
1362 enum debug_info_type save_write_symbols = write_symbols;
1363 write_symbols = NO_DEBUG;
1365 build_selector_template ();
1366 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1368 write_symbols = save_write_symbols;
1371 temp_type = build_array_type (selector_type, NULL_TREE);
1373 layout_type (temp_type);
1374 UOBJC_SELECTOR_TABLE_decl
1375 = create_builtin_decl (VAR_DECL, temp_type,
1376 "_OBJC_SELECTOR_TABLE");
1378 /* Avoid warning when not sending messages. */
1379 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1382 generate_forward_declaration_to_string_table ();
1384 /* Forward declare constant_string_id and constant_string_type. */
1385 if (!constant_string_class_name)
1386 constant_string_class_name = STRING_OBJECT_CLASS_NAME;
1388 constant_string_id = get_identifier (constant_string_class_name);
1389 constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
1392 /* Custom build_string which sets TREE_TYPE! */
1395 my_build_string (len, str)
1400 tree a_string = build_string (len, str);
1402 /* Some code from combine_strings, which is local to c-parse.y. */
1403 if (TREE_TYPE (a_string) == int_array_type_node)
1406 TREE_TYPE (a_string)
1407 = build_array_type (wide_flag ? integer_type_node : char_type_node,
1408 build_index_type (build_int_2 (len - 1, 0)));
1410 TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */
1411 TREE_STATIC (a_string) = 1;
1416 /* Given a chain of STRING_CST's, build a static instance of
1417 NXConstanString which points at the concatenation of those strings.
1418 We place the string object in the __string_objects section of the
1419 __OBJC segment. The Objective-C runtime will initialize the isa
1420 pointers of the string objects to point at the NXConstandString class
1424 build_objc_string_object (strings)
1427 tree string, initlist, constructor;
1430 if (!doing_objc_thang)
1433 if (lookup_interface (constant_string_id) == NULL_TREE)
1435 error ("Cannot find interface declaration for `%s'",
1436 IDENTIFIER_POINTER (constant_string_id));
1437 return error_mark_node;
1440 add_class_reference (constant_string_id);
1442 string = combine_strings (strings);
1443 TREE_SET_CODE (string, STRING_CST);
1444 length = TREE_STRING_LENGTH (string) - 1;
1446 /* & ((NXConstantString) {0, string, length}) */
1448 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1450 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1452 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1453 constructor = build_constructor (constant_string_type, nreverse (initlist));
1455 if (!flag_next_runtime)
1458 = objc_add_static_instance (constructor, constant_string_type);
1461 return (build_unary_op (ADDR_EXPR, constructor, 1));
1464 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1467 objc_add_static_instance (constructor, class_decl)
1468 tree constructor, class_decl;
1470 static int num_static_inst;
1474 /* Find the list of static instances for the CLASS_DECL. Create one if
1476 for (chain = &objc_static_instances;
1477 *chain && TREE_VALUE (*chain) != class_decl;
1478 chain = &TREE_CHAIN (*chain));
1481 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1482 add_objc_string (TYPE_NAME (class_decl), class_names);
1485 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1486 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1487 DECL_COMMON (decl) = 1;
1488 TREE_STATIC (decl) = 1;
1489 DECL_ARTIFICIAL (decl) = 1;
1490 pushdecl_top_level (decl);
1491 rest_of_decl_compilation (decl, 0, 1, 0);
1493 /* Do this here so it gets output later instead of possibly
1494 inside something else we are writing. */
1495 DECL_INITIAL (decl) = constructor;
1497 /* Add the DECL to the head of this CLASS' list. */
1498 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1503 /* Build a static constant CONSTRUCTOR
1504 with type TYPE and elements ELTS. */
1507 build_constructor (type, elts)
1510 tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
1512 TREE_CONSTANT (constructor) = 1;
1513 TREE_STATIC (constructor) = 1;
1514 TREE_READONLY (constructor) = 1;
1519 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1521 /* Predefine the following data type:
1529 void *defs[cls_def_cnt + cat_def_cnt];
1533 build_objc_symtab_template ()
1535 tree field_decl, field_decl_chain, index;
1537 objc_symtab_template
1538 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1540 /* long sel_ref_cnt; */
1542 field_decl = create_builtin_decl (FIELD_DECL,
1543 long_integer_type_node,
1545 field_decl_chain = field_decl;
1549 field_decl = create_builtin_decl (FIELD_DECL,
1550 build_pointer_type (selector_type),
1552 chainon (field_decl_chain, field_decl);
1554 /* short cls_def_cnt; */
1556 field_decl = create_builtin_decl (FIELD_DECL,
1557 short_integer_type_node,
1559 chainon (field_decl_chain, field_decl);
1561 /* short cat_def_cnt; */
1563 field_decl = create_builtin_decl (FIELD_DECL,
1564 short_integer_type_node,
1566 chainon (field_decl_chain, field_decl);
1568 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1570 if (!flag_next_runtime)
1571 index = build_index_type (build_int_2 (imp_count + cat_count, 0));
1573 index = build_index_type (build_int_2 (imp_count + cat_count - 1,
1574 imp_count == 0 && cat_count == 0
1576 field_decl = create_builtin_decl (FIELD_DECL,
1577 build_array_type (ptr_type_node, index),
1579 chainon (field_decl_chain, field_decl);
1581 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1584 /* Create the initial value for the `defs' field of _objc_symtab.
1585 This is a CONSTRUCTOR. */
1588 init_def_list (type)
1591 tree expr, initlist = NULL_TREE;
1592 struct imp_entry *impent;
1595 for (impent = imp_list; impent; impent = impent->next)
1597 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1599 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1600 initlist = tree_cons (NULL_TREE, expr, initlist);
1605 for (impent = imp_list; impent; impent = impent->next)
1607 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1609 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1610 initlist = tree_cons (NULL_TREE, expr, initlist);
1614 if (!flag_next_runtime)
1616 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1619 if (static_instances_decl)
1620 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1622 expr = build_int_2 (0, 0);
1624 initlist = tree_cons (NULL_TREE, expr, initlist);
1627 return build_constructor (type, nreverse (initlist));
1630 /* Construct the initial value for all of _objc_symtab. */
1633 init_objc_symtab (type)
1638 /* sel_ref_cnt = { ..., 5, ... } */
1640 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1642 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1644 if (flag_next_runtime || ! sel_ref_chain)
1645 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1647 initlist = tree_cons (NULL_TREE,
1648 build_unary_op (ADDR_EXPR,
1649 UOBJC_SELECTOR_TABLE_decl, 1),
1652 /* cls_def_cnt = { ..., 5, ... } */
1654 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1656 /* cat_def_cnt = { ..., 5, ... } */
1658 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1660 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1662 if (imp_count || cat_count || static_instances_decl)
1665 tree field = TYPE_FIELDS (type);
1666 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1668 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1672 return build_constructor (type, nreverse (initlist));
1675 /* Push forward-declarations of all the categories
1676 so that init_def_list can use them in a CONSTRUCTOR. */
1679 forward_declare_categories ()
1681 struct imp_entry *impent;
1682 tree sav = implementation_context;
1684 for (impent = imp_list; impent; impent = impent->next)
1686 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1688 /* Set an invisible arg to synth_id_with_class_suffix. */
1689 implementation_context = impent->imp_context;
1691 = create_builtin_decl (VAR_DECL, objc_category_template,
1692 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context)));
1695 implementation_context = sav;
1698 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1699 and initialized appropriately. */
1702 generate_objc_symtab_decl ()
1706 if (!objc_category_template)
1707 build_category_template ();
1709 /* forward declare categories */
1711 forward_declare_categories ();
1713 if (!objc_symtab_template)
1714 build_objc_symtab_template ();
1716 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1718 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1719 tree_cons (NULL_TREE,
1720 objc_symtab_template, sc_spec),
1722 NULL_TREE, NULL_TREE);
1724 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1725 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1726 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1727 finish_decl (UOBJC_SYMBOLS_decl,
1728 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1733 init_module_descriptor (type)
1736 tree initlist, expr;
1738 /* version = { 1, ... } */
1740 expr = build_int_2 (OBJC_VERSION, 0);
1741 initlist = build_tree_list (NULL_TREE, expr);
1743 /* size = { ..., sizeof (struct objc_module), ... } */
1745 expr = size_in_bytes (objc_module_template);
1746 initlist = tree_cons (NULL_TREE, expr, initlist);
1748 /* name = { ..., "foo.m", ... } */
1750 expr = add_objc_string (get_identifier (input_filename), class_names);
1751 initlist = tree_cons (NULL_TREE, expr, initlist);
1753 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1755 if (UOBJC_SYMBOLS_decl)
1756 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1758 expr = build_int_2 (0, 0);
1759 initlist = tree_cons (NULL_TREE, expr, initlist);
1761 return build_constructor (type, nreverse (initlist));
1764 /* Write out the data structures to describe Objective C classes defined.
1765 If appropriate, compile and output a setup function to initialize them.
1766 Return a string which is the name of a function to call to initialize
1767 the Objective C data structures for this file (and perhaps for other files
1770 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1773 build_module_descriptor ()
1775 tree decl_specs, field_decl, field_decl_chain;
1777 objc_module_template
1778 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1782 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1783 field_decl = get_identifier ("version");
1785 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1786 field_decl_chain = field_decl;
1790 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1791 field_decl = get_identifier ("size");
1793 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1794 chainon (field_decl_chain, field_decl);
1798 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1799 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1801 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1802 chainon (field_decl_chain, field_decl);
1804 /* struct objc_symtab *symtab; */
1806 decl_specs = get_identifier (UTAG_SYMTAB);
1807 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1808 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1810 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
1811 chainon (field_decl_chain, field_decl);
1813 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1815 /* Create an instance of "objc_module". */
1817 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1818 build_tree_list (NULL_TREE,
1819 ridpointers[(int) RID_STATIC]));
1821 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1822 decl_specs, 1, NULL_TREE, NULL_TREE);
1824 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1825 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1826 finish_decl (UOBJC_MODULES_decl,
1827 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1830 /* Mark the decl to avoid "defined but not used" warning. */
1831 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1833 /* Generate a constructor call for the module descriptor.
1834 This code was generated by reading the grammar rules
1835 of c-parse.in; Therefore, it may not be the most efficient
1836 way of generating the requisite code. */
1838 if (flag_next_runtime)
1842 tree parms, function_decl, decelerator, void_list_node_1;
1844 tree init_function_name = get_file_function_name ('I');
1846 /* Declare void __objc_execClass (void *); */
1848 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1850 = build_function_type (void_type_node,
1851 tree_cons (NULL_TREE, ptr_type_node,
1853 function_decl = build_decl (FUNCTION_DECL,
1854 get_identifier (TAG_EXECCLASS),
1856 DECL_EXTERNAL (function_decl) = 1;
1857 DECL_ARTIFICIAL (function_decl) = 1;
1858 TREE_PUBLIC (function_decl) = 1;
1860 pushdecl (function_decl);
1861 rest_of_decl_compilation (function_decl, 0, 0, 0);
1864 = build_tree_list (NULL_TREE,
1865 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1866 decelerator = build_function_call (function_decl, parms);
1868 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1870 start_function (void_list_node_1,
1871 build_parse_node (CALL_EXPR, init_function_name,
1872 /* This has the format of the output
1873 of get_parm_info. */
1874 tree_cons (NULL_TREE, NULL_TREE,
1877 NULL_TREE, NULL_TREE);
1878 #if 0 /* This should be turned back on later
1879 for the systems where collect is not needed. */
1880 /* Make these functions nonglobal
1881 so each file can use the same name. */
1882 TREE_PUBLIC (current_function_decl) = 0;
1884 TREE_USED (current_function_decl) = 1;
1885 store_parm_decls ();
1887 assemble_external (function_decl);
1888 c_expand_expr_stmt (decelerator);
1890 TREE_PUBLIC (current_function_decl) = 1;
1892 function_decl = current_function_decl;
1893 finish_function (0);
1895 /* Return the name of the constructor function. */
1896 return XSTR (XEXP (DECL_RTL (function_decl), 0), 0);
1900 /* extern const char _OBJC_STRINGS[]; */
1903 generate_forward_declaration_to_string_table ()
1905 tree sc_spec, decl_specs, expr_decl;
1907 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1908 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1911 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1913 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1916 /* Return the DECL of the string IDENT in the SECTION. */
1919 get_objc_string_decl (ident, section)
1921 enum string_section section;
1925 if (section == class_names)
1926 chain = class_names_chain;
1927 else if (section == meth_var_names)
1928 chain = meth_var_names_chain;
1929 else if (section == meth_var_types)
1930 chain = meth_var_types_chain;
1934 for (; chain != 0; chain = TREE_VALUE (chain))
1935 if (TREE_VALUE (chain) == ident)
1936 return (TREE_PURPOSE (chain));
1942 /* Output references to all statically allocated objects. Return the DECL
1943 for the array built. */
1946 generate_static_references ()
1948 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1949 tree class_name, class, decl, initlist;
1950 tree cl_chain, in_chain, type;
1951 int num_inst, num_class;
1954 if (flag_next_runtime)
1957 for (cl_chain = objc_static_instances, num_class = 0;
1958 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1960 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1961 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1963 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1964 ident = get_identifier (buf);
1966 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1967 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1968 build_tree_list (NULL_TREE,
1969 ridpointers[(int) RID_STATIC]));
1970 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
1971 DECL_CONTEXT (decl) = 0;
1972 DECL_ARTIFICIAL (decl) = 1;
1974 /* Output {class_name, ...}. */
1975 class = TREE_VALUE (cl_chain);
1976 class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
1977 initlist = build_tree_list (NULL_TREE,
1978 build_unary_op (ADDR_EXPR, class_name, 1));
1980 /* Output {..., instance, ...}. */
1981 for (in_chain = TREE_PURPOSE (cl_chain);
1982 in_chain; in_chain = TREE_CHAIN (in_chain))
1984 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1985 initlist = tree_cons (NULL_TREE, expr, initlist);
1988 /* Output {..., NULL}. */
1989 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1991 expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
1992 finish_decl (decl, expr, NULL_TREE);
1993 TREE_USED (decl) = 1;
1995 type = build_array_type (build_pointer_type (void_type_node), 0);
1996 decl = build_decl (VAR_DECL, ident, type);
1997 make_decl_rtl (decl, 0, 1);
1998 TREE_USED (decl) = 1;
2000 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2003 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2004 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2005 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2006 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2007 build_tree_list (NULL_TREE,
2008 ridpointers[(int) RID_STATIC]));
2009 static_instances_decl
2010 = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE);
2011 TREE_USED (static_instances_decl) = 1;
2012 DECL_CONTEXT (static_instances_decl) = 0;
2013 DECL_ARTIFICIAL (static_instances_decl) = 1;
2014 expr = build_constructor (TREE_TYPE (static_instances_decl),
2016 finish_decl (static_instances_decl, expr, NULL_TREE);
2019 /* Output all strings. */
2024 tree sc_spec, decl_specs, expr_decl;
2025 tree chain, string_expr;
2028 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2030 string = TREE_VALUE (chain);
2031 decl = TREE_PURPOSE (chain);
2033 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2034 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2035 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2036 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2037 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2038 IDENTIFIER_POINTER (string));
2039 finish_decl (decl, string_expr, NULL_TREE);
2042 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2044 string = TREE_VALUE (chain);
2045 decl = TREE_PURPOSE (chain);
2047 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2048 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2049 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2050 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2051 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2052 IDENTIFIER_POINTER (string));
2053 finish_decl (decl, string_expr, NULL_TREE);
2056 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2058 string = TREE_VALUE (chain);
2059 decl = TREE_PURPOSE (chain);
2061 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2062 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2063 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2064 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2065 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2066 IDENTIFIER_POINTER (string));
2067 finish_decl (decl, string_expr, NULL_TREE);
2072 build_selector_reference_decl ()
2078 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
2080 ident = get_identifier (buf);
2082 decl = build_decl (VAR_DECL, ident, selector_type);
2083 DECL_EXTERNAL (decl) = 1;
2084 TREE_PUBLIC (decl) = 1;
2085 TREE_USED (decl) = 1;
2086 TREE_READONLY (decl) = 1;
2087 DECL_ARTIFICIAL (decl) = 1;
2088 DECL_CONTEXT (decl) = 0;
2090 make_decl_rtl (decl, 0, 1);
2091 pushdecl_top_level (decl);
2096 /* Just a handy wrapper for add_objc_string. */
2099 build_selector (ident)
2102 tree expr = add_objc_string (ident, meth_var_names);
2103 if (flag_typed_selectors)
2106 return build_c_cast (selector_type, expr); /* cast! */
2109 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2110 The cast stops the compiler from issuing the following message:
2111 grok.m: warning: initialization of non-const * pointer from const *
2112 grok.m: warning: initialization between incompatible pointer types. */
2116 build_msg_pool_reference (offset)
2119 tree expr = build_int_2 (offset, 0);
2122 expr = build_array_ref (UOBJC_STRINGS_decl, expr);
2123 expr = build_unary_op (ADDR_EXPR, expr, 0);
2125 cast = build_tree_list (build_tree_list (NULL_TREE,
2126 ridpointers[(int) RID_CHAR]),
2127 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
2128 TREE_TYPE (expr) = groktypename (cast);
2133 init_selector (offset)
2136 tree expr = build_msg_pool_reference (offset);
2137 TREE_TYPE (expr) = selector_type;
2143 build_selector_translation_table ()
2145 tree sc_spec, decl_specs;
2146 tree chain, initlist = NULL_TREE;
2148 tree decl = NULL_TREE, var_decl, name;
2150 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2154 expr = build_selector (TREE_VALUE (chain));
2156 if (flag_next_runtime)
2158 name = DECL_NAME (TREE_PURPOSE (chain));
2160 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2162 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2163 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2167 /* The `decl' that is returned from start_decl is the one that we
2168 forward declared in `build_selector_reference' */
2169 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
2172 /* add one for the '\0' character */
2173 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2175 if (flag_next_runtime)
2176 finish_decl (decl, expr, NULL_TREE);
2179 if (flag_typed_selectors)
2181 tree eltlist = NULL_TREE;
2182 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2183 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2184 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2185 expr = build_constructor (objc_selector_template,
2186 nreverse (eltlist));
2188 initlist = tree_cons (NULL_TREE, expr, initlist);
2193 if (! flag_next_runtime)
2195 /* Cause the variable and its initial value to be actually output. */
2196 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2197 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2198 /* NULL terminate the list and fix the decl for output. */
2199 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2200 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2201 initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2202 nreverse (initlist));
2203 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2204 current_function_decl = NULL_TREE;
2209 get_proto_encoding (proto)
2217 if (! METHOD_ENCODING (proto))
2219 tmp_decl = build_tmp_function_decl ();
2220 hack_method_prototype (proto, tmp_decl);
2221 encoding = encode_method_prototype (proto, tmp_decl);
2222 METHOD_ENCODING (proto) = encoding;
2225 encoding = METHOD_ENCODING (proto);
2227 return add_objc_string (encoding, meth_var_types);
2230 return build_int_2 (0, 0);
2233 /* sel_ref_chain is a list whose "value" fields will be instances of
2234 identifier_node that represent the selector. */
2237 build_typed_selector_reference (ident, proto)
2240 tree *chain = &sel_ref_chain;
2246 if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto)
2247 goto return_at_index;
2250 chain = &TREE_CHAIN (*chain);
2253 *chain = tree_cons (proto, ident, NULL_TREE);
2256 expr = build_unary_op (ADDR_EXPR,
2257 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2258 build_int_2 (index, 0)),
2260 return build_c_cast (selector_type, expr);
2264 build_selector_reference (ident)
2267 tree *chain = &sel_ref_chain;
2273 if (TREE_VALUE (*chain) == ident)
2274 return (flag_next_runtime
2275 ? TREE_PURPOSE (*chain)
2276 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2277 build_int_2 (index, 0)));
2280 chain = &TREE_CHAIN (*chain);
2283 expr = build_selector_reference_decl ();
2285 *chain = tree_cons (expr, ident, NULL_TREE);
2287 return (flag_next_runtime
2289 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2290 build_int_2 (index, 0)));
2294 build_class_reference_decl ()
2300 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
2302 ident = get_identifier (buf);
2304 decl = build_decl (VAR_DECL, ident, objc_class_type);
2305 DECL_EXTERNAL (decl) = 1;
2306 TREE_PUBLIC (decl) = 1;
2307 TREE_USED (decl) = 1;
2308 TREE_READONLY (decl) = 1;
2309 DECL_CONTEXT (decl) = 0;
2310 DECL_ARTIFICIAL (decl) = 1;
2312 make_decl_rtl (decl, 0, 1);
2313 pushdecl_top_level (decl);
2318 /* Create a class reference, but don't create a variable to reference
2322 add_class_reference (ident)
2327 if ((chain = cls_ref_chain))
2332 if (ident == TREE_VALUE (chain))
2336 chain = TREE_CHAIN (chain);
2340 /* Append to the end of the list */
2341 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2344 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2347 /* Get a class reference, creating it if necessary. Also create the
2348 reference variable. */
2351 get_class_reference (ident)
2354 if (flag_next_runtime)
2359 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2360 if (TREE_VALUE (*chain) == ident)
2362 if (! TREE_PURPOSE (*chain))
2363 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2365 return TREE_PURPOSE (*chain);
2368 decl = build_class_reference_decl ();
2369 *chain = tree_cons (decl, ident, NULL_TREE);
2376 add_class_reference (ident);
2378 params = build_tree_list (NULL_TREE,
2379 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2380 IDENTIFIER_POINTER (ident)));
2382 assemble_external (objc_get_class_decl);
2383 return build_function_call (objc_get_class_decl, params);
2387 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2388 of identifier_node that represent the selector. It returns the
2389 offset of the selector from the beginning of the _OBJC_STRINGS
2390 pool. This offset is typically used by init_selector during code
2393 For each string section we have a chain which maps identifier nodes
2394 to decls for the strings. */
2397 add_objc_string (ident, section)
2399 enum string_section section;
2403 if (section == class_names)
2404 chain = &class_names_chain;
2405 else if (section == meth_var_names)
2406 chain = &meth_var_names_chain;
2407 else if (section == meth_var_types)
2408 chain = &meth_var_types_chain;
2414 if (TREE_VALUE (*chain) == ident)
2415 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2417 chain = &TREE_CHAIN (*chain);
2420 decl = build_objc_string_decl (section);
2422 *chain = tree_cons (decl, ident, NULL_TREE);
2424 return build_unary_op (ADDR_EXPR, decl, 1);
2428 build_objc_string_decl (section)
2429 enum string_section section;
2433 static int class_names_idx = 0;
2434 static int meth_var_names_idx = 0;
2435 static int meth_var_types_idx = 0;
2437 if (section == class_names)
2438 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2439 else if (section == meth_var_names)
2440 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2441 else if (section == meth_var_types)
2442 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2444 ident = get_identifier (buf);
2446 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2447 DECL_EXTERNAL (decl) = 1;
2448 TREE_PUBLIC (decl) = 1;
2449 TREE_USED (decl) = 1;
2450 TREE_READONLY (decl) = 1;
2451 TREE_CONSTANT (decl) = 1;
2452 DECL_CONTEXT (decl) = 0;
2453 DECL_ARTIFICIAL (decl) = 1;
2455 make_decl_rtl (decl, 0, 1);
2456 pushdecl_top_level (decl);
2463 objc_declare_alias (alias_ident, class_ident)
2467 if (!doing_objc_thang)
2470 if (is_class_name (class_ident) != class_ident)
2471 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2472 else if (is_class_name (alias_ident))
2473 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2475 alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
2479 objc_declare_class (ident_list)
2484 if (!doing_objc_thang)
2487 for (list = ident_list; list; list = TREE_CHAIN (list))
2489 tree ident = TREE_VALUE (list);
2492 if ((decl = lookup_name (ident)))
2494 error ("`%s' redeclared as different kind of symbol",
2495 IDENTIFIER_POINTER (ident));
2496 error_with_decl (decl, "previous declaration of `%s'");
2499 if (! is_class_name (ident))
2501 tree record = xref_tag (RECORD_TYPE, ident);
2502 TREE_STATIC_TEMPLATE (record) = 1;
2503 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2509 is_class_name (ident)
2514 if (lookup_interface (ident))
2517 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2519 if (ident == TREE_VALUE (chain))
2523 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2525 if (ident == TREE_VALUE (chain))
2526 return TREE_PURPOSE (chain);
2533 lookup_interface (ident)
2538 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2540 if (ident == CLASS_NAME (chain))
2547 objc_copy_list (list, head)
2551 tree newlist = NULL_TREE, tail = NULL_TREE;
2555 tail = copy_node (list);
2557 /* The following statement fixes a bug when inheriting instance
2558 variables that are declared to be bitfields. finish_struct
2559 expects to find the width of the bitfield in DECL_INITIAL. */
2560 if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
2561 DECL_INITIAL (tail) = DECL_SIZE (tail);
2563 newlist = chainon (newlist, tail);
2564 list = TREE_CHAIN (list);
2571 /* Used by: build_private_template, get_class_ivars, and
2572 continue_class. COPY is 1 when called from @defs. In this case
2573 copy all fields. Otherwise don't copy leaf ivars since we rely on
2574 them being side-effected exactly once by finish_struct. */
2577 build_ivar_chain (interface, copy)
2581 tree my_name, super_name, ivar_chain;
2583 my_name = CLASS_NAME (interface);
2584 super_name = CLASS_SUPER_NAME (interface);
2586 /* Possibly copy leaf ivars. */
2588 objc_copy_list (CLASS_IVARS (interface), &ivar_chain);
2590 ivar_chain = CLASS_IVARS (interface);
2595 tree super_interface = lookup_interface (super_name);
2597 if (!super_interface)
2599 /* fatal did not work with 2 args...should fix */
2600 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2601 IDENTIFIER_POINTER (super_name),
2602 IDENTIFIER_POINTER (my_name));
2603 exit (FATAL_EXIT_CODE);
2606 if (super_interface == interface)
2608 fatal ("Circular inheritance in interface declaration for `%s'",
2609 IDENTIFIER_POINTER (super_name));
2612 interface = super_interface;
2613 my_name = CLASS_NAME (interface);
2614 super_name = CLASS_SUPER_NAME (interface);
2616 op1 = CLASS_IVARS (interface);
2619 tree head, tail = objc_copy_list (op1, &head);
2621 /* Prepend super class ivars...make a copy of the list, we
2622 do not want to alter the original. */
2623 TREE_CHAIN (tail) = ivar_chain;
2630 /* struct <classname> {
2631 struct objc_class *isa;
2636 build_private_template (class)
2641 if (CLASS_STATIC_TEMPLATE (class))
2643 uprivate_record = CLASS_STATIC_TEMPLATE (class);
2644 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2648 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
2650 ivar_context = build_ivar_chain (class, 0);
2652 finish_struct (uprivate_record, ivar_context, NULL_TREE);
2654 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
2656 /* mark this record as class template - for class type checking */
2657 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
2661 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
2663 build1 (INDIRECT_REF, NULL_TREE,
2666 return ivar_context;
2669 /* Begin code generation for protocols... */
2671 /* struct objc_protocol {
2672 char *protocol_name;
2673 struct objc_protocol **protocol_list;
2674 struct objc_method_desc *instance_methods;
2675 struct objc_method_desc *class_methods;
2679 build_protocol_template ()
2681 tree decl_specs, field_decl, field_decl_chain;
2684 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
2686 /* struct objc_class *isa; */
2688 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
2689 get_identifier (UTAG_CLASS)));
2690 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
2692 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2693 field_decl_chain = field_decl;
2695 /* char *protocol_name; */
2697 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
2699 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
2701 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2702 chainon (field_decl_chain, field_decl);
2704 /* struct objc_protocol **protocol_list; */
2706 decl_specs = build_tree_list (NULL_TREE, template);
2708 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
2709 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
2711 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2712 chainon (field_decl_chain, field_decl);
2714 /* struct objc_method_list *instance_methods; */
2717 = build_tree_list (NULL_TREE,
2718 xref_tag (RECORD_TYPE,
2719 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2721 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
2723 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2724 chainon (field_decl_chain, field_decl);
2726 /* struct objc_method_list *class_methods; */
2729 = build_tree_list (NULL_TREE,
2730 xref_tag (RECORD_TYPE,
2731 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2733 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
2735 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2736 chainon (field_decl_chain, field_decl);
2738 return finish_struct (template, field_decl_chain, NULL_TREE);
2742 build_descriptor_table_initializer (type, entries)
2746 tree initlist = NULL_TREE;
2750 tree eltlist = NULL_TREE;
2753 = tree_cons (NULL_TREE,
2754 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
2756 = tree_cons (NULL_TREE,
2757 add_objc_string (METHOD_ENCODING (entries),
2762 = tree_cons (NULL_TREE,
2763 build_constructor (type, nreverse (eltlist)), initlist);
2765 entries = TREE_CHAIN (entries);
2769 return build_constructor (build_array_type (type, 0), nreverse (initlist));
2772 /* struct objc_method_prototype_list {
2774 struct objc_method_prototype {
2781 build_method_prototype_list_template (list_type, size)
2785 tree objc_ivar_list_record;
2786 tree decl_specs, field_decl, field_decl_chain;
2788 /* Generate an unnamed struct definition. */
2790 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
2792 /* int method_count; */
2794 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
2795 field_decl = get_identifier ("method_count");
2798 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2799 field_decl_chain = field_decl;
2801 /* struct objc_method method_list[]; */
2803 decl_specs = build_tree_list (NULL_TREE, list_type);
2804 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
2805 build_int_2 (size, 0));
2808 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2809 chainon (field_decl_chain, field_decl);
2811 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
2813 return objc_ivar_list_record;
2817 build_method_prototype_template ()
2820 tree decl_specs, field_decl, field_decl_chain;
2823 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
2825 #ifdef OBJC_INT_SELECTORS
2826 /* unsigned int _cmd; */
2828 = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE);
2829 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
2830 field_decl = get_identifier ("_cmd");
2831 #else /* OBJC_INT_SELECTORS */
2832 /* struct objc_selector *_cmd; */
2833 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
2834 get_identifier (TAG_SELECTOR)), NULL_TREE);
2835 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
2836 #endif /* OBJC_INT_SELECTORS */
2839 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2840 field_decl_chain = field_decl;
2842 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
2844 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
2846 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
2847 chainon (field_decl_chain, field_decl);
2849 finish_struct (proto_record, field_decl_chain, NULL_TREE);
2851 return proto_record;
2854 /* True if last call to forwarding_offset yielded a register offset. */
2855 static int offset_is_register;
2858 forwarding_offset (parm)
2861 int offset_in_bytes;
2863 if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
2865 rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
2867 /* ??? Here we assume that the parm address is indexed
2868 off the frame pointer or arg pointer.
2869 If that is not true, we produce meaningless results,
2870 but do not crash. */
2871 if (GET_CODE (addr) == PLUS
2872 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2873 offset_in_bytes = INTVAL (XEXP (addr, 1));
2875 offset_in_bytes = 0;
2877 offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
2878 offset_is_register = 0;
2880 else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
2882 int regno = REGNO (DECL_INCOMING_RTL (parm));
2883 offset_in_bytes = apply_args_register_offset (regno);
2884 offset_is_register = 1;
2889 /* This is the case where the parm is passed as an int or double
2890 and it is converted to a char, short or float and stored back
2891 in the parmlist. In this case, describe the parm
2892 with the variable's declared type, and adjust the address
2893 if the least significant bytes (which we are using) are not
2895 if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
2896 offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
2897 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
2899 return offset_in_bytes;
2903 encode_method_prototype (method_decl, func_decl)
2910 HOST_WIDE_INT max_parm_end = 0;
2914 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2915 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
2918 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
2919 obstack_object_size (&util_obstack),
2920 OBJC_ENCODE_INLINE_DEFS);
2923 for (parms = DECL_ARGUMENTS (func_decl); parms;
2924 parms = TREE_CHAIN (parms))
2926 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
2927 + int_size_in_bytes (TREE_TYPE (parms)));
2929 if (!offset_is_register && max_parm_end < parm_end)
2930 max_parm_end = parm_end;
2933 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
2935 sprintf (buf, "%d", stack_size);
2936 obstack_grow (&util_obstack, buf, strlen (buf));
2938 user_args = METHOD_SEL_ARGS (method_decl);
2940 /* Argument types. */
2941 for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
2942 parms = TREE_CHAIN (parms), i++)
2944 /* Process argument qualifiers for user supplied arguments. */
2947 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
2948 user_args = TREE_CHAIN (user_args);
2952 encode_type (TREE_TYPE (parms),
2953 obstack_object_size (&util_obstack),
2954 OBJC_ENCODE_INLINE_DEFS);
2956 /* Compute offset. */
2957 sprintf (buf, "%d", forwarding_offset (parms));
2959 /* Indicate register. */
2960 if (offset_is_register)
2961 obstack_1grow (&util_obstack, '+');
2963 obstack_grow (&util_obstack, buf, strlen (buf));
2966 obstack_1grow (&util_obstack, '\0');
2967 result = get_identifier (obstack_finish (&util_obstack));
2968 obstack_free (&util_obstack, util_firstobj);
2973 generate_descriptor_table (type, name, size, list, proto)
2980 tree sc_spec, decl_specs, decl, initlist;
2982 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2983 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
2985 decl = start_decl (synth_id_with_class_suffix (name, proto),
2986 decl_specs, 1, NULL_TREE, NULL_TREE);
2988 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
2989 initlist = tree_cons (NULL_TREE, list, initlist);
2991 finish_decl (decl, build_constructor (type, nreverse (initlist)),
2998 generate_method_descriptors (protocol) /* generate_dispatch_tables */
3001 static tree objc_method_prototype_template;
3002 tree initlist, chain, method_list_template;
3003 tree cast, variable_length_type;
3006 if (!objc_method_prototype_template)
3008 objc_method_prototype_template = build_method_prototype_template ();
3009 ggc_add_tree_root (&objc_method_prototype_template, 1);
3012 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3013 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3015 variable_length_type = groktypename (cast);
3017 chain = PROTOCOL_CLS_METHODS (protocol);
3020 size = list_length (chain);
3022 method_list_template
3023 = build_method_prototype_list_template (objc_method_prototype_template,
3027 = build_descriptor_table_initializer (objc_method_prototype_template,
3030 UOBJC_CLASS_METHODS_decl
3031 = generate_descriptor_table (method_list_template,
3032 "_OBJC_PROTOCOL_CLASS_METHODS",
3033 size, initlist, protocol);
3034 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3037 UOBJC_CLASS_METHODS_decl = 0;
3039 chain = PROTOCOL_NST_METHODS (protocol);
3042 size = list_length (chain);
3044 method_list_template
3045 = build_method_prototype_list_template (objc_method_prototype_template,
3048 = build_descriptor_table_initializer (objc_method_prototype_template,
3051 UOBJC_INSTANCE_METHODS_decl
3052 = generate_descriptor_table (method_list_template,
3053 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3054 size, initlist, protocol);
3055 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3058 UOBJC_INSTANCE_METHODS_decl = 0;
3062 build_tmp_function_decl ()
3064 tree decl_specs, expr_decl, parms;
3068 /* struct objc_object *objc_xxx (id, SEL, ...); */
3070 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3071 push_parm_decl (build_tree_list
3072 (build_tree_list (decl_specs,
3073 build1 (INDIRECT_REF, NULL_TREE,
3075 build_tree_list (NULL_TREE, NULL_TREE)));
3077 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3078 get_identifier (TAG_SELECTOR)));
3079 expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
3081 push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
3082 build_tree_list (NULL_TREE, NULL_TREE)));
3083 parms = get_parm_info (0);
3086 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3087 sprintf (buffer, "__objc_tmp_%x", xxx++);
3088 expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
3089 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
3091 return define_decl (expr_decl, decl_specs);
3095 hack_method_prototype (nst_methods, tmp_decl)
3102 /* Hack to avoid problem with static typing of self arg. */
3103 TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
3104 start_method_def (nst_methods);
3105 TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
3107 if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
3108 parms = get_parm_info (0); /* we have a `, ...' */
3110 parms = get_parm_info (1); /* place a `void_at_end' */
3112 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3114 /* Usually called from store_parm_decls -> init_function_start. */
3116 DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
3117 current_function_decl = tmp_decl;
3120 /* Code taken from start_function. */
3121 tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
3122 /* Promote the value to int before returning it. */
3123 if (TREE_CODE (restype) == INTEGER_TYPE
3124 && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
3125 restype = integer_type_node;
3126 DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
3129 for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
3130 DECL_CONTEXT (parm) = tmp_decl;
3132 init_function_start (tmp_decl, "objc-act", 0);
3134 /* Typically called from expand_function_start for function definitions. */
3135 assign_parms (tmp_decl);
3137 /* install return type */
3138 TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
3143 generate_protocol_references (plist)
3148 /* Forward declare protocols referenced. */
3149 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3151 tree proto = TREE_VALUE (lproto);
3153 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3154 && PROTOCOL_NAME (proto))
3156 if (! PROTOCOL_FORWARD_DECL (proto))
3157 build_protocol_reference (proto);
3159 if (PROTOCOL_LIST (proto))
3160 generate_protocol_references (PROTOCOL_LIST (proto));
3166 generate_protocols ()
3168 tree p, tmp_decl, encoding;
3169 tree sc_spec, decl_specs, decl;
3170 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3173 tmp_decl = build_tmp_function_decl ();
3175 if (! objc_protocol_template)
3176 objc_protocol_template = build_protocol_template ();
3178 /* If a protocol was directly referenced, pull in indirect references. */
3179 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3180 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3181 generate_protocol_references (PROTOCOL_LIST (p));
3183 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3185 tree nst_methods = PROTOCOL_NST_METHODS (p);
3186 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3188 /* If protocol wasn't referenced, don't generate any code. */
3189 if (! PROTOCOL_FORWARD_DECL (p))
3192 /* Make sure we link in the Protocol class. */
3193 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3197 if (! METHOD_ENCODING (nst_methods))
3199 hack_method_prototype (nst_methods, tmp_decl);
3200 encoding = encode_method_prototype (nst_methods, tmp_decl);
3201 METHOD_ENCODING (nst_methods) = encoding;
3203 nst_methods = TREE_CHAIN (nst_methods);
3208 if (! METHOD_ENCODING (cls_methods))
3210 hack_method_prototype (cls_methods, tmp_decl);
3211 encoding = encode_method_prototype (cls_methods, tmp_decl);
3212 METHOD_ENCODING (cls_methods) = encoding;
3215 cls_methods = TREE_CHAIN (cls_methods);
3217 generate_method_descriptors (p);
3219 if (PROTOCOL_LIST (p))
3220 refs_decl = generate_protocol_list (p);
3224 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3226 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3228 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3230 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3231 decl_specs, 1, NULL_TREE, NULL_TREE);
3233 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3239 (build_tree_list (build_tree_list (NULL_TREE,
3240 objc_protocol_template),
3241 build1 (INDIRECT_REF, NULL_TREE,
3242 build1 (INDIRECT_REF, NULL_TREE,
3245 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3246 TREE_TYPE (refs_expr) = cast_type2;
3249 refs_expr = build_int_2 (0, 0);
3251 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3252 by generate_method_descriptors, which is called above. */
3253 initlist = build_protocol_initializer (TREE_TYPE (decl),
3254 protocol_name_expr, refs_expr,
3255 UOBJC_INSTANCE_METHODS_decl,
3256 UOBJC_CLASS_METHODS_decl);
3257 finish_decl (decl, initlist, NULL_TREE);
3259 /* Mark the decl as used to avoid "defined but not used" warning. */
3260 TREE_USED (decl) = 1;
3265 build_protocol_initializer (type, protocol_name, protocol_list,
3266 instance_methods, class_methods)
3270 tree instance_methods;
3273 tree initlist = NULL_TREE, expr;
3276 cast_type = groktypename
3278 (build_tree_list (NULL_TREE,
3279 xref_tag (RECORD_TYPE,
3280 get_identifier (UTAG_CLASS))),
3281 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3283 /* Filling the "isa" in with one allows the runtime system to
3284 detect that the version change...should remove before final release. */
3286 expr = build_int_2 (PROTOCOL_VERSION, 0);
3287 TREE_TYPE (expr) = cast_type;
3288 initlist = tree_cons (NULL_TREE, expr, initlist);
3289 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3290 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3292 if (!instance_methods)
3293 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3296 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3297 initlist = tree_cons (NULL_TREE, expr, initlist);
3301 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3304 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3305 initlist = tree_cons (NULL_TREE, expr, initlist);
3308 return build_constructor (type, nreverse (initlist));
3311 /* struct objc_category {
3312 char *category_name;
3314 struct objc_method_list *instance_methods;
3315 struct objc_method_list *class_methods;
3316 struct objc_protocol_list *protocols;
3320 build_category_template ()
3322 tree decl_specs, field_decl, field_decl_chain;
3324 objc_category_template = start_struct (RECORD_TYPE,
3325 get_identifier (UTAG_CATEGORY));
3326 /* char *category_name; */
3328 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3330 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3332 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3333 field_decl_chain = field_decl;
3335 /* char *class_name; */
3337 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3338 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3340 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3341 chainon (field_decl_chain, field_decl);
3343 /* struct objc_method_list *instance_methods; */
3345 decl_specs = build_tree_list (NULL_TREE,
3346 xref_tag (RECORD_TYPE,
3347 get_identifier (UTAG_METHOD_LIST)));
3349 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3351 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3352 chainon (field_decl_chain, field_decl);
3354 /* struct objc_method_list *class_methods; */
3356 decl_specs = build_tree_list (NULL_TREE,
3357 xref_tag (RECORD_TYPE,
3358 get_identifier (UTAG_METHOD_LIST)));
3360 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3362 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3363 chainon (field_decl_chain, field_decl);
3365 /* struct objc_protocol **protocol_list; */
3367 decl_specs = build_tree_list (NULL_TREE,
3368 xref_tag (RECORD_TYPE,
3369 get_identifier (UTAG_PROTOCOL)));
3371 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3372 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3374 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3375 chainon (field_decl_chain, field_decl);
3377 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3380 /* struct objc_selector {
3386 build_selector_template ()
3389 tree decl_specs, field_decl, field_decl_chain;
3391 objc_selector_template
3392 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
3396 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3397 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3399 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3400 field_decl_chain = field_decl;
3402 /* char *sel_type; */
3404 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3405 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
3407 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3408 chainon (field_decl_chain, field_decl);
3410 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
3413 /* struct objc_class {
3414 struct objc_class *isa;
3415 struct objc_class *super_class;
3420 struct objc_ivar_list *ivars;
3421 struct objc_method_list *methods;
3422 if (flag_next_runtime)
3423 struct objc_cache *cache;
3425 struct sarray *dtable;
3426 struct objc_class *subclass_list;
3427 struct objc_class *sibling_class;
3429 struct objc_protocol_list *protocols;
3430 void *gc_object_type;
3434 build_class_template ()
3436 tree decl_specs, field_decl, field_decl_chain;
3439 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
3441 /* struct objc_class *isa; */
3443 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3444 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3446 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3447 field_decl_chain = field_decl;
3449 /* struct objc_class *super_class; */
3451 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3453 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
3455 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3456 chainon (field_decl_chain, field_decl);
3460 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3461 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
3463 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3464 chainon (field_decl_chain, field_decl);
3468 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3469 field_decl = get_identifier ("version");
3471 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3472 chainon (field_decl_chain, field_decl);
3476 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3477 field_decl = get_identifier ("info");
3479 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3480 chainon (field_decl_chain, field_decl);
3482 /* long instance_size; */
3484 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
3485 field_decl = get_identifier ("instance_size");
3487 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3488 chainon (field_decl_chain, field_decl);
3490 /* struct objc_ivar_list *ivars; */
3492 decl_specs = build_tree_list (NULL_TREE,
3493 xref_tag (RECORD_TYPE,
3494 get_identifier (UTAG_IVAR_LIST)));
3495 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
3497 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3498 chainon (field_decl_chain, field_decl);
3500 /* struct objc_method_list *methods; */
3502 decl_specs = build_tree_list (NULL_TREE,
3503 xref_tag (RECORD_TYPE,
3504 get_identifier (UTAG_METHOD_LIST)));
3505 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
3507 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3508 chainon (field_decl_chain, field_decl);
3510 if (flag_next_runtime)
3512 /* struct objc_cache *cache; */
3514 decl_specs = build_tree_list (NULL_TREE,
3515 xref_tag (RECORD_TYPE,
3516 get_identifier ("objc_cache")));
3517 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
3518 field_decl = grokfield (input_filename, lineno, field_decl,
3519 decl_specs, NULL_TREE);
3520 chainon (field_decl_chain, field_decl);
3524 /* struct sarray *dtable; */
3526 decl_specs = build_tree_list (NULL_TREE,
3527 xref_tag (RECORD_TYPE,
3528 get_identifier ("sarray")));
3529 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
3530 field_decl = grokfield (input_filename, lineno, field_decl,
3531 decl_specs, NULL_TREE);
3532 chainon (field_decl_chain, field_decl);
3534 /* struct objc_class *subclass_list; */
3536 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3538 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
3539 field_decl = grokfield (input_filename, lineno, field_decl,
3540 decl_specs, NULL_TREE);
3541 chainon (field_decl_chain, field_decl);
3543 /* struct objc_class *sibling_class; */
3545 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
3547 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
3548 field_decl = grokfield (input_filename, lineno, field_decl,
3549 decl_specs, NULL_TREE);
3550 chainon (field_decl_chain, field_decl);
3553 /* struct objc_protocol **protocol_list; */
3555 decl_specs = build_tree_list (NULL_TREE,
3556 xref_tag (RECORD_TYPE,
3557 get_identifier (UTAG_PROTOCOL)));
3559 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3561 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3562 field_decl = grokfield (input_filename, lineno, field_decl,
3563 decl_specs, NULL_TREE);
3564 chainon (field_decl_chain, field_decl);
3568 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3569 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
3571 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3572 chainon (field_decl_chain, field_decl);
3574 /* void *gc_object_type; */
3576 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
3577 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
3579 = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
3580 chainon (field_decl_chain, field_decl);
3582 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
3585 /* Generate appropriate forward declarations for an implementation. */
3588 synth_forward_declarations ()
3590 tree sc_spec, decl_specs, an_id;
3592 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3594 an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context);
3596 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
3597 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
3598 UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
3599 TREE_USED (UOBJC_CLASS_decl) = 1;
3600 DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
3602 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3604 an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
3605 implementation_context);
3607 UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
3608 TREE_USED (UOBJC_METACLASS_decl) = 1;
3609 DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
3611 /* Pre-build the following entities - for speed/convenience. */
3613 an_id = get_identifier ("super_class");
3614 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
3615 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
3619 error_with_ivar (message, decl, rawdecl)
3620 const char *message;
3626 report_error_function (DECL_SOURCE_FILE (decl));
3628 fprintf (stderr, "%s:%d: ",
3629 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3630 memset (errbuf, 0, BUFSIZE);
3631 fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf));
3634 #define USERTYPE(t) \
3635 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3636 || TREE_CODE (t) == ENUMERAL_TYPE)
3639 check_ivars (inter, imp)
3643 tree intdecls = CLASS_IVARS (inter);
3644 tree impdecls = CLASS_IVARS (imp);
3645 tree rawintdecls = CLASS_RAW_IVARS (inter);
3646 tree rawimpdecls = CLASS_RAW_IVARS (imp);
3652 if (intdecls == 0 && impdecls == 0)
3654 if (intdecls == 0 || impdecls == 0)
3656 error ("inconsistent instance variable specification");
3660 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
3662 if (!comptypes (t1, t2))
3664 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
3666 error_with_ivar ("conflicting instance variable type",
3667 impdecls, rawimpdecls);
3668 error_with_ivar ("previous declaration of",
3669 intdecls, rawintdecls);
3671 else /* both the type and the name don't match */
3673 error ("inconsistent instance variable specification");
3678 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
3680 error_with_ivar ("conflicting instance variable name",
3681 impdecls, rawimpdecls);
3682 error_with_ivar ("previous declaration of",
3683 intdecls, rawintdecls);
3686 intdecls = TREE_CHAIN (intdecls);
3687 impdecls = TREE_CHAIN (impdecls);
3688 rawintdecls = TREE_CHAIN (rawintdecls);
3689 rawimpdecls = TREE_CHAIN (rawimpdecls);
3693 /* Set super_type to the data type node for struct objc_super *,
3694 first defining struct objc_super itself.
3695 This needs to be done just once per compilation. */
3698 build_super_template ()
3700 tree record, decl_specs, field_decl, field_decl_chain;
3702 record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
3704 /* struct objc_object *self; */
3706 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
3707 field_decl = get_identifier ("self");
3708 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3709 field_decl = grokfield (input_filename, lineno,
3710 field_decl, decl_specs, NULL_TREE);
3711 field_decl_chain = field_decl;
3713 /* struct objc_class *class; */
3715 decl_specs = get_identifier (UTAG_CLASS);
3716 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
3717 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
3719 field_decl = grokfield (input_filename, lineno,
3720 field_decl, decl_specs, NULL_TREE);
3721 chainon (field_decl_chain, field_decl);
3723 finish_struct (record, field_decl_chain, NULL_TREE);
3725 /* `struct objc_super *' */
3726 super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3728 build1 (INDIRECT_REF,
3729 NULL_TREE, NULL_TREE)));
3733 /* struct objc_ivar {
3740 build_ivar_template ()
3742 tree objc_ivar_id, objc_ivar_record;
3743 tree decl_specs, field_decl, field_decl_chain;
3745 objc_ivar_id = get_identifier (UTAG_IVAR);
3746 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
3748 /* char *ivar_name; */
3750 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3751 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
3753 field_decl = grokfield (input_filename, lineno, field_decl,
3754 decl_specs, NULL_TREE);
3755 field_decl_chain = field_decl;
3757 /* char *ivar_type; */
3759 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3760 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
3762 field_decl = grokfield (input_filename, lineno, field_decl,
3763 decl_specs, NULL_TREE);
3764 chainon (field_decl_chain, field_decl);
3766 /* int ivar_offset; */
3768 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3769 field_decl = get_identifier ("ivar_offset");
3771 field_decl = grokfield (input_filename, lineno, field_decl,
3772 decl_specs, NULL_TREE);
3773 chainon (field_decl_chain, field_decl);
3775 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
3777 return objc_ivar_record;
3782 struct objc_ivar ivar_list[ivar_count];
3786 build_ivar_list_template (list_type, size)
3790 tree objc_ivar_list_record;
3791 tree decl_specs, field_decl, field_decl_chain;
3793 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3795 /* int ivar_count; */
3797 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3798 field_decl = get_identifier ("ivar_count");
3800 field_decl = grokfield (input_filename, lineno, field_decl,
3801 decl_specs, NULL_TREE);
3802 field_decl_chain = field_decl;
3804 /* struct objc_ivar ivar_list[]; */
3806 decl_specs = build_tree_list (NULL_TREE, list_type);
3807 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
3808 build_int_2 (size, 0));
3810 field_decl = grokfield (input_filename, lineno,
3811 field_decl, decl_specs, NULL_TREE);
3812 chainon (field_decl_chain, field_decl);
3814 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3816 return objc_ivar_list_record;
3822 struct objc_method method_list[method_count];
3826 build_method_list_template (list_type, size)
3830 tree objc_ivar_list_record;
3831 tree decl_specs, field_decl, field_decl_chain;
3833 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3835 /* int method_next; */
3840 xref_tag (RECORD_TYPE,
3841 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3843 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
3844 field_decl = grokfield (input_filename, lineno, field_decl,
3845 decl_specs, NULL_TREE);
3846 field_decl_chain = field_decl;
3848 /* int method_count; */
3850 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3851 field_decl = get_identifier ("method_count");
3853 field_decl = grokfield (input_filename, lineno,
3854 field_decl, decl_specs, NULL_TREE);
3855 chainon (field_decl_chain, field_decl);
3857 /* struct objc_method method_list[]; */
3859 decl_specs = build_tree_list (NULL_TREE, list_type);
3860 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3861 build_int_2 (size, 0));
3863 field_decl = grokfield (input_filename, lineno,
3864 field_decl, decl_specs, NULL_TREE);
3865 chainon (field_decl_chain, field_decl);
3867 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3869 return objc_ivar_list_record;
3873 build_ivar_list_initializer (type, field_decl)
3877 tree initlist = NULL_TREE;
3881 tree ivar = NULL_TREE;
3884 if (DECL_NAME (field_decl))
3885 ivar = tree_cons (NULL_TREE,
3886 add_objc_string (DECL_NAME (field_decl),
3890 /* Unnamed bit-field ivar (yuck). */
3891 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
3894 encode_field_decl (field_decl,
3895 obstack_object_size (&util_obstack),
3896 OBJC_ENCODE_DONT_INLINE_DEFS);
3898 /* Null terminate string. */
3899 obstack_1grow (&util_obstack, 0);
3903 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
3906 obstack_free (&util_obstack, util_firstobj);
3909 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
3910 initlist = tree_cons (NULL_TREE,
3911 build_constructor (type, nreverse (ivar)),
3914 field_decl = TREE_CHAIN (field_decl);
3918 return build_constructor (build_array_type (type, 0), nreverse (initlist));
3922 generate_ivars_list (type, name, size, list)
3928 tree sc_spec, decl_specs, decl, initlist;
3930 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3931 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3933 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
3934 decl_specs, 1, NULL_TREE, NULL_TREE);
3936 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3937 initlist = tree_cons (NULL_TREE, list, initlist);
3940 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
3947 generate_ivar_lists ()
3949 tree initlist, ivar_list_template, chain;
3950 tree cast, variable_length_type;
3953 generating_instance_variables = 1;
3955 if (!objc_ivar_template)
3956 objc_ivar_template = build_ivar_template ();
3960 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3961 get_identifier (UTAG_IVAR_LIST))),
3963 variable_length_type = groktypename (cast);
3965 /* Only generate class variables for the root of the inheritance
3966 hierarchy since these will be the same for every class. */
3968 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
3969 && (chain = TYPE_FIELDS (objc_class_template)))
3971 size = list_length (chain);
3973 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3974 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3976 UOBJC_CLASS_VARIABLES_decl
3977 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
3979 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
3982 UOBJC_CLASS_VARIABLES_decl = 0;
3984 chain = CLASS_IVARS (implementation_template);
3987 size = list_length (chain);
3988 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
3989 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
3991 UOBJC_INSTANCE_VARIABLES_decl
3992 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
3994 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
3997 UOBJC_INSTANCE_VARIABLES_decl = 0;
3999 generating_instance_variables = 0;
4003 build_dispatch_table_initializer (type, entries)
4007 tree initlist = NULL_TREE;
4011 tree elemlist = NULL_TREE;
4013 elemlist = tree_cons (NULL_TREE,
4014 build_selector (METHOD_SEL_NAME (entries)),
4017 elemlist = tree_cons (NULL_TREE,
4018 add_objc_string (METHOD_ENCODING (entries),
4022 elemlist = tree_cons (NULL_TREE,
4023 build_unary_op (ADDR_EXPR,
4024 METHOD_DEFINITION (entries), 1),
4027 initlist = tree_cons (NULL_TREE,
4028 build_constructor (type, nreverse (elemlist)),
4031 entries = TREE_CHAIN (entries);
4035 return build_constructor (build_array_type (type, 0), nreverse (initlist));
4038 /* To accomplish method prototyping without generating all kinds of
4039 inane warnings, the definition of the dispatch table entries were
4042 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4044 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4047 build_method_template ()
4050 tree decl_specs, field_decl, field_decl_chain;
4052 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4054 #ifdef OBJC_INT_SELECTORS
4055 /* unsigned int _cmd; */
4056 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED],
4058 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
4059 field_decl = get_identifier ("_cmd");
4060 #else /* not OBJC_INT_SELECTORS */
4061 /* struct objc_selector *_cmd; */
4062 decl_specs = tree_cons (NULL_TREE,
4063 xref_tag (RECORD_TYPE,
4064 get_identifier (TAG_SELECTOR)),
4066 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4067 #endif /* not OBJC_INT_SELECTORS */
4069 field_decl = grokfield (input_filename, lineno, field_decl,
4070 decl_specs, NULL_TREE);
4071 field_decl_chain = field_decl;
4073 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4074 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4075 get_identifier ("method_types"));
4076 field_decl = grokfield (input_filename, lineno, field_decl,
4077 decl_specs, NULL_TREE);
4078 chainon (field_decl_chain, field_decl);
4082 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4083 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4084 field_decl = grokfield (input_filename, lineno, field_decl,
4085 decl_specs, NULL_TREE);
4086 chainon (field_decl_chain, field_decl);
4088 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4095 generate_dispatch_table (type, name, size, list)
4101 tree sc_spec, decl_specs, decl, initlist;
4103 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4104 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4106 decl = start_decl (synth_id_with_class_suffix (name, implementation_context),
4107 decl_specs, 1, NULL_TREE, NULL_TREE);
4109 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4110 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4111 initlist = tree_cons (NULL_TREE, list, initlist);
4114 build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4121 generate_dispatch_tables ()
4123 tree initlist, chain, method_list_template;
4124 tree cast, variable_length_type;
4127 if (!objc_method_template)
4128 objc_method_template = build_method_template ();
4132 (build_tree_list (NULL_TREE,
4133 xref_tag (RECORD_TYPE,
4134 get_identifier (UTAG_METHOD_LIST))),
4137 variable_length_type = groktypename (cast);
4139 chain = CLASS_CLS_METHODS (implementation_context);
4142 size = list_length (chain);
4144 method_list_template
4145 = build_method_list_template (objc_method_template, size);
4147 = build_dispatch_table_initializer (objc_method_template, chain);
4149 UOBJC_CLASS_METHODS_decl
4150 = generate_dispatch_table (method_list_template,
4151 ((TREE_CODE (implementation_context)
4152 == CLASS_IMPLEMENTATION_TYPE)
4153 ? "_OBJC_CLASS_METHODS"
4154 : "_OBJC_CATEGORY_CLASS_METHODS"),
4156 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4159 UOBJC_CLASS_METHODS_decl = 0;
4161 chain = CLASS_NST_METHODS (implementation_context);
4164 size = list_length (chain);
4166 method_list_template
4167 = build_method_list_template (objc_method_template, size);
4169 = build_dispatch_table_initializer (objc_method_template, chain);
4171 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4172 UOBJC_INSTANCE_METHODS_decl
4173 = generate_dispatch_table (method_list_template,
4174 "_OBJC_INSTANCE_METHODS",
4177 /* We have a category. */
4178 UOBJC_INSTANCE_METHODS_decl
4179 = generate_dispatch_table (method_list_template,
4180 "_OBJC_CATEGORY_INSTANCE_METHODS",
4182 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4185 UOBJC_INSTANCE_METHODS_decl = 0;
4189 generate_protocol_list (i_or_p)
4192 tree initlist, decl_specs, sc_spec;
4193 tree refs_decl, expr_decl, lproto, e, plist;
4197 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4198 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4199 plist = CLASS_PROTOCOL_LIST (i_or_p);
4200 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4201 plist = PROTOCOL_LIST (i_or_p);
4205 cast_type = groktypename
4207 (build_tree_list (NULL_TREE,
4208 xref_tag (RECORD_TYPE,
4209 get_identifier (UTAG_PROTOCOL))),
4210 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4213 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4214 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4215 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4218 /* Build initializer. */
4219 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4221 e = build_int_2 (size, 0);
4222 TREE_TYPE (e) = cast_type;
4223 initlist = tree_cons (NULL_TREE, e, initlist);
4225 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4227 tree pval = TREE_VALUE (lproto);
4229 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4230 && PROTOCOL_FORWARD_DECL (pval))
4232 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4233 initlist = tree_cons (NULL_TREE, e, initlist);
4237 /* static struct objc_protocol *refs[n]; */
4239 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4240 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4241 get_identifier (UTAG_PROTOCOL)),
4244 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4245 expr_decl = build_nt (ARRAY_REF,
4246 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4248 build_int_2 (size + 2, 0));
4249 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4250 expr_decl = build_nt (ARRAY_REF,
4251 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4253 build_int_2 (size + 2, 0));
4254 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4256 = build_nt (ARRAY_REF,
4257 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4259 build_int_2 (size + 2, 0));
4263 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4265 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE);
4267 finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
4268 nreverse (initlist)),
4275 build_category_initializer (type, cat_name, class_name,
4276 instance_methods, class_methods, protocol_list)
4280 tree instance_methods;
4284 tree initlist = NULL_TREE, expr;
4286 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4287 initlist = tree_cons (NULL_TREE, class_name, initlist);
4289 if (!instance_methods)
4290 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4293 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4294 initlist = tree_cons (NULL_TREE, expr, initlist);
4297 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4300 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4301 initlist = tree_cons (NULL_TREE, expr, initlist);
4304 /* protocol_list = */
4306 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4309 tree cast_type2 = groktypename
4311 (build_tree_list (NULL_TREE,
4312 xref_tag (RECORD_TYPE,
4313 get_identifier (UTAG_PROTOCOL))),
4314 build1 (INDIRECT_REF, NULL_TREE,
4315 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4317 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4318 TREE_TYPE (expr) = cast_type2;
4319 initlist = tree_cons (NULL_TREE, expr, initlist);
4322 return build_constructor (type, nreverse (initlist));
4325 /* struct objc_class {
4326 struct objc_class *isa;
4327 struct objc_class *super_class;
4332 struct objc_ivar_list *ivars;
4333 struct objc_method_list *methods;
4334 if (flag_next_runtime)
4335 struct objc_cache *cache;
4337 struct sarray *dtable;
4338 struct objc_class *subclass_list;
4339 struct objc_class *sibling_class;
4341 struct objc_protocol_list *protocols;
4342 void *gc_object_type;
4346 build_shared_structure_initializer (type, isa, super, name, size, status,
4347 dispatch_table, ivar_list, protocol_list)
4354 tree dispatch_table;
4358 tree initlist = NULL_TREE, expr;
4361 initlist = tree_cons (NULL_TREE, isa, initlist);
4364 initlist = tree_cons (NULL_TREE, super, initlist);
4367 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4370 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4373 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4375 /* instance_size = */
4376 initlist = tree_cons (NULL_TREE, size, initlist);
4378 /* objc_ivar_list = */
4380 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4383 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4384 initlist = tree_cons (NULL_TREE, expr, initlist);
4387 /* objc_method_list = */
4388 if (!dispatch_table)
4389 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4392 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4393 initlist = tree_cons (NULL_TREE, expr, initlist);
4396 if (flag_next_runtime)
4397 /* method_cache = */
4398 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4402 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4404 /* subclass_list = */
4405 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4407 /* sibling_class = */
4408 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4411 /* protocol_list = */
4412 if (! protocol_list)
4413 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4419 (build_tree_list (NULL_TREE,
4420 xref_tag (RECORD_TYPE,
4421 get_identifier (UTAG_PROTOCOL))),
4422 build1 (INDIRECT_REF, NULL_TREE,
4423 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4425 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4426 TREE_TYPE (expr) = cast_type2;
4427 initlist = tree_cons (NULL_TREE, expr, initlist);
4430 /* gc_object_type = NULL */
4431 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4433 return build_constructor (type, nreverse (initlist));
4436 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4439 generate_category (cat)
4442 tree sc_spec, decl_specs, decl;
4443 tree initlist, cat_name_expr, class_name_expr;
4444 tree protocol_decl, category;
4446 add_class_reference (CLASS_NAME (cat));
4447 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4449 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4451 category = CLASS_CATEGORY_LIST (implementation_template);
4453 /* find the category interface from the class it is associated with */
4456 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
4458 category = CLASS_CATEGORY_LIST (category);
4461 if (category && CLASS_PROTOCOL_LIST (category))
4463 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4464 protocol_decl = generate_protocol_list (category);
4469 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4470 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
4472 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4473 implementation_context),
4474 decl_specs, 1, NULL_TREE, NULL_TREE);
4476 initlist = build_category_initializer (TREE_TYPE (decl),
4477 cat_name_expr, class_name_expr,
4478 UOBJC_INSTANCE_METHODS_decl,
4479 UOBJC_CLASS_METHODS_decl,
4482 TREE_USED (decl) = 1;
4483 finish_decl (decl, initlist, NULL_TREE);
4486 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4487 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4490 generate_shared_structures ()
4492 tree sc_spec, decl_specs, decl;
4493 tree name_expr, super_expr, root_expr;
4494 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4495 tree cast_type, initlist, protocol_decl;
4497 my_super_id = CLASS_SUPER_NAME (implementation_template);
4500 add_class_reference (my_super_id);
4502 /* Compute "my_root_id" - this is required for code generation.
4503 the "isa" for all meta class structures points to the root of
4504 the inheritance hierarchy (e.g. "__Object")... */
4505 my_root_id = my_super_id;
4508 tree my_root_int = lookup_interface (my_root_id);
4510 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4511 my_root_id = CLASS_SUPER_NAME (my_root_int);
4518 /* No super class. */
4519 my_root_id = CLASS_NAME (implementation_template);
4522 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
4523 objc_class_template),
4524 build1 (INDIRECT_REF,
4525 NULL_TREE, NULL_TREE)));
4527 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4530 /* Install class `isa' and `super' pointers at runtime. */
4533 super_expr = add_objc_string (my_super_id, class_names);
4534 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
4537 super_expr = build_int_2 (0, 0);
4539 root_expr = add_objc_string (my_root_id, class_names);
4540 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
4542 if (CLASS_PROTOCOL_LIST (implementation_template))
4544 generate_protocol_references
4545 (CLASS_PROTOCOL_LIST (implementation_template));
4546 protocol_decl = generate_protocol_list (implementation_template);
4551 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4553 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
4554 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
4556 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
4557 NULL_TREE, NULL_TREE);
4560 = build_shared_structure_initializer
4562 root_expr, super_expr, name_expr,
4563 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
4565 UOBJC_CLASS_METHODS_decl,
4566 UOBJC_CLASS_VARIABLES_decl,
4569 finish_decl (decl, initlist, NULL_TREE);
4571 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4573 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
4574 NULL_TREE, NULL_TREE);
4577 = build_shared_structure_initializer
4579 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
4580 super_expr, name_expr,
4581 convert (integer_type_node,
4582 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4583 (implementation_template))),
4585 UOBJC_INSTANCE_METHODS_decl,
4586 UOBJC_INSTANCE_VARIABLES_decl,
4589 finish_decl (decl, initlist, NULL_TREE);
4593 synth_id_with_class_suffix (preamble, ctxt)
4594 const char *preamble;
4598 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
4599 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
4601 const char *class_name
4602 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4603 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
4604 sprintf (string, "%s_%s", preamble,
4605 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
4607 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
4608 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
4610 /* We have a category. */
4611 const char *class_name
4612 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
4613 const char *class_super_name
4614 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context));
4615 string = (char *) alloca (strlen (preamble)
4616 + strlen (class_name)
4617 + strlen (class_super_name)
4619 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
4621 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
4623 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
4625 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
4626 sprintf (string, "%s_%s", preamble, protocol_name);
4631 return get_identifier (string);
4635 is_objc_type_qualifier (node)
4638 return (TREE_CODE (node) == IDENTIFIER_NODE
4639 && (node == ridpointers [(int) RID_CONST]
4640 || node == ridpointers [(int) RID_VOLATILE]
4641 || node == ridpointers [(int) RID_IN]
4642 || node == ridpointers [(int) RID_OUT]
4643 || node == ridpointers [(int) RID_INOUT]
4644 || node == ridpointers [(int) RID_BYCOPY]
4645 || node == ridpointers [(int) RID_BYREF]
4646 || node == ridpointers [(int) RID_ONEWAY]));
4649 /* If type is empty or only type qualifiers are present, add default
4650 type of id (otherwise grokdeclarator will default to int). */
4653 adjust_type_for_id_default (type)
4656 tree declspecs, chain;
4659 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
4660 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4662 declspecs = TREE_PURPOSE (type);
4664 /* Determine if a typespec is present. */
4665 for (chain = declspecs;
4667 chain = TREE_CHAIN (chain))
4669 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
4673 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
4675 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
4680 selector ':' '(' typename ')' identifier
4683 Transform an Objective-C keyword argument into
4684 the C equivalent parameter declarator.
4686 In: key_name, an "identifier_node" (optional).
4687 arg_type, a "tree_list" (optional).
4688 arg_name, an "identifier_node".
4690 Note: It would be really nice to strongly type the preceding
4691 arguments in the function prototype; however, then I
4692 could not use the "accessor" macros defined in "tree.h".
4694 Out: an instance of "keyword_decl". */
4697 build_keyword_decl (key_name, arg_type, arg_name)
4704 /* If no type is specified, default to "id". */
4705 arg_type = adjust_type_for_id_default (arg_type);
4707 keyword_decl = make_node (KEYWORD_DECL);
4709 TREE_TYPE (keyword_decl) = arg_type;
4710 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
4711 KEYWORD_KEY_NAME (keyword_decl) = key_name;
4713 return keyword_decl;
4716 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4719 build_keyword_selector (selector)
4723 tree key_chain, key_name;
4726 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4728 if (TREE_CODE (selector) == KEYWORD_DECL)
4729 key_name = KEYWORD_KEY_NAME (key_chain);
4730 else if (TREE_CODE (selector) == TREE_LIST)
4731 key_name = TREE_PURPOSE (key_chain);
4736 len += IDENTIFIER_LENGTH (key_name) + 1;
4738 /* Just a ':' arg. */
4742 buf = (char *)alloca (len + 1);
4743 memset (buf, 0, len + 1);
4745 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
4747 if (TREE_CODE (selector) == KEYWORD_DECL)
4748 key_name = KEYWORD_KEY_NAME (key_chain);
4749 else if (TREE_CODE (selector) == TREE_LIST)
4750 key_name = TREE_PURPOSE (key_chain);
4755 strcat (buf, IDENTIFIER_POINTER (key_name));
4759 return get_identifier (buf);
4762 /* Used for declarations and definitions. */
4765 build_method_decl (code, ret_type, selector, add_args)
4766 enum tree_code code;
4773 /* If no type is specified, default to "id". */
4774 ret_type = adjust_type_for_id_default (ret_type);
4776 method_decl = make_node (code);
4777 TREE_TYPE (method_decl) = ret_type;
4779 /* If we have a keyword selector, create an identifier_node that
4780 represents the full selector name (`:' included)... */
4781 if (TREE_CODE (selector) == KEYWORD_DECL)
4783 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
4784 METHOD_SEL_ARGS (method_decl) = selector;
4785 METHOD_ADD_ARGS (method_decl) = add_args;
4789 METHOD_SEL_NAME (method_decl) = selector;
4790 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
4791 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
4797 #define METHOD_DEF 0
4798 #define METHOD_REF 1
4800 /* Used by `build_message_expr' and `comp_method_types'. Return an
4801 argument list for method METH. CONTEXT is either METHOD_DEF or
4802 METHOD_REF, saying whether we are trying to define a method or call
4803 one. SUPERFLAG says this is for a send to super; this makes a
4804 difference for the NeXT calling sequence in which the lookup and
4805 the method call are done together. */
4808 get_arg_type_list (meth, context, superflag)
4815 /* Receiver type. */
4816 if (flag_next_runtime && superflag)
4817 arglist = build_tree_list (NULL_TREE, super_type);
4818 else if (context == METHOD_DEF)
4819 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
4821 arglist = build_tree_list (NULL_TREE, id_type);
4823 /* Selector type - will eventually change to `int'. */
4824 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
4826 /* Build a list of argument types. */
4827 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
4829 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
4830 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
4833 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
4834 /* We have a `, ...' immediately following the selector,
4835 finalize the arglist...simulate get_parm_info (0). */
4837 else if (METHOD_ADD_ARGS (meth))
4839 /* we have a variable length selector */
4840 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
4841 chainon (arglist, add_arg_list);
4844 /* finalize the arglist...simulate get_parm_info (1) */
4845 chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
4851 check_duplicates (hsh)
4854 tree meth = NULL_TREE;
4862 /* We have two methods with the same name and different types. */
4864 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
4866 warning ("multiple declarations for method `%s'",
4867 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
4869 warn_with_method ("using", type, meth);
4870 for (loop = hsh->list; loop; loop = loop->next)
4871 warn_with_method ("also found", type, loop->value);
4877 /* If RECEIVER is a class reference, return the identifier node for the
4878 referenced class. RECEIVER is created by get_class_reference, so we
4879 check the exact form created depending on which runtimes are used. */
4882 receiver_is_class_object (receiver)
4885 tree chain, exp, arg;
4886 if (flag_next_runtime)
4888 /* The receiver is a variable created by build_class_reference_decl. */
4889 if (TREE_CODE (receiver) == VAR_DECL
4890 && TREE_TYPE (receiver) == objc_class_type)
4891 /* Look up the identifier. */
4892 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
4893 if (TREE_PURPOSE (chain) == receiver)
4894 return TREE_VALUE (chain);
4898 /* The receiver is a function call that returns an id. Check if
4899 it is a call to objc_getClass, if so, pick up the class name. */
4900 if ((exp = TREE_OPERAND (receiver, 0))
4901 && TREE_CODE (exp) == ADDR_EXPR
4902 && (exp = TREE_OPERAND (exp, 0))
4903 && TREE_CODE (exp) == FUNCTION_DECL
4904 && exp == objc_get_class_decl
4905 /* we have a call to objc_getClass! */
4906 && (arg = TREE_OPERAND (receiver, 1))
4907 && TREE_CODE (arg) == TREE_LIST
4908 && (arg = TREE_VALUE (arg)))
4911 if (TREE_CODE (arg) == ADDR_EXPR
4912 && (arg = TREE_OPERAND (arg, 0))
4913 && TREE_CODE (arg) == STRING_CST)
4914 /* Finally, we have the class name. */
4915 return get_identifier (TREE_STRING_POINTER (arg));
4921 /* If we are currently building a message expr, this holds
4922 the identifier of the selector of the message. This is
4923 used when printing warnings about argument mismatches. */
4925 static tree building_objc_message_expr = 0;
4928 maybe_building_objc_message_expr ()
4930 return building_objc_message_expr;
4933 /* Construct an expression for sending a message.
4934 MESS has the object to send to in TREE_PURPOSE
4935 and the argument list (including selector) in TREE_VALUE.
4937 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4938 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4941 build_message_expr (mess)
4944 tree receiver = TREE_PURPOSE (mess);
4945 tree selector, self_object;
4946 tree rtype, sel_name;
4947 tree args = TREE_VALUE (mess);
4948 tree method_params = NULL_TREE;
4949 tree method_prototype = NULL_TREE;
4951 int statically_typed = 0, statically_allocated = 0;
4952 tree class_ident = 0;
4954 /* 1 if this is sending to the superclass. */
4957 if (!doing_objc_thang)
4960 if (TREE_CODE (receiver) == ERROR_MARK)
4961 return error_mark_node;
4963 /* Determine receiver type. */
4964 rtype = TREE_TYPE (receiver);
4965 super = IS_SUPER (rtype);
4969 if (TREE_STATIC_TEMPLATE (rtype))
4970 statically_allocated = 1;
4971 else if (TREE_CODE (rtype) == POINTER_TYPE
4972 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
4973 statically_typed = 1;
4974 else if ((flag_next_runtime
4975 || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
4976 && (class_ident = receiver_is_class_object (receiver)))
4978 else if (! IS_ID (rtype)
4979 /* Allow any type that matches objc_class_type. */
4980 && ! comptypes (rtype, objc_class_type))
4982 memset (errbuf, 0, BUFSIZE);
4983 warning ("invalid receiver type `%s'",
4984 gen_declaration (rtype, errbuf));
4987 if (statically_allocated)
4988 receiver = build_unary_op (ADDR_EXPR, receiver, 0);
4990 /* Don't evaluate the receiver twice. */
4991 receiver = save_expr (receiver);
4992 self_object = receiver;
4995 /* If sending to `super', use current self as the object. */
4996 self_object = self_decl;
4998 /* Obtain the full selector name. */
5000 if (TREE_CODE (args) == IDENTIFIER_NODE)
5001 /* A unary selector. */
5003 else if (TREE_CODE (args) == TREE_LIST)
5004 sel_name = build_keyword_selector (args);
5008 /* Build the parameter list to give to the method. */
5010 method_params = NULL_TREE;
5011 if (TREE_CODE (args) == TREE_LIST)
5013 tree chain = args, prev = NULL_TREE;
5015 /* We have a keyword selector--check for comma expressions. */
5018 tree element = TREE_VALUE (chain);
5020 /* We have a comma expression, must collapse... */
5021 if (TREE_CODE (element) == TREE_LIST)
5024 TREE_CHAIN (prev) = element;
5029 chain = TREE_CHAIN (chain);
5031 method_params = args;
5034 /* Determine operation return type. */
5036 if (IS_SUPER (rtype))
5040 if (CLASS_SUPER_NAME (implementation_template))
5043 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5045 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
5046 method_prototype = lookup_instance_method_static (iface, sel_name);
5048 method_prototype = lookup_class_method_static (iface, sel_name);
5050 if (iface && !method_prototype)
5051 warning ("`%s' does not respond to `%s'",
5052 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
5053 IDENTIFIER_POINTER (sel_name));
5057 error ("no super class declared in interface for `%s'",
5058 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5059 return error_mark_node;
5063 else if (statically_allocated)
5065 tree ctype = TREE_TYPE (rtype);
5066 tree iface = lookup_interface (TYPE_NAME (rtype));
5069 method_prototype = lookup_instance_method_static (iface, sel_name);
5071 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5073 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5076 if (!method_prototype)
5077 warning ("`%s' does not respond to `%s'",
5078 IDENTIFIER_POINTER (TYPE_NAME (rtype)),
5079 IDENTIFIER_POINTER (sel_name));
5081 else if (statically_typed)
5083 tree ctype = TREE_TYPE (rtype);
5085 /* `self' is now statically_typed. All methods should be visible
5086 within the context of the implementation. */
5087 if (implementation_context
5088 && CLASS_NAME (implementation_context) == TYPE_NAME (ctype))
5091 = lookup_instance_method_static (implementation_template,
5094 if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
5096 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
5099 if (! method_prototype
5100 && implementation_template != implementation_context)
5101 /* The method is not published in the interface. Check
5104 = lookup_method (CLASS_NST_METHODS (implementation_context),
5111 if ((iface = lookup_interface (TYPE_NAME (ctype))))
5112 method_prototype = lookup_instance_method_static (iface, sel_name);
5114 if (! method_prototype)
5116 tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
5119 = lookup_method_in_protocol_list (protocol_list,
5124 if (!method_prototype)
5125 warning ("`%s' does not respond to `%s'",
5126 IDENTIFIER_POINTER (TYPE_NAME (ctype)),
5127 IDENTIFIER_POINTER (sel_name));
5129 else if (class_ident)
5131 if (implementation_context
5132 && CLASS_NAME (implementation_context) == class_ident)
5135 = lookup_class_method_static (implementation_template, sel_name);
5137 if (!method_prototype
5138 && implementation_template != implementation_context)
5139 /* The method is not published in the interface. Check
5142 = lookup_method (CLASS_CLS_METHODS (implementation_context),
5149 if ((iface = lookup_interface (class_ident)))
5150 method_prototype = lookup_class_method_static (iface, sel_name);
5153 if (!method_prototype)
5155 warning ("cannot find class (factory) method.");
5156 warning ("return type for `%s' defaults to id",
5157 IDENTIFIER_POINTER (sel_name));
5160 else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
5162 /* An anonymous object that has been qualified with a protocol. */
5164 tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
5166 method_prototype = lookup_method_in_protocol_list (protocol_list,
5169 if (!method_prototype)
5173 warning ("method `%s' not implemented by protocol.",
5174 IDENTIFIER_POINTER (sel_name));
5176 /* Try and find the method signature in the global pools. */
5178 if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
5179 hsh = hash_lookup (cls_method_hash_list, sel_name);
5181 if (!(method_prototype = check_duplicates (hsh)))
5182 warning ("return type defaults to id");
5189 /* We think we have an instance...loophole: extern id Object; */
5190 hsh = hash_lookup (nst_method_hash_list, sel_name);
5192 /* For various loopholes, like sending messages to self in a
5194 hsh = hash_lookup (cls_method_hash_list, sel_name);
5196 method_prototype = check_duplicates (hsh);
5197 if (!method_prototype)
5199 warning ("cannot find method.");
5200 warning ("return type for `%s' defaults to id",
5201 IDENTIFIER_POINTER (sel_name));
5205 /* Save the selector name for printing error messages. */
5206 building_objc_message_expr = sel_name;
5208 /* Build the parameters list for looking up the method.
5209 These are the object itself and the selector. */
5211 if (flag_typed_selectors)
5212 selector = build_typed_selector_reference (sel_name, method_prototype);
5214 selector = build_selector_reference (sel_name);
5216 retval = build_objc_method_call (super, method_prototype,
5217 receiver, self_object,
5218 selector, method_params);
5220 building_objc_message_expr = 0;
5225 /* Build a tree expression to send OBJECT the operation SELECTOR,
5226 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5227 assuming the method has prototype METHOD_PROTOTYPE.
5228 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5229 Use METHOD_PARAMS as list of args to pass to the method.
5230 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5233 build_objc_method_call (super_flag, method_prototype, lookup_object, object,
5234 selector, method_params)
5236 tree method_prototype, lookup_object, object, selector, method_params;
5238 tree sender = (super_flag ? umsg_super_decl : umsg_decl);
5239 tree rcv_p = (super_flag
5240 ? build_pointer_type (xref_tag (RECORD_TYPE,
5241 get_identifier (TAG_SUPER)))
5244 if (flag_next_runtime)
5246 if (! method_prototype)
5248 method_params = tree_cons (NULL_TREE, lookup_object,
5249 tree_cons (NULL_TREE, selector,
5251 assemble_external (sender);
5252 return build_function_call (sender, method_params);
5256 /* This is a real kludge, but it is used only for the Next.
5257 Clobber the data type of SENDER temporarily to accept
5258 all the arguments for this operation, and to return
5259 whatever this operation returns. */
5260 tree arglist = NULL_TREE;
5263 /* Save the proper contents of SENDER's data type. */
5264 tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
5265 tree savret = TREE_TYPE (TREE_TYPE (sender));
5267 /* Install this method's argument types. */
5268 arglist = get_arg_type_list (method_prototype, METHOD_REF,
5270 TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
5272 /* Install this method's return type. */
5273 TREE_TYPE (TREE_TYPE (sender))
5274 = groktypename (TREE_TYPE (method_prototype));
5276 /* Call SENDER with all the parameters. This will do type
5277 checking using the arg types for this method. */
5278 method_params = tree_cons (NULL_TREE, lookup_object,
5279 tree_cons (NULL_TREE, selector,
5281 assemble_external (sender);
5282 retval = build_function_call (sender, method_params);
5284 /* Restore SENDER's return/argument types. */
5285 TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
5286 TREE_TYPE (TREE_TYPE (sender)) = savret;
5292 /* This is the portable way.
5293 First call the lookup function to get a pointer to the method,
5294 then cast the pointer, then call it with the method arguments. */
5297 /* Avoid trouble since we may evaluate each of these twice. */
5298 object = save_expr (object);
5299 selector = save_expr (selector);
5301 lookup_object = build_c_cast (rcv_p, lookup_object);
5303 assemble_external (sender);
5305 = build_function_call (sender,
5306 tree_cons (NULL_TREE, lookup_object,
5307 tree_cons (NULL_TREE, selector,
5310 /* If we have a method prototype, construct the data type this
5311 method needs, and cast what we got from SENDER into a pointer
5313 if (method_prototype)
5315 tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
5317 tree valtype = groktypename (TREE_TYPE (method_prototype));
5318 tree fake_function_type = build_function_type (valtype, arglist);
5319 TREE_TYPE (method) = build_pointer_type (fake_function_type);
5323 = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
5325 /* Pass the object to the method. */
5326 assemble_external (method);
5327 return build_function_call (method,
5328 tree_cons (NULL_TREE, object,
5329 tree_cons (NULL_TREE, selector,
5335 build_protocol_reference (p)
5338 tree decl, ident, ptype;
5340 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5342 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5344 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5345 objc_protocol_template),
5348 if (IDENTIFIER_GLOBAL_VALUE (ident))
5349 decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
5352 decl = build_decl (VAR_DECL, ident, ptype);
5353 DECL_EXTERNAL (decl) = 1;
5354 TREE_PUBLIC (decl) = 1;
5355 TREE_USED (decl) = 1;
5356 DECL_ARTIFICIAL (decl) = 1;
5358 make_decl_rtl (decl, 0, 1);
5359 pushdecl_top_level (decl);
5362 PROTOCOL_FORWARD_DECL (p) = decl;
5366 build_protocol_expr (protoname)
5372 if (!doing_objc_thang)
5375 p = lookup_protocol (protoname);
5379 error ("Cannot find protocol declaration for `%s'",
5380 IDENTIFIER_POINTER (protoname));
5381 return error_mark_node;
5384 if (!PROTOCOL_FORWARD_DECL (p))
5385 build_protocol_reference (p);
5387 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5389 TREE_TYPE (expr) = protocol_type;
5395 build_selector_expr (selnamelist)
5400 if (!doing_objc_thang)
5403 /* Obtain the full selector name. */
5404 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5405 /* A unary selector. */
5406 selname = selnamelist;
5407 else if (TREE_CODE (selnamelist) == TREE_LIST)
5408 selname = build_keyword_selector (selnamelist);
5412 if (flag_typed_selectors)
5413 return build_typed_selector_reference (selname, 0);
5415 return build_selector_reference (selname);
5419 build_encode_expr (type)
5425 if (!doing_objc_thang)
5428 encode_type (type, obstack_object_size (&util_obstack),
5429 OBJC_ENCODE_INLINE_DEFS);
5430 obstack_1grow (&util_obstack, 0); /* null terminate string */
5431 string = obstack_finish (&util_obstack);
5433 /* Synthesize a string that represents the encoded struct/union. */
5434 result = my_build_string (strlen (string) + 1, string);
5435 obstack_free (&util_obstack, util_firstobj);
5440 build_ivar_reference (id)
5443 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
5445 /* Historically, a class method that produced objects (factory
5446 method) would assign `self' to the instance that it
5447 allocated. This would effectively turn the class method into
5448 an instance method. Following this assignment, the instance
5449 variables could be accessed. That practice, while safe,
5450 violates the simple rule that a class method should not refer
5451 to an instance variable. It's better to catch the cases
5452 where this is done unknowingly than to support the above
5454 warning ("instance variable `%s' accessed in class method",
5455 IDENTIFIER_POINTER (id));
5456 TREE_TYPE (self_decl) = instance_type; /* cast */
5459 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5462 #define HASH_ALLOC_LIST_SIZE 170
5463 #define ATTR_ALLOC_LIST_SIZE 170
5464 #define SIZEHASHTABLE 257
5467 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5472 nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5473 cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash));
5475 if (!nst_method_hash_list || !cls_method_hash_list)
5476 perror ("unable to allocate space in objc-tree.c");
5481 for (i = 0; i < SIZEHASHTABLE; i++)
5483 nst_method_hash_list[i] = 0;
5484 cls_method_hash_list[i] = 0;
5490 hash_enter (hashlist, method)
5494 static hash hash_alloc_list = 0;
5495 static int hash_alloc_index = 0;
5497 int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5499 if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
5501 hash_alloc_index = 0;
5502 hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
5503 * HASH_ALLOC_LIST_SIZE);
5504 if (! hash_alloc_list)
5505 perror ("unable to allocate in objc-tree.c");
5507 obj = &hash_alloc_list[hash_alloc_index++];
5509 obj->next = hashlist[slot];
5512 hashlist[slot] = obj; /* append to front */
5516 hash_lookup (hashlist, sel_name)
5522 target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE];
5526 if (sel_name == METHOD_SEL_NAME (target->key))
5529 target = target->next;
5535 hash_add_attr (entry, value)
5539 static attr attr_alloc_list = 0;
5540 static int attr_alloc_index = 0;
5543 if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
5545 attr_alloc_index = 0;
5546 attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
5547 * ATTR_ALLOC_LIST_SIZE);
5548 if (! attr_alloc_list)
5549 perror ("unable to allocate in objc-tree.c");
5551 obj = &attr_alloc_list[attr_alloc_index++];
5552 obj->next = entry->list;
5555 entry->list = obj; /* append to front */
5559 lookup_method (mchain, method)
5565 if (TREE_CODE (method) == IDENTIFIER_NODE)
5568 key = METHOD_SEL_NAME (method);
5572 if (METHOD_SEL_NAME (mchain) == key)
5574 mchain = TREE_CHAIN (mchain);
5580 lookup_instance_method_static (interface, ident)
5584 tree inter = interface;
5585 tree chain = CLASS_NST_METHODS (inter);
5586 tree meth = NULL_TREE;
5590 if ((meth = lookup_method (chain, ident)))
5593 if (CLASS_CATEGORY_LIST (inter))
5595 tree category = CLASS_CATEGORY_LIST (inter);
5596 chain = CLASS_NST_METHODS (category);
5600 if ((meth = lookup_method (chain, ident)))
5603 /* Check for instance methods in protocols in categories. */
5604 if (CLASS_PROTOCOL_LIST (category))
5606 if ((meth = (lookup_method_in_protocol_list
5607 (CLASS_PROTOCOL_LIST (category), ident, 0))))
5611 if ((category = CLASS_CATEGORY_LIST (category)))
5612 chain = CLASS_NST_METHODS (category);
5617 if (CLASS_PROTOCOL_LIST (inter))
5619 if ((meth = (lookup_method_in_protocol_list
5620 (CLASS_PROTOCOL_LIST (inter), ident, 0))))
5624 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5625 chain = CLASS_NST_METHODS (inter);
5633 lookup_class_method_static (interface, ident)
5637 tree inter = interface;
5638 tree chain = CLASS_CLS_METHODS (inter);
5639 tree meth = NULL_TREE;
5640 tree root_inter = NULL_TREE;
5644 if ((meth = lookup_method (chain, ident)))
5647 if (CLASS_CATEGORY_LIST (inter))
5649 tree category = CLASS_CATEGORY_LIST (inter);
5650 chain = CLASS_CLS_METHODS (category);
5654 if ((meth = lookup_method (chain, ident)))
5657 /* Check for class methods in protocols in categories. */
5658 if (CLASS_PROTOCOL_LIST (category))
5660 if ((meth = (lookup_method_in_protocol_list
5661 (CLASS_PROTOCOL_LIST (category), ident, 1))))
5665 if ((category = CLASS_CATEGORY_LIST (category)))
5666 chain = CLASS_CLS_METHODS (category);
5671 /* Check for class methods in protocols. */
5672 if (CLASS_PROTOCOL_LIST (inter))
5674 if ((meth = (lookup_method_in_protocol_list
5675 (CLASS_PROTOCOL_LIST (inter), ident, 1))))
5680 if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
5681 chain = CLASS_CLS_METHODS (inter);
5685 /* Simulate wrap around. */
5686 return lookup_instance_method_static (root_inter, ident);
5690 add_class_method (class, method)
5697 if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
5699 /* put method on list in reverse order */
5700 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
5701 CLASS_CLS_METHODS (class) = method;
5705 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5706 error ("duplicate definition of class method `%s'.",
5707 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5710 /* Check types; if different, complain. */
5711 if (!comp_proto_with_proto (method, mth))
5712 error ("duplicate declaration of class method `%s'.",
5713 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5717 if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
5719 /* Install on a global chain. */
5720 hash_enter (cls_method_hash_list, method);
5724 /* Check types; if different, add to a list. */
5725 if (!comp_proto_with_proto (method, hsh->key))
5726 hash_add_attr (hsh, method);
5732 add_instance_method (class, method)
5739 if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
5741 /* Put method on list in reverse order. */
5742 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
5743 CLASS_NST_METHODS (class) = method;
5747 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
5748 error ("duplicate definition of instance method `%s'.",
5749 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5752 /* Check types; if different, complain. */
5753 if (!comp_proto_with_proto (method, mth))
5754 error ("duplicate declaration of instance method `%s'.",
5755 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
5759 if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
5761 /* Install on a global chain. */
5762 hash_enter (nst_method_hash_list, method);
5766 /* Check types; if different, add to a list. */
5767 if (!comp_proto_with_proto (method, hsh->key))
5768 hash_add_attr (hsh, method);
5777 /* Put interfaces on list in reverse order. */
5778 TREE_CHAIN (class) = interface_chain;
5779 interface_chain = class;
5780 return interface_chain;
5784 add_category (class, category)
5788 /* Put categories on list in reverse order. */
5789 tree cat = CLASS_CATEGORY_LIST (class);
5793 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5794 warning ("duplicate interface declaration for category `%s(%s)'",
5795 IDENTIFIER_POINTER (CLASS_NAME (class)),
5796 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
5797 cat = CLASS_CATEGORY_LIST (cat);
5800 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
5801 CLASS_CATEGORY_LIST (class) = category;
5804 /* Called after parsing each instance variable declaration. Necessary to
5805 preserve typedefs and implement public/private...
5807 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5810 add_instance_variable (class, public, declarator, declspecs, width)
5817 tree field_decl, raw_decl;
5819 raw_decl = build_tree_list (declspecs, declarator);
5821 if (CLASS_RAW_IVARS (class))
5822 chainon (CLASS_RAW_IVARS (class), raw_decl);
5824 CLASS_RAW_IVARS (class) = raw_decl;
5826 field_decl = grokfield (input_filename, lineno,
5827 declarator, declspecs, width);
5829 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5833 TREE_PUBLIC (field_decl) = 0;
5834 TREE_PRIVATE (field_decl) = 0;
5835 TREE_PROTECTED (field_decl) = 1;
5839 TREE_PUBLIC (field_decl) = 1;
5840 TREE_PRIVATE (field_decl) = 0;
5841 TREE_PROTECTED (field_decl) = 0;
5845 TREE_PUBLIC (field_decl) = 0;
5846 TREE_PRIVATE (field_decl) = 1;
5847 TREE_PROTECTED (field_decl) = 0;
5852 if (CLASS_IVARS (class))
5853 chainon (CLASS_IVARS (class), field_decl);
5855 CLASS_IVARS (class) = field_decl;
5861 is_ivar (decl_chain, ident)
5865 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
5866 if (DECL_NAME (decl_chain) == ident)
5871 /* True if the ivar is private and we are not in its implementation. */
5877 if (TREE_PRIVATE (decl)
5878 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
5880 error ("instance variable `%s' is declared private",
5881 IDENTIFIER_POINTER (DECL_NAME (decl)));
5888 /* We have an instance variable reference;, check to see if it is public. */
5891 is_public (expr, identifier)
5895 tree basetype = TREE_TYPE (expr);
5896 enum tree_code code = TREE_CODE (basetype);
5899 if (code == RECORD_TYPE)
5901 if (TREE_STATIC_TEMPLATE (basetype))
5903 if (!lookup_interface (TYPE_NAME (basetype)))
5905 error ("Cannot find interface declaration for `%s'",
5906 IDENTIFIER_POINTER (TYPE_NAME (basetype)));
5910 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
5912 if (TREE_PUBLIC (decl))
5915 /* Important difference between the Stepstone translator:
5916 all instance variables should be public within the context
5917 of the implementation. */
5918 if (implementation_context
5919 && (((TREE_CODE (implementation_context)
5920 == CLASS_IMPLEMENTATION_TYPE)
5921 || (TREE_CODE (implementation_context)
5922 == CATEGORY_IMPLEMENTATION_TYPE))
5923 && (CLASS_NAME (implementation_context)
5924 == TYPE_NAME (basetype))))
5925 return ! is_private (decl);
5927 error ("instance variable `%s' is declared %s",
5928 IDENTIFIER_POINTER (identifier),
5929 TREE_PRIVATE (decl) ? "private" : "protected");
5934 else if (implementation_context && (basetype == objc_object_reference))
5936 TREE_TYPE (expr) = uprivate_record;
5937 warning ("static access to object of type `id'");
5944 /* Implement @defs (<classname>) within struct bodies. */
5947 get_class_ivars (interface)
5950 if (!doing_objc_thang)
5953 return build_ivar_chain (interface, 1);
5956 /* Make sure all entries in CHAIN are also in LIST. */
5959 check_methods (chain, list, mtype)
5968 if (!lookup_method (list, chain))
5972 if (TREE_CODE (implementation_context)
5973 == CLASS_IMPLEMENTATION_TYPE)
5974 warning ("incomplete implementation of class `%s'",
5975 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
5976 else if (TREE_CODE (implementation_context)
5977 == CATEGORY_IMPLEMENTATION_TYPE)
5978 warning ("incomplete implementation of category `%s'",
5979 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
5983 warning ("method definition for `%c%s' not found",
5984 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
5987 chain = TREE_CHAIN (chain);
5994 conforms_to_protocol (class, protocol)
6000 tree p = CLASS_PROTOCOL_LIST (class);
6002 while (p && TREE_VALUE (p) != TREE_VALUE (protocol))
6007 tree super = (CLASS_SUPER_NAME (class)
6008 ? lookup_interface (CLASS_SUPER_NAME (class))
6010 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6015 protocol = TREE_CHAIN (protocol);
6021 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6022 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6025 check_methods_accessible (chain, context, mtype)
6032 tree base_context = context;
6036 context = base_context;
6040 list = CLASS_CLS_METHODS (context);
6042 list = CLASS_NST_METHODS (context);
6044 if (lookup_method (list, chain))
6047 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6048 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6049 context = (CLASS_SUPER_NAME (context)
6050 ? lookup_interface (CLASS_SUPER_NAME (context))
6053 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6054 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6055 context = (CLASS_NAME (context)
6056 ? lookup_interface (CLASS_NAME (context))
6062 if (context == NULL_TREE)
6066 if (TREE_CODE (implementation_context)
6067 == CLASS_IMPLEMENTATION_TYPE)
6068 warning ("incomplete implementation of class `%s'",
6070 (CLASS_NAME (implementation_context)));
6071 else if (TREE_CODE (implementation_context)
6072 == CATEGORY_IMPLEMENTATION_TYPE)
6073 warning ("incomplete implementation of category `%s'",
6075 (CLASS_SUPER_NAME (implementation_context)));
6078 warning ("method definition for `%c%s' not found",
6079 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6082 chain = TREE_CHAIN (chain); /* next method... */
6088 check_protocols (proto_list, type, name)
6093 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6095 tree p = TREE_VALUE (proto_list);
6097 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6101 /* Ensure that all protocols have bodies. */
6102 if (flag_warn_protocol) {
6103 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6104 CLASS_CLS_METHODS (implementation_context),
6106 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6107 CLASS_NST_METHODS (implementation_context),
6110 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6111 implementation_context,
6113 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6114 implementation_context,
6119 warning ("%s `%s' does not fully implement the `%s' protocol",
6120 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6125 ; /* An identifier if we could not find a protocol. */
6128 /* Check protocols recursively. */
6129 if (PROTOCOL_LIST (p))
6132 = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6133 if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p)))
6134 check_protocols (PROTOCOL_LIST (p), type, name);
6139 /* Make sure that the class CLASS_NAME is defined
6140 CODE says which kind of thing CLASS_NAME ought to be.
6141 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6142 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6145 start_class (code, class_name, super_name, protocol_list)
6146 enum tree_code code;
6153 if (!doing_objc_thang)
6156 class = make_node (code);
6157 TYPE_BINFO (class) = make_tree_vec (5);
6159 CLASS_NAME (class) = class_name;
6160 CLASS_SUPER_NAME (class) = super_name;
6161 CLASS_CLS_METHODS (class) = NULL_TREE;
6163 if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
6165 error ("`%s' redeclared as different kind of symbol",
6166 IDENTIFIER_POINTER (class_name));
6167 error_with_decl (decl, "previous declaration of `%s'");
6170 if (code == CLASS_IMPLEMENTATION_TYPE)
6173 static tree implemented_classes = 0;
6174 tree chain = implemented_classes;
6175 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6176 if (TREE_VALUE (chain) == class_name)
6178 error ("reimplementation of class `%s'",
6179 IDENTIFIER_POINTER (class_name));
6180 return error_mark_node;
6182 implemented_classes = tree_cons (NULL_TREE, class_name,
6183 implemented_classes);
6186 /* Pre-build the following entities - for speed/convenience. */
6188 self_id = get_identifier ("self");
6190 ucmd_id = get_identifier ("_cmd");
6193 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6194 if (!objc_super_template)
6195 objc_super_template = build_super_template ();
6197 /* Reset for multiple classes per file. */
6200 implementation_context = class;
6202 /* Lookup the interface for this implementation. */
6204 if (!(implementation_template = lookup_interface (class_name)))
6206 warning ("Cannot find interface declaration for `%s'",
6207 IDENTIFIER_POINTER (class_name));
6208 add_class (implementation_template = implementation_context);
6211 /* If a super class has been specified in the implementation,
6212 insure it conforms to the one specified in the interface. */
6215 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6217 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6219 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6220 error ("conflicting super class name `%s'",
6221 IDENTIFIER_POINTER (super_name));
6222 error ("previous declaration of `%s'", name);
6225 else if (! super_name)
6227 CLASS_SUPER_NAME (implementation_context)
6228 = CLASS_SUPER_NAME (implementation_template);
6232 else if (code == CLASS_INTERFACE_TYPE)
6234 if (lookup_interface (class_name))
6235 warning ("duplicate interface declaration for class `%s'",
6236 IDENTIFIER_POINTER (class_name));
6241 CLASS_PROTOCOL_LIST (class)
6242 = lookup_and_install_protocols (protocol_list);
6245 else if (code == CATEGORY_INTERFACE_TYPE)
6247 tree class_category_is_assoc_with;
6249 /* For a category, class_name is really the name of the class that
6250 the following set of methods will be associated with. We must
6251 find the interface so that can derive the objects template. */
6253 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6255 error ("Cannot find interface declaration for `%s'",
6256 IDENTIFIER_POINTER (class_name));
6257 exit (FATAL_EXIT_CODE);
6260 add_category (class_category_is_assoc_with, class);
6263 CLASS_PROTOCOL_LIST (class)
6264 = lookup_and_install_protocols (protocol_list);
6267 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6269 /* Pre-build the following entities for speed/convenience. */
6271 self_id = get_identifier ("self");
6273 ucmd_id = get_identifier ("_cmd");
6276 = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
6277 if (!objc_super_template)
6278 objc_super_template = build_super_template ();
6280 /* Reset for multiple classes per file. */
6283 implementation_context = class;
6285 /* For a category, class_name is really the name of the class that
6286 the following set of methods will be associated with. We must
6287 find the interface so that can derive the objects template. */
6289 if (!(implementation_template = lookup_interface (class_name)))
6291 error ("Cannot find interface declaration for `%s'",
6292 IDENTIFIER_POINTER (class_name));
6293 exit (FATAL_EXIT_CODE);
6300 continue_class (class)
6303 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6304 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6306 struct imp_entry *imp_entry;
6309 /* Check consistency of the instance variables. */
6311 if (CLASS_IVARS (class))
6312 check_ivars (implementation_template, class);
6314 /* code generation */
6316 ivar_context = build_private_template (implementation_template);
6318 if (!objc_class_template)
6319 build_class_template ();
6322 = (struct imp_entry *) xmalloc (sizeof (struct imp_entry))))
6323 perror ("unable to allocate in objc-tree.c");
6325 imp_entry->next = imp_list;
6326 imp_entry->imp_context = class;
6327 imp_entry->imp_template = implementation_template;
6329 synth_forward_declarations ();
6330 imp_entry->class_decl = UOBJC_CLASS_decl;
6331 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6333 /* Append to front and increment count. */
6334 imp_list = imp_entry;
6335 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6340 return ivar_context;
6343 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6345 tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
6347 if (!TYPE_FIELDS (record))
6349 finish_struct (record, build_ivar_chain (class, 0), NULL_TREE);
6350 CLASS_STATIC_TEMPLATE (class) = record;
6352 /* Mark this record as a class template for static typing. */
6353 TREE_STATIC_TEMPLATE (record) = 1;
6360 return error_mark_node;
6363 /* This is called once we see the "@end" in an interface/implementation. */
6366 finish_class (class)
6369 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6371 /* All code generation is done in finish_objc. */
6373 if (implementation_template != implementation_context)
6375 /* Ensure that all method listed in the interface contain bodies. */
6376 check_methods (CLASS_CLS_METHODS (implementation_template),
6377 CLASS_CLS_METHODS (implementation_context), '+');
6378 check_methods (CLASS_NST_METHODS (implementation_template),
6379 CLASS_NST_METHODS (implementation_context), '-');
6381 if (CLASS_PROTOCOL_LIST (implementation_template))
6382 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6384 IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));
6388 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6390 tree category = CLASS_CATEGORY_LIST (implementation_template);
6392 /* Find the category interface from the class it is associated with. */
6395 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6397 category = CLASS_CATEGORY_LIST (category);
6402 /* Ensure all method listed in the interface contain bodies. */
6403 check_methods (CLASS_CLS_METHODS (category),
6404 CLASS_CLS_METHODS (implementation_context), '+');
6405 check_methods (CLASS_NST_METHODS (category),
6406 CLASS_NST_METHODS (implementation_context), '-');
6408 if (CLASS_PROTOCOL_LIST (category))
6409 check_protocols (CLASS_PROTOCOL_LIST (category),
6411 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
6415 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6418 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6419 char *string = (char *) alloca (strlen (class_name) + 3);
6421 /* extern struct objc_object *_<my_name>; */
6423 sprintf (string, "_%s", class_name);
6425 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6426 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6427 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6433 add_protocol (protocol)
6436 /* Put protocol on list in reverse order. */
6437 TREE_CHAIN (protocol) = protocol_chain;
6438 protocol_chain = protocol;
6439 return protocol_chain;
6443 lookup_protocol (ident)
6448 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6450 if (ident == PROTOCOL_NAME (chain))
6458 start_protocol (code, name, list)
6459 enum tree_code code;
6465 if (!doing_objc_thang)
6468 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6469 if (!objc_protocol_template)
6470 objc_protocol_template = build_protocol_template ();
6472 protocol = make_node (code);
6473 TYPE_BINFO (protocol) = make_tree_vec (2);
6475 PROTOCOL_NAME (protocol) = name;
6476 PROTOCOL_LIST (protocol) = list;
6478 lookup_and_install_protocols (list);
6480 if (lookup_protocol (name))
6481 warning ("duplicate declaration for protocol `%s'",
6482 IDENTIFIER_POINTER (name));
6484 add_protocol (protocol);
6486 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6492 finish_protocol (protocol)
6493 tree protocol ATTRIBUTE_UNUSED;
6498 /* "Encode" a data type into a string, which grows in util_obstack.
6499 ??? What is the FORMAT? Someone please document this! */
6502 encode_type_qualifiers (declspecs)
6507 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6509 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
6510 obstack_1grow (&util_obstack, 'r');
6511 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6512 obstack_1grow (&util_obstack, 'n');
6513 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6514 obstack_1grow (&util_obstack, 'N');
6515 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6516 obstack_1grow (&util_obstack, 'o');
6517 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6518 obstack_1grow (&util_obstack, 'O');
6519 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6520 obstack_1grow (&util_obstack, 'R');
6521 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6522 obstack_1grow (&util_obstack, 'V');
6526 /* Encode a pointer type. */
6529 encode_pointer (type, curtype, format)
6534 tree pointer_to = TREE_TYPE (type);
6536 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6538 if (TYPE_NAME (pointer_to)
6539 && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6541 const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
6543 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6545 obstack_1grow (&util_obstack, '@');
6548 else if (TREE_STATIC_TEMPLATE (pointer_to))
6550 if (generating_instance_variables)
6552 obstack_1grow (&util_obstack, '@');
6553 obstack_1grow (&util_obstack, '"');
6554 obstack_grow (&util_obstack, name, strlen (name));
6555 obstack_1grow (&util_obstack, '"');
6560 obstack_1grow (&util_obstack, '@');
6564 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
6566 obstack_1grow (&util_obstack, '#');
6569 #ifndef OBJC_INT_SELECTORS
6570 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
6572 obstack_1grow (&util_obstack, ':');
6575 #endif /* OBJC_INT_SELECTORS */
6578 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
6579 && TYPE_MODE (pointer_to) == QImode)
6581 obstack_1grow (&util_obstack, '*');
6585 /* We have a type that does not get special treatment. */
6587 /* NeXT extension */
6588 obstack_1grow (&util_obstack, '^');
6589 encode_type (pointer_to, curtype, format);
6593 encode_array (type, curtype, format)
6598 tree an_int_cst = TYPE_SIZE (type);
6599 tree array_of = TREE_TYPE (type);
6602 /* An incomplete array is treated like a pointer. */
6603 if (an_int_cst == NULL)
6605 encode_pointer (type, curtype, format);
6609 sprintf (buffer, "[%ld",
6610 (long) (TREE_INT_CST_LOW (an_int_cst)
6611 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
6613 obstack_grow (&util_obstack, buffer, strlen (buffer));
6614 encode_type (array_of, curtype, format);
6615 obstack_1grow (&util_obstack, ']');
6620 encode_aggregate_within (type, curtype, format, left, right)
6627 if (obstack_object_size (&util_obstack) > 0
6628 && *(obstack_next_free (&util_obstack) - 1) == '^')
6630 tree name = TYPE_NAME (type);
6632 /* we have a reference; this is a NeXT extension. */
6634 if (obstack_object_size (&util_obstack) - curtype == 1
6635 && format == OBJC_ENCODE_INLINE_DEFS)
6637 /* Output format of struct for first level only. */
6638 tree fields = TYPE_FIELDS (type);
6640 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6642 obstack_1grow (&util_obstack, left);
6643 obstack_grow (&util_obstack,
6644 IDENTIFIER_POINTER (name),
6645 strlen (IDENTIFIER_POINTER (name)));
6646 obstack_1grow (&util_obstack, '=');
6650 obstack_1grow (&util_obstack, left);
6651 obstack_grow (&util_obstack, "?=", 2);
6654 for ( ; fields; fields = TREE_CHAIN (fields))
6655 encode_field_decl (fields, curtype, format);
6657 obstack_1grow (&util_obstack, right);
6660 else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6662 obstack_1grow (&util_obstack, left);
6663 obstack_grow (&util_obstack,
6664 IDENTIFIER_POINTER (name),
6665 strlen (IDENTIFIER_POINTER (name)));
6666 obstack_1grow (&util_obstack, right);
6671 /* We have an untagged structure or a typedef. */
6672 obstack_1grow (&util_obstack, left);
6673 obstack_1grow (&util_obstack, '?');
6674 obstack_1grow (&util_obstack, right);
6680 tree name = TYPE_NAME (type);
6681 tree fields = TYPE_FIELDS (type);
6683 if (format == OBJC_ENCODE_INLINE_DEFS
6684 || generating_instance_variables)
6686 obstack_1grow (&util_obstack, left);
6687 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6688 obstack_grow (&util_obstack,
6689 IDENTIFIER_POINTER (name),
6690 strlen (IDENTIFIER_POINTER (name)));
6692 obstack_1grow (&util_obstack, '?');
6694 obstack_1grow (&util_obstack, '=');
6696 for (; fields; fields = TREE_CHAIN (fields))
6698 if (generating_instance_variables)
6700 tree fname = DECL_NAME (fields);
6702 obstack_1grow (&util_obstack, '"');
6703 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
6705 obstack_grow (&util_obstack,
6706 IDENTIFIER_POINTER (fname),
6707 strlen (IDENTIFIER_POINTER (fname)));
6710 obstack_1grow (&util_obstack, '"');
6713 encode_field_decl (fields, curtype, format);
6716 obstack_1grow (&util_obstack, right);
6721 obstack_1grow (&util_obstack, left);
6722 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
6723 obstack_grow (&util_obstack,
6724 IDENTIFIER_POINTER (name),
6725 strlen (IDENTIFIER_POINTER (name)));
6727 /* We have an untagged structure or a typedef. */
6728 obstack_1grow (&util_obstack, '?');
6730 obstack_1grow (&util_obstack, right);
6736 encode_aggregate (type, curtype, format)
6741 enum tree_code code = TREE_CODE (type);
6747 encode_aggregate_within(type, curtype, format, '{', '}');
6752 encode_aggregate_within(type, curtype, format, '(', ')');
6757 obstack_1grow (&util_obstack, 'i');
6765 /* Support bitfields. The current version of Objective-C does not support
6766 them. The string will consist of one or more "b:n"'s where n is an
6767 integer describing the width of the bitfield. Currently, classes in
6768 the kit implement a method "-(char *)describeBitfieldStruct:" that
6769 simulates this. If they do not implement this method, the archiver
6770 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6771 according to the GNU compiler. After looking at the "kit", it appears
6772 that all classes currently rely on this default behavior, rather than
6773 hand generating this string (which is tedious). */
6776 encode_bitfield (width)
6780 sprintf (buffer, "b%d", width);
6781 obstack_grow (&util_obstack, buffer, strlen (buffer));
6784 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6787 encode_type (type, curtype, format)
6792 enum tree_code code = TREE_CODE (type);
6794 if (code == INTEGER_TYPE)
6796 if (integer_zerop (TYPE_MIN_VALUE (type)))
6798 /* Unsigned integer types. */
6800 if (TYPE_MODE (type) == QImode)
6801 obstack_1grow (&util_obstack, 'C');
6802 else if (TYPE_MODE (type) == HImode)
6803 obstack_1grow (&util_obstack, 'S');
6804 else if (TYPE_MODE (type) == SImode)
6806 if (type == long_unsigned_type_node)
6807 obstack_1grow (&util_obstack, 'L');
6809 obstack_1grow (&util_obstack, 'I');
6811 else if (TYPE_MODE (type) == DImode)
6812 obstack_1grow (&util_obstack, 'Q');
6816 /* Signed integer types. */
6818 if (TYPE_MODE (type) == QImode)
6819 obstack_1grow (&util_obstack, 'c');
6820 else if (TYPE_MODE (type) == HImode)
6821 obstack_1grow (&util_obstack, 's');
6822 else if (TYPE_MODE (type) == SImode)
6824 if (type == long_integer_type_node)
6825 obstack_1grow (&util_obstack, 'l');
6827 obstack_1grow (&util_obstack, 'i');
6830 else if (TYPE_MODE (type) == DImode)
6831 obstack_1grow (&util_obstack, 'q');
6835 else if (code == REAL_TYPE)
6837 /* Floating point types. */
6839 if (TYPE_MODE (type) == SFmode)
6840 obstack_1grow (&util_obstack, 'f');
6841 else if (TYPE_MODE (type) == DFmode
6842 || TYPE_MODE (type) == TFmode)
6843 obstack_1grow (&util_obstack, 'd');
6846 else if (code == VOID_TYPE)
6847 obstack_1grow (&util_obstack, 'v');
6849 else if (code == ARRAY_TYPE)
6850 encode_array (type, curtype, format);
6852 else if (code == POINTER_TYPE)
6853 encode_pointer (type, curtype, format);
6855 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
6856 encode_aggregate (type, curtype, format);
6858 else if (code == FUNCTION_TYPE) /* '?' */
6859 obstack_1grow (&util_obstack, '?');
6863 encode_complete_bitfield (int position, tree type, int size)
6865 enum tree_code code = TREE_CODE (type);
6867 char charType = '?';
6869 if (code == INTEGER_TYPE)
6871 if (integer_zerop (TYPE_MIN_VALUE (type)))
6873 /* Unsigned integer types. */
6875 if (TYPE_MODE (type) == QImode)
6877 else if (TYPE_MODE (type) == HImode)
6879 else if (TYPE_MODE (type) == SImode)
6881 if (type == long_unsigned_type_node)
6886 else if (TYPE_MODE (type) == DImode)
6891 /* Signed integer types. */
6893 if (TYPE_MODE (type) == QImode)
6895 else if (TYPE_MODE (type) == HImode)
6897 else if (TYPE_MODE (type) == SImode)
6899 if (type == long_integer_type_node)
6905 else if (TYPE_MODE (type) == DImode)
6913 sprintf (buffer, "b%d%c%d", position, charType, size);
6914 obstack_grow (&util_obstack, buffer, strlen (buffer));
6918 encode_field_decl (field_decl, curtype, format)
6925 type = TREE_TYPE (field_decl);
6927 /* If this field is obviously a bitfield, or is a bitfield that has been
6928 clobbered to look like a ordinary integer mode, go ahead and generate
6929 the bitfield typing information. */
6930 if (flag_next_runtime)
6932 if (DECL_BIT_FIELD (field_decl))
6933 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
6935 encode_type (TREE_TYPE (field_decl), curtype, format);
6939 if (DECL_BIT_FIELD (field_decl))
6940 encode_complete_bitfield (int_bit_position (field_decl),
6941 DECL_BIT_FIELD_TYPE (field_decl),
6942 tree_low_cst (DECL_SIZE (field_decl), 1));
6944 encode_type (TREE_TYPE (field_decl), curtype, format);
6949 expr_last (complex_expr)
6955 while ((next = TREE_OPERAND (complex_expr, 0)))
6956 complex_expr = next;
6958 return complex_expr;
6961 /* The selector of the current method,
6962 or NULL if we aren't compiling a method. */
6965 maybe_objc_method_name (decl)
6966 tree decl ATTRIBUTE_UNUSED;
6969 return METHOD_SEL_NAME (method_context);
6974 /* Transform a method definition into a function definition as follows:
6975 - synthesize the first two arguments, "self" and "_cmd". */
6978 start_method_def (method)
6983 /* Required to implement _msgSuper. */
6984 method_context = method;
6985 UOBJC_SUPER_decl = NULL_TREE;
6987 /* Must be called BEFORE start_function. */
6990 /* Generate prototype declarations for arguments..."new-style". */
6992 if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL)
6993 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
6995 /* Really a `struct objc_class *'. However, we allow people to
6996 assign to self, which changes its type midstream. */
6997 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
6999 push_parm_decl (build_tree_list
7000 (build_tree_list (decl_specs,
7001 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7002 build_tree_list (unused_list, NULL_TREE)));
7004 #ifdef OBJC_INT_SELECTORS
7005 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]);
7006 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs);
7007 push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id),
7008 build_tree_list (unused_list, NULL_TREE)));
7009 #else /* not OBJC_INT_SELECTORS */
7010 decl_specs = build_tree_list (NULL_TREE,
7011 xref_tag (RECORD_TYPE,
7012 get_identifier (TAG_SELECTOR)));
7013 push_parm_decl (build_tree_list
7014 (build_tree_list (decl_specs,
7015 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7016 build_tree_list (unused_list, NULL_TREE)));
7017 #endif /* not OBJC_INT_SELECTORS */
7019 /* Generate argument declarations if a keyword_decl. */
7020 if (METHOD_SEL_ARGS (method))
7022 tree arglist = METHOD_SEL_ARGS (method);
7025 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7026 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7030 tree last_expr = expr_last (arg_decl);
7032 /* Unite the abstract decl with its name. */
7033 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7034 push_parm_decl (build_tree_list
7035 (build_tree_list (arg_spec, arg_decl),
7036 build_tree_list (NULL_TREE, NULL_TREE)));
7038 /* Unhook: restore the abstract declarator. */
7039 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7043 push_parm_decl (build_tree_list
7044 (build_tree_list (arg_spec,
7045 KEYWORD_ARG_NAME (arglist)),
7046 build_tree_list (NULL_TREE, NULL_TREE)));
7048 arglist = TREE_CHAIN (arglist);
7053 if (METHOD_ADD_ARGS (method) != NULL_TREE
7054 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7056 /* We have a variable length selector - in "prototype" format. */
7057 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7060 /* This must be done prior to calling pushdecl. pushdecl is
7061 going to change our chain on us. */
7062 tree nextkey = TREE_CHAIN (akey);
7070 warn_with_method (message, mtype, method)
7071 const char *message;
7075 if (count_error (1) == 0)
7078 report_error_function (DECL_SOURCE_FILE (method));
7080 fprintf (stderr, "%s:%d: warning: ",
7081 DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method));
7082 memset (errbuf, 0, BUFSIZE);
7083 fprintf (stderr, "%s `%c%s'\n",
7084 message, mtype, gen_method_decl (method, errbuf));
7087 /* Return 1 if METHOD is consistent with PROTO. */
7090 comp_method_with_proto (method, proto)
7093 static tree function_type = 0;
7095 /* Create a function_type node once. */
7098 function_type = make_node (FUNCTION_TYPE);
7099 ggc_add_tree_root (&function_type, 1);
7102 /* Install argument types - normally set by build_function_type. */
7103 TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0);
7105 /* install return type */
7106 TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto));
7108 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type);
7111 /* Return 1 if PROTO1 is consistent with PROTO2. */
7114 comp_proto_with_proto (proto0, proto1)
7115 tree proto0, proto1;
7117 static tree function_type[2];
7119 /* Create a couple function_type node's once. */
7120 if (!function_type[0])
7122 function_type[0] = make_node (FUNCTION_TYPE);
7123 function_type[1] = make_node (FUNCTION_TYPE);
7124 ggc_add_tree_root (function_type, 2);
7127 /* Install argument types; normally set by build_function_type. */
7128 TYPE_ARG_TYPES (function_type[0]) = get_arg_type_list (proto0, METHOD_REF, 0);
7129 TYPE_ARG_TYPES (function_type[1]) = get_arg_type_list (proto1, METHOD_REF, 0);
7131 /* Install return type. */
7132 TREE_TYPE (function_type[0]) = groktypename (TREE_TYPE (proto0));
7133 TREE_TYPE (function_type[1]) = groktypename (TREE_TYPE (proto1));
7135 return comptypes (function_type[0], function_type[1]);
7138 /* - Generate an identifier for the function. the format is "_n_cls",
7139 where 1 <= n <= nMethods, and cls is the name the implementation we
7141 - Install the return type from the method declaration.
7142 - If we have a prototype, check for type consistency. */
7145 really_start_method (method, parmlist)
7146 tree method, parmlist;
7148 tree sc_spec, ret_spec, ret_decl, decl_specs;
7149 tree method_decl, method_id;
7150 const char *sel_name, *class_name, *cat_name;
7153 /* Synth the storage class & assemble the return type. */
7154 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7155 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7156 decl_specs = chainon (sc_spec, ret_spec);
7158 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7159 class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context));
7160 cat_name = ((TREE_CODE (implementation_context)
7161 == CLASS_IMPLEMENTATION_TYPE)
7163 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));
7166 /* Make sure this is big enough for any plausible method label. */
7167 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7168 + (cat_name ? strlen (cat_name) : 0));
7170 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7171 class_name, cat_name, sel_name, method_slot);
7173 method_id = get_identifier (buf);
7175 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7177 /* Check the declarator portion of the return type for the method. */
7178 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7180 /* Unite the complex decl (specified in the abstract decl) with the
7181 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7182 tree save_expr = expr_last (ret_decl);
7184 TREE_OPERAND (save_expr, 0) = method_decl;
7185 method_decl = ret_decl;
7187 /* Fool the parser into thinking it is starting a function. */
7188 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE);
7190 /* Unhook: this has the effect of restoring the abstract declarator. */
7191 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7196 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7198 /* Fool the parser into thinking it is starting a function. */
7199 start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE);
7201 /* Unhook: this has the effect of restoring the abstract declarator. */
7202 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7205 METHOD_DEFINITION (method) = current_function_decl;
7207 if (implementation_template != implementation_context)
7211 if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
7212 proto = lookup_instance_method_static (implementation_template,
7213 METHOD_SEL_NAME (method));
7215 proto = lookup_class_method_static (implementation_template,
7216 METHOD_SEL_NAME (method));
7218 if (proto && ! comp_method_with_proto (method, proto))
7220 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7222 warn_with_method ("conflicting types for", type, method);
7223 warn_with_method ("previous declaration of", type, proto);
7228 /* The following routine is always called...this "architecture" is to
7229 accommodate "old-style" variable length selectors.
7231 - a:a b:b // prototype ; id c; id d; // old-style. */
7234 continue_method_def ()
7238 if (METHOD_ADD_ARGS (method_context) == objc_ellipsis_node)
7239 /* We have a `, ...' immediately following the selector. */
7240 parmlist = get_parm_info (0);
7242 parmlist = get_parm_info (1); /* place a `void_at_end' */
7244 /* Set self_decl from the first argument...this global is used by
7245 build_ivar_reference calling build_indirect_ref. */
7246 self_decl = TREE_PURPOSE (parmlist);
7249 really_start_method (method_context, parmlist);
7250 store_parm_decls ();
7253 /* Called by the parser, from the `pushlevel' production. */
7258 if (!UOBJC_SUPER_decl)
7260 UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
7261 build_tree_list (NULL_TREE,
7262 objc_super_template),
7263 0, NULL_TREE, NULL_TREE);
7265 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7267 /* This prevents `unused variable' warnings when compiling with -Wall. */
7268 TREE_USED (UOBJC_SUPER_decl) = 1;
7269 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7273 /* _n_Method (id self, SEL sel, ...)
7275 struct objc_super _S;
7276 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7280 get_super_receiver ()
7284 tree super_expr, super_expr_list;
7286 /* Set receiver to self. */
7287 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7288 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7289 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7291 /* Set class to begin searching. */
7292 super_expr = build_component_ref (UOBJC_SUPER_decl,
7293 get_identifier ("class"));
7295 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7297 /* [_cls, __cls]Super are "pre-built" in
7298 synth_forward_declarations. */
7300 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7301 ((TREE_CODE (method_context)
7302 == INSTANCE_METHOD_DECL)
7304 : uucls_super_ref));
7308 /* We have a category. */
7310 tree super_name = CLASS_SUPER_NAME (implementation_template);
7315 error ("no super class declared in interface for `%s'",
7316 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7317 return error_mark_node;
7320 if (flag_next_runtime)
7322 super_class = get_class_reference (super_name);
7323 if (TREE_CODE (method_context) == CLASS_METHOD_DECL)
7325 = build_component_ref (build_indirect_ref (super_class, "->"),
7326 get_identifier ("isa"));
7330 add_class_reference (super_name);
7331 super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL
7332 ? objc_get_class_decl : objc_get_meta_class_decl);
7333 assemble_external (super_class);
7335 = build_function_call
7339 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7340 IDENTIFIER_POINTER (super_name))));
7343 TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
7344 super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
7347 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7349 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7350 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7352 return build_compound_expr (super_expr_list);
7356 error ("[super ...] must appear in a method context");
7357 return error_mark_node;
7362 encode_method_def (func_decl)
7367 HOST_WIDE_INT max_parm_end = 0;
7372 encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
7373 obstack_object_size (&util_obstack),
7374 OBJC_ENCODE_INLINE_DEFS);
7377 for (parms = DECL_ARGUMENTS (func_decl); parms;
7378 parms = TREE_CHAIN (parms))
7380 HOST_WIDE_INT parm_end = (forwarding_offset (parms)
7381 + int_size_in_bytes (TREE_TYPE (parms)));
7383 if (! offset_is_register && parm_end > max_parm_end)
7384 max_parm_end = parm_end;
7387 stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
7389 sprintf (buffer, "%d", stack_size);
7390 obstack_grow (&util_obstack, buffer, strlen (buffer));
7392 /* Argument types. */
7393 for (parms = DECL_ARGUMENTS (func_decl); parms;
7394 parms = TREE_CHAIN (parms))
7397 encode_type (TREE_TYPE (parms),
7398 obstack_object_size (&util_obstack),
7399 OBJC_ENCODE_INLINE_DEFS);
7401 /* Compute offset. */
7402 sprintf (buffer, "%d", forwarding_offset (parms));
7404 /* Indicate register. */
7405 if (offset_is_register)
7406 obstack_1grow (&util_obstack, '+');
7408 obstack_grow (&util_obstack, buffer, strlen (buffer));
7411 obstack_1grow (&util_obstack, 0);
7412 result = get_identifier (obstack_finish (&util_obstack));
7413 obstack_free (&util_obstack, util_firstobj);
7418 objc_expand_function_end ()
7420 METHOD_ENCODING (method_context) = encode_method_def (current_function_decl);
7424 finish_method_def ()
7426 lang_expand_function_end = objc_expand_function_end;
7427 finish_function (0);
7428 lang_expand_function_end = NULL;
7430 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7431 since the optimizer may find "may be used before set" errors. */
7432 method_context = NULL_TREE;
7437 lang_report_error_function (decl)
7442 fprintf (stderr, "In method `%s'\n",
7443 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context)));
7453 is_complex_decl (type)
7456 return (TREE_CODE (type) == ARRAY_TYPE
7457 || TREE_CODE (type) == FUNCTION_TYPE
7458 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7462 /* Code to convert a decl node into text for a declaration in C. */
7464 static char tmpbuf[256];
7467 adorn_decl (decl, str)
7471 enum tree_code code = TREE_CODE (decl);
7473 if (code == ARRAY_REF)
7475 tree an_int_cst = TREE_OPERAND (decl, 1);
7477 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
7478 sprintf (str + strlen (str), "[%ld]",
7479 (long) TREE_INT_CST_LOW (an_int_cst));
7484 else if (code == ARRAY_TYPE)
7486 tree an_int_cst = TYPE_SIZE (decl);
7487 tree array_of = TREE_TYPE (decl);
7489 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
7490 sprintf (str + strlen (str), "[%ld]",
7491 (long) (TREE_INT_CST_LOW (an_int_cst)
7492 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7497 else if (code == CALL_EXPR)
7499 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
7504 gen_declaration (chain, str);
7505 chain = TREE_CHAIN (chain);
7512 else if (code == FUNCTION_TYPE)
7514 tree chain = TYPE_ARG_TYPES (decl);
7517 while (chain && TREE_VALUE (chain) != void_type_node)
7519 gen_declaration (TREE_VALUE (chain), str);
7520 chain = TREE_CHAIN (chain);
7521 if (chain && TREE_VALUE (chain) != void_type_node)
7527 else if (code == INDIRECT_REF)
7529 strcpy (tmpbuf, "*");
7530 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
7534 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
7536 chain = TREE_CHAIN (chain))
7538 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
7540 strcat (tmpbuf, " ");
7541 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
7545 strcat (tmpbuf, " ");
7547 strcat (tmpbuf, str);
7548 strcpy (str, tmpbuf);
7551 else if (code == POINTER_TYPE)
7553 strcpy (tmpbuf, "*");
7554 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
7556 if (TREE_READONLY (decl))
7557 strcat (tmpbuf, " const");
7558 if (TYPE_VOLATILE (decl))
7559 strcat (tmpbuf, " volatile");
7561 strcat (tmpbuf, " ");
7563 strcat (tmpbuf, str);
7564 strcpy (str, tmpbuf);
7569 gen_declarator (decl, buf, name)
7576 enum tree_code code = TREE_CODE (decl);
7586 op = TREE_OPERAND (decl, 0);
7588 /* We have a pointer to a function or array...(*)(), (*)[] */
7589 if ((code == ARRAY_REF || code == CALL_EXPR)
7590 && op && TREE_CODE (op) == INDIRECT_REF)
7593 str = gen_declarator (op, buf, name);
7597 strcpy (tmpbuf, "(");
7598 strcat (tmpbuf, str);
7599 strcat (tmpbuf, ")");
7600 strcpy (str, tmpbuf);
7603 adorn_decl (decl, str);
7612 /* This clause is done iteratively rather than recursively. */
7615 op = (is_complex_decl (TREE_TYPE (decl))
7616 ? TREE_TYPE (decl) : NULL_TREE);
7618 adorn_decl (decl, str);
7620 /* We have a pointer to a function or array...(*)(), (*)[] */
7621 if (code == POINTER_TYPE
7622 && op && (TREE_CODE (op) == FUNCTION_TYPE
7623 || TREE_CODE (op) == ARRAY_TYPE))
7625 strcpy (tmpbuf, "(");
7626 strcat (tmpbuf, str);
7627 strcat (tmpbuf, ")");
7628 strcpy (str, tmpbuf);
7631 decl = (is_complex_decl (TREE_TYPE (decl))
7632 ? TREE_TYPE (decl) : NULL_TREE);
7635 while (decl && (code = TREE_CODE (decl)))
7640 case IDENTIFIER_NODE:
7641 /* Will only happen if we are processing a "raw" expr-decl. */
7642 strcpy (buf, IDENTIFIER_POINTER (decl));
7653 /* We have an abstract declarator or a _DECL node. */
7661 gen_declspecs (declspecs, buf, raw)
7670 for (chain = nreverse (copy_list (declspecs));
7671 chain; chain = TREE_CHAIN (chain))
7673 tree aspec = TREE_VALUE (chain);
7675 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
7676 strcat (buf, IDENTIFIER_POINTER (aspec));
7677 else if (TREE_CODE (aspec) == RECORD_TYPE)
7679 if (TYPE_NAME (aspec))
7681 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7683 if (! TREE_STATIC_TEMPLATE (aspec))
7684 strcat (buf, "struct ");
7685 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7690 tree chain = protocol_list;
7697 (PROTOCOL_NAME (TREE_VALUE (chain))));
7698 chain = TREE_CHAIN (chain);
7707 strcat (buf, "untagged struct");
7710 else if (TREE_CODE (aspec) == UNION_TYPE)
7712 if (TYPE_NAME (aspec))
7714 if (! TREE_STATIC_TEMPLATE (aspec))
7715 strcat (buf, "union ");
7716 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7719 strcat (buf, "untagged union");
7722 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
7724 if (TYPE_NAME (aspec))
7726 if (! TREE_STATIC_TEMPLATE (aspec))
7727 strcat (buf, "enum ");
7728 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
7731 strcat (buf, "untagged enum");
7734 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
7735 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
7737 else if (IS_ID (aspec))
7739 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
7744 tree chain = protocol_list;
7751 (PROTOCOL_NAME (TREE_VALUE (chain))));
7752 chain = TREE_CHAIN (chain);
7759 if (TREE_CHAIN (chain))
7765 /* Type qualifiers. */
7766 if (TREE_READONLY (declspecs))
7767 strcat (buf, "const ");
7768 if (TYPE_VOLATILE (declspecs))
7769 strcat (buf, "volatile ");
7771 switch (TREE_CODE (declspecs))
7773 /* Type specifiers. */
7776 declspecs = TYPE_MAIN_VARIANT (declspecs);
7778 /* Signed integer types. */
7780 if (declspecs == short_integer_type_node)
7781 strcat (buf, "short int ");
7782 else if (declspecs == integer_type_node)
7783 strcat (buf, "int ");
7784 else if (declspecs == long_integer_type_node)
7785 strcat (buf, "long int ");
7786 else if (declspecs == long_long_integer_type_node)
7787 strcat (buf, "long long int ");
7788 else if (declspecs == signed_char_type_node
7789 || declspecs == char_type_node)
7790 strcat (buf, "char ");
7792 /* Unsigned integer types. */
7794 else if (declspecs == short_unsigned_type_node)
7795 strcat (buf, "unsigned short ");
7796 else if (declspecs == unsigned_type_node)
7797 strcat (buf, "unsigned int ");
7798 else if (declspecs == long_unsigned_type_node)
7799 strcat (buf, "unsigned long ");
7800 else if (declspecs == long_long_unsigned_type_node)
7801 strcat (buf, "unsigned long long ");
7802 else if (declspecs == unsigned_char_type_node)
7803 strcat (buf, "unsigned char ");
7807 declspecs = TYPE_MAIN_VARIANT (declspecs);
7809 if (declspecs == float_type_node)
7810 strcat (buf, "float ");
7811 else if (declspecs == double_type_node)
7812 strcat (buf, "double ");
7813 else if (declspecs == long_double_type_node)
7814 strcat (buf, "long double ");
7818 if (TYPE_NAME (declspecs)
7819 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7821 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7823 if (! TREE_STATIC_TEMPLATE (declspecs))
7824 strcat (buf, "struct ");
7825 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7829 tree chain = protocol_list;
7836 (PROTOCOL_NAME (TREE_VALUE (chain))));
7837 chain = TREE_CHAIN (chain);
7846 strcat (buf, "untagged struct");
7852 if (TYPE_NAME (declspecs)
7853 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7855 strcat (buf, "union ");
7856 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7861 strcat (buf, "untagged union ");
7865 if (TYPE_NAME (declspecs)
7866 && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
7868 strcat (buf, "enum ");
7869 strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
7874 strcat (buf, "untagged enum ");
7878 strcat (buf, "void ");
7883 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
7888 tree chain = protocol_list;
7895 (PROTOCOL_NAME (TREE_VALUE (chain))));
7896 chain = TREE_CHAIN (chain);
7913 gen_declaration (atype_or_adecl, buf)
7914 tree atype_or_adecl;
7919 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
7921 tree declspecs; /* "identifier_node", "record_type" */
7922 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
7924 /* We have a "raw", abstract declarator (typename). */
7925 declarator = TREE_VALUE (atype_or_adecl);
7926 declspecs = TREE_PURPOSE (atype_or_adecl);
7928 gen_declspecs (declspecs, buf, 1);
7932 strcat (buf, gen_declarator (declarator, declbuf, ""));
7939 tree declspecs; /* "integer_type", "real_type", "record_type"... */
7940 tree declarator; /* "array_type", "function_type", "pointer_type". */
7942 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7943 || TREE_CODE (atype_or_adecl) == PARM_DECL
7944 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7945 atype = TREE_TYPE (atype_or_adecl);
7947 /* Assume we have a *_type node. */
7948 atype = atype_or_adecl;
7950 if (is_complex_decl (atype))
7954 /* Get the declaration specifier; it is at the end of the list. */
7955 declarator = chain = atype;
7957 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
7958 while (is_complex_decl (chain));
7965 declarator = NULL_TREE;
7968 gen_declspecs (declspecs, buf, 0);
7970 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
7971 || TREE_CODE (atype_or_adecl) == PARM_DECL
7972 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
7974 const char *decl_name =
7975 (DECL_NAME (atype_or_adecl)
7976 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
7981 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
7984 else if (decl_name[0])
7987 strcat (buf, decl_name);
7990 else if (declarator)
7993 strcat (buf, gen_declarator (declarator, declbuf, ""));
8000 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8003 gen_method_decl (method, buf)
8009 if (RAW_TYPESPEC (method) != objc_object_reference)
8012 gen_declaration (TREE_TYPE (method), buf);
8016 chain = METHOD_SEL_ARGS (method);
8019 /* We have a chain of keyword_decls. */
8022 if (KEYWORD_KEY_NAME (chain))
8023 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8026 if (RAW_TYPESPEC (chain) != objc_object_reference)
8029 gen_declaration (TREE_TYPE (chain), buf);
8033 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8034 if ((chain = TREE_CHAIN (chain)))
8039 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8040 strcat (buf, ", ...");
8041 else if (METHOD_ADD_ARGS (method))
8043 /* We have a tree list node as generate by get_parm_info. */
8044 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8046 /* Know we have a chain of parm_decls. */
8050 gen_declaration (chain, buf);
8051 chain = TREE_CHAIN (chain);
8057 /* We have a unary selector. */
8058 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8066 dump_interface (fp, chain)
8070 char *buf = (char *)xmalloc (256);
8071 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8072 tree ivar_decls = CLASS_RAW_IVARS (chain);
8073 tree nst_methods = CLASS_NST_METHODS (chain);
8074 tree cls_methods = CLASS_CLS_METHODS (chain);
8076 fprintf (fp, "\n@interface %s", my_name);
8078 if (CLASS_SUPER_NAME (chain))
8080 const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8081 fprintf (fp, " : %s\n", super_name);
8088 fprintf (fp, "{\n");
8091 memset (buf, 0, 256);
8092 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8093 ivar_decls = TREE_CHAIN (ivar_decls);
8096 fprintf (fp, "}\n");
8101 memset (buf, 0, 256);
8102 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8103 nst_methods = TREE_CHAIN (nst_methods);
8108 memset (buf, 0, 256);
8109 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8110 cls_methods = TREE_CHAIN (cls_methods);
8112 fprintf (fp, "\n@end");
8115 /* Demangle function for Objective-C */
8117 objc_demangle (mangled)
8118 const char *mangled;
8120 char *demangled, *cp;
8122 if (mangled[0] == '_' &&
8123 (mangled[1] == 'i' || mangled[1] == 'c') &&
8126 cp = demangled = xmalloc(strlen(mangled) + 2);
8127 if (mangled[1] == 'i')
8128 *cp++ = '-'; /* for instance method */
8130 *cp++ = '+'; /* for class method */
8131 *cp++ = '['; /* opening left brace */
8132 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8133 while (*cp && *cp == '_')
8134 cp++; /* skip any initial underbars in class name */
8135 cp = strchr(cp, '_'); /* find first non-initial underbar */
8138 free(demangled); /* not mangled name */
8141 if (cp[1] == '_') /* easy case: no category name */
8143 *cp++ = ' '; /* replace two '_' with one ' ' */
8144 strcpy(cp, mangled + (cp - demangled) + 2);
8148 *cp++ = '('; /* less easy case: category name */
8149 cp = strchr(cp, '_');
8152 free(demangled); /* not mangled name */
8156 *cp++ = ' '; /* overwriting 1st char of method name... */
8157 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8159 while (*cp && *cp == '_')
8160 cp++; /* skip any initial underbars in method name */
8163 *cp = ':'; /* replace remaining '_' with ':' */
8164 *cp++ = ']'; /* closing right brace */
8165 *cp++ = 0; /* string terminator */
8169 return mangled; /* not an objc mangled name */
8173 objc_printable_name (decl, kind)
8175 int kind ATTRIBUTE_UNUSED;
8177 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8183 /* Add the special tree codes of Objective C to the tables. */
8185 #define LAST_CODE LAST_C_TREE_CODE
8187 gcc_obstack_init (&util_obstack);
8188 util_firstobj = (char *) obstack_finish (&util_obstack);
8190 memcpy (tree_code_type + (int) LAST_CODE,
8191 objc_tree_code_type,
8192 (int) LAST_OBJC_TREE_CODE - (int) LAST_CODE);
8193 memcpy (tree_code_length + (int) LAST_CODE,
8194 objc_tree_code_length,
8195 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) * sizeof (int)));
8196 memcpy (tree_code_name + (int) LAST_CODE,
8197 objc_tree_code_name,
8198 (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) * sizeof (char *)));
8200 errbuf = (char *)xmalloc (BUFSIZE);
8202 synth_module_prologue ();
8204 /* Change the default error function */
8205 decl_printable_name = objc_printable_name;
8206 lang_expand_expr = c_expand_expr;
8207 lang_expand_decl_stmt = c_expand_decl_stmt;
8213 struct imp_entry *impent;
8215 /* The internally generated initializers appear to have missing braces.
8216 Don't warn about this. */
8217 int save_warn_missing_braces = warn_missing_braces;
8218 warn_missing_braces = 0;
8220 generate_forward_declaration_to_string_table ();
8222 #ifdef OBJC_PROLOGUE
8226 /* Process the static instances here because initialization of objc_symtab
8228 if (objc_static_instances)
8229 generate_static_references ();
8231 if (implementation_context || class_names_chain
8232 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8233 generate_objc_symtab_decl ();
8235 for (impent = imp_list; impent; impent = impent->next)
8237 implementation_context = impent->imp_context;
8238 implementation_template = impent->imp_template;
8240 UOBJC_CLASS_decl = impent->class_decl;
8241 UOBJC_METACLASS_decl = impent->meta_decl;
8243 if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8245 /* all of the following reference the string pool... */
8246 generate_ivar_lists ();
8247 generate_dispatch_tables ();
8248 generate_shared_structures ();
8252 generate_dispatch_tables ();
8253 generate_category (implementation_context);
8257 /* If we are using an array of selectors, we must always
8258 finish up the array decl even if no selectors were used. */
8259 if (! flag_next_runtime || sel_ref_chain)
8260 build_selector_translation_table ();
8263 generate_protocols ();
8265 if (implementation_context || class_names_chain || objc_static_instances
8266 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8268 /* Arrange for Objc data structures to be initialized at run time. */
8269 const char *init_name = build_module_descriptor ();
8271 assemble_constructor (init_name);
8274 /* Dump the class references. This forces the appropriate classes
8275 to be linked into the executable image, preserving unix archive
8276 semantics. This can be removed when we move to a more dynamically
8277 linked environment. */
8279 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8281 handle_class_ref (chain);
8282 if (TREE_PURPOSE (chain))
8283 generate_classref_translation_entry (chain);
8286 for (impent = imp_list; impent; impent = impent->next)
8287 handle_impent (impent);
8289 /* Dump the string table last. */
8291 generate_strings ();
8293 if (flag_gen_declaration)
8295 add_class (implementation_context);
8296 dump_interface (gen_declaration_file, implementation_context);
8304 /* Run through the selector hash tables and print a warning for any
8305 selector which has multiple methods. */
8307 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8308 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8311 tree meth = hsh->key;
8312 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8316 warning ("potential selector conflict for method `%s'",
8317 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8318 warn_with_method ("found", type, meth);
8319 for (loop = hsh->list; loop; loop = loop->next)
8320 warn_with_method ("found", type, loop->value);
8323 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8324 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8327 tree meth = hsh->key;
8328 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
8332 warning ("potential selector conflict for method `%s'",
8333 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
8334 warn_with_method ("found", type, meth);
8335 for (loop = hsh->list; loop; loop = loop->next)
8336 warn_with_method ("found", type, loop->value);
8340 warn_missing_braces = save_warn_missing_braces;
8343 /* Subroutines of finish_objc. */
8346 generate_classref_translation_entry (chain)
8349 tree expr, name, decl_specs, decl, sc_spec;
8352 type = TREE_TYPE (TREE_PURPOSE (chain));
8354 expr = add_objc_string (TREE_VALUE (chain), class_names);
8355 expr = build_c_cast (type, expr); /* cast! */
8357 name = DECL_NAME (TREE_PURPOSE (chain));
8359 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8361 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8362 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8364 /* The decl that is returned from start_decl is the one that we
8365 forward declared in build_class_reference. */
8366 decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE);
8367 finish_decl (decl, expr, NULL_TREE);
8372 handle_class_ref (chain)
8375 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8376 if (! flag_next_runtime)
8379 char *string = (char *) alloca (strlen (name) + 30);
8382 sprintf (string, "%sobjc_class_name_%s",
8383 (flag_next_runtime ? "." : "__"), name);
8385 /* Make a decl for this name, so we can use its address in a tree. */
8386 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8387 DECL_EXTERNAL (decl) = 1;
8388 TREE_PUBLIC (decl) = 1;
8391 rest_of_decl_compilation (decl, 0, 0, 0);
8393 /* Make following constant read-only (why not)? */
8394 readonly_data_section ();
8396 exp = build1 (ADDR_EXPR, string_type_node, decl);
8398 /* Align the section properly. */
8399 assemble_constant_align (exp);
8401 /* Inform the assembler about this new external thing. */
8402 assemble_external (decl);
8404 /* Output a constant to reference this address. */
8405 output_constant (exp, int_size_in_bytes (string_type_node));
8409 /* This overreliance on our assembler (i.e. lack of portability)
8410 should be dealt with at some point. The GNU strategy (above)
8411 won't work either, but it is a start. */
8412 char *string = (char *) alloca (strlen (name) + 30);
8413 sprintf (string, ".reference .objc_class_name_%s", name);
8414 assemble_asm (my_build_string (strlen (string) + 1, string));
8419 handle_impent (impent)
8420 struct imp_entry *impent;
8422 implementation_context = impent->imp_context;
8423 implementation_template = impent->imp_template;
8425 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8427 const char *class_name =
8428 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8429 char *string = (char *) alloca (strlen (class_name) + 30);
8431 if (flag_next_runtime)
8433 /* Grossly unportable.
8434 People should know better than to assume
8435 such things about assembler syntax! */
8436 sprintf (string, ".objc_class_name_%s=0", class_name);
8437 assemble_asm (my_build_string (strlen (string) + 1, string));
8439 sprintf (string, ".globl .objc_class_name_%s", class_name);
8440 assemble_asm (my_build_string (strlen (string) + 1, string));
8445 sprintf (string, "%sobjc_class_name_%s",
8446 (flag_next_runtime ? "." : "__"), class_name);
8447 assemble_global (string);
8448 assemble_label (string);
8452 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8454 const char *class_name =
8455 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8456 const char *class_super_name =
8457 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8458 char *string = (char *) alloca (strlen (class_name)
8459 + strlen (class_super_name) + 30);
8461 /* Do the same for categories. Even though no references to these
8462 symbols are generated automatically by the compiler, it gives
8463 you a handle to pull them into an archive by hand. */
8464 if (flag_next_runtime)
8466 /* Grossly unportable. */
8467 sprintf (string, ".objc_category_name_%s_%s=0",
8468 class_name, class_super_name);
8469 assemble_asm (my_build_string (strlen (string) + 1, string));
8471 sprintf (string, ".globl .objc_category_name_%s_%s",
8472 class_name, class_super_name);
8473 assemble_asm (my_build_string (strlen (string) + 1, string));
8478 sprintf (string, "%sobjc_category_name_%s_%s",
8479 (flag_next_runtime ? "." : "__"),
8480 class_name, class_super_name);
8481 assemble_global (string);
8482 assemble_label (string);
8493 char *buf = (char *)xmalloc (256);
8495 { /* dump function prototypes */
8496 tree loop = UOBJC_MODULES_decl;
8498 fprintf (fp, "\n\nfunction prototypes:\n");
8501 if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop))
8503 /* We have a function definition: generate prototype. */
8504 memset (errbuf, 0, BUFSIZE);
8505 gen_declaration (loop, errbuf);
8506 fprintf (fp, "%s;\n", errbuf);
8508 loop = TREE_CHAIN (loop);
8512 /* Dump global chains. */
8514 int i, index = 0, offset = 0;
8517 for (i = 0; i < SIZEHASHTABLE; i++)
8519 if (hashlist = nst_method_hash_list[i])
8521 fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i);
8524 memset (buf, 0, 256);
8525 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8526 hashlist = hashlist->next;
8532 for (i = 0; i < SIZEHASHTABLE; i++)
8534 if (hashlist = cls_method_hash_list[i])
8536 fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i);
8539 memset (buf, 0, 256);
8540 fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf));
8541 hashlist = hashlist->next;
8547 fprintf (fp, "\nsel_refdef_chain:\n");
8548 for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop))
8550 fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset,
8551 IDENTIFIER_POINTER (TREE_VALUE (loop)));
8553 /* add one for the '\0' character */
8554 offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1;
8557 fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index);
8563 print_lang_statistics ()
8568 ggc_mark_imp_list (arg)
8571 struct imp_entry *impent;
8573 for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
8575 ggc_mark_tree (impent->imp_context);
8576 ggc_mark_tree (impent->imp_template);
8577 ggc_mark_tree (impent->class_decl);
8578 ggc_mark_tree (impent->meta_decl);
8583 ggc_mark_hash_table (arg)
8586 hash *hash_table = *(hash **)arg;
8591 if (hash_table == NULL)
8593 for (i = 0; i < SIZEHASHTABLE; i++)
8594 for (hst = hash_table [i]; hst; hst = hst->next)
8596 ggc_mark_tree (hst->key);
8597 for (list = hst->list; list; list = list->next)
8598 ggc_mark_tree (list->value);
8602 /* Add GC roots for variables local to this file. */
8604 objc_act_parse_init ()
8606 ggc_add_tree_root (&objc_ellipsis_node, 1);
8607 ggc_add_tree_root (objc_global_trees, OCTI_MAX);
8608 ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
8609 ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
8610 ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
8613 /* Look up ID as an instance variable. */
8615 lookup_objc_ivar (id)
8620 if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8621 /* we have a message to super */
8622 return get_super_receiver ();
8623 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8625 if (is_private (decl))
8626 return error_mark_node;
8628 return build_ivar_reference (id);
8634 /* Parser callbacks. */
8636 forget_protocol_qualifiers ()
8638 C_IS_RESERVED_WORD (ridpointers[(int) RID_IN]) = 0;
8639 C_IS_RESERVED_WORD (ridpointers[(int) RID_OUT]) = 0;
8640 C_IS_RESERVED_WORD (ridpointers[(int) RID_INOUT]) = 0;
8641 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYCOPY]) = 0;
8642 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYREF]) = 0;
8643 C_IS_RESERVED_WORD (ridpointers[(int) RID_ONEWAY]) = 0;
8647 remember_protocol_qualifiers ()
8649 C_IS_RESERVED_WORD (ridpointers[(int) RID_IN]) = 1;
8650 C_IS_RESERVED_WORD (ridpointers[(int) RID_OUT]) = 1;
8651 C_IS_RESERVED_WORD (ridpointers[(int) RID_INOUT]) = 1;
8652 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYCOPY]) = 1;
8653 C_IS_RESERVED_WORD (ridpointers[(int) RID_BYREF]) = 1;
8654 C_IS_RESERVED_WORD (ridpointers[(int) RID_ONEWAY]) = 1;