1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
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':
62 /* This is the default way of generating a method name. */
63 /* I am not sure it is really correct.
64 Perhaps there's a danger that it will make name conflicts
65 if method names contain underscores. -- rms. */
66 #ifndef OBJC_GEN_METHOD_LABEL
67 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
70 sprintf ((BUF), "_%s_%s_%s_%s", \
71 ((IS_INST) ? "i" : "c"), \
73 ((CAT_NAME)? (CAT_NAME) : ""), \
75 for (temp = (BUF); *temp; temp++) \
76 if (*temp == ':') *temp = '_'; \
80 /* These need specifying. */
81 #ifndef OBJC_FORWARDING_STACK_OFFSET
82 #define OBJC_FORWARDING_STACK_OFFSET 0
85 #ifndef OBJC_FORWARDING_MIN_OFFSET
86 #define OBJC_FORWARDING_MIN_OFFSET 0
89 /* Define the special tree codes that we use. */
91 /* Table indexed by tree code giving a string containing a character
92 classifying the tree code. */
94 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
96 static const char objc_tree_code_type
[] = {
98 #include "objc-tree.def"
102 /* Table indexed by tree code giving number of expression
103 operands beyond the fixed part of the node structure.
104 Not used for types or decls. */
106 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
108 static const int objc_tree_code_length
[] = {
110 #include "objc-tree.def"
114 /* Names of tree components.
115 Used for printing out the tree and error messages. */
116 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
118 static const char * const objc_tree_code_name
[] = {
120 #include "objc-tree.def"
124 /* Set up for use of obstacks. */
128 #define obstack_chunk_alloc xmalloc
129 #define obstack_chunk_free free
131 /* This obstack is used to accumulate the encoding of a data type. */
132 static struct obstack util_obstack
;
133 /* This points to the beginning of obstack contents,
134 so we can free the whole contents. */
137 /* for encode_method_def */
140 /* The version identifies which language generation and runtime
141 the module (file) was compiled for, and is recorded in the
142 module descriptor. */
144 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
145 #define PROTOCOL_VERSION 2
147 /* (Decide if these can ever be validly changed.) */
148 #define OBJC_ENCODE_INLINE_DEFS 0
149 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
151 /* Needed to help fix missing @end situations. */
152 extern tree objc_implementation_context
;
154 /*** Private Interface (procedures) ***/
156 /* Used by compile_file. */
158 static void init_objc
PARAMS ((void));
159 static void finish_objc
PARAMS ((void));
160 static void objc_init
PARAMS ((void));
161 static void objc_init_options
PARAMS ((void));
162 static int objc_decode_option
PARAMS ((int, char **));
163 static void objc_post_options
PARAMS ((void));
165 /* Code generation. */
167 static void synth_module_prologue
PARAMS ((void));
168 static tree build_constructor
PARAMS ((tree
, tree
));
169 static rtx build_module_descriptor
PARAMS ((void));
170 static tree init_module_descriptor
PARAMS ((tree
));
171 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
173 static void generate_strings
PARAMS ((void));
174 static tree get_proto_encoding
PARAMS ((tree
));
175 static void build_selector_translation_table
PARAMS ((void));
176 static tree build_ivar_chain
PARAMS ((tree
, int));
178 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
180 static tree build_ivar_template
PARAMS ((void));
181 static tree build_method_template
PARAMS ((void));
182 static tree build_private_template
PARAMS ((tree
));
183 static void build_class_template
PARAMS ((void));
184 static void build_selector_template
PARAMS ((void));
185 static void build_category_template
PARAMS ((void));
186 static tree build_super_template
PARAMS ((void));
187 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
189 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
192 static void synth_forward_declarations
PARAMS ((void));
193 static void generate_ivar_lists
PARAMS ((void));
194 static void generate_dispatch_tables
PARAMS ((void));
195 static void generate_shared_structures
PARAMS ((void));
196 static tree generate_protocol_list
PARAMS ((tree
));
197 static void generate_forward_declaration_to_string_table
PARAMS ((void));
198 static void build_protocol_reference
PARAMS ((tree
));
200 static tree build_keyword_selector
PARAMS ((tree
));
201 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
203 static void generate_static_references
PARAMS ((void));
204 static int check_methods_accessible
PARAMS ((tree
, tree
,
206 static void encode_aggregate_within
PARAMS ((tree
, int, int,
208 static const char *objc_demangle
PARAMS ((const char *));
209 static const char *objc_printable_name
PARAMS ((tree
, int));
210 static void objc_expand_function_end
PARAMS ((void));
212 /* Misc. bookkeeping */
214 typedef struct hashed_entry
*hash
;
215 typedef struct hashed_attribute
*attr
;
217 struct hashed_attribute
229 static void hash_init
PARAMS ((void));
230 static void hash_enter
PARAMS ((hash
*, tree
));
231 static hash hash_lookup
PARAMS ((hash
*, tree
));
232 static void hash_add_attr
PARAMS ((hash
, tree
));
233 static tree lookup_method
PARAMS ((tree
, tree
));
234 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
235 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
236 static tree add_class
PARAMS ((tree
));
237 static void add_category
PARAMS ((tree
, tree
));
241 class_names
, /* class, category, protocol, module names */
242 meth_var_names
, /* method and variable names */
243 meth_var_types
/* method and variable type descriptors */
246 static tree add_objc_string
PARAMS ((tree
,
247 enum string_section
));
248 static tree get_objc_string_decl
PARAMS ((tree
,
249 enum string_section
));
250 static tree build_objc_string_decl
PARAMS ((enum string_section
));
251 static tree build_selector_reference_decl
PARAMS ((void));
253 /* Protocol additions. */
255 static tree add_protocol
PARAMS ((tree
));
256 static tree lookup_protocol
PARAMS ((tree
));
257 static void check_protocol_recursively
PARAMS ((tree
, tree
));
258 static tree lookup_and_install_protocols
PARAMS ((tree
));
262 static void encode_type_qualifiers
PARAMS ((tree
));
263 static void encode_pointer
PARAMS ((tree
, int, int));
264 static void encode_array
PARAMS ((tree
, int, int));
265 static void encode_aggregate
PARAMS ((tree
, int, int));
266 static void encode_bitfield
PARAMS ((int));
267 static void encode_type
PARAMS ((tree
, int, int));
268 static void encode_field_decl
PARAMS ((tree
, int, int));
270 static void really_start_method
PARAMS ((tree
, tree
));
271 static int comp_method_with_proto
PARAMS ((tree
, tree
));
272 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
273 static tree get_arg_type_list
PARAMS ((tree
, int, int));
274 static tree expr_last
PARAMS ((tree
));
276 /* Utilities for debugging and error diagnostics. */
278 static void warn_with_method
PARAMS ((const char *, int, tree
));
279 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
280 static char *gen_method_decl
PARAMS ((tree
, char *));
281 static char *gen_declaration
PARAMS ((tree
, char *));
282 static void gen_declaration_1
PARAMS ((tree
, char *));
283 static char *gen_declarator
PARAMS ((tree
, char *,
285 static int is_complex_decl
PARAMS ((tree
));
286 static void adorn_decl
PARAMS ((tree
, char *));
287 static void dump_interface
PARAMS ((FILE *, tree
));
289 /* Everything else. */
291 static tree define_decl
PARAMS ((tree
, tree
));
292 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
293 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
294 static tree create_builtin_decl
PARAMS ((enum tree_code
,
295 tree
, const char *));
296 static void setup_string_decl
PARAMS ((void));
297 static tree my_build_string
PARAMS ((int, const char *));
298 static void build_objc_symtab_template
PARAMS ((void));
299 static tree init_def_list
PARAMS ((tree
));
300 static tree init_objc_symtab
PARAMS ((tree
));
301 static void forward_declare_categories
PARAMS ((void));
302 static void generate_objc_symtab_decl
PARAMS ((void));
303 static tree build_selector
PARAMS ((tree
));
304 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
305 static tree build_selector_reference
PARAMS ((tree
));
306 static tree build_class_reference_decl
PARAMS ((void));
307 static void add_class_reference
PARAMS ((tree
));
308 static tree objc_copy_list
PARAMS ((tree
, tree
*));
309 static tree build_protocol_template
PARAMS ((void));
310 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
311 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
312 static tree build_method_prototype_template
PARAMS ((void));
313 static int forwarding_offset
PARAMS ((tree
));
314 static tree encode_method_prototype
PARAMS ((tree
, tree
));
315 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
317 static void generate_method_descriptors
PARAMS ((tree
));
318 static tree build_tmp_function_decl
PARAMS ((void));
319 static void hack_method_prototype
PARAMS ((tree
, tree
));
320 static void generate_protocol_references
PARAMS ((tree
));
321 static void generate_protocols
PARAMS ((void));
322 static void check_ivars
PARAMS ((tree
, tree
));
323 static tree build_ivar_list_template
PARAMS ((tree
, int));
324 static tree build_method_list_template
PARAMS ((tree
, int));
325 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
326 static tree generate_ivars_list
PARAMS ((tree
, const char *,
328 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
329 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
331 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
332 tree
, int, tree
, tree
,
334 static void generate_category
PARAMS ((tree
));
335 static int is_objc_type_qualifier
PARAMS ((tree
));
336 static tree adjust_type_for_id_default
PARAMS ((tree
));
337 static tree check_duplicates
PARAMS ((hash
));
338 static tree receiver_is_class_object
PARAMS ((tree
));
339 static int check_methods
PARAMS ((tree
, tree
, int));
340 static int conforms_to_protocol
PARAMS ((tree
, tree
));
341 static void check_protocol
PARAMS ((tree
, const char *,
343 static void check_protocols
PARAMS ((tree
, const char *,
345 static tree encode_method_def
PARAMS ((tree
));
346 static void gen_declspecs
PARAMS ((tree
, char *, int));
347 static void generate_classref_translation_entry
PARAMS ((tree
));
348 static void handle_class_ref
PARAMS ((tree
));
349 static void generate_struct_by_value_array
PARAMS ((void))
351 static void objc_act_parse_init
PARAMS ((void));
352 static void ggc_mark_imp_list
PARAMS ((void *));
353 static void ggc_mark_hash_table
PARAMS ((void *));
355 /*** Private Interface (data) ***/
357 /* Reserved tag definitions. */
360 #define TAG_OBJECT "objc_object"
361 #define TAG_CLASS "objc_class"
362 #define TAG_SUPER "objc_super"
363 #define TAG_SELECTOR "objc_selector"
365 #define UTAG_CLASS "_objc_class"
366 #define UTAG_IVAR "_objc_ivar"
367 #define UTAG_IVAR_LIST "_objc_ivar_list"
368 #define UTAG_METHOD "_objc_method"
369 #define UTAG_METHOD_LIST "_objc_method_list"
370 #define UTAG_CATEGORY "_objc_category"
371 #define UTAG_MODULE "_objc_module"
372 #define UTAG_STATICS "_objc_statics"
373 #define UTAG_SYMTAB "_objc_symtab"
374 #define UTAG_SUPER "_objc_super"
375 #define UTAG_SELECTOR "_objc_selector"
377 #define UTAG_PROTOCOL "_objc_protocol"
378 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
379 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
380 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
382 #ifdef NEXT_OBJC_RUNTIME
383 #define STRING_OBJECT_CLASS_NAME "NSConstantString"
385 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
387 /* Note that the string object global name is only needed for the
389 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
391 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
393 static const char *constant_string_class_name
= NULL
;
395 static const char *TAG_GETCLASS
;
396 static const char *TAG_GETMETACLASS
;
397 static const char *TAG_MSGSEND
;
398 static const char *TAG_MSGSENDSUPER
;
399 static const char *TAG_EXECCLASS
;
401 /* Set by `continue_class' and checked by `is_public'. */
403 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
404 #define TYPED_OBJECT(type) \
405 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
407 tree objc_ellipsis_node
;
412 OCTI_STATIC_NST_DECL
,
418 OCTI_UMSG_SUPER_DECL
,
420 OCTI_GET_MCLASS_DECL
,
434 OCTI_CLS_NAMES_CHAIN
,
435 OCTI_METH_VAR_NAMES_CHAIN
,
436 OCTI_METH_VAR_TYPES_CHAIN
,
458 OCTI_UUCLS_SUPER_REF
,
470 OCTI_CNST_STR_GLOB_ID
,
471 OCTI_STRING_CLASS_DECL
,
478 static tree objc_global_trees
[OCTI_MAX
];
480 /* List of classes with list of their static instances. */
481 #define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
483 /* The declaration of the array administrating the static instances. */
484 #define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
486 /* Some commonly used instances of "identifier_node". */
488 #define self_id objc_global_trees[OCTI_SELF_ID]
489 #define ucmd_id objc_global_trees[OCTI_UCMD_ID]
490 #define unused_list objc_global_trees[OCTI_UNUSED_LIST]
492 #define self_decl objc_global_trees[OCTI_SELF_DECL]
493 #define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
494 #define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
495 #define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
496 #define objc_get_meta_class_decl \
497 objc_global_trees[OCTI_GET_MCLASS_DECL]
499 #define super_type objc_global_trees[OCTI_SUPER_TYPE]
500 #define selector_type objc_global_trees[OCTI_SEL_TYPE]
501 #define id_type objc_global_trees[OCTI_ID_TYPE]
502 #define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
503 #define instance_type objc_global_trees[OCTI_NST_TYPE]
504 #define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
506 /* Type checking macros. */
508 #define IS_ID(TYPE) \
509 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
510 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
511 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
512 #define IS_SUPER(TYPE) \
513 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
515 #define class_chain objc_global_trees[OCTI_CLS_CHAIN]
516 #define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
517 #define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
518 #define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
520 /* Chains to manage selectors that are referenced and defined in the
523 #define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
524 #define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
526 /* Chains to manage uniquing of strings. */
528 #define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
529 #define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
530 #define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
532 /* Hash tables to manage the global pool of method prototypes. */
534 static hash
*nst_method_hash_list
= 0;
535 static hash
*cls_method_hash_list
= 0;
537 /* Backend data declarations. */
539 #define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
540 #define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
541 #define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
542 #define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
543 #define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
544 #define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
545 #define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
546 #define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
547 #define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
548 #define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
550 /* The following are used when compiling a class implementation.
551 implementation_template will normally be an interface, however if
552 none exists this will be equal to implementation_context...it is
553 set in start_class. */
555 #define implementation_context objc_global_trees[OCTI_IMPL_CTX]
556 #define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
560 struct imp_entry
*next
;
563 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
564 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
567 static void handle_impent
PARAMS ((struct imp_entry
*));
569 static struct imp_entry
*imp_list
= 0;
570 static int imp_count
= 0; /* `@implementation' */
571 static int cat_count
= 0; /* `@category' */
573 #define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
574 #define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
575 #define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
576 #define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
577 #define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
578 #define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
579 #define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
581 #define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
582 #define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
583 #define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
584 #define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
585 #define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
586 #define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
588 #define objc_object_id objc_global_trees[OCTI_OBJ_ID]
589 #define objc_class_id objc_global_trees[OCTI_CLS_ID]
590 #define objc_id_id objc_global_trees[OCTI_ID_ID]
591 #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
592 #define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
593 #define constant_string_global_id objc_global_trees[OCTI_CNST_STR_GLOB_ID]
594 #define string_class_decl objc_global_trees[OCTI_STRING_CLASS_DECL]
595 #define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
597 #define method_context objc_global_trees[OCTI_METH_CTX]
598 static int method_slot
= 0; /* Used by start_method_def, */
602 static char *errbuf
; /* Buffer for error diagnostics */
604 /* Data imported from tree.c. */
606 extern enum debug_info_type write_symbols
;
608 /* Data imported from toplev.c. */
610 extern const char *dump_base_name
;
612 /* Generate code for GNU or NeXT runtime environment. */
614 #ifdef NEXT_OBJC_RUNTIME
615 int flag_next_runtime
= 1;
617 int flag_next_runtime
= 0;
620 int flag_typed_selectors
;
622 /* Open and close the file for outputting class declarations, if requested. */
624 int flag_gen_declaration
= 0;
626 FILE *gen_declaration_file
;
628 /* Warn if multiple methods are seen for the same selector, but with
629 different argument types. */
631 int warn_selector
= 0;
633 /* Warn if methods required by a protocol are not implemented in the
634 class adopting it. When turned off, methods inherited to that
635 class are also considered implemented */
637 int flag_warn_protocol
= 1;
639 /* Tells "encode_pointer/encode_aggregate" whether we are generating
640 type descriptors for instance variables (as opposed to methods).
641 Type descriptors for instance variables contain more information
642 than methods (for static typing and embedded structures). This
643 was added to support features being planned for dbkit2. */
645 static int generating_instance_variables
= 0;
647 /* Tells the compiler that this is a special run. Do not perform
648 any compiling, instead we are to test some platform dependent
649 features and output a C header file with appropriate definitions. */
651 static int print_struct_values
= 0;
653 /* Each front end provides its own. */
654 struct lang_hooks lang_hooks
= {objc_init
,
655 NULL
, /* objc_finish */
660 /* Post-switch processing. */
664 cpp_post_options (parse_in
);
667 /* Some platforms pass small structures through registers versus through
668 an invisible pointer. Determine at what size structure is the
669 transition point between the two possibilities. */
672 generate_struct_by_value_array ()
675 tree field_decl
, field_decl_chain
;
677 int aggregate_in_mem
[32];
680 /* Presumably no platform passes 32 byte structures in a register. */
681 for (i
= 1; i
< 32; i
++)
685 /* Create an unnamed struct that has `i' character components */
686 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
688 strcpy (buffer
, "c1");
689 field_decl
= create_builtin_decl (FIELD_DECL
,
692 field_decl_chain
= field_decl
;
694 for (j
= 1; j
< i
; j
++)
696 sprintf (buffer
, "c%d", j
+ 1);
697 field_decl
= create_builtin_decl (FIELD_DECL
,
700 chainon (field_decl_chain
, field_decl
);
702 finish_struct (type
, field_decl_chain
, NULL_TREE
);
704 aggregate_in_mem
[i
] = aggregate_value_p (type
);
705 if (!aggregate_in_mem
[i
])
709 /* We found some structures that are returned in registers instead of memory
710 so output the necessary data. */
713 for (i
= 31; i
>= 0; i
--)
714 if (!aggregate_in_mem
[i
])
716 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
718 /* The first member of the structure is always 0 because we don't handle
719 structures with 0 members */
720 printf ("static int struct_forward_array[] = {\n 0");
722 for (j
= 1; j
<= i
; j
++)
723 printf (", %d", aggregate_in_mem
[j
]);
733 /* Make identifier nodes long enough for the language-specific slots. */
734 set_identifier_size (sizeof (struct lang_identifier
));
736 parse_in
= cpp_create_reader (ident_hash
, CLK_OBJC
);
737 c_language
= clk_objective_c
;
743 /* Force the line number back to 0; check_newline will have
744 raised it to 1, which will make the builtin functions appear
745 not to be built in. */
748 c_common_lang_init ();
750 /* If gen_declaration desired, open the output file. */
751 if (flag_gen_declaration
)
753 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
754 gen_declaration_file
= fopen (dumpname
, "w");
755 if (gen_declaration_file
== 0)
756 fatal_io_error ("can't open %s", dumpname
);
760 if (flag_next_runtime
)
762 TAG_GETCLASS
= "objc_getClass";
763 TAG_GETMETACLASS
= "objc_getMetaClass";
764 TAG_MSGSEND
= "objc_msgSend";
765 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
766 TAG_EXECCLASS
= "__objc_execClass";
770 TAG_GETCLASS
= "objc_get_class";
771 TAG_GETMETACLASS
= "objc_get_meta_class";
772 TAG_MSGSEND
= "objc_msg_lookup";
773 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
774 TAG_EXECCLASS
= "__objc_exec_class";
775 flag_typed_selectors
= 1;
778 objc_ellipsis_node
= make_node (ERROR_MARK
);
782 if (print_struct_values
)
783 generate_struct_by_value_array ();
785 objc_act_parse_init ();
792 finish_objc (); /* Objective-C finalization */
794 if (gen_declaration_file
)
795 fclose (gen_declaration_file
);
805 objc_decode_option (argc
, argv
)
809 const char *p
= argv
[0];
811 if (!strcmp (p
, "-gen-decls"))
812 flag_gen_declaration
= 1;
813 else if (!strcmp (p
, "-Wselector"))
815 else if (!strcmp (p
, "-Wno-selector"))
817 else if (!strcmp (p
, "-Wprotocol"))
818 flag_warn_protocol
= 1;
819 else if (!strcmp (p
, "-Wno-protocol"))
820 flag_warn_protocol
= 0;
821 else if (!strcmp (p
, "-fgnu-runtime"))
822 flag_next_runtime
= 0;
823 else if (!strcmp (p
, "-fno-next-runtime"))
824 flag_next_runtime
= 0;
825 else if (!strcmp (p
, "-fno-gnu-runtime"))
826 flag_next_runtime
= 1;
827 else if (!strcmp (p
, "-fnext-runtime"))
828 flag_next_runtime
= 1;
829 else if (!strcmp (p
, "-print-objc-runtime-info"))
830 print_struct_values
= 1;
831 #define CSTSTRCLASS "-fconstant-string-class="
832 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
833 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
834 error ("no class name specified as argument to -fconstant-string-class");
835 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
839 return c_decode_option (argc
, argv
);
844 /* used by print-tree.c */
847 lang_print_xnode (file
, node
, indent
)
848 FILE *file ATTRIBUTE_UNUSED
;
849 tree node ATTRIBUTE_UNUSED
;
850 int indent ATTRIBUTE_UNUSED
;
856 define_decl (declarator
, declspecs
)
860 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
861 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
865 /* Return 1 if LHS and RHS are compatible types for assignment or
866 various other operations. Return 0 if they are incompatible, and
867 return -1 if we choose to not decide. When the operation is
868 REFLEXIVE, check for compatibility in either direction.
870 For statically typed objects, an assignment of the form `a' = `b'
874 `a' and `b' are the same class type, or
875 `a' and `b' are of class types A and B such that B is a descendant of A. */
878 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
882 return objc_comptypes (lhs
, rhs
, reflexive
);
886 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
894 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
896 p
= TREE_VALUE (rproto
);
898 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
900 if ((fnd
= lookup_method (class_meth
901 ? PROTOCOL_CLS_METHODS (p
)
902 : PROTOCOL_NST_METHODS (p
), sel_name
)))
904 else if (PROTOCOL_LIST (p
))
905 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
906 sel_name
, class_meth
);
910 ; /* An identifier...if we could not find a protocol. */
921 lookup_protocol_in_reflist (rproto_list
, lproto
)
927 /* Make sure the protocol is supported by the object on the rhs. */
928 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
931 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
933 p
= TREE_VALUE (rproto
);
935 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
940 else if (PROTOCOL_LIST (p
))
941 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
950 ; /* An identifier...if we could not find a protocol. */
956 /* Return 1 if LHS and RHS are compatible types for assignment
957 or various other operations. Return 0 if they are incompatible,
958 and return -1 if we choose to not decide. When the operation
959 is REFLEXIVE, check for compatibility in either direction. */
962 objc_comptypes (lhs
, rhs
, reflexive
)
967 /* New clause for protocols. */
969 if (TREE_CODE (lhs
) == POINTER_TYPE
970 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
971 && TREE_CODE (rhs
) == POINTER_TYPE
972 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
974 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
975 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
979 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
980 tree rproto
, rproto_list
;
985 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
987 /* Make sure the protocol is supported by the object
989 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
991 p
= TREE_VALUE (lproto
);
992 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
995 warning ("object does not conform to the `%s' protocol",
996 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
999 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
1001 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
1004 /* Make sure the protocol is supported by the object
1006 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
1008 p
= TREE_VALUE (lproto
);
1010 rinter
= lookup_interface (rname
);
1012 while (rinter
&& !rproto
)
1016 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
1017 /* If the underlying ObjC class does not have
1018 protocols attached to it, perhaps there are
1019 "one-off" protocols attached to the rhs?
1020 E.g., 'id<MyProt> foo;'. */
1022 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
1023 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
1025 /* Check for protocols adopted by categories. */
1026 cat
= CLASS_CATEGORY_LIST (rinter
);
1027 while (cat
&& !rproto
)
1029 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
1030 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
1032 cat
= CLASS_CATEGORY_LIST (cat
);
1035 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
1039 warning ("class `%s' does not implement the `%s' protocol",
1040 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
1041 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1045 /* May change...based on whether there was any mismatch */
1048 else if (rhs_is_proto
)
1049 /* Lhs is not a protocol...warn if it is statically typed */
1050 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
1053 /* Defer to comptypes. */
1057 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
1058 ; /* Fall thru. This is the case we have been handling all along */
1060 /* Defer to comptypes. */
1063 /* `id' = `<class> *', `<class> *' = `id' */
1065 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
1066 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
1069 /* `id' = `Class', `Class' = `id' */
1071 else if ((TYPE_NAME (lhs
) == objc_object_id
1072 && TYPE_NAME (rhs
) == objc_class_id
)
1073 || (TYPE_NAME (lhs
) == objc_class_id
1074 && TYPE_NAME (rhs
) == objc_object_id
))
1077 /* `<class> *' = `<class> *' */
1079 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1081 tree lname
= TYPE_NAME (lhs
);
1082 tree rname
= TYPE_NAME (rhs
);
1088 /* If the left hand side is a super class of the right hand side,
1090 for (inter
= lookup_interface (rname
); inter
;
1091 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1092 if (lname
== CLASS_SUPER_NAME (inter
))
1095 /* Allow the reverse when reflexive. */
1097 for (inter
= lookup_interface (lname
); inter
;
1098 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1099 if (rname
== CLASS_SUPER_NAME (inter
))
1105 /* Defer to comptypes. */
1109 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1112 objc_check_decl (decl
)
1115 tree type
= TREE_TYPE (decl
);
1117 if (TREE_CODE (type
) == RECORD_TYPE
1118 && TREE_STATIC_TEMPLATE (type
)
1119 && type
!= constant_string_type
)
1120 error_with_decl (decl
, "`%s' cannot be statically allocated");
1124 maybe_objc_check_decl (decl
)
1127 objc_check_decl (decl
);
1130 /* Implement static typing. At this point, we know we have an interface. */
1133 get_static_reference (interface
, protocols
)
1137 tree type
= xref_tag (RECORD_TYPE
, interface
);
1141 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1143 t
= copy_node (type
);
1144 TYPE_BINFO (t
) = make_tree_vec (2);
1146 /* Add this type to the chain of variants of TYPE. */
1147 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1148 TYPE_NEXT_VARIANT (m
) = t
;
1150 /* Look up protocols and install in lang specific list. Note
1151 that the protocol list can have a different lifetime than T! */
1152 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1154 /* This forces a new pointer type to be created later
1155 (in build_pointer_type)...so that the new template
1156 we just created will actually be used...what a hack! */
1157 if (TYPE_POINTER_TO (t
))
1158 TYPE_POINTER_TO (t
) = NULL_TREE
;
1167 get_object_reference (protocols
)
1170 tree type_decl
= lookup_name (objc_id_id
);
1173 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1175 type
= TREE_TYPE (type_decl
);
1176 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1177 warning ("Unexpected type for `id' (%s)",
1178 gen_declaration (type
, errbuf
));
1182 error ("Undefined type `id', please import <objc/objc.h>");
1183 return error_mark_node
;
1186 /* This clause creates a new pointer type that is qualified with
1187 the protocol specification...this info is used later to do more
1188 elaborate type checking. */
1192 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1194 t
= copy_node (type
);
1195 TYPE_BINFO (t
) = make_tree_vec (2);
1197 /* Add this type to the chain of variants of TYPE. */
1198 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1199 TYPE_NEXT_VARIANT (m
) = t
;
1201 /* Look up protocols...and install in lang specific list */
1202 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1204 /* This forces a new pointer type to be created later
1205 (in build_pointer_type)...so that the new template
1206 we just created will actually be used...what a hack! */
1207 if (TYPE_POINTER_TO (t
))
1208 TYPE_POINTER_TO (t
) = NULL_TREE
;
1215 /* Check for circular dependencies in protocols. The arguments are
1216 PROTO, the protocol to check, and LIST, a list of protocol it
1220 check_protocol_recursively (proto
, list
)
1226 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1228 tree pp
= TREE_VALUE (p
);
1230 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1231 pp
= lookup_protocol (pp
);
1234 fatal_error ("protocol `%s' has circular dependency",
1235 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1237 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1242 lookup_and_install_protocols (protocols
)
1247 tree return_value
= protocols
;
1249 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1251 tree ident
= TREE_VALUE (proto
);
1252 tree p
= lookup_protocol (ident
);
1256 error ("Cannot find protocol declaration for `%s'",
1257 IDENTIFIER_POINTER (ident
));
1259 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1261 return_value
= TREE_CHAIN (proto
);
1265 /* Replace identifier with actual protocol node. */
1266 TREE_VALUE (proto
) = p
;
1271 return return_value
;
1274 /* Create and push a decl for a built-in external variable or field NAME.
1276 TYPE is its data type. */
1279 create_builtin_decl (code
, type
, name
)
1280 enum tree_code code
;
1284 tree decl
= build_decl (code
, get_identifier (name
), type
);
1286 if (code
== VAR_DECL
)
1288 TREE_STATIC (decl
) = 1;
1289 make_decl_rtl (decl
, 0);
1293 DECL_ARTIFICIAL (decl
) = 1;
1297 /* Find the decl for the constant string class. */
1300 setup_string_decl ()
1302 if (!string_class_decl
)
1304 if (!constant_string_global_id
)
1305 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1306 string_class_decl
= lookup_name (constant_string_global_id
);
1310 /* Purpose: "play" parser, creating/installing representations
1311 of the declarations that are required by Objective-C.
1315 type_spec--------->sc_spec
1316 (tree_list) (tree_list)
1319 identifier_node identifier_node */
1322 synth_module_prologue ()
1327 /* Defined in `objc.h' */
1328 objc_object_id
= get_identifier (TAG_OBJECT
);
1330 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1332 id_type
= build_pointer_type (objc_object_reference
);
1334 objc_id_id
= get_identifier (TYPE_ID
);
1335 objc_class_id
= get_identifier (TAG_CLASS
);
1337 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1338 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1339 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1341 /* Declare type of selector-objects that represent an operation name. */
1343 /* `struct objc_selector *' */
1345 = build_pointer_type (xref_tag (RECORD_TYPE
,
1346 get_identifier (TAG_SELECTOR
)));
1348 /* Forward declare type, or else the prototype for msgSendSuper will
1351 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1352 get_identifier (TAG_SUPER
)));
1355 /* id objc_msgSend (id, SEL, ...); */
1358 = build_function_type (id_type
,
1359 tree_cons (NULL_TREE
, id_type
,
1360 tree_cons (NULL_TREE
, selector_type
,
1363 if (! flag_next_runtime
)
1365 umsg_decl
= build_decl (FUNCTION_DECL
,
1366 get_identifier (TAG_MSGSEND
), temp_type
);
1367 DECL_EXTERNAL (umsg_decl
) = 1;
1368 TREE_PUBLIC (umsg_decl
) = 1;
1369 DECL_INLINE (umsg_decl
) = 1;
1370 DECL_ARTIFICIAL (umsg_decl
) = 1;
1372 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1373 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1375 make_decl_rtl (umsg_decl
, NULL
);
1376 pushdecl (umsg_decl
);
1379 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1381 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1384 = build_function_type (id_type
,
1385 tree_cons (NULL_TREE
, super_p
,
1386 tree_cons (NULL_TREE
, selector_type
,
1389 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1390 temp_type
, 0, NOT_BUILT_IN
, 0);
1392 /* id objc_getClass (const char *); */
1394 temp_type
= build_function_type (id_type
,
1395 tree_cons (NULL_TREE
,
1396 const_string_type_node
,
1397 tree_cons (NULL_TREE
, void_type_node
,
1401 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1403 /* id objc_getMetaClass (const char *); */
1405 objc_get_meta_class_decl
1406 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1408 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1410 if (! flag_next_runtime
)
1412 if (flag_typed_selectors
)
1414 /* Suppress outputting debug symbols, because
1415 dbxout_init hasn'r been called yet. */
1416 enum debug_info_type save_write_symbols
= write_symbols
;
1417 struct gcc_debug_hooks
*save_hooks
= debug_hooks
;
1418 write_symbols
= NO_DEBUG
;
1419 debug_hooks
= &do_nothing_debug_hooks
;
1421 build_selector_template ();
1422 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1424 write_symbols
= save_write_symbols
;
1425 debug_hooks
= save_hooks
;
1428 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1430 layout_type (temp_type
);
1431 UOBJC_SELECTOR_TABLE_decl
1432 = create_builtin_decl (VAR_DECL
, temp_type
,
1433 "_OBJC_SELECTOR_TABLE");
1435 /* Avoid warning when not sending messages. */
1436 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1439 generate_forward_declaration_to_string_table ();
1441 /* Forward declare constant_string_id and constant_string_type. */
1442 if (!constant_string_class_name
)
1443 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1445 constant_string_id
= get_identifier (constant_string_class_name
);
1446 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1449 /* Custom build_string which sets TREE_TYPE! */
1452 my_build_string (len
, str
)
1457 tree a_string
= build_string (len
, str
);
1459 /* Some code from combine_strings, which is local to c-parse.y. */
1460 if (TREE_TYPE (a_string
) == int_array_type_node
)
1463 TREE_TYPE (a_string
)
1464 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1465 build_index_type (build_int_2 (len
- 1, 0)));
1467 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1468 TREE_STATIC (a_string
) = 1;
1473 /* Given a chain of STRING_CST's, build a static instance of
1474 NXConstantString which points at the concatenation of those strings.
1475 We place the string object in the __string_objects section of the
1476 __OBJC segment. The Objective-C runtime will initialize the isa
1477 pointers of the string objects to point at the NXConstantString
1481 build_objc_string_object (strings
)
1484 tree string
, initlist
, constructor
;
1487 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1489 error ("Cannot find interface declaration for `%s'",
1490 IDENTIFIER_POINTER (constant_string_id
));
1491 return error_mark_node
;
1494 add_class_reference (constant_string_id
);
1496 string
= combine_strings (strings
);
1497 TREE_SET_CODE (string
, STRING_CST
);
1498 length
= TREE_STRING_LENGTH (string
) - 1;
1500 /* & ((NXConstantString) {0, string, length}) */
1502 if (flag_next_runtime
)
1504 /* For the NeXT runtime, we can generate a literal reference
1505 to the string class, don't need to run a constructor. */
1506 setup_string_decl ();
1507 if (string_class_decl
== NULL_TREE
)
1509 error ("Cannot find reference tag for class `%s'",
1510 IDENTIFIER_POINTER (constant_string_id
));
1511 return error_mark_node
;
1513 initlist
= build_tree_list
1515 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1519 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1523 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1525 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1526 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1528 if (!flag_next_runtime
)
1531 = objc_add_static_instance (constructor
, constant_string_type
);
1534 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1537 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1540 objc_add_static_instance (constructor
, class_decl
)
1541 tree constructor
, class_decl
;
1543 static int num_static_inst
;
1547 /* Find the list of static instances for the CLASS_DECL. Create one if
1549 for (chain
= &objc_static_instances
;
1550 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1551 chain
= &TREE_CHAIN (*chain
));
1554 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1555 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1558 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1559 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1560 DECL_COMMON (decl
) = 1;
1561 TREE_STATIC (decl
) = 1;
1562 DECL_ARTIFICIAL (decl
) = 1;
1563 DECL_INITIAL (decl
) = constructor
;
1565 /* We may be writing something else just now.
1566 Postpone till end of input. */
1567 DECL_DEFER_OUTPUT (decl
) = 1;
1568 pushdecl_top_level (decl
);
1569 rest_of_decl_compilation (decl
, 0, 1, 0);
1571 /* Add the DECL to the head of this CLASS' list. */
1572 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1577 /* Build a static constant CONSTRUCTOR
1578 with type TYPE and elements ELTS. */
1581 build_constructor (type
, elts
)
1584 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1586 TREE_CONSTANT (constructor
) = 1;
1587 TREE_STATIC (constructor
) = 1;
1588 TREE_READONLY (constructor
) = 1;
1593 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1595 /* Predefine the following data type:
1603 void *defs[cls_def_cnt + cat_def_cnt];
1607 build_objc_symtab_template ()
1609 tree field_decl
, field_decl_chain
, index
;
1611 objc_symtab_template
1612 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1614 /* long sel_ref_cnt; */
1616 field_decl
= create_builtin_decl (FIELD_DECL
,
1617 long_integer_type_node
,
1619 field_decl_chain
= field_decl
;
1623 field_decl
= create_builtin_decl (FIELD_DECL
,
1624 build_pointer_type (selector_type
),
1626 chainon (field_decl_chain
, field_decl
);
1628 /* short cls_def_cnt; */
1630 field_decl
= create_builtin_decl (FIELD_DECL
,
1631 short_integer_type_node
,
1633 chainon (field_decl_chain
, field_decl
);
1635 /* short cat_def_cnt; */
1637 field_decl
= create_builtin_decl (FIELD_DECL
,
1638 short_integer_type_node
,
1640 chainon (field_decl_chain
, field_decl
);
1642 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1644 if (!flag_next_runtime
)
1645 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1647 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1648 imp_count
== 0 && cat_count
== 0
1650 field_decl
= create_builtin_decl (FIELD_DECL
,
1651 build_array_type (ptr_type_node
, index
),
1653 chainon (field_decl_chain
, field_decl
);
1655 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1658 /* Create the initial value for the `defs' field of _objc_symtab.
1659 This is a CONSTRUCTOR. */
1662 init_def_list (type
)
1665 tree expr
, initlist
= NULL_TREE
;
1666 struct imp_entry
*impent
;
1669 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1671 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1673 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1674 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1679 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1681 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1683 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1684 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1688 if (!flag_next_runtime
)
1690 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1693 if (static_instances_decl
)
1694 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1696 expr
= build_int_2 (0, 0);
1698 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1701 return build_constructor (type
, nreverse (initlist
));
1704 /* Construct the initial value for all of _objc_symtab. */
1707 init_objc_symtab (type
)
1712 /* sel_ref_cnt = { ..., 5, ... } */
1714 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1716 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1718 if (flag_next_runtime
|| ! sel_ref_chain
)
1719 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1721 initlist
= tree_cons (NULL_TREE
,
1722 build_unary_op (ADDR_EXPR
,
1723 UOBJC_SELECTOR_TABLE_decl
, 1),
1726 /* cls_def_cnt = { ..., 5, ... } */
1728 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1730 /* cat_def_cnt = { ..., 5, ... } */
1732 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1734 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1736 if (imp_count
|| cat_count
|| static_instances_decl
)
1739 tree field
= TYPE_FIELDS (type
);
1740 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1742 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1746 return build_constructor (type
, nreverse (initlist
));
1749 /* Push forward-declarations of all the categories
1750 so that init_def_list can use them in a CONSTRUCTOR. */
1753 forward_declare_categories ()
1755 struct imp_entry
*impent
;
1756 tree sav
= implementation_context
;
1758 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1760 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1762 /* Set an invisible arg to synth_id_with_class_suffix. */
1763 implementation_context
= impent
->imp_context
;
1765 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1766 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1769 implementation_context
= sav
;
1772 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1773 and initialized appropriately. */
1776 generate_objc_symtab_decl ()
1780 if (!objc_category_template
)
1781 build_category_template ();
1783 /* forward declare categories */
1785 forward_declare_categories ();
1787 if (!objc_symtab_template
)
1788 build_objc_symtab_template ();
1790 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1792 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1793 tree_cons (NULL_TREE
,
1794 objc_symtab_template
, sc_spec
),
1798 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1799 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1800 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1801 finish_decl (UOBJC_SYMBOLS_decl
,
1802 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1807 init_module_descriptor (type
)
1810 tree initlist
, expr
;
1812 /* version = { 1, ... } */
1814 expr
= build_int_2 (OBJC_VERSION
, 0);
1815 initlist
= build_tree_list (NULL_TREE
, expr
);
1817 /* size = { ..., sizeof (struct objc_module), ... } */
1819 expr
= size_in_bytes (objc_module_template
);
1820 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1822 /* name = { ..., "foo.m", ... } */
1824 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1825 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1827 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1829 if (UOBJC_SYMBOLS_decl
)
1830 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1832 expr
= build_int_2 (0, 0);
1833 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1835 return build_constructor (type
, nreverse (initlist
));
1838 /* Write out the data structures to describe Objective C classes defined.
1839 If appropriate, compile and output a setup function to initialize them.
1840 Return a symbol_ref to the function to call to initialize the Objective C
1841 data structures for this file (and perhaps for other files also).
1843 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1846 build_module_descriptor ()
1848 tree decl_specs
, field_decl
, field_decl_chain
;
1850 objc_module_template
1851 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1855 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1856 field_decl
= get_identifier ("version");
1858 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1859 field_decl_chain
= field_decl
;
1863 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1864 field_decl
= get_identifier ("size");
1866 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1867 chainon (field_decl_chain
, field_decl
);
1871 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1872 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1874 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1875 chainon (field_decl_chain
, field_decl
);
1877 /* struct objc_symtab *symtab; */
1879 decl_specs
= get_identifier (UTAG_SYMTAB
);
1880 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1881 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1883 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1884 chainon (field_decl_chain
, field_decl
);
1886 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1888 /* Create an instance of "objc_module". */
1890 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1891 build_tree_list (NULL_TREE
,
1892 ridpointers
[(int) RID_STATIC
]));
1894 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1895 decl_specs
, 1, NULL_TREE
);
1897 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1898 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1899 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1901 finish_decl (UOBJC_MODULES_decl
,
1902 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1905 /* Mark the decl to avoid "defined but not used" warning. */
1906 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1908 /* Generate a constructor call for the module descriptor.
1909 This code was generated by reading the grammar rules
1910 of c-parse.in; Therefore, it may not be the most efficient
1911 way of generating the requisite code. */
1913 if (flag_next_runtime
)
1917 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1918 tree init_function_name
, init_function_decl
;
1920 /* Declare void __objc_execClass (void *); */
1922 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1923 execclass_decl
= build_decl (FUNCTION_DECL
,
1924 get_identifier (TAG_EXECCLASS
),
1925 build_function_type (void_type_node
,
1926 tree_cons (NULL_TREE
, ptr_type_node
,
1927 void_list_node_1
)));
1928 DECL_EXTERNAL (execclass_decl
) = 1;
1929 DECL_ARTIFICIAL (execclass_decl
) = 1;
1930 TREE_PUBLIC (execclass_decl
) = 1;
1931 pushdecl (execclass_decl
);
1932 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1933 assemble_external (execclass_decl
);
1935 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1937 init_function_name
= get_file_function_name ('I');
1938 start_function (void_list_node_1
,
1939 build_nt (CALL_EXPR
, init_function_name
,
1940 tree_cons (NULL_TREE
, NULL_TREE
,
1944 store_parm_decls ();
1946 init_function_decl
= current_function_decl
;
1947 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1948 TREE_USED (init_function_decl
) = 1;
1949 current_function_cannot_inline
1950 = "static constructors and destructors cannot be inlined";
1953 = build_tree_list (NULL_TREE
,
1954 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1955 decelerator
= build_function_call (execclass_decl
, parms
);
1957 c_expand_expr_stmt (decelerator
);
1959 finish_function (0);
1961 return XEXP (DECL_RTL (init_function_decl
), 0);
1965 /* extern const char _OBJC_STRINGS[]; */
1968 generate_forward_declaration_to_string_table ()
1970 tree sc_spec
, decl_specs
, expr_decl
;
1972 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1973 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1976 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1978 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1981 /* Return the DECL of the string IDENT in the SECTION. */
1984 get_objc_string_decl (ident
, section
)
1986 enum string_section section
;
1990 if (section
== class_names
)
1991 chain
= class_names_chain
;
1992 else if (section
== meth_var_names
)
1993 chain
= meth_var_names_chain
;
1994 else if (section
== meth_var_types
)
1995 chain
= meth_var_types_chain
;
1999 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
2000 if (TREE_VALUE (chain
) == ident
)
2001 return (TREE_PURPOSE (chain
));
2007 /* Output references to all statically allocated objects. Return the DECL
2008 for the array built. */
2011 generate_static_references ()
2013 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
2014 tree class_name
, class, decl
, initlist
;
2015 tree cl_chain
, in_chain
, type
;
2016 int num_inst
, num_class
;
2019 if (flag_next_runtime
)
2022 for (cl_chain
= objc_static_instances
, num_class
= 0;
2023 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
2025 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
2026 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
2028 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
2029 ident
= get_identifier (buf
);
2031 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
2032 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
2033 build_tree_list (NULL_TREE
,
2034 ridpointers
[(int) RID_STATIC
]));
2035 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
2036 DECL_CONTEXT (decl
) = 0;
2037 DECL_ARTIFICIAL (decl
) = 1;
2039 /* Output {class_name, ...}. */
2040 class = TREE_VALUE (cl_chain
);
2041 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
2042 initlist
= build_tree_list (NULL_TREE
,
2043 build_unary_op (ADDR_EXPR
, class_name
, 1));
2045 /* Output {..., instance, ...}. */
2046 for (in_chain
= TREE_PURPOSE (cl_chain
);
2047 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
2049 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
2050 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2053 /* Output {..., NULL}. */
2054 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2056 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
2057 finish_decl (decl
, expr
, NULL_TREE
);
2058 TREE_USED (decl
) = 1;
2060 type
= build_array_type (build_pointer_type (void_type_node
), 0);
2061 decl
= build_decl (VAR_DECL
, ident
, type
);
2062 TREE_USED (decl
) = 1;
2063 TREE_STATIC (decl
) = 1;
2065 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
2068 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
2069 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
2070 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
2071 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
2072 build_tree_list (NULL_TREE
,
2073 ridpointers
[(int) RID_STATIC
]));
2074 static_instances_decl
2075 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
2076 TREE_USED (static_instances_decl
) = 1;
2077 DECL_CONTEXT (static_instances_decl
) = 0;
2078 DECL_ARTIFICIAL (static_instances_decl
) = 1;
2079 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
2081 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
2084 /* Output all strings. */
2089 tree sc_spec
, decl_specs
, expr_decl
;
2090 tree chain
, string_expr
;
2093 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2095 string
= TREE_VALUE (chain
);
2096 decl
= TREE_PURPOSE (chain
);
2098 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2099 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2100 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2101 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
2102 DECL_CONTEXT (decl
) = NULL_TREE
;
2103 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2104 IDENTIFIER_POINTER (string
));
2105 finish_decl (decl
, string_expr
, NULL_TREE
);
2108 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2110 string
= TREE_VALUE (chain
);
2111 decl
= TREE_PURPOSE (chain
);
2113 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2114 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2115 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2116 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
2117 DECL_CONTEXT (decl
) = NULL_TREE
;
2118 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2119 IDENTIFIER_POINTER (string
));
2120 finish_decl (decl
, string_expr
, NULL_TREE
);
2123 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2125 string
= TREE_VALUE (chain
);
2126 decl
= TREE_PURPOSE (chain
);
2128 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2129 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2130 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2131 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
2132 DECL_CONTEXT (decl
) = NULL_TREE
;
2133 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2134 IDENTIFIER_POINTER (string
));
2135 finish_decl (decl
, string_expr
, NULL_TREE
);
2140 build_selector_reference_decl ()
2146 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2148 ident
= get_identifier (buf
);
2150 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2151 DECL_EXTERNAL (decl
) = 1;
2152 TREE_PUBLIC (decl
) = 1;
2153 TREE_USED (decl
) = 1;
2154 TREE_READONLY (decl
) = 1;
2155 DECL_ARTIFICIAL (decl
) = 1;
2156 DECL_CONTEXT (decl
) = 0;
2158 make_decl_rtl (decl
, 0);
2159 pushdecl_top_level (decl
);
2164 /* Just a handy wrapper for add_objc_string. */
2167 build_selector (ident
)
2170 tree expr
= add_objc_string (ident
, meth_var_names
);
2171 if (flag_typed_selectors
)
2174 return build_c_cast (selector_type
, expr
); /* cast! */
2178 build_selector_translation_table ()
2180 tree sc_spec
, decl_specs
;
2181 tree chain
, initlist
= NULL_TREE
;
2183 tree decl
= NULL_TREE
, var_decl
, name
;
2185 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2189 expr
= build_selector (TREE_VALUE (chain
));
2191 if (flag_next_runtime
)
2193 name
= DECL_NAME (TREE_PURPOSE (chain
));
2195 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2197 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2198 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2202 /* The `decl' that is returned from start_decl is the one that we
2203 forward declared in `build_selector_reference' */
2204 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2207 /* add one for the '\0' character */
2208 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2210 if (flag_next_runtime
)
2211 finish_decl (decl
, expr
, NULL_TREE
);
2214 if (flag_typed_selectors
)
2216 tree eltlist
= NULL_TREE
;
2217 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2218 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2219 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2220 expr
= build_constructor (objc_selector_template
,
2221 nreverse (eltlist
));
2223 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2228 if (! flag_next_runtime
)
2230 /* Cause the variable and its initial value to be actually output. */
2231 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2232 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2233 /* NULL terminate the list and fix the decl for output. */
2234 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2235 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2236 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2237 nreverse (initlist
));
2238 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2239 current_function_decl
= NULL_TREE
;
2244 get_proto_encoding (proto
)
2252 if (! METHOD_ENCODING (proto
))
2254 tmp_decl
= build_tmp_function_decl ();
2255 hack_method_prototype (proto
, tmp_decl
);
2256 encoding
= encode_method_prototype (proto
, tmp_decl
);
2257 METHOD_ENCODING (proto
) = encoding
;
2260 encoding
= METHOD_ENCODING (proto
);
2262 return add_objc_string (encoding
, meth_var_types
);
2265 return build_int_2 (0, 0);
2268 /* sel_ref_chain is a list whose "value" fields will be instances of
2269 identifier_node that represent the selector. */
2272 build_typed_selector_reference (ident
, proto
)
2275 tree
*chain
= &sel_ref_chain
;
2281 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2282 goto return_at_index
;
2285 chain
= &TREE_CHAIN (*chain
);
2288 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2291 expr
= build_unary_op (ADDR_EXPR
,
2292 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2293 build_int_2 (index
, 0)),
2295 return build_c_cast (selector_type
, expr
);
2299 build_selector_reference (ident
)
2302 tree
*chain
= &sel_ref_chain
;
2308 if (TREE_VALUE (*chain
) == ident
)
2309 return (flag_next_runtime
2310 ? TREE_PURPOSE (*chain
)
2311 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2312 build_int_2 (index
, 0)));
2315 chain
= &TREE_CHAIN (*chain
);
2318 expr
= build_selector_reference_decl ();
2320 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2322 return (flag_next_runtime
2324 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2325 build_int_2 (index
, 0)));
2329 build_class_reference_decl ()
2335 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2337 ident
= get_identifier (buf
);
2339 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2340 DECL_EXTERNAL (decl
) = 1;
2341 TREE_PUBLIC (decl
) = 1;
2342 TREE_USED (decl
) = 1;
2343 TREE_READONLY (decl
) = 1;
2344 DECL_CONTEXT (decl
) = 0;
2345 DECL_ARTIFICIAL (decl
) = 1;
2347 make_decl_rtl (decl
, 0);
2348 pushdecl_top_level (decl
);
2353 /* Create a class reference, but don't create a variable to reference
2357 add_class_reference (ident
)
2362 if ((chain
= cls_ref_chain
))
2367 if (ident
== TREE_VALUE (chain
))
2371 chain
= TREE_CHAIN (chain
);
2375 /* Append to the end of the list */
2376 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2379 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2382 /* Get a class reference, creating it if necessary. Also create the
2383 reference variable. */
2386 get_class_reference (ident
)
2389 if (flag_next_runtime
)
2394 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2395 if (TREE_VALUE (*chain
) == ident
)
2397 if (! TREE_PURPOSE (*chain
))
2398 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2400 return TREE_PURPOSE (*chain
);
2403 decl
= build_class_reference_decl ();
2404 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2411 add_class_reference (ident
);
2413 params
= build_tree_list (NULL_TREE
,
2414 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2415 IDENTIFIER_POINTER (ident
)));
2417 assemble_external (objc_get_class_decl
);
2418 return build_function_call (objc_get_class_decl
, params
);
2422 /* For each string section we have a chain which maps identifier nodes
2423 to decls for the strings. */
2426 add_objc_string (ident
, section
)
2428 enum string_section section
;
2432 if (section
== class_names
)
2433 chain
= &class_names_chain
;
2434 else if (section
== meth_var_names
)
2435 chain
= &meth_var_names_chain
;
2436 else if (section
== meth_var_types
)
2437 chain
= &meth_var_types_chain
;
2443 if (TREE_VALUE (*chain
) == ident
)
2444 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2446 chain
= &TREE_CHAIN (*chain
);
2449 decl
= build_objc_string_decl (section
);
2451 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2453 return build_unary_op (ADDR_EXPR
, decl
, 1);
2457 build_objc_string_decl (section
)
2458 enum string_section section
;
2462 static int class_names_idx
= 0;
2463 static int meth_var_names_idx
= 0;
2464 static int meth_var_types_idx
= 0;
2466 if (section
== class_names
)
2467 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2468 else if (section
== meth_var_names
)
2469 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2470 else if (section
== meth_var_types
)
2471 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2473 ident
= get_identifier (buf
);
2475 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2476 DECL_EXTERNAL (decl
) = 1;
2477 TREE_PUBLIC (decl
) = 1;
2478 TREE_USED (decl
) = 1;
2479 TREE_READONLY (decl
) = 1;
2480 TREE_CONSTANT (decl
) = 1;
2481 DECL_CONTEXT (decl
) = 0;
2482 DECL_ARTIFICIAL (decl
) = 1;
2484 make_decl_rtl (decl
, 0);
2485 pushdecl_top_level (decl
);
2492 objc_declare_alias (alias_ident
, class_ident
)
2496 if (is_class_name (class_ident
) != class_ident
)
2497 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2498 else if (is_class_name (alias_ident
))
2499 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2501 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2505 objc_declare_class (ident_list
)
2510 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2512 tree ident
= TREE_VALUE (list
);
2515 if ((decl
= lookup_name (ident
)))
2517 error ("`%s' redeclared as different kind of symbol",
2518 IDENTIFIER_POINTER (ident
));
2519 error_with_decl (decl
, "previous declaration of `%s'");
2522 if (! is_class_name (ident
))
2524 tree record
= xref_tag (RECORD_TYPE
, ident
);
2525 TREE_STATIC_TEMPLATE (record
) = 1;
2526 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2532 is_class_name (ident
)
2537 if (lookup_interface (ident
))
2540 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2542 if (ident
== TREE_VALUE (chain
))
2546 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2548 if (ident
== TREE_VALUE (chain
))
2549 return TREE_PURPOSE (chain
);
2556 lookup_interface (ident
)
2561 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2563 if (ident
== CLASS_NAME (chain
))
2570 objc_copy_list (list
, head
)
2574 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2578 tail
= copy_node (list
);
2580 /* The following statement fixes a bug when inheriting instance
2581 variables that are declared to be bitfields. finish_struct
2582 expects to find the width of the bitfield in DECL_INITIAL. */
2583 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2584 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2586 newlist
= chainon (newlist
, tail
);
2587 list
= TREE_CHAIN (list
);
2594 /* Used by: build_private_template, get_class_ivars, and
2595 continue_class. COPY is 1 when called from @defs. In this case
2596 copy all fields. Otherwise don't copy leaf ivars since we rely on
2597 them being side-effected exactly once by finish_struct. */
2600 build_ivar_chain (interface
, copy
)
2604 tree my_name
, super_name
, ivar_chain
;
2606 my_name
= CLASS_NAME (interface
);
2607 super_name
= CLASS_SUPER_NAME (interface
);
2609 /* Possibly copy leaf ivars. */
2611 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2613 ivar_chain
= CLASS_IVARS (interface
);
2618 tree super_interface
= lookup_interface (super_name
);
2620 if (!super_interface
)
2622 /* fatal did not work with 2 args...should fix */
2623 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2624 IDENTIFIER_POINTER (super_name
),
2625 IDENTIFIER_POINTER (my_name
));
2626 exit (FATAL_EXIT_CODE
);
2629 if (super_interface
== interface
)
2630 fatal_error ("Circular inheritance in interface declaration for `%s'",
2631 IDENTIFIER_POINTER (super_name
));
2633 interface
= super_interface
;
2634 my_name
= CLASS_NAME (interface
);
2635 super_name
= CLASS_SUPER_NAME (interface
);
2637 op1
= CLASS_IVARS (interface
);
2640 tree head
, tail
= objc_copy_list (op1
, &head
);
2642 /* Prepend super class ivars...make a copy of the list, we
2643 do not want to alter the original. */
2644 TREE_CHAIN (tail
) = ivar_chain
;
2651 /* struct <classname> {
2652 struct objc_class *isa;
2657 build_private_template (class)
2662 if (CLASS_STATIC_TEMPLATE (class))
2664 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2665 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2669 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2671 ivar_context
= build_ivar_chain (class, 0);
2673 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2675 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2677 /* mark this record as class template - for class type checking */
2678 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2682 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2684 build1 (INDIRECT_REF
, NULL_TREE
,
2687 return ivar_context
;
2690 /* Begin code generation for protocols... */
2692 /* struct objc_protocol {
2693 char *protocol_name;
2694 struct objc_protocol **protocol_list;
2695 struct objc_method_desc *instance_methods;
2696 struct objc_method_desc *class_methods;
2700 build_protocol_template ()
2702 tree decl_specs
, field_decl
, field_decl_chain
;
2705 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2707 /* struct objc_class *isa; */
2709 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2710 get_identifier (UTAG_CLASS
)));
2711 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2713 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2714 field_decl_chain
= field_decl
;
2716 /* char *protocol_name; */
2718 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2720 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2722 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2723 chainon (field_decl_chain
, field_decl
);
2725 /* struct objc_protocol **protocol_list; */
2727 decl_specs
= build_tree_list (NULL_TREE
, template);
2729 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2730 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2732 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2733 chainon (field_decl_chain
, field_decl
);
2735 /* struct objc_method_list *instance_methods; */
2738 = build_tree_list (NULL_TREE
,
2739 xref_tag (RECORD_TYPE
,
2740 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2742 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2744 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2745 chainon (field_decl_chain
, field_decl
);
2747 /* struct objc_method_list *class_methods; */
2750 = build_tree_list (NULL_TREE
,
2751 xref_tag (RECORD_TYPE
,
2752 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2754 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2756 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2757 chainon (field_decl_chain
, field_decl
);
2759 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2763 build_descriptor_table_initializer (type
, entries
)
2767 tree initlist
= NULL_TREE
;
2771 tree eltlist
= NULL_TREE
;
2774 = tree_cons (NULL_TREE
,
2775 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2777 = tree_cons (NULL_TREE
,
2778 add_objc_string (METHOD_ENCODING (entries
),
2783 = tree_cons (NULL_TREE
,
2784 build_constructor (type
, nreverse (eltlist
)), initlist
);
2786 entries
= TREE_CHAIN (entries
);
2790 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2793 /* struct objc_method_prototype_list {
2795 struct objc_method_prototype {
2802 build_method_prototype_list_template (list_type
, size
)
2806 tree objc_ivar_list_record
;
2807 tree decl_specs
, field_decl
, field_decl_chain
;
2809 /* Generate an unnamed struct definition. */
2811 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2813 /* int method_count; */
2815 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2816 field_decl
= get_identifier ("method_count");
2819 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2820 field_decl_chain
= field_decl
;
2822 /* struct objc_method method_list[]; */
2824 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2825 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2826 build_int_2 (size
, 0));
2829 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2830 chainon (field_decl_chain
, field_decl
);
2832 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2834 return objc_ivar_list_record
;
2838 build_method_prototype_template ()
2841 tree decl_specs
, field_decl
, field_decl_chain
;
2844 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2846 /* struct objc_selector *_cmd; */
2847 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2848 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2849 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2852 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2853 field_decl_chain
= field_decl
;
2855 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2857 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2859 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2860 chainon (field_decl_chain
, field_decl
);
2862 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2864 return proto_record
;
2867 /* True if last call to forwarding_offset yielded a register offset. */
2868 static int offset_is_register
;
2871 forwarding_offset (parm
)
2874 int offset_in_bytes
;
2876 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2878 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2880 /* ??? Here we assume that the parm address is indexed
2881 off the frame pointer or arg pointer.
2882 If that is not true, we produce meaningless results,
2883 but do not crash. */
2884 if (GET_CODE (addr
) == PLUS
2885 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2886 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2888 offset_in_bytes
= 0;
2890 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2891 offset_is_register
= 0;
2893 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2895 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2896 offset_in_bytes
= apply_args_register_offset (regno
);
2897 offset_is_register
= 1;
2902 /* This is the case where the parm is passed as an int or double
2903 and it is converted to a char, short or float and stored back
2904 in the parmlist. In this case, describe the parm
2905 with the variable's declared type, and adjust the address
2906 if the least significant bytes (which we are using) are not
2908 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2909 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2910 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2912 return offset_in_bytes
;
2916 encode_method_prototype (method_decl
, func_decl
)
2923 HOST_WIDE_INT max_parm_end
= 0;
2927 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2928 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2931 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2932 obstack_object_size (&util_obstack
),
2933 OBJC_ENCODE_INLINE_DEFS
);
2936 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2937 parms
= TREE_CHAIN (parms
))
2939 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2940 + int_size_in_bytes (TREE_TYPE (parms
)));
2942 if (!offset_is_register
&& max_parm_end
< parm_end
)
2943 max_parm_end
= parm_end
;
2946 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2948 sprintf (buf
, "%d", stack_size
);
2949 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2951 user_args
= METHOD_SEL_ARGS (method_decl
);
2953 /* Argument types. */
2954 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2955 parms
= TREE_CHAIN (parms
), i
++)
2957 /* Process argument qualifiers for user supplied arguments. */
2960 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2961 user_args
= TREE_CHAIN (user_args
);
2965 encode_type (TREE_TYPE (parms
),
2966 obstack_object_size (&util_obstack
),
2967 OBJC_ENCODE_INLINE_DEFS
);
2969 /* Compute offset. */
2970 sprintf (buf
, "%d", forwarding_offset (parms
));
2972 /* Indicate register. */
2973 if (offset_is_register
)
2974 obstack_1grow (&util_obstack
, '+');
2976 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2979 obstack_1grow (&util_obstack
, '\0');
2980 result
= get_identifier (obstack_finish (&util_obstack
));
2981 obstack_free (&util_obstack
, util_firstobj
);
2986 generate_descriptor_table (type
, name
, size
, list
, proto
)
2993 tree sc_spec
, decl_specs
, decl
, initlist
;
2995 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2996 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2998 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2999 decl_specs
, 1, NULL_TREE
);
3000 DECL_CONTEXT (decl
) = NULL_TREE
;
3002 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3003 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3005 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
3012 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
3015 static tree objc_method_prototype_template
;
3016 tree initlist
, chain
, method_list_template
;
3017 tree cast
, variable_length_type
;
3020 if (!objc_method_prototype_template
)
3022 objc_method_prototype_template
= build_method_prototype_template ();
3023 ggc_add_tree_root (&objc_method_prototype_template
, 1);
3026 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3027 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
3029 variable_length_type
= groktypename (cast
);
3031 chain
= PROTOCOL_CLS_METHODS (protocol
);
3034 size
= list_length (chain
);
3036 method_list_template
3037 = build_method_prototype_list_template (objc_method_prototype_template
,
3041 = build_descriptor_table_initializer (objc_method_prototype_template
,
3044 UOBJC_CLASS_METHODS_decl
3045 = generate_descriptor_table (method_list_template
,
3046 "_OBJC_PROTOCOL_CLASS_METHODS",
3047 size
, initlist
, protocol
);
3048 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3051 UOBJC_CLASS_METHODS_decl
= 0;
3053 chain
= PROTOCOL_NST_METHODS (protocol
);
3056 size
= list_length (chain
);
3058 method_list_template
3059 = build_method_prototype_list_template (objc_method_prototype_template
,
3062 = build_descriptor_table_initializer (objc_method_prototype_template
,
3065 UOBJC_INSTANCE_METHODS_decl
3066 = generate_descriptor_table (method_list_template
,
3067 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3068 size
, initlist
, protocol
);
3069 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3072 UOBJC_INSTANCE_METHODS_decl
= 0;
3075 /* Generate a temporary FUNCTION_DECL node to be used in
3076 hack_method_prototype below. */
3079 build_tmp_function_decl ()
3081 tree decl_specs
, expr_decl
, parms
;
3085 /* struct objc_object *objc_xxx (id, SEL, ...); */
3087 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3088 push_parm_decl (build_tree_list
3089 (build_tree_list (decl_specs
,
3090 build1 (INDIRECT_REF
, NULL_TREE
,
3094 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3095 get_identifier (TAG_SELECTOR
)));
3096 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3098 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3100 parms
= get_parm_info (0);
3103 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3104 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3105 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3106 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3108 return define_decl (expr_decl
, decl_specs
);
3111 /* Generate the prototypes for protocol methods. This is used to
3112 generate method encodings for these.
3114 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
3115 a decl node to be used. This is also where the return value is
3119 hack_method_prototype (nst_methods
, tmp_decl
)
3126 /* Hack to avoid problem with static typing of self arg. */
3127 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3128 start_method_def (nst_methods
);
3129 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3131 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
3132 parms
= get_parm_info (0); /* we have a `, ...' */
3134 parms
= get_parm_info (1); /* place a `void_at_end' */
3136 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3138 /* Usually called from store_parm_decls -> init_function_start. */
3140 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3141 current_function_decl
= tmp_decl
;
3144 /* Code taken from start_function. */
3145 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3146 /* Promote the value to int before returning it. */
3147 if (TREE_CODE (restype
) == INTEGER_TYPE
3148 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3149 restype
= integer_type_node
;
3150 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3153 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3154 DECL_CONTEXT (parm
) = tmp_decl
;
3156 init_function_start (tmp_decl
, "objc-act", 0);
3158 /* Typically called from expand_function_start for function definitions. */
3159 assign_parms (tmp_decl
);
3161 /* install return type */
3162 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3167 generate_protocol_references (plist
)
3172 /* Forward declare protocols referenced. */
3173 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3175 tree proto
= TREE_VALUE (lproto
);
3177 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3178 && PROTOCOL_NAME (proto
))
3180 if (! PROTOCOL_FORWARD_DECL (proto
))
3181 build_protocol_reference (proto
);
3183 if (PROTOCOL_LIST (proto
))
3184 generate_protocol_references (PROTOCOL_LIST (proto
));
3190 generate_protocols ()
3192 tree p
, tmp_decl
, encoding
;
3193 tree sc_spec
, decl_specs
, decl
;
3194 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3197 tmp_decl
= build_tmp_function_decl ();
3199 if (! objc_protocol_template
)
3200 objc_protocol_template
= build_protocol_template ();
3202 /* If a protocol was directly referenced, pull in indirect references. */
3203 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3204 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3205 generate_protocol_references (PROTOCOL_LIST (p
));
3207 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3209 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3210 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3212 /* If protocol wasn't referenced, don't generate any code. */
3213 if (! PROTOCOL_FORWARD_DECL (p
))
3216 /* Make sure we link in the Protocol class. */
3217 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3221 if (! METHOD_ENCODING (nst_methods
))
3223 hack_method_prototype (nst_methods
, tmp_decl
);
3224 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3225 METHOD_ENCODING (nst_methods
) = encoding
;
3227 nst_methods
= TREE_CHAIN (nst_methods
);
3232 if (! METHOD_ENCODING (cls_methods
))
3234 hack_method_prototype (cls_methods
, tmp_decl
);
3235 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3236 METHOD_ENCODING (cls_methods
) = encoding
;
3239 cls_methods
= TREE_CHAIN (cls_methods
);
3241 generate_method_descriptors (p
);
3243 if (PROTOCOL_LIST (p
))
3244 refs_decl
= generate_protocol_list (p
);
3248 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3250 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3252 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3254 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3255 decl_specs
, 1, NULL_TREE
);
3257 DECL_CONTEXT (decl
) = NULL_TREE
;
3259 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3265 (build_tree_list (build_tree_list (NULL_TREE
,
3266 objc_protocol_template
),
3267 build1 (INDIRECT_REF
, NULL_TREE
,
3268 build1 (INDIRECT_REF
, NULL_TREE
,
3271 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3272 TREE_TYPE (refs_expr
) = cast_type2
;
3275 refs_expr
= build_int_2 (0, 0);
3277 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3278 by generate_method_descriptors, which is called above. */
3279 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3280 protocol_name_expr
, refs_expr
,
3281 UOBJC_INSTANCE_METHODS_decl
,
3282 UOBJC_CLASS_METHODS_decl
);
3283 finish_decl (decl
, initlist
, NULL_TREE
);
3285 /* Mark the decl as used to avoid "defined but not used" warning. */
3286 TREE_USED (decl
) = 1;
3291 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3292 instance_methods
, class_methods
)
3296 tree instance_methods
;
3299 tree initlist
= NULL_TREE
, expr
;
3302 cast_type
= groktypename
3304 (build_tree_list (NULL_TREE
,
3305 xref_tag (RECORD_TYPE
,
3306 get_identifier (UTAG_CLASS
))),
3307 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3309 /* Filling the "isa" in with one allows the runtime system to
3310 detect that the version change...should remove before final release. */
3312 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3313 TREE_TYPE (expr
) = cast_type
;
3314 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3315 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3316 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3318 if (!instance_methods
)
3319 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3322 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3323 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3327 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3330 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3331 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3334 return build_constructor (type
, nreverse (initlist
));
3337 /* struct objc_category {
3338 char *category_name;
3340 struct objc_method_list *instance_methods;
3341 struct objc_method_list *class_methods;
3342 struct objc_protocol_list *protocols;
3346 build_category_template ()
3348 tree decl_specs
, field_decl
, field_decl_chain
;
3350 objc_category_template
= start_struct (RECORD_TYPE
,
3351 get_identifier (UTAG_CATEGORY
));
3352 /* char *category_name; */
3354 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3356 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3358 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3359 field_decl_chain
= field_decl
;
3361 /* char *class_name; */
3363 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3364 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3366 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3367 chainon (field_decl_chain
, field_decl
);
3369 /* struct objc_method_list *instance_methods; */
3371 decl_specs
= build_tree_list (NULL_TREE
,
3372 xref_tag (RECORD_TYPE
,
3373 get_identifier (UTAG_METHOD_LIST
)));
3375 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3377 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3378 chainon (field_decl_chain
, field_decl
);
3380 /* struct objc_method_list *class_methods; */
3382 decl_specs
= build_tree_list (NULL_TREE
,
3383 xref_tag (RECORD_TYPE
,
3384 get_identifier (UTAG_METHOD_LIST
)));
3386 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3388 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3389 chainon (field_decl_chain
, field_decl
);
3391 /* struct objc_protocol **protocol_list; */
3393 decl_specs
= build_tree_list (NULL_TREE
,
3394 xref_tag (RECORD_TYPE
,
3395 get_identifier (UTAG_PROTOCOL
)));
3397 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3398 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3400 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3401 chainon (field_decl_chain
, field_decl
);
3403 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3406 /* struct objc_selector {
3412 build_selector_template ()
3415 tree decl_specs
, field_decl
, field_decl_chain
;
3417 objc_selector_template
3418 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3422 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3423 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3425 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3426 field_decl_chain
= field_decl
;
3428 /* char *sel_type; */
3430 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3431 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3433 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3434 chainon (field_decl_chain
, field_decl
);
3436 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3439 /* struct objc_class {
3440 struct objc_class *isa;
3441 struct objc_class *super_class;
3446 struct objc_ivar_list *ivars;
3447 struct objc_method_list *methods;
3448 if (flag_next_runtime)
3449 struct objc_cache *cache;
3451 struct sarray *dtable;
3452 struct objc_class *subclass_list;
3453 struct objc_class *sibling_class;
3455 struct objc_protocol_list *protocols;
3456 void *gc_object_type;
3460 build_class_template ()
3462 tree decl_specs
, field_decl
, field_decl_chain
;
3465 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3467 /* struct objc_class *isa; */
3469 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3470 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3472 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3473 field_decl_chain
= field_decl
;
3475 /* struct objc_class *super_class; */
3477 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3479 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3481 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3482 chainon (field_decl_chain
, field_decl
);
3486 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3487 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3489 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3490 chainon (field_decl_chain
, field_decl
);
3494 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3495 field_decl
= get_identifier ("version");
3497 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3498 chainon (field_decl_chain
, field_decl
);
3502 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3503 field_decl
= get_identifier ("info");
3505 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3506 chainon (field_decl_chain
, field_decl
);
3508 /* long instance_size; */
3510 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3511 field_decl
= get_identifier ("instance_size");
3513 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3514 chainon (field_decl_chain
, field_decl
);
3516 /* struct objc_ivar_list *ivars; */
3518 decl_specs
= build_tree_list (NULL_TREE
,
3519 xref_tag (RECORD_TYPE
,
3520 get_identifier (UTAG_IVAR_LIST
)));
3521 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3523 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3524 chainon (field_decl_chain
, field_decl
);
3526 /* struct objc_method_list *methods; */
3528 decl_specs
= build_tree_list (NULL_TREE
,
3529 xref_tag (RECORD_TYPE
,
3530 get_identifier (UTAG_METHOD_LIST
)));
3531 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3533 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3534 chainon (field_decl_chain
, field_decl
);
3536 if (flag_next_runtime
)
3538 /* struct objc_cache *cache; */
3540 decl_specs
= build_tree_list (NULL_TREE
,
3541 xref_tag (RECORD_TYPE
,
3542 get_identifier ("objc_cache")));
3543 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3544 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3545 decl_specs
, NULL_TREE
);
3546 chainon (field_decl_chain
, field_decl
);
3550 /* struct sarray *dtable; */
3552 decl_specs
= build_tree_list (NULL_TREE
,
3553 xref_tag (RECORD_TYPE
,
3554 get_identifier ("sarray")));
3555 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3556 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3557 decl_specs
, NULL_TREE
);
3558 chainon (field_decl_chain
, field_decl
);
3560 /* struct objc_class *subclass_list; */
3562 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3564 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3565 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3566 decl_specs
, NULL_TREE
);
3567 chainon (field_decl_chain
, field_decl
);
3569 /* struct objc_class *sibling_class; */
3571 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3573 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3574 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3575 decl_specs
, NULL_TREE
);
3576 chainon (field_decl_chain
, field_decl
);
3579 /* struct objc_protocol **protocol_list; */
3581 decl_specs
= build_tree_list (NULL_TREE
,
3582 xref_tag (RECORD_TYPE
,
3583 get_identifier (UTAG_PROTOCOL
)));
3585 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3587 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3588 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3589 decl_specs
, NULL_TREE
);
3590 chainon (field_decl_chain
, field_decl
);
3594 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3595 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3597 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3598 chainon (field_decl_chain
, field_decl
);
3600 /* void *gc_object_type; */
3602 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3603 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3605 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3606 chainon (field_decl_chain
, field_decl
);
3608 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3611 /* Generate appropriate forward declarations for an implementation. */
3614 synth_forward_declarations ()
3616 tree sc_spec
, decl_specs
, an_id
;
3618 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3620 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3622 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3623 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3624 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3625 TREE_USED (UOBJC_CLASS_decl
) = 1;
3626 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3628 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3630 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3631 implementation_context
);
3633 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3634 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3635 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3637 /* Pre-build the following entities - for speed/convenience. */
3639 an_id
= get_identifier ("super_class");
3640 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3641 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3645 error_with_ivar (message
, decl
, rawdecl
)
3646 const char *message
;
3652 report_error_function (DECL_SOURCE_FILE (decl
));
3654 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3655 DECL_SOURCE_LINE (decl
),
3657 message
, gen_declaration (rawdecl
, errbuf
));
3661 #define USERTYPE(t) \
3662 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3663 || TREE_CODE (t) == ENUMERAL_TYPE)
3666 check_ivars (inter
, imp
)
3670 tree intdecls
= CLASS_IVARS (inter
);
3671 tree impdecls
= CLASS_IVARS (imp
);
3672 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3673 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3679 if (intdecls
== 0 && impdecls
== 0)
3681 if (intdecls
== 0 || impdecls
== 0)
3683 error ("inconsistent instance variable specification");
3687 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3689 if (!comptypes (t1
, t2
))
3691 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3693 error_with_ivar ("conflicting instance variable type",
3694 impdecls
, rawimpdecls
);
3695 error_with_ivar ("previous declaration of",
3696 intdecls
, rawintdecls
);
3698 else /* both the type and the name don't match */
3700 error ("inconsistent instance variable specification");
3705 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3707 error_with_ivar ("conflicting instance variable name",
3708 impdecls
, rawimpdecls
);
3709 error_with_ivar ("previous declaration of",
3710 intdecls
, rawintdecls
);
3713 intdecls
= TREE_CHAIN (intdecls
);
3714 impdecls
= TREE_CHAIN (impdecls
);
3715 rawintdecls
= TREE_CHAIN (rawintdecls
);
3716 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3720 /* Set super_type to the data type node for struct objc_super *,
3721 first defining struct objc_super itself.
3722 This needs to be done just once per compilation. */
3725 build_super_template ()
3727 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3729 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3731 /* struct objc_object *self; */
3733 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3734 field_decl
= get_identifier ("self");
3735 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3736 field_decl
= grokfield (input_filename
, lineno
,
3737 field_decl
, decl_specs
, NULL_TREE
);
3738 field_decl_chain
= field_decl
;
3740 /* struct objc_class *class; */
3742 decl_specs
= get_identifier (UTAG_CLASS
);
3743 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3744 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3746 field_decl
= grokfield (input_filename
, lineno
,
3747 field_decl
, decl_specs
, NULL_TREE
);
3748 chainon (field_decl_chain
, field_decl
);
3750 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3752 /* `struct objc_super *' */
3753 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3755 build1 (INDIRECT_REF
,
3756 NULL_TREE
, NULL_TREE
)));
3760 /* struct objc_ivar {
3767 build_ivar_template ()
3769 tree objc_ivar_id
, objc_ivar_record
;
3770 tree decl_specs
, field_decl
, field_decl_chain
;
3772 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3773 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3775 /* char *ivar_name; */
3777 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3778 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3780 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3781 decl_specs
, NULL_TREE
);
3782 field_decl_chain
= field_decl
;
3784 /* char *ivar_type; */
3786 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3787 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3789 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3790 decl_specs
, NULL_TREE
);
3791 chainon (field_decl_chain
, field_decl
);
3793 /* int ivar_offset; */
3795 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3796 field_decl
= get_identifier ("ivar_offset");
3798 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3799 decl_specs
, NULL_TREE
);
3800 chainon (field_decl_chain
, field_decl
);
3802 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3804 return objc_ivar_record
;
3809 struct objc_ivar ivar_list[ivar_count];
3813 build_ivar_list_template (list_type
, size
)
3817 tree objc_ivar_list_record
;
3818 tree decl_specs
, field_decl
, field_decl_chain
;
3820 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3822 /* int ivar_count; */
3824 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3825 field_decl
= get_identifier ("ivar_count");
3827 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3828 decl_specs
, NULL_TREE
);
3829 field_decl_chain
= field_decl
;
3831 /* struct objc_ivar ivar_list[]; */
3833 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3834 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3835 build_int_2 (size
, 0));
3837 field_decl
= grokfield (input_filename
, lineno
,
3838 field_decl
, decl_specs
, NULL_TREE
);
3839 chainon (field_decl_chain
, field_decl
);
3841 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3843 return objc_ivar_list_record
;
3849 struct objc_method method_list[method_count];
3853 build_method_list_template (list_type
, size
)
3857 tree objc_ivar_list_record
;
3858 tree decl_specs
, field_decl
, field_decl_chain
;
3860 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3862 /* int method_next; */
3867 xref_tag (RECORD_TYPE
,
3868 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3870 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3871 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3872 decl_specs
, NULL_TREE
);
3873 field_decl_chain
= field_decl
;
3875 /* int method_count; */
3877 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3878 field_decl
= get_identifier ("method_count");
3880 field_decl
= grokfield (input_filename
, lineno
,
3881 field_decl
, decl_specs
, NULL_TREE
);
3882 chainon (field_decl_chain
, field_decl
);
3884 /* struct objc_method method_list[]; */
3886 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3887 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3888 build_int_2 (size
, 0));
3890 field_decl
= grokfield (input_filename
, lineno
,
3891 field_decl
, decl_specs
, NULL_TREE
);
3892 chainon (field_decl_chain
, field_decl
);
3894 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3896 return objc_ivar_list_record
;
3900 build_ivar_list_initializer (type
, field_decl
)
3904 tree initlist
= NULL_TREE
;
3908 tree ivar
= NULL_TREE
;
3911 if (DECL_NAME (field_decl
))
3912 ivar
= tree_cons (NULL_TREE
,
3913 add_objc_string (DECL_NAME (field_decl
),
3917 /* Unnamed bit-field ivar (yuck). */
3918 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3921 encode_field_decl (field_decl
,
3922 obstack_object_size (&util_obstack
),
3923 OBJC_ENCODE_DONT_INLINE_DEFS
);
3925 /* Null terminate string. */
3926 obstack_1grow (&util_obstack
, 0);
3930 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3933 obstack_free (&util_obstack
, util_firstobj
);
3936 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3937 initlist
= tree_cons (NULL_TREE
,
3938 build_constructor (type
, nreverse (ivar
)),
3941 field_decl
= TREE_CHAIN (field_decl
);
3945 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3949 generate_ivars_list (type
, name
, size
, list
)
3955 tree sc_spec
, decl_specs
, decl
, initlist
;
3957 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3958 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3960 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3961 decl_specs
, 1, NULL_TREE
);
3963 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3964 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3967 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3974 generate_ivar_lists ()
3976 tree initlist
, ivar_list_template
, chain
;
3977 tree cast
, variable_length_type
;
3980 generating_instance_variables
= 1;
3982 if (!objc_ivar_template
)
3983 objc_ivar_template
= build_ivar_template ();
3987 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3988 get_identifier (UTAG_IVAR_LIST
))),
3990 variable_length_type
= groktypename (cast
);
3992 /* Only generate class variables for the root of the inheritance
3993 hierarchy since these will be the same for every class. */
3995 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3996 && (chain
= TYPE_FIELDS (objc_class_template
)))
3998 size
= list_length (chain
);
4000 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4001 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4003 UOBJC_CLASS_VARIABLES_decl
4004 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
4006 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
4009 UOBJC_CLASS_VARIABLES_decl
= 0;
4011 chain
= CLASS_IVARS (implementation_template
);
4014 size
= list_length (chain
);
4015 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4016 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4018 UOBJC_INSTANCE_VARIABLES_decl
4019 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
4021 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
4024 UOBJC_INSTANCE_VARIABLES_decl
= 0;
4026 generating_instance_variables
= 0;
4030 build_dispatch_table_initializer (type
, entries
)
4034 tree initlist
= NULL_TREE
;
4038 tree elemlist
= NULL_TREE
;
4040 elemlist
= tree_cons (NULL_TREE
,
4041 build_selector (METHOD_SEL_NAME (entries
)),
4044 elemlist
= tree_cons (NULL_TREE
,
4045 add_objc_string (METHOD_ENCODING (entries
),
4049 elemlist
= tree_cons (NULL_TREE
,
4050 build_unary_op (ADDR_EXPR
,
4051 METHOD_DEFINITION (entries
), 1),
4054 initlist
= tree_cons (NULL_TREE
,
4055 build_constructor (type
, nreverse (elemlist
)),
4058 entries
= TREE_CHAIN (entries
);
4062 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4065 /* To accomplish method prototyping without generating all kinds of
4066 inane warnings, the definition of the dispatch table entries were
4069 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4071 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4074 build_method_template ()
4077 tree decl_specs
, field_decl
, field_decl_chain
;
4079 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4081 /* struct objc_selector *_cmd; */
4082 decl_specs
= tree_cons (NULL_TREE
,
4083 xref_tag (RECORD_TYPE
,
4084 get_identifier (TAG_SELECTOR
)),
4086 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4088 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4089 decl_specs
, NULL_TREE
);
4090 field_decl_chain
= field_decl
;
4092 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4093 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4094 get_identifier ("method_types"));
4095 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4096 decl_specs
, NULL_TREE
);
4097 chainon (field_decl_chain
, field_decl
);
4101 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4102 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4103 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4104 decl_specs
, NULL_TREE
);
4105 chainon (field_decl_chain
, field_decl
);
4107 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4114 generate_dispatch_table (type
, name
, size
, list
)
4120 tree sc_spec
, decl_specs
, decl
, initlist
;
4122 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4123 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4125 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4126 decl_specs
, 1, NULL_TREE
);
4128 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4129 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4130 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4133 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4140 generate_dispatch_tables ()
4142 tree initlist
, chain
, method_list_template
;
4143 tree cast
, variable_length_type
;
4146 if (!objc_method_template
)
4147 objc_method_template
= build_method_template ();
4151 (build_tree_list (NULL_TREE
,
4152 xref_tag (RECORD_TYPE
,
4153 get_identifier (UTAG_METHOD_LIST
))),
4156 variable_length_type
= groktypename (cast
);
4158 chain
= CLASS_CLS_METHODS (implementation_context
);
4161 size
= list_length (chain
);
4163 method_list_template
4164 = build_method_list_template (objc_method_template
, size
);
4166 = build_dispatch_table_initializer (objc_method_template
, chain
);
4168 UOBJC_CLASS_METHODS_decl
4169 = generate_dispatch_table (method_list_template
,
4170 ((TREE_CODE (implementation_context
)
4171 == CLASS_IMPLEMENTATION_TYPE
)
4172 ? "_OBJC_CLASS_METHODS"
4173 : "_OBJC_CATEGORY_CLASS_METHODS"),
4175 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4178 UOBJC_CLASS_METHODS_decl
= 0;
4180 chain
= CLASS_NST_METHODS (implementation_context
);
4183 size
= list_length (chain
);
4185 method_list_template
4186 = build_method_list_template (objc_method_template
, size
);
4188 = build_dispatch_table_initializer (objc_method_template
, chain
);
4190 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4191 UOBJC_INSTANCE_METHODS_decl
4192 = generate_dispatch_table (method_list_template
,
4193 "_OBJC_INSTANCE_METHODS",
4196 /* We have a category. */
4197 UOBJC_INSTANCE_METHODS_decl
4198 = generate_dispatch_table (method_list_template
,
4199 "_OBJC_CATEGORY_INSTANCE_METHODS",
4201 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4204 UOBJC_INSTANCE_METHODS_decl
= 0;
4208 generate_protocol_list (i_or_p
)
4211 tree initlist
, decl_specs
, sc_spec
;
4212 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4216 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4217 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4218 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4219 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4220 plist
= PROTOCOL_LIST (i_or_p
);
4224 cast_type
= groktypename
4226 (build_tree_list (NULL_TREE
,
4227 xref_tag (RECORD_TYPE
,
4228 get_identifier (UTAG_PROTOCOL
))),
4229 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4232 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4233 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4234 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4237 /* Build initializer. */
4238 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4240 e
= build_int_2 (size
, 0);
4241 TREE_TYPE (e
) = cast_type
;
4242 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4244 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4246 tree pval
= TREE_VALUE (lproto
);
4248 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4249 && PROTOCOL_FORWARD_DECL (pval
))
4251 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4252 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4256 /* static struct objc_protocol *refs[n]; */
4258 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4259 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4260 get_identifier (UTAG_PROTOCOL
)),
4263 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4264 expr_decl
= build_nt (ARRAY_REF
,
4265 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4267 build_int_2 (size
+ 2, 0));
4268 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4269 expr_decl
= build_nt (ARRAY_REF
,
4270 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4272 build_int_2 (size
+ 2, 0));
4273 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4275 = build_nt (ARRAY_REF
,
4276 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4278 build_int_2 (size
+ 2, 0));
4282 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4284 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4285 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4287 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4288 nreverse (initlist
)),
4295 build_category_initializer (type
, cat_name
, class_name
,
4296 instance_methods
, class_methods
, protocol_list
)
4300 tree instance_methods
;
4304 tree initlist
= NULL_TREE
, expr
;
4306 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4307 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4309 if (!instance_methods
)
4310 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4313 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4314 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4317 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4320 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4321 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4324 /* protocol_list = */
4326 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4329 tree cast_type2
= groktypename
4331 (build_tree_list (NULL_TREE
,
4332 xref_tag (RECORD_TYPE
,
4333 get_identifier (UTAG_PROTOCOL
))),
4334 build1 (INDIRECT_REF
, NULL_TREE
,
4335 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4337 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4338 TREE_TYPE (expr
) = cast_type2
;
4339 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4342 return build_constructor (type
, nreverse (initlist
));
4345 /* struct objc_class {
4346 struct objc_class *isa;
4347 struct objc_class *super_class;
4352 struct objc_ivar_list *ivars;
4353 struct objc_method_list *methods;
4354 if (flag_next_runtime)
4355 struct objc_cache *cache;
4357 struct sarray *dtable;
4358 struct objc_class *subclass_list;
4359 struct objc_class *sibling_class;
4361 struct objc_protocol_list *protocols;
4362 void *gc_object_type;
4366 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4367 dispatch_table
, ivar_list
, protocol_list
)
4374 tree dispatch_table
;
4378 tree initlist
= NULL_TREE
, expr
;
4381 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4384 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4387 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4390 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4393 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4395 /* instance_size = */
4396 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4398 /* objc_ivar_list = */
4400 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4403 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4404 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4407 /* objc_method_list = */
4408 if (!dispatch_table
)
4409 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4412 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4413 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4416 if (flag_next_runtime
)
4417 /* method_cache = */
4418 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4422 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4424 /* subclass_list = */
4425 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4427 /* sibling_class = */
4428 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4431 /* protocol_list = */
4432 if (! protocol_list
)
4433 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4439 (build_tree_list (NULL_TREE
,
4440 xref_tag (RECORD_TYPE
,
4441 get_identifier (UTAG_PROTOCOL
))),
4442 build1 (INDIRECT_REF
, NULL_TREE
,
4443 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4445 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4446 TREE_TYPE (expr
) = cast_type2
;
4447 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4450 /* gc_object_type = NULL */
4451 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4453 return build_constructor (type
, nreverse (initlist
));
4456 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4459 generate_category (cat
)
4462 tree sc_spec
, decl_specs
, decl
;
4463 tree initlist
, cat_name_expr
, class_name_expr
;
4464 tree protocol_decl
, category
;
4466 add_class_reference (CLASS_NAME (cat
));
4467 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4469 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4471 category
= CLASS_CATEGORY_LIST (implementation_template
);
4473 /* find the category interface from the class it is associated with */
4476 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4478 category
= CLASS_CATEGORY_LIST (category
);
4481 if (category
&& CLASS_PROTOCOL_LIST (category
))
4483 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4484 protocol_decl
= generate_protocol_list (category
);
4489 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4490 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4492 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4493 implementation_context
),
4494 decl_specs
, 1, NULL_TREE
);
4496 initlist
= build_category_initializer (TREE_TYPE (decl
),
4497 cat_name_expr
, class_name_expr
,
4498 UOBJC_INSTANCE_METHODS_decl
,
4499 UOBJC_CLASS_METHODS_decl
,
4502 TREE_USED (decl
) = 1;
4503 finish_decl (decl
, initlist
, NULL_TREE
);
4506 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4507 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4510 generate_shared_structures ()
4512 tree sc_spec
, decl_specs
, decl
;
4513 tree name_expr
, super_expr
, root_expr
;
4514 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4515 tree cast_type
, initlist
, protocol_decl
;
4517 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4520 add_class_reference (my_super_id
);
4522 /* Compute "my_root_id" - this is required for code generation.
4523 the "isa" for all meta class structures points to the root of
4524 the inheritance hierarchy (e.g. "__Object")... */
4525 my_root_id
= my_super_id
;
4528 tree my_root_int
= lookup_interface (my_root_id
);
4530 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4531 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4538 /* No super class. */
4539 my_root_id
= CLASS_NAME (implementation_template
);
4542 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4543 objc_class_template
),
4544 build1 (INDIRECT_REF
,
4545 NULL_TREE
, NULL_TREE
)));
4547 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4550 /* Install class `isa' and `super' pointers at runtime. */
4553 super_expr
= add_objc_string (my_super_id
, class_names
);
4554 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4557 super_expr
= build_int_2 (0, 0);
4559 root_expr
= add_objc_string (my_root_id
, class_names
);
4560 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4562 if (CLASS_PROTOCOL_LIST (implementation_template
))
4564 generate_protocol_references
4565 (CLASS_PROTOCOL_LIST (implementation_template
));
4566 protocol_decl
= generate_protocol_list (implementation_template
);
4571 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4573 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4574 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4576 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4580 = build_shared_structure_initializer
4582 root_expr
, super_expr
, name_expr
,
4583 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4585 UOBJC_CLASS_METHODS_decl
,
4586 UOBJC_CLASS_VARIABLES_decl
,
4589 finish_decl (decl
, initlist
, NULL_TREE
);
4591 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4593 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4597 = build_shared_structure_initializer
4599 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4600 super_expr
, name_expr
,
4601 convert (integer_type_node
,
4602 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4603 (implementation_template
))),
4605 UOBJC_INSTANCE_METHODS_decl
,
4606 UOBJC_INSTANCE_VARIABLES_decl
,
4609 finish_decl (decl
, initlist
, NULL_TREE
);
4613 synth_id_with_class_suffix (preamble
, ctxt
)
4614 const char *preamble
;
4618 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4619 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4621 const char *class_name
4622 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4623 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4624 sprintf (string
, "%s_%s", preamble
,
4625 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4627 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4628 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4630 /* We have a category. */
4631 const char *class_name
4632 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4633 const char *class_super_name
4634 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4635 string
= (char *) alloca (strlen (preamble
)
4636 + strlen (class_name
)
4637 + strlen (class_super_name
)
4639 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4641 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4643 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4645 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4646 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4651 return get_identifier (string
);
4655 is_objc_type_qualifier (node
)
4658 return (TREE_CODE (node
) == IDENTIFIER_NODE
4659 && (node
== ridpointers
[(int) RID_CONST
]
4660 || node
== ridpointers
[(int) RID_VOLATILE
]
4661 || node
== ridpointers
[(int) RID_IN
]
4662 || node
== ridpointers
[(int) RID_OUT
]
4663 || node
== ridpointers
[(int) RID_INOUT
]
4664 || node
== ridpointers
[(int) RID_BYCOPY
]
4665 || node
== ridpointers
[(int) RID_BYREF
]
4666 || node
== ridpointers
[(int) RID_ONEWAY
]));
4669 /* If type is empty or only type qualifiers are present, add default
4670 type of id (otherwise grokdeclarator will default to int). */
4673 adjust_type_for_id_default (type
)
4676 tree declspecs
, chain
;
4679 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4680 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4682 declspecs
= TREE_PURPOSE (type
);
4684 /* Determine if a typespec is present. */
4685 for (chain
= declspecs
;
4687 chain
= TREE_CHAIN (chain
))
4689 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4693 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4695 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4700 selector ':' '(' typename ')' identifier
4703 Transform an Objective-C keyword argument into
4704 the C equivalent parameter declarator.
4706 In: key_name, an "identifier_node" (optional).
4707 arg_type, a "tree_list" (optional).
4708 arg_name, an "identifier_node".
4710 Note: It would be really nice to strongly type the preceding
4711 arguments in the function prototype; however, then I
4712 could not use the "accessor" macros defined in "tree.h".
4714 Out: an instance of "keyword_decl". */
4717 build_keyword_decl (key_name
, arg_type
, arg_name
)
4724 /* If no type is specified, default to "id". */
4725 arg_type
= adjust_type_for_id_default (arg_type
);
4727 keyword_decl
= make_node (KEYWORD_DECL
);
4729 TREE_TYPE (keyword_decl
) = arg_type
;
4730 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4731 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4733 return keyword_decl
;
4736 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4739 build_keyword_selector (selector
)
4743 tree key_chain
, key_name
;
4746 /* Scan the selector to see how much space we'll need. */
4747 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4749 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4750 key_name
= KEYWORD_KEY_NAME (key_chain
);
4751 else if (TREE_CODE (selector
) == TREE_LIST
)
4752 key_name
= TREE_PURPOSE (key_chain
);
4757 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4759 /* Just a ':' arg. */
4763 buf
= (char *) alloca (len
+ 1);
4764 /* Start the buffer out as an empty string. */
4767 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4769 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4770 key_name
= KEYWORD_KEY_NAME (key_chain
);
4771 else if (TREE_CODE (selector
) == TREE_LIST
)
4772 key_name
= TREE_PURPOSE (key_chain
);
4777 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4781 return get_identifier (buf
);
4784 /* Used for declarations and definitions. */
4787 build_method_decl (code
, ret_type
, selector
, add_args
)
4788 enum tree_code code
;
4795 /* If no type is specified, default to "id". */
4796 ret_type
= adjust_type_for_id_default (ret_type
);
4798 method_decl
= make_node (code
);
4799 TREE_TYPE (method_decl
) = ret_type
;
4801 /* If we have a keyword selector, create an identifier_node that
4802 represents the full selector name (`:' included)... */
4803 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4805 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4806 METHOD_SEL_ARGS (method_decl
) = selector
;
4807 METHOD_ADD_ARGS (method_decl
) = add_args
;
4811 METHOD_SEL_NAME (method_decl
) = selector
;
4812 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4813 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4819 #define METHOD_DEF 0
4820 #define METHOD_REF 1
4822 /* Used by `build_message_expr' and `comp_method_types'. Return an
4823 argument list for method METH. CONTEXT is either METHOD_DEF or
4824 METHOD_REF, saying whether we are trying to define a method or call
4825 one. SUPERFLAG says this is for a send to super; this makes a
4826 difference for the NeXT calling sequence in which the lookup and
4827 the method call are done together. */
4830 get_arg_type_list (meth
, context
, superflag
)
4837 /* Receiver type. */
4838 if (flag_next_runtime
&& superflag
)
4839 arglist
= build_tree_list (NULL_TREE
, super_type
);
4840 else if (context
== METHOD_DEF
)
4841 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4843 arglist
= build_tree_list (NULL_TREE
, id_type
);
4845 /* Selector type - will eventually change to `int'. */
4846 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4848 /* Build a list of argument types. */
4849 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4851 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4852 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4855 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4856 /* We have a `, ...' immediately following the selector,
4857 finalize the arglist...simulate get_parm_info (0). */
4859 else if (METHOD_ADD_ARGS (meth
))
4861 /* we have a variable length selector */
4862 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4863 chainon (arglist
, add_arg_list
);
4866 /* finalize the arglist...simulate get_parm_info (1) */
4867 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4873 check_duplicates (hsh
)
4876 tree meth
= NULL_TREE
;
4884 /* We have two methods with the same name and different types. */
4886 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4888 warning ("multiple declarations for method `%s'",
4889 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4891 warn_with_method ("using", type
, meth
);
4892 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4893 warn_with_method ("also found", type
, loop
->value
);
4899 /* If RECEIVER is a class reference, return the identifier node for
4900 the referenced class. RECEIVER is created by get_class_reference,
4901 so we check the exact form created depending on which runtimes are
4905 receiver_is_class_object (receiver
)
4908 tree chain
, exp
, arg
;
4910 if (flag_next_runtime
)
4912 /* The receiver is 'self' in the context of a class method. */
4913 if (objc_method_context
4914 && receiver
== self_decl
4915 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4916 return CLASS_NAME (objc_implementation_context
);
4918 /* The receiver is a variable created by
4919 build_class_reference_decl. */
4920 if (TREE_CODE (receiver
) == VAR_DECL
4921 && TREE_TYPE (receiver
) == objc_class_type
)
4922 /* Look up the identifier. */
4923 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4924 if (TREE_PURPOSE (chain
) == receiver
)
4925 return TREE_VALUE (chain
);
4929 /* The receiver is a function call that returns an id. Check if
4930 it is a call to objc_getClass, if so, pick up the class name. */
4931 if ((exp
= TREE_OPERAND (receiver
, 0))
4932 && TREE_CODE (exp
) == ADDR_EXPR
4933 && (exp
= TREE_OPERAND (exp
, 0))
4934 && TREE_CODE (exp
) == FUNCTION_DECL
4935 && exp
== objc_get_class_decl
4936 /* We have a call to objc_getClass! */
4937 && (arg
= TREE_OPERAND (receiver
, 1))
4938 && TREE_CODE (arg
) == TREE_LIST
4939 && (arg
= TREE_VALUE (arg
)))
4942 if (TREE_CODE (arg
) == ADDR_EXPR
4943 && (arg
= TREE_OPERAND (arg
, 0))
4944 && TREE_CODE (arg
) == STRING_CST
)
4945 /* Finally, we have the class name. */
4946 return get_identifier (TREE_STRING_POINTER (arg
));
4952 /* If we are currently building a message expr, this holds
4953 the identifier of the selector of the message. This is
4954 used when printing warnings about argument mismatches. */
4956 static tree building_objc_message_expr
= 0;
4959 maybe_building_objc_message_expr ()
4961 return building_objc_message_expr
;
4964 /* Construct an expression for sending a message.
4965 MESS has the object to send to in TREE_PURPOSE
4966 and the argument list (including selector) in TREE_VALUE.
4968 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4969 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4972 build_message_expr (mess
)
4975 tree receiver
= TREE_PURPOSE (mess
);
4976 tree selector
, self_object
;
4977 tree rtype
, sel_name
;
4978 tree args
= TREE_VALUE (mess
);
4979 tree method_params
= NULL_TREE
;
4980 tree method_prototype
= NULL_TREE
;
4982 int statically_typed
= 0, statically_allocated
= 0;
4983 tree class_ident
= 0;
4985 /* 1 if this is sending to the superclass. */
4988 if (TREE_CODE (receiver
) == ERROR_MARK
)
4989 return error_mark_node
;
4991 /* Determine receiver type. */
4992 rtype
= TREE_TYPE (receiver
);
4993 super
= IS_SUPER (rtype
);
4997 if (TREE_STATIC_TEMPLATE (rtype
))
4998 statically_allocated
= 1;
4999 else if (TREE_CODE (rtype
) == POINTER_TYPE
5000 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
5001 statically_typed
= 1;
5002 else if ((flag_next_runtime
5003 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
5004 && (class_ident
= receiver_is_class_object (receiver
)))
5006 else if (! IS_ID (rtype
)
5007 /* Allow any type that matches objc_class_type. */
5008 && ! comptypes (rtype
, objc_class_type
))
5010 warning ("invalid receiver type `%s'",
5011 gen_declaration (rtype
, errbuf
));
5014 if (statically_allocated
)
5015 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
5017 /* Don't evaluate the receiver twice. */
5018 receiver
= save_expr (receiver
);
5019 self_object
= receiver
;
5022 /* If sending to `super', use current self as the object. */
5023 self_object
= self_decl
;
5025 /* Obtain the full selector name. */
5027 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
5028 /* A unary selector. */
5030 else if (TREE_CODE (args
) == TREE_LIST
)
5031 sel_name
= build_keyword_selector (args
);
5035 /* Build the parameter list to give to the method. */
5037 method_params
= NULL_TREE
;
5038 if (TREE_CODE (args
) == TREE_LIST
)
5040 tree chain
= args
, prev
= NULL_TREE
;
5042 /* We have a keyword selector--check for comma expressions. */
5045 tree element
= TREE_VALUE (chain
);
5047 /* We have a comma expression, must collapse... */
5048 if (TREE_CODE (element
) == TREE_LIST
)
5051 TREE_CHAIN (prev
) = element
;
5056 chain
= TREE_CHAIN (chain
);
5058 method_params
= args
;
5061 /* Determine operation return type. */
5063 if (IS_SUPER (rtype
))
5067 if (CLASS_SUPER_NAME (implementation_template
))
5070 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5072 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5073 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5075 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5077 if (iface
&& !method_prototype
)
5078 warning ("`%s' does not respond to `%s'",
5079 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5080 IDENTIFIER_POINTER (sel_name
));
5084 error ("no super class declared in interface for `%s'",
5085 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5086 return error_mark_node
;
5090 else if (statically_allocated
)
5092 tree ctype
= TREE_TYPE (rtype
);
5093 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5096 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5098 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5100 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5103 if (!method_prototype
)
5104 warning ("`%s' does not respond to `%s'",
5105 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5106 IDENTIFIER_POINTER (sel_name
));
5108 else if (statically_typed
)
5110 tree ctype
= TREE_TYPE (rtype
);
5112 /* `self' is now statically_typed. All methods should be visible
5113 within the context of the implementation. */
5114 if (implementation_context
5115 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5118 = lookup_instance_method_static (implementation_template
,
5121 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5123 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5126 if (! method_prototype
5127 && implementation_template
!= implementation_context
)
5128 /* The method is not published in the interface. Check
5131 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5138 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5139 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5141 if (! method_prototype
)
5143 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5146 = lookup_method_in_protocol_list (protocol_list
,
5151 if (!method_prototype
)
5152 warning ("`%s' does not respond to `%s'",
5153 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5154 IDENTIFIER_POINTER (sel_name
));
5156 else if (class_ident
)
5158 if (implementation_context
5159 && CLASS_NAME (implementation_context
) == class_ident
)
5162 = lookup_class_method_static (implementation_template
, sel_name
);
5164 if (!method_prototype
5165 && implementation_template
!= implementation_context
)
5166 /* The method is not published in the interface. Check
5169 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5176 if ((iface
= lookup_interface (class_ident
)))
5177 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5180 if (!method_prototype
5181 || TREE_CODE (method_prototype
) != CLASS_METHOD_DECL
)
5183 warning ("cannot find class (factory) method.");
5184 warning ("return type for `%s' defaults to id",
5185 IDENTIFIER_POINTER (sel_name
));
5188 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5190 /* An anonymous object that has been qualified with a protocol. */
5192 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5194 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5197 if (!method_prototype
)
5201 warning ("method `%s' not implemented by protocol.",
5202 IDENTIFIER_POINTER (sel_name
));
5204 /* Try and find the method signature in the global pools. */
5206 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5207 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5209 if (!(method_prototype
= check_duplicates (hsh
)))
5210 warning ("return type defaults to id");
5217 /* We think we have an instance...loophole: extern id Object; */
5218 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5220 /* For various loopholes, like sending messages to self in a
5222 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5224 method_prototype
= check_duplicates (hsh
);
5225 if (!method_prototype
)
5227 warning ("cannot find method.");
5228 warning ("return type for `%s' defaults to id",
5229 IDENTIFIER_POINTER (sel_name
));
5233 /* Save the selector name for printing error messages. */
5234 building_objc_message_expr
= sel_name
;
5236 /* Build the parameters list for looking up the method.
5237 These are the object itself and the selector. */
5239 if (flag_typed_selectors
)
5240 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5242 selector
= build_selector_reference (sel_name
);
5244 retval
= build_objc_method_call (super
, method_prototype
,
5245 receiver
, self_object
,
5246 selector
, method_params
);
5248 building_objc_message_expr
= 0;
5253 /* Build a tree expression to send OBJECT the operation SELECTOR,
5254 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5255 assuming the method has prototype METHOD_PROTOTYPE.
5256 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5257 Use METHOD_PARAMS as list of args to pass to the method.
5258 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5261 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5262 selector
, method_params
)
5264 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5266 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5267 tree rcv_p
= (super_flag
5268 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5269 get_identifier (TAG_SUPER
)))
5272 if (flag_next_runtime
)
5274 if (! method_prototype
)
5276 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5277 tree_cons (NULL_TREE
, selector
,
5279 assemble_external (sender
);
5280 return build_function_call (sender
, method_params
);
5284 /* This is a real kludge, but it is used only for the Next.
5285 Clobber the data type of SENDER temporarily to accept
5286 all the arguments for this operation, and to return
5287 whatever this operation returns. */
5288 tree arglist
= NULL_TREE
;
5291 /* Save the proper contents of SENDER's data type. */
5292 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5293 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5295 /* Install this method's argument types. */
5296 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5298 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5300 /* Install this method's return type. */
5301 TREE_TYPE (TREE_TYPE (sender
))
5302 = groktypename (TREE_TYPE (method_prototype
));
5304 /* Call SENDER with all the parameters. This will do type
5305 checking using the arg types for this method. */
5306 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5307 tree_cons (NULL_TREE
, selector
,
5309 assemble_external (sender
);
5310 retval
= build_function_call (sender
, method_params
);
5312 /* Restore SENDER's return/argument types. */
5313 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5314 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5320 /* This is the portable way.
5321 First call the lookup function to get a pointer to the method,
5322 then cast the pointer, then call it with the method arguments. */
5325 /* Avoid trouble since we may evaluate each of these twice. */
5326 object
= save_expr (object
);
5327 selector
= save_expr (selector
);
5329 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5331 assemble_external (sender
);
5333 = build_function_call (sender
,
5334 tree_cons (NULL_TREE
, lookup_object
,
5335 tree_cons (NULL_TREE
, selector
,
5338 /* If we have a method prototype, construct the data type this
5339 method needs, and cast what we got from SENDER into a pointer
5341 if (method_prototype
)
5343 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5345 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5346 tree fake_function_type
= build_function_type (valtype
, arglist
);
5347 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5351 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5353 /* Pass the object to the method. */
5354 assemble_external (method
);
5355 return build_function_call (method
,
5356 tree_cons (NULL_TREE
, object
,
5357 tree_cons (NULL_TREE
, selector
,
5363 build_protocol_reference (p
)
5366 tree decl
, ident
, ptype
;
5368 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5370 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5372 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5373 objc_protocol_template
),
5376 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5377 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5380 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5381 DECL_EXTERNAL (decl
) = 1;
5382 TREE_PUBLIC (decl
) = 1;
5383 TREE_USED (decl
) = 1;
5384 DECL_ARTIFICIAL (decl
) = 1;
5386 make_decl_rtl (decl
, 0);
5387 pushdecl_top_level (decl
);
5390 PROTOCOL_FORWARD_DECL (p
) = decl
;
5394 build_protocol_expr (protoname
)
5398 tree p
= lookup_protocol (protoname
);
5402 error ("Cannot find protocol declaration for `%s'",
5403 IDENTIFIER_POINTER (protoname
));
5404 return error_mark_node
;
5407 if (!PROTOCOL_FORWARD_DECL (p
))
5408 build_protocol_reference (p
);
5410 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5412 TREE_TYPE (expr
) = protocol_type
;
5418 build_selector_expr (selnamelist
)
5423 /* Obtain the full selector name. */
5424 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5425 /* A unary selector. */
5426 selname
= selnamelist
;
5427 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5428 selname
= build_keyword_selector (selnamelist
);
5432 if (flag_typed_selectors
)
5433 return build_typed_selector_reference (selname
, 0);
5435 return build_selector_reference (selname
);
5439 build_encode_expr (type
)
5445 encode_type (type
, obstack_object_size (&util_obstack
),
5446 OBJC_ENCODE_INLINE_DEFS
);
5447 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5448 string
= obstack_finish (&util_obstack
);
5450 /* Synthesize a string that represents the encoded struct/union. */
5451 result
= my_build_string (strlen (string
) + 1, string
);
5452 obstack_free (&util_obstack
, util_firstobj
);
5457 build_ivar_reference (id
)
5460 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5462 /* Historically, a class method that produced objects (factory
5463 method) would assign `self' to the instance that it
5464 allocated. This would effectively turn the class method into
5465 an instance method. Following this assignment, the instance
5466 variables could be accessed. That practice, while safe,
5467 violates the simple rule that a class method should not refer
5468 to an instance variable. It's better to catch the cases
5469 where this is done unknowingly than to support the above
5471 warning ("instance variable `%s' accessed in class method",
5472 IDENTIFIER_POINTER (id
));
5473 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5476 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5479 #define HASH_ALLOC_LIST_SIZE 170
5480 #define ATTR_ALLOC_LIST_SIZE 170
5481 #define SIZEHASHTABLE 257
5484 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5489 nst_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5490 cls_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5493 /* WARNING!!!! hash_enter is called with a method, and will peek
5494 inside to find its selector! But hash_lookup is given a selector
5495 directly, and looks for the selector that's inside the found
5496 entry's key (method) for comparison. */
5499 hash_enter (hashlist
, method
)
5503 static hash hash_alloc_list
= 0;
5504 static int hash_alloc_index
= 0;
5506 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5508 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5510 hash_alloc_index
= 0;
5511 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5512 * HASH_ALLOC_LIST_SIZE
);
5514 obj
= &hash_alloc_list
[hash_alloc_index
++];
5516 obj
->next
= hashlist
[slot
];
5519 hashlist
[slot
] = obj
; /* append to front */
5523 hash_lookup (hashlist
, sel_name
)
5529 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5533 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5536 target
= target
->next
;
5542 hash_add_attr (entry
, value
)
5546 static attr attr_alloc_list
= 0;
5547 static int attr_alloc_index
= 0;
5550 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5552 attr_alloc_index
= 0;
5553 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5554 * ATTR_ALLOC_LIST_SIZE
);
5556 obj
= &attr_alloc_list
[attr_alloc_index
++];
5557 obj
->next
= entry
->list
;
5560 entry
->list
= obj
; /* append to front */
5564 lookup_method (mchain
, method
)
5570 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5573 key
= METHOD_SEL_NAME (method
);
5577 if (METHOD_SEL_NAME (mchain
) == key
)
5579 mchain
= TREE_CHAIN (mchain
);
5585 lookup_instance_method_static (interface
, ident
)
5589 tree inter
= interface
;
5590 tree chain
= CLASS_NST_METHODS (inter
);
5591 tree meth
= NULL_TREE
;
5595 if ((meth
= lookup_method (chain
, ident
)))
5598 if (CLASS_CATEGORY_LIST (inter
))
5600 tree category
= CLASS_CATEGORY_LIST (inter
);
5601 chain
= CLASS_NST_METHODS (category
);
5605 if ((meth
= lookup_method (chain
, ident
)))
5608 /* Check for instance methods in protocols in categories. */
5609 if (CLASS_PROTOCOL_LIST (category
))
5611 if ((meth
= (lookup_method_in_protocol_list
5612 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5616 if ((category
= CLASS_CATEGORY_LIST (category
)))
5617 chain
= CLASS_NST_METHODS (category
);
5622 if (CLASS_PROTOCOL_LIST (inter
))
5624 if ((meth
= (lookup_method_in_protocol_list
5625 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5629 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5630 chain
= CLASS_NST_METHODS (inter
);
5638 lookup_class_method_static (interface
, ident
)
5642 tree inter
= interface
;
5643 tree chain
= CLASS_CLS_METHODS (inter
);
5644 tree meth
= NULL_TREE
;
5645 tree root_inter
= NULL_TREE
;
5649 if ((meth
= lookup_method (chain
, ident
)))
5652 if (CLASS_CATEGORY_LIST (inter
))
5654 tree category
= CLASS_CATEGORY_LIST (inter
);
5655 chain
= CLASS_CLS_METHODS (category
);
5659 if ((meth
= lookup_method (chain
, ident
)))
5662 /* Check for class methods in protocols in categories. */
5663 if (CLASS_PROTOCOL_LIST (category
))
5665 if ((meth
= (lookup_method_in_protocol_list
5666 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5670 if ((category
= CLASS_CATEGORY_LIST (category
)))
5671 chain
= CLASS_CLS_METHODS (category
);
5676 /* Check for class methods in protocols. */
5677 if (CLASS_PROTOCOL_LIST (inter
))
5679 if ((meth
= (lookup_method_in_protocol_list
5680 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5685 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5686 chain
= CLASS_CLS_METHODS (inter
);
5690 /* Simulate wrap around. */
5691 return lookup_instance_method_static (root_inter
, ident
);
5695 add_class_method (class, method
)
5702 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5704 /* put method on list in reverse order */
5705 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5706 CLASS_CLS_METHODS (class) = method
;
5710 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5711 error ("duplicate definition of class method `%s'.",
5712 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5715 /* Check types; if different, complain. */
5716 if (!comp_proto_with_proto (method
, mth
))
5717 error ("duplicate declaration of class method `%s'.",
5718 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5722 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5724 /* Install on a global chain. */
5725 hash_enter (cls_method_hash_list
, method
);
5729 /* Check types; if different, add to a list. */
5730 if (!comp_proto_with_proto (method
, hsh
->key
))
5731 hash_add_attr (hsh
, method
);
5737 add_instance_method (class, method
)
5744 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5746 /* Put method on list in reverse order. */
5747 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5748 CLASS_NST_METHODS (class) = method
;
5752 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5753 error ("duplicate definition of instance method `%s'.",
5754 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5757 /* Check types; if different, complain. */
5758 if (!comp_proto_with_proto (method
, mth
))
5759 error ("duplicate declaration of instance method `%s'.",
5760 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5764 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5766 /* Install on a global chain. */
5767 hash_enter (nst_method_hash_list
, method
);
5771 /* Check types; if different, add to a list. */
5772 if (!comp_proto_with_proto (method
, hsh
->key
))
5773 hash_add_attr (hsh
, method
);
5782 /* Put interfaces on list in reverse order. */
5783 TREE_CHAIN (class) = interface_chain
;
5784 interface_chain
= class;
5785 return interface_chain
;
5789 add_category (class, category
)
5793 /* Put categories on list in reverse order. */
5794 tree cat
= CLASS_CATEGORY_LIST (class);
5798 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5799 warning ("duplicate interface declaration for category `%s(%s)'",
5800 IDENTIFIER_POINTER (CLASS_NAME (class)),
5801 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5802 cat
= CLASS_CATEGORY_LIST (cat
);
5805 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5806 CLASS_CATEGORY_LIST (class) = category
;
5809 /* Called after parsing each instance variable declaration. Necessary to
5810 preserve typedefs and implement public/private...
5812 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5815 add_instance_variable (class, public, declarator
, declspecs
, width
)
5822 tree field_decl
, raw_decl
;
5824 raw_decl
= build_tree_list (declspecs
, declarator
);
5826 if (CLASS_RAW_IVARS (class))
5827 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5829 CLASS_RAW_IVARS (class) = raw_decl
;
5831 field_decl
= grokfield (input_filename
, lineno
,
5832 declarator
, declspecs
, width
);
5834 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5838 TREE_PUBLIC (field_decl
) = 0;
5839 TREE_PRIVATE (field_decl
) = 0;
5840 TREE_PROTECTED (field_decl
) = 1;
5844 TREE_PUBLIC (field_decl
) = 1;
5845 TREE_PRIVATE (field_decl
) = 0;
5846 TREE_PROTECTED (field_decl
) = 0;
5850 TREE_PUBLIC (field_decl
) = 0;
5851 TREE_PRIVATE (field_decl
) = 1;
5852 TREE_PROTECTED (field_decl
) = 0;
5857 if (CLASS_IVARS (class))
5858 chainon (CLASS_IVARS (class), field_decl
);
5860 CLASS_IVARS (class) = field_decl
;
5866 is_ivar (decl_chain
, ident
)
5870 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5871 if (DECL_NAME (decl_chain
) == ident
)
5876 /* True if the ivar is private and we are not in its implementation. */
5882 if (TREE_PRIVATE (decl
)
5883 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5885 error ("instance variable `%s' is declared private",
5886 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5893 /* We have an instance variable reference;, check to see if it is public. */
5896 is_public (expr
, identifier
)
5900 tree basetype
= TREE_TYPE (expr
);
5901 enum tree_code code
= TREE_CODE (basetype
);
5904 if (code
== RECORD_TYPE
)
5906 if (TREE_STATIC_TEMPLATE (basetype
))
5908 if (!lookup_interface (TYPE_NAME (basetype
)))
5910 error ("Cannot find interface declaration for `%s'",
5911 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5915 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5917 if (TREE_PUBLIC (decl
))
5920 /* Important difference between the Stepstone translator:
5921 all instance variables should be public within the context
5922 of the implementation. */
5923 if (implementation_context
5924 && (((TREE_CODE (implementation_context
)
5925 == CLASS_IMPLEMENTATION_TYPE
)
5926 || (TREE_CODE (implementation_context
)
5927 == CATEGORY_IMPLEMENTATION_TYPE
))
5928 && (CLASS_NAME (implementation_context
)
5929 == TYPE_NAME (basetype
))))
5930 return ! is_private (decl
);
5932 error ("instance variable `%s' is declared %s",
5933 IDENTIFIER_POINTER (identifier
),
5934 TREE_PRIVATE (decl
) ? "private" : "protected");
5939 else if (implementation_context
&& (basetype
== objc_object_reference
))
5941 TREE_TYPE (expr
) = uprivate_record
;
5942 warning ("static access to object of type `id'");
5949 /* Implement @defs (<classname>) within struct bodies. */
5952 get_class_ivars (interface
)
5955 /* Make sure we copy the leaf ivars in case @defs is used in a local
5956 context. Otherwise finish_struct will overwrite the layout info
5957 using temporary storage. */
5958 return build_ivar_chain (interface
, 1);
5961 /* Make sure all entries in CHAIN are also in LIST. */
5964 check_methods (chain
, list
, mtype
)
5973 if (!lookup_method (list
, chain
))
5977 if (TREE_CODE (implementation_context
)
5978 == CLASS_IMPLEMENTATION_TYPE
)
5979 warning ("incomplete implementation of class `%s'",
5980 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5981 else if (TREE_CODE (implementation_context
)
5982 == CATEGORY_IMPLEMENTATION_TYPE
)
5983 warning ("incomplete implementation of category `%s'",
5984 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5988 warning ("method definition for `%c%s' not found",
5989 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5992 chain
= TREE_CHAIN (chain
);
5998 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6001 conforms_to_protocol (class, protocol
)
6005 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
6007 tree p
= CLASS_PROTOCOL_LIST (class);
6008 while (p
&& TREE_VALUE (p
) != protocol
)
6013 tree super
= (CLASS_SUPER_NAME (class)
6014 ? lookup_interface (CLASS_SUPER_NAME (class))
6016 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
6025 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6026 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6029 check_methods_accessible (chain
, context
, mtype
)
6036 tree base_context
= context
;
6040 context
= base_context
;
6044 list
= CLASS_CLS_METHODS (context
);
6046 list
= CLASS_NST_METHODS (context
);
6048 if (lookup_method (list
, chain
))
6051 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6052 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6053 context
= (CLASS_SUPER_NAME (context
)
6054 ? lookup_interface (CLASS_SUPER_NAME (context
))
6057 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6058 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6059 context
= (CLASS_NAME (context
)
6060 ? lookup_interface (CLASS_NAME (context
))
6066 if (context
== NULL_TREE
)
6070 if (TREE_CODE (implementation_context
)
6071 == CLASS_IMPLEMENTATION_TYPE
)
6072 warning ("incomplete implementation of class `%s'",
6074 (CLASS_NAME (implementation_context
)));
6075 else if (TREE_CODE (implementation_context
)
6076 == CATEGORY_IMPLEMENTATION_TYPE
)
6077 warning ("incomplete implementation of category `%s'",
6079 (CLASS_SUPER_NAME (implementation_context
)));
6082 warning ("method definition for `%c%s' not found",
6083 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6086 chain
= TREE_CHAIN (chain
); /* next method... */
6091 /* Check whether the current interface (accessible via
6092 'implementation_context') actually implements protocol P, along
6093 with any protocols that P inherits. */
6096 check_protocol (p
, type
, name
)
6101 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6105 /* Ensure that all protocols have bodies! */
6106 if (flag_warn_protocol
)
6108 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6109 CLASS_CLS_METHODS (implementation_context
),
6111 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6112 CLASS_NST_METHODS (implementation_context
),
6117 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6118 implementation_context
,
6120 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6121 implementation_context
,
6126 warning ("%s `%s' does not fully implement the `%s' protocol",
6127 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6130 /* Check protocols recursively. */
6131 if (PROTOCOL_LIST (p
))
6133 tree subs
= PROTOCOL_LIST (p
);
6135 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6138 tree sub
= TREE_VALUE (subs
);
6140 /* If the superclass does not conform to the protocols
6141 inherited by P, then we must! */
6142 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
6143 check_protocol (sub
, type
, name
);
6144 subs
= TREE_CHAIN (subs
);
6149 /* Check whether the current interface (accessible via
6150 'implementation_context') actually implements the protocols listed
6154 check_protocols (proto_list
, type
, name
)
6159 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6161 tree p
= TREE_VALUE (proto_list
);
6163 check_protocol (p
, type
, name
);
6167 /* Make sure that the class CLASS_NAME is defined
6168 CODE says which kind of thing CLASS_NAME ought to be.
6169 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6170 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6173 start_class (code
, class_name
, super_name
, protocol_list
)
6174 enum tree_code code
;
6181 if (objc_implementation_context
)
6183 warning ("`@end' missing in implementation context");
6184 finish_class (objc_implementation_context
);
6185 objc_ivar_chain
= NULL_TREE
;
6186 objc_implementation_context
= NULL_TREE
;
6189 class = make_node (code
);
6190 TYPE_BINFO (class) = make_tree_vec (5);
6192 CLASS_NAME (class) = class_name
;
6193 CLASS_SUPER_NAME (class) = super_name
;
6194 CLASS_CLS_METHODS (class) = NULL_TREE
;
6196 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6198 error ("`%s' redeclared as different kind of symbol",
6199 IDENTIFIER_POINTER (class_name
));
6200 error_with_decl (decl
, "previous declaration of `%s'");
6203 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6206 static tree implemented_classes
= 0;
6209 if (!implemented_classes
)
6210 ggc_add_tree_root (&implemented_classes
, 1);
6211 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6212 if (TREE_VALUE (chain
) == class_name
)
6214 error ("reimplementation of class `%s'",
6215 IDENTIFIER_POINTER (class_name
));
6216 return error_mark_node
;
6218 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6219 implemented_classes
);
6222 /* Pre-build the following entities - for speed/convenience. */
6224 self_id
= get_identifier ("self");
6226 ucmd_id
= get_identifier ("_cmd");
6229 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6230 if (!objc_super_template
)
6231 objc_super_template
= build_super_template ();
6233 /* Reset for multiple classes per file. */
6236 implementation_context
= class;
6238 /* Lookup the interface for this implementation. */
6240 if (!(implementation_template
= lookup_interface (class_name
)))
6242 warning ("Cannot find interface declaration for `%s'",
6243 IDENTIFIER_POINTER (class_name
));
6244 add_class (implementation_template
= implementation_context
);
6247 /* If a super class has been specified in the implementation,
6248 insure it conforms to the one specified in the interface. */
6251 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6253 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6255 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6256 error ("conflicting super class name `%s'",
6257 IDENTIFIER_POINTER (super_name
));
6258 error ("previous declaration of `%s'", name
);
6261 else if (! super_name
)
6263 CLASS_SUPER_NAME (implementation_context
)
6264 = CLASS_SUPER_NAME (implementation_template
);
6268 else if (code
== CLASS_INTERFACE_TYPE
)
6270 if (lookup_interface (class_name
))
6271 warning ("duplicate interface declaration for class `%s'",
6272 IDENTIFIER_POINTER (class_name
));
6277 CLASS_PROTOCOL_LIST (class)
6278 = lookup_and_install_protocols (protocol_list
);
6281 else if (code
== CATEGORY_INTERFACE_TYPE
)
6283 tree class_category_is_assoc_with
;
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 (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6291 error ("Cannot find interface declaration for `%s'",
6292 IDENTIFIER_POINTER (class_name
));
6293 exit (FATAL_EXIT_CODE
);
6296 add_category (class_category_is_assoc_with
, class);
6299 CLASS_PROTOCOL_LIST (class)
6300 = lookup_and_install_protocols (protocol_list
);
6303 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6305 /* Pre-build the following entities for speed/convenience. */
6307 self_id
= get_identifier ("self");
6309 ucmd_id
= get_identifier ("_cmd");
6312 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6313 if (!objc_super_template
)
6314 objc_super_template
= build_super_template ();
6316 /* Reset for multiple classes per file. */
6319 implementation_context
= class;
6321 /* For a category, class_name is really the name of the class that
6322 the following set of methods will be associated with. We must
6323 find the interface so that can derive the objects template. */
6325 if (!(implementation_template
= lookup_interface (class_name
)))
6327 error ("Cannot find interface declaration for `%s'",
6328 IDENTIFIER_POINTER (class_name
));
6329 exit (FATAL_EXIT_CODE
);
6336 continue_class (class)
6339 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6340 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6342 struct imp_entry
*imp_entry
;
6345 /* Check consistency of the instance variables. */
6347 if (CLASS_IVARS (class))
6348 check_ivars (implementation_template
, class);
6350 /* code generation */
6352 ivar_context
= build_private_template (implementation_template
);
6354 if (!objc_class_template
)
6355 build_class_template ();
6357 imp_entry
= (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
));
6359 imp_entry
->next
= imp_list
;
6360 imp_entry
->imp_context
= class;
6361 imp_entry
->imp_template
= implementation_template
;
6363 synth_forward_declarations ();
6364 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6365 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6367 /* Append to front and increment count. */
6368 imp_list
= imp_entry
;
6369 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6374 return ivar_context
;
6377 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6379 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6381 if (!TYPE_FIELDS (record
))
6383 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6384 CLASS_STATIC_TEMPLATE (class) = record
;
6386 /* Mark this record as a class template for static typing. */
6387 TREE_STATIC_TEMPLATE (record
) = 1;
6394 return error_mark_node
;
6397 /* This is called once we see the "@end" in an interface/implementation. */
6400 finish_class (class)
6403 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6405 /* All code generation is done in finish_objc. */
6407 if (implementation_template
!= implementation_context
)
6409 /* Ensure that all method listed in the interface contain bodies. */
6410 check_methods (CLASS_CLS_METHODS (implementation_template
),
6411 CLASS_CLS_METHODS (implementation_context
), '+');
6412 check_methods (CLASS_NST_METHODS (implementation_template
),
6413 CLASS_NST_METHODS (implementation_context
), '-');
6415 if (CLASS_PROTOCOL_LIST (implementation_template
))
6416 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6418 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6422 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6424 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6426 /* Find the category interface from the class it is associated with. */
6429 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6431 category
= CLASS_CATEGORY_LIST (category
);
6436 /* Ensure all method listed in the interface contain bodies. */
6437 check_methods (CLASS_CLS_METHODS (category
),
6438 CLASS_CLS_METHODS (implementation_context
), '+');
6439 check_methods (CLASS_NST_METHODS (category
),
6440 CLASS_NST_METHODS (implementation_context
), '-');
6442 if (CLASS_PROTOCOL_LIST (category
))
6443 check_protocols (CLASS_PROTOCOL_LIST (category
),
6445 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6449 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6452 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6453 char *string
= (char *) alloca (strlen (class_name
) + 3);
6455 /* extern struct objc_object *_<my_name>; */
6457 sprintf (string
, "_%s", class_name
);
6459 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6460 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6461 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6467 add_protocol (protocol
)
6470 /* Put protocol on list in reverse order. */
6471 TREE_CHAIN (protocol
) = protocol_chain
;
6472 protocol_chain
= protocol
;
6473 return protocol_chain
;
6477 lookup_protocol (ident
)
6482 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6484 if (ident
== PROTOCOL_NAME (chain
))
6491 /* This function forward declares the protocols named by NAMES. If
6492 they are already declared or defined, the function has no effect. */
6495 objc_declare_protocols (names
)
6500 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6502 tree name
= TREE_VALUE (list
);
6504 if (lookup_protocol (name
) == NULL_TREE
)
6506 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6508 TYPE_BINFO (protocol
) = make_tree_vec (2);
6509 PROTOCOL_NAME (protocol
) = name
;
6510 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6511 add_protocol (protocol
);
6512 PROTOCOL_DEFINED (protocol
) = 0;
6513 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6519 start_protocol (code
, name
, list
)
6520 enum tree_code code
;
6526 /* This is as good a place as any. Need to invoke
6527 push_tag_toplevel. */
6528 if (!objc_protocol_template
)
6529 objc_protocol_template
= build_protocol_template ();
6531 protocol
= lookup_protocol (name
);
6535 protocol
= make_node (code
);
6536 TYPE_BINFO (protocol
) = make_tree_vec (2);
6538 PROTOCOL_NAME (protocol
) = name
;
6539 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6540 add_protocol (protocol
);
6541 PROTOCOL_DEFINED (protocol
) = 1;
6542 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6544 check_protocol_recursively (protocol
, list
);
6546 else if (! PROTOCOL_DEFINED (protocol
))
6548 PROTOCOL_DEFINED (protocol
) = 1;
6549 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6551 check_protocol_recursively (protocol
, list
);
6555 warning ("duplicate declaration for protocol `%s'",
6556 IDENTIFIER_POINTER (name
));
6562 finish_protocol (protocol
)
6563 tree protocol ATTRIBUTE_UNUSED
;
6568 /* "Encode" a data type into a string, which grows in util_obstack.
6569 ??? What is the FORMAT? Someone please document this! */
6572 encode_type_qualifiers (declspecs
)
6577 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6579 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6580 obstack_1grow (&util_obstack
, 'r');
6581 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6582 obstack_1grow (&util_obstack
, 'n');
6583 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6584 obstack_1grow (&util_obstack
, 'N');
6585 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6586 obstack_1grow (&util_obstack
, 'o');
6587 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6588 obstack_1grow (&util_obstack
, 'O');
6589 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6590 obstack_1grow (&util_obstack
, 'R');
6591 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6592 obstack_1grow (&util_obstack
, 'V');
6596 /* Encode a pointer type. */
6599 encode_pointer (type
, curtype
, format
)
6604 tree pointer_to
= TREE_TYPE (type
);
6606 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6608 if (TYPE_NAME (pointer_to
)
6609 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6611 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6613 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6615 obstack_1grow (&util_obstack
, '@');
6618 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6620 if (generating_instance_variables
)
6622 obstack_1grow (&util_obstack
, '@');
6623 obstack_1grow (&util_obstack
, '"');
6624 obstack_grow (&util_obstack
, name
, strlen (name
));
6625 obstack_1grow (&util_obstack
, '"');
6630 obstack_1grow (&util_obstack
, '@');
6634 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6636 obstack_1grow (&util_obstack
, '#');
6639 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6641 obstack_1grow (&util_obstack
, ':');
6646 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6647 && TYPE_MODE (pointer_to
) == QImode
)
6649 obstack_1grow (&util_obstack
, '*');
6653 /* We have a type that does not get special treatment. */
6655 /* NeXT extension */
6656 obstack_1grow (&util_obstack
, '^');
6657 encode_type (pointer_to
, curtype
, format
);
6661 encode_array (type
, curtype
, format
)
6666 tree an_int_cst
= TYPE_SIZE (type
);
6667 tree array_of
= TREE_TYPE (type
);
6670 /* An incomplete array is treated like a pointer. */
6671 if (an_int_cst
== NULL
)
6673 encode_pointer (type
, curtype
, format
);
6677 sprintf (buffer
, "[%ld",
6678 (long) (TREE_INT_CST_LOW (an_int_cst
)
6679 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6681 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6682 encode_type (array_of
, curtype
, format
);
6683 obstack_1grow (&util_obstack
, ']');
6688 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6695 /* The RECORD_TYPE may in fact be a typedef! For purposes
6696 of encoding, we need the real underlying enchilada. */
6697 if (TYPE_MAIN_VARIANT (type
))
6698 type
= TYPE_MAIN_VARIANT (type
);
6700 if (obstack_object_size (&util_obstack
) > 0
6701 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6703 tree name
= TYPE_NAME (type
);
6705 /* we have a reference; this is a NeXT extension. */
6707 if (obstack_object_size (&util_obstack
) - curtype
== 1
6708 && format
== OBJC_ENCODE_INLINE_DEFS
)
6710 /* Output format of struct for first level only. */
6711 tree fields
= TYPE_FIELDS (type
);
6713 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6715 obstack_1grow (&util_obstack
, left
);
6716 obstack_grow (&util_obstack
,
6717 IDENTIFIER_POINTER (name
),
6718 strlen (IDENTIFIER_POINTER (name
)));
6719 obstack_1grow (&util_obstack
, '=');
6723 obstack_1grow (&util_obstack
, left
);
6724 obstack_grow (&util_obstack
, "?=", 2);
6727 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6728 encode_field_decl (fields
, curtype
, format
);
6730 obstack_1grow (&util_obstack
, right
);
6733 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6735 obstack_1grow (&util_obstack
, left
);
6736 obstack_grow (&util_obstack
,
6737 IDENTIFIER_POINTER (name
),
6738 strlen (IDENTIFIER_POINTER (name
)));
6739 obstack_1grow (&util_obstack
, right
);
6744 /* We have an untagged structure or a typedef. */
6745 obstack_1grow (&util_obstack
, left
);
6746 obstack_1grow (&util_obstack
, '?');
6747 obstack_1grow (&util_obstack
, right
);
6753 tree name
= TYPE_NAME (type
);
6754 tree fields
= TYPE_FIELDS (type
);
6756 if (format
== OBJC_ENCODE_INLINE_DEFS
6757 || generating_instance_variables
)
6759 obstack_1grow (&util_obstack
, left
);
6760 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6761 obstack_grow (&util_obstack
,
6762 IDENTIFIER_POINTER (name
),
6763 strlen (IDENTIFIER_POINTER (name
)));
6765 obstack_1grow (&util_obstack
, '?');
6767 obstack_1grow (&util_obstack
, '=');
6769 for (; fields
; fields
= TREE_CHAIN (fields
))
6771 if (generating_instance_variables
)
6773 tree fname
= DECL_NAME (fields
);
6775 obstack_1grow (&util_obstack
, '"');
6776 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6778 obstack_grow (&util_obstack
,
6779 IDENTIFIER_POINTER (fname
),
6780 strlen (IDENTIFIER_POINTER (fname
)));
6783 obstack_1grow (&util_obstack
, '"');
6786 encode_field_decl (fields
, curtype
, format
);
6789 obstack_1grow (&util_obstack
, right
);
6794 obstack_1grow (&util_obstack
, left
);
6795 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6796 obstack_grow (&util_obstack
,
6797 IDENTIFIER_POINTER (name
),
6798 strlen (IDENTIFIER_POINTER (name
)));
6800 /* We have an untagged structure or a typedef. */
6801 obstack_1grow (&util_obstack
, '?');
6803 obstack_1grow (&util_obstack
, right
);
6809 encode_aggregate (type
, curtype
, format
)
6814 enum tree_code code
= TREE_CODE (type
);
6820 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6825 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6830 obstack_1grow (&util_obstack
, 'i');
6838 /* Support bitfields. The current version of Objective-C does not support
6839 them. The string will consist of one or more "b:n"'s where n is an
6840 integer describing the width of the bitfield. Currently, classes in
6841 the kit implement a method "-(char *)describeBitfieldStruct:" that
6842 simulates this. If they do not implement this method, the archiver
6843 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6844 according to the GNU compiler. After looking at the "kit", it appears
6845 that all classes currently rely on this default behavior, rather than
6846 hand generating this string (which is tedious). */
6849 encode_bitfield (width
)
6853 sprintf (buffer
, "b%d", width
);
6854 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6857 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6860 encode_type (type
, curtype
, format
)
6865 enum tree_code code
= TREE_CODE (type
);
6867 if (code
== INTEGER_TYPE
)
6869 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6871 /* Unsigned integer types. */
6873 if (TYPE_MODE (type
) == QImode
)
6874 obstack_1grow (&util_obstack
, 'C');
6875 else if (TYPE_MODE (type
) == HImode
)
6876 obstack_1grow (&util_obstack
, 'S');
6877 else if (TYPE_MODE (type
) == SImode
)
6879 if (type
== long_unsigned_type_node
)
6880 obstack_1grow (&util_obstack
, 'L');
6882 obstack_1grow (&util_obstack
, 'I');
6884 else if (TYPE_MODE (type
) == DImode
)
6885 obstack_1grow (&util_obstack
, 'Q');
6889 /* Signed integer types. */
6891 if (TYPE_MODE (type
) == QImode
)
6892 obstack_1grow (&util_obstack
, 'c');
6893 else if (TYPE_MODE (type
) == HImode
)
6894 obstack_1grow (&util_obstack
, 's');
6895 else if (TYPE_MODE (type
) == SImode
)
6897 if (type
== long_integer_type_node
)
6898 obstack_1grow (&util_obstack
, 'l');
6900 obstack_1grow (&util_obstack
, 'i');
6903 else if (TYPE_MODE (type
) == DImode
)
6904 obstack_1grow (&util_obstack
, 'q');
6908 else if (code
== REAL_TYPE
)
6910 /* Floating point types. */
6912 if (TYPE_MODE (type
) == SFmode
)
6913 obstack_1grow (&util_obstack
, 'f');
6914 else if (TYPE_MODE (type
) == DFmode
6915 || TYPE_MODE (type
) == TFmode
)
6916 obstack_1grow (&util_obstack
, 'd');
6919 else if (code
== VOID_TYPE
)
6920 obstack_1grow (&util_obstack
, 'v');
6922 else if (code
== ARRAY_TYPE
)
6923 encode_array (type
, curtype
, format
);
6925 else if (code
== POINTER_TYPE
)
6926 encode_pointer (type
, curtype
, format
);
6928 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6929 encode_aggregate (type
, curtype
, format
);
6931 else if (code
== FUNCTION_TYPE
) /* '?' */
6932 obstack_1grow (&util_obstack
, '?');
6936 encode_complete_bitfield (int position
, tree type
, int size
)
6938 enum tree_code code
= TREE_CODE (type
);
6940 char charType
= '?';
6942 if (code
== INTEGER_TYPE
)
6944 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6946 /* Unsigned integer types. */
6948 if (TYPE_MODE (type
) == QImode
)
6950 else if (TYPE_MODE (type
) == HImode
)
6952 else if (TYPE_MODE (type
) == SImode
)
6954 if (type
== long_unsigned_type_node
)
6959 else if (TYPE_MODE (type
) == DImode
)
6964 /* Signed integer types. */
6966 if (TYPE_MODE (type
) == QImode
)
6968 else if (TYPE_MODE (type
) == HImode
)
6970 else if (TYPE_MODE (type
) == SImode
)
6972 if (type
== long_integer_type_node
)
6978 else if (TYPE_MODE (type
) == DImode
)
6986 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6987 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6991 encode_field_decl (field_decl
, curtype
, format
)
6998 type
= TREE_TYPE (field_decl
);
7000 /* If this field is obviously a bitfield, or is a bitfield that has been
7001 clobbered to look like a ordinary integer mode, go ahead and generate
7002 the bitfield typing information. */
7003 if (flag_next_runtime
)
7005 if (DECL_BIT_FIELD (field_decl
))
7006 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
7008 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
7012 if (DECL_BIT_FIELD (field_decl
))
7013 encode_complete_bitfield (int_bit_position (field_decl
),
7014 DECL_BIT_FIELD_TYPE (field_decl
),
7015 tree_low_cst (DECL_SIZE (field_decl
), 1));
7017 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
7022 expr_last (complex_expr
)
7028 while ((next
= TREE_OPERAND (complex_expr
, 0)))
7029 complex_expr
= next
;
7031 return complex_expr
;
7034 /* Transform a method definition into a function definition as follows:
7035 - synthesize the first two arguments, "self" and "_cmd". */
7038 start_method_def (method
)
7043 /* Required to implement _msgSuper. */
7044 method_context
= method
;
7045 UOBJC_SUPER_decl
= NULL_TREE
;
7047 /* Must be called BEFORE start_function. */
7050 /* Generate prototype declarations for arguments..."new-style". */
7052 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
7053 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
7055 /* Really a `struct objc_class *'. However, we allow people to
7056 assign to self, which changes its type midstream. */
7057 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
7059 push_parm_decl (build_tree_list
7060 (build_tree_list (decl_specs
,
7061 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
7064 decl_specs
= build_tree_list (NULL_TREE
,
7065 xref_tag (RECORD_TYPE
,
7066 get_identifier (TAG_SELECTOR
)));
7067 push_parm_decl (build_tree_list
7068 (build_tree_list (decl_specs
,
7069 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
7072 /* Generate argument declarations if a keyword_decl. */
7073 if (METHOD_SEL_ARGS (method
))
7075 tree arglist
= METHOD_SEL_ARGS (method
);
7078 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
7079 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
7083 tree last_expr
= expr_last (arg_decl
);
7085 /* Unite the abstract decl with its name. */
7086 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
7087 push_parm_decl (build_tree_list
7088 (build_tree_list (arg_spec
, arg_decl
),
7091 /* Unhook: restore the abstract declarator. */
7092 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
7096 push_parm_decl (build_tree_list
7097 (build_tree_list (arg_spec
,
7098 KEYWORD_ARG_NAME (arglist
)),
7101 arglist
= TREE_CHAIN (arglist
);
7106 if (METHOD_ADD_ARGS (method
) != NULL_TREE
7107 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7109 /* We have a variable length selector - in "prototype" format. */
7110 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7113 /* This must be done prior to calling pushdecl. pushdecl is
7114 going to change our chain on us. */
7115 tree nextkey
= TREE_CHAIN (akey
);
7123 warn_with_method (message
, mtype
, method
)
7124 const char *message
;
7128 if (count_error (1) == 0)
7131 report_error_function (DECL_SOURCE_FILE (method
));
7133 /* Add a readable method name to the warning. */
7134 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
7135 DECL_SOURCE_LINE (method
),
7138 gen_method_decl (method
, errbuf
));
7141 /* Return 1 if METHOD is consistent with PROTO. */
7144 comp_method_with_proto (method
, proto
)
7147 static tree function_type
= 0;
7149 /* Create a function_type node once. */
7152 function_type
= make_node (FUNCTION_TYPE
);
7153 ggc_add_tree_root (&function_type
, 1);
7156 /* Install argument types - normally set by build_function_type. */
7157 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7159 /* install return type */
7160 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7162 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7165 /* Return 1 if PROTO1 is consistent with PROTO2. */
7168 comp_proto_with_proto (proto0
, proto1
)
7169 tree proto0
, proto1
;
7171 static tree function_type
[2];
7173 /* Create a couple function_type node's once. */
7174 if (!function_type
[0])
7176 function_type
[0] = make_node (FUNCTION_TYPE
);
7177 function_type
[1] = make_node (FUNCTION_TYPE
);
7178 ggc_add_tree_root (function_type
, 2);
7181 /* Install argument types; normally set by build_function_type. */
7182 TYPE_ARG_TYPES (function_type
[0]) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7183 TYPE_ARG_TYPES (function_type
[1]) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7185 /* Install return type. */
7186 TREE_TYPE (function_type
[0]) = groktypename (TREE_TYPE (proto0
));
7187 TREE_TYPE (function_type
[1]) = groktypename (TREE_TYPE (proto1
));
7189 return comptypes (function_type
[0], function_type
[1]);
7192 /* - Generate an identifier for the function. the format is "_n_cls",
7193 where 1 <= n <= nMethods, and cls is the name the implementation we
7195 - Install the return type from the method declaration.
7196 - If we have a prototype, check for type consistency. */
7199 really_start_method (method
, parmlist
)
7200 tree method
, parmlist
;
7202 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7203 tree method_decl
, method_id
;
7204 const char *sel_name
, *class_name
, *cat_name
;
7207 /* Synth the storage class & assemble the return type. */
7208 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7209 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7210 decl_specs
= chainon (sc_spec
, ret_spec
);
7212 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7213 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7214 cat_name
= ((TREE_CODE (implementation_context
)
7215 == CLASS_IMPLEMENTATION_TYPE
)
7217 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7220 /* Make sure this is big enough for any plausible method label. */
7221 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7222 + (cat_name
? strlen (cat_name
) : 0));
7224 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7225 class_name
, cat_name
, sel_name
, method_slot
);
7227 method_id
= get_identifier (buf
);
7229 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7231 /* Check the declarator portion of the return type for the method. */
7232 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7234 /* Unite the complex decl (specified in the abstract decl) with the
7235 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7236 tree save_expr
= expr_last (ret_decl
);
7238 TREE_OPERAND (save_expr
, 0) = method_decl
;
7239 method_decl
= ret_decl
;
7241 /* Fool the parser into thinking it is starting a function. */
7242 start_function (decl_specs
, method_decl
, NULL_TREE
);
7244 /* Unhook: this has the effect of restoring the abstract declarator. */
7245 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7250 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7252 /* Fool the parser into thinking it is starting a function. */
7253 start_function (decl_specs
, method_decl
, NULL_TREE
);
7255 /* Unhook: this has the effect of restoring the abstract declarator. */
7256 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7259 METHOD_DEFINITION (method
) = current_function_decl
;
7261 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7263 if (implementation_template
!= implementation_context
)
7267 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7268 proto
= lookup_instance_method_static (implementation_template
,
7269 METHOD_SEL_NAME (method
));
7271 proto
= lookup_class_method_static (implementation_template
,
7272 METHOD_SEL_NAME (method
));
7274 if (proto
&& ! comp_method_with_proto (method
, proto
))
7276 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7278 warn_with_method ("conflicting types for", type
, method
);
7279 warn_with_method ("previous declaration of", type
, proto
);
7284 /* The following routine is always called...this "architecture" is to
7285 accommodate "old-style" variable length selectors.
7287 - a:a b:b // prototype ; id c; id d; // old-style. */
7290 continue_method_def ()
7294 if (METHOD_ADD_ARGS (method_context
) == objc_ellipsis_node
)
7295 /* We have a `, ...' immediately following the selector. */
7296 parmlist
= get_parm_info (0);
7298 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7300 /* Set self_decl from the first argument...this global is used by
7301 build_ivar_reference calling build_indirect_ref. */
7302 self_decl
= TREE_PURPOSE (parmlist
);
7305 really_start_method (method_context
, parmlist
);
7306 store_parm_decls ();
7309 /* Called by the parser, from the `pushlevel' production. */
7314 if (!UOBJC_SUPER_decl
)
7316 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7317 build_tree_list (NULL_TREE
,
7318 objc_super_template
),
7321 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7323 /* This prevents `unused variable' warnings when compiling with -Wall. */
7324 TREE_USED (UOBJC_SUPER_decl
) = 1;
7325 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7329 /* _n_Method (id self, SEL sel, ...)
7331 struct objc_super _S;
7332 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7336 get_super_receiver ()
7340 tree super_expr
, super_expr_list
;
7342 /* Set receiver to self. */
7343 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7344 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7345 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7347 /* Set class to begin searching. */
7348 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7349 get_identifier ("class"));
7351 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7353 /* [_cls, __cls]Super are "pre-built" in
7354 synth_forward_declarations. */
7356 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7357 ((TREE_CODE (method_context
)
7358 == INSTANCE_METHOD_DECL
)
7360 : uucls_super_ref
));
7364 /* We have a category. */
7366 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7369 /* Barf if super used in a category of Object. */
7372 error ("no super class declared in interface for `%s'",
7373 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7374 return error_mark_node
;
7377 if (flag_next_runtime
)
7379 super_class
= get_class_reference (super_name
);
7380 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7382 = build_component_ref (build_indirect_ref (super_class
, "->"),
7383 get_identifier ("isa"));
7387 add_class_reference (super_name
);
7388 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7389 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7390 assemble_external (super_class
);
7392 = build_function_call
7396 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7397 IDENTIFIER_POINTER (super_name
))));
7400 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7401 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7404 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7406 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7407 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7409 return build_compound_expr (super_expr_list
);
7413 error ("[super ...] must appear in a method context");
7414 return error_mark_node
;
7419 encode_method_def (func_decl
)
7424 HOST_WIDE_INT max_parm_end
= 0;
7429 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7430 obstack_object_size (&util_obstack
),
7431 OBJC_ENCODE_INLINE_DEFS
);
7434 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7435 parms
= TREE_CHAIN (parms
))
7437 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7438 + int_size_in_bytes (TREE_TYPE (parms
)));
7440 if (! offset_is_register
&& parm_end
> max_parm_end
)
7441 max_parm_end
= parm_end
;
7444 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7446 sprintf (buffer
, "%d", stack_size
);
7447 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7449 /* Argument types. */
7450 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7451 parms
= TREE_CHAIN (parms
))
7454 encode_type (TREE_TYPE (parms
),
7455 obstack_object_size (&util_obstack
),
7456 OBJC_ENCODE_INLINE_DEFS
);
7458 /* Compute offset. */
7459 sprintf (buffer
, "%d", forwarding_offset (parms
));
7461 /* Indicate register. */
7462 if (offset_is_register
)
7463 obstack_1grow (&util_obstack
, '+');
7465 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7468 /* Null terminate string. */
7469 obstack_1grow (&util_obstack
, 0);
7470 result
= get_identifier (obstack_finish (&util_obstack
));
7471 obstack_free (&util_obstack
, util_firstobj
);
7476 objc_expand_function_end ()
7478 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7482 finish_method_def ()
7484 lang_expand_function_end
= objc_expand_function_end
;
7485 finish_function (0);
7486 lang_expand_function_end
= NULL
;
7488 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7489 since the optimizer may find "may be used before set" errors. */
7490 method_context
= NULL_TREE
;
7495 lang_report_error_function (decl
)
7500 fprintf (stderr
, "In method `%s'\n",
7501 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7511 is_complex_decl (type
)
7514 return (TREE_CODE (type
) == ARRAY_TYPE
7515 || TREE_CODE (type
) == FUNCTION_TYPE
7516 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7520 /* Code to convert a decl node into text for a declaration in C. */
7522 static char tmpbuf
[256];
7525 adorn_decl (decl
, str
)
7529 enum tree_code code
= TREE_CODE (decl
);
7531 if (code
== ARRAY_REF
)
7533 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7535 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7536 sprintf (str
+ strlen (str
), "[%ld]",
7537 (long) TREE_INT_CST_LOW (an_int_cst
));
7542 else if (code
== ARRAY_TYPE
)
7544 tree an_int_cst
= TYPE_SIZE (decl
);
7545 tree array_of
= TREE_TYPE (decl
);
7547 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7548 sprintf (str
+ strlen (str
), "[%ld]",
7549 (long) (TREE_INT_CST_LOW (an_int_cst
)
7550 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7555 else if (code
== CALL_EXPR
)
7557 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7562 gen_declaration_1 (chain
, str
);
7563 chain
= TREE_CHAIN (chain
);
7570 else if (code
== FUNCTION_TYPE
)
7572 tree chain
= TYPE_ARG_TYPES (decl
);
7575 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7577 gen_declaration_1 (TREE_VALUE (chain
), str
);
7578 chain
= TREE_CHAIN (chain
);
7579 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7585 else if (code
== INDIRECT_REF
)
7587 strcpy (tmpbuf
, "*");
7588 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7592 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7594 chain
= TREE_CHAIN (chain
))
7596 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7598 strcat (tmpbuf
, " ");
7599 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7603 strcat (tmpbuf
, " ");
7605 strcat (tmpbuf
, str
);
7606 strcpy (str
, tmpbuf
);
7609 else if (code
== POINTER_TYPE
)
7611 strcpy (tmpbuf
, "*");
7612 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7614 if (TREE_READONLY (decl
))
7615 strcat (tmpbuf
, " const");
7616 if (TYPE_VOLATILE (decl
))
7617 strcat (tmpbuf
, " volatile");
7619 strcat (tmpbuf
, " ");
7621 strcat (tmpbuf
, str
);
7622 strcpy (str
, tmpbuf
);
7627 gen_declarator (decl
, buf
, name
)
7634 enum tree_code code
= TREE_CODE (decl
);
7644 op
= TREE_OPERAND (decl
, 0);
7646 /* We have a pointer to a function or array...(*)(), (*)[] */
7647 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7648 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7651 str
= gen_declarator (op
, buf
, name
);
7655 strcpy (tmpbuf
, "(");
7656 strcat (tmpbuf
, str
);
7657 strcat (tmpbuf
, ")");
7658 strcpy (str
, tmpbuf
);
7661 adorn_decl (decl
, str
);
7670 /* This clause is done iteratively rather than recursively. */
7673 op
= (is_complex_decl (TREE_TYPE (decl
))
7674 ? TREE_TYPE (decl
) : NULL_TREE
);
7676 adorn_decl (decl
, str
);
7678 /* We have a pointer to a function or array...(*)(), (*)[] */
7679 if (code
== POINTER_TYPE
7680 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7681 || TREE_CODE (op
) == ARRAY_TYPE
))
7683 strcpy (tmpbuf
, "(");
7684 strcat (tmpbuf
, str
);
7685 strcat (tmpbuf
, ")");
7686 strcpy (str
, tmpbuf
);
7689 decl
= (is_complex_decl (TREE_TYPE (decl
))
7690 ? TREE_TYPE (decl
) : NULL_TREE
);
7693 while (decl
&& (code
= TREE_CODE (decl
)))
7698 case IDENTIFIER_NODE
:
7699 /* Will only happen if we are processing a "raw" expr-decl. */
7700 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7711 /* We have an abstract declarator or a _DECL node. */
7719 gen_declspecs (declspecs
, buf
, raw
)
7728 for (chain
= nreverse (copy_list (declspecs
));
7729 chain
; chain
= TREE_CHAIN (chain
))
7731 tree aspec
= TREE_VALUE (chain
);
7733 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7734 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7735 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7737 if (TYPE_NAME (aspec
))
7739 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7741 if (! TREE_STATIC_TEMPLATE (aspec
))
7742 strcat (buf
, "struct ");
7743 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7748 tree chain
= protocol_list
;
7755 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7756 chain
= TREE_CHAIN (chain
);
7765 strcat (buf
, "untagged struct");
7768 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7770 if (TYPE_NAME (aspec
))
7772 if (! TREE_STATIC_TEMPLATE (aspec
))
7773 strcat (buf
, "union ");
7774 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7777 strcat (buf
, "untagged union");
7780 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7782 if (TYPE_NAME (aspec
))
7784 if (! TREE_STATIC_TEMPLATE (aspec
))
7785 strcat (buf
, "enum ");
7786 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7789 strcat (buf
, "untagged enum");
7792 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7793 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7795 else if (IS_ID (aspec
))
7797 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7802 tree chain
= protocol_list
;
7809 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7810 chain
= TREE_CHAIN (chain
);
7817 if (TREE_CHAIN (chain
))
7823 /* Type qualifiers. */
7824 if (TREE_READONLY (declspecs
))
7825 strcat (buf
, "const ");
7826 if (TYPE_VOLATILE (declspecs
))
7827 strcat (buf
, "volatile ");
7829 switch (TREE_CODE (declspecs
))
7831 /* Type specifiers. */
7834 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7836 /* Signed integer types. */
7838 if (declspecs
== short_integer_type_node
)
7839 strcat (buf
, "short int ");
7840 else if (declspecs
== integer_type_node
)
7841 strcat (buf
, "int ");
7842 else if (declspecs
== long_integer_type_node
)
7843 strcat (buf
, "long int ");
7844 else if (declspecs
== long_long_integer_type_node
)
7845 strcat (buf
, "long long int ");
7846 else if (declspecs
== signed_char_type_node
7847 || declspecs
== char_type_node
)
7848 strcat (buf
, "char ");
7850 /* Unsigned integer types. */
7852 else if (declspecs
== short_unsigned_type_node
)
7853 strcat (buf
, "unsigned short ");
7854 else if (declspecs
== unsigned_type_node
)
7855 strcat (buf
, "unsigned int ");
7856 else if (declspecs
== long_unsigned_type_node
)
7857 strcat (buf
, "unsigned long ");
7858 else if (declspecs
== long_long_unsigned_type_node
)
7859 strcat (buf
, "unsigned long long ");
7860 else if (declspecs
== unsigned_char_type_node
)
7861 strcat (buf
, "unsigned char ");
7865 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7867 if (declspecs
== float_type_node
)
7868 strcat (buf
, "float ");
7869 else if (declspecs
== double_type_node
)
7870 strcat (buf
, "double ");
7871 else if (declspecs
== long_double_type_node
)
7872 strcat (buf
, "long double ");
7876 if (TYPE_NAME (declspecs
)
7877 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7879 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7881 if (! TREE_STATIC_TEMPLATE (declspecs
))
7882 strcat (buf
, "struct ");
7883 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7887 tree chain
= protocol_list
;
7894 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7895 chain
= TREE_CHAIN (chain
);
7904 strcat (buf
, "untagged struct");
7910 if (TYPE_NAME (declspecs
)
7911 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7913 strcat (buf
, "union ");
7914 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7919 strcat (buf
, "untagged union ");
7923 if (TYPE_NAME (declspecs
)
7924 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7926 strcat (buf
, "enum ");
7927 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7932 strcat (buf
, "untagged enum ");
7936 strcat (buf
, "void ");
7941 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7946 tree chain
= protocol_list
;
7953 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7954 chain
= TREE_CHAIN (chain
);
7970 /* Given a tree node, produce a printable description of it in the given
7971 buffer, overwriting the buffer. */
7974 gen_declaration (atype_or_adecl
, buf
)
7975 tree atype_or_adecl
;
7979 gen_declaration_1 (atype_or_adecl
, buf
);
7983 /* Given a tree node, append a printable description to the end of the
7987 gen_declaration_1 (atype_or_adecl
, buf
)
7988 tree atype_or_adecl
;
7993 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7995 tree declspecs
; /* "identifier_node", "record_type" */
7996 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7998 /* We have a "raw", abstract declarator (typename). */
7999 declarator
= TREE_VALUE (atype_or_adecl
);
8000 declspecs
= TREE_PURPOSE (atype_or_adecl
);
8002 gen_declspecs (declspecs
, buf
, 1);
8006 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
8013 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
8014 tree declarator
; /* "array_type", "function_type", "pointer_type". */
8016 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
8017 || TREE_CODE (atype_or_adecl
) == PARM_DECL
8018 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
8019 atype
= TREE_TYPE (atype_or_adecl
);
8021 /* Assume we have a *_type node. */
8022 atype
= atype_or_adecl
;
8024 if (is_complex_decl (atype
))
8028 /* Get the declaration specifier; it is at the end of the list. */
8029 declarator
= chain
= atype
;
8031 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
8032 while (is_complex_decl (chain
));
8039 declarator
= NULL_TREE
;
8042 gen_declspecs (declspecs
, buf
, 0);
8044 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
8045 || TREE_CODE (atype_or_adecl
) == PARM_DECL
8046 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
8048 const char *decl_name
=
8049 (DECL_NAME (atype_or_adecl
)
8050 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
8055 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
8058 else if (decl_name
[0])
8061 strcat (buf
, decl_name
);
8064 else if (declarator
)
8067 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
8072 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8074 /* Given a method tree, put a printable description into the given
8075 buffer (overwriting) and return a pointer to the buffer. */
8078 gen_method_decl (method
, buf
)
8085 if (RAW_TYPESPEC (method
) != objc_object_reference
)
8088 gen_declaration_1 (TREE_TYPE (method
), buf
);
8092 chain
= METHOD_SEL_ARGS (method
);
8095 /* We have a chain of keyword_decls. */
8098 if (KEYWORD_KEY_NAME (chain
))
8099 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8102 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
8105 gen_declaration_1 (TREE_TYPE (chain
), buf
);
8109 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8110 if ((chain
= TREE_CHAIN (chain
)))
8115 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
8116 strcat (buf
, ", ...");
8117 else if (METHOD_ADD_ARGS (method
))
8119 /* We have a tree list node as generate by get_parm_info. */
8120 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8122 /* Know we have a chain of parm_decls. */
8126 gen_declaration_1 (chain
, buf
);
8127 chain
= TREE_CHAIN (chain
);
8133 /* We have a unary selector. */
8134 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8142 dump_interface (fp
, chain
)
8146 char *buf
= (char *)xmalloc (256);
8147 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8148 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8149 tree nst_methods
= CLASS_NST_METHODS (chain
);
8150 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8152 fprintf (fp
, "\n@interface %s", my_name
);
8154 if (CLASS_SUPER_NAME (chain
))
8156 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8157 fprintf (fp
, " : %s\n", super_name
);
8164 fprintf (fp
, "{\n");
8167 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8168 ivar_decls
= TREE_CHAIN (ivar_decls
);
8171 fprintf (fp
, "}\n");
8176 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8177 nst_methods
= TREE_CHAIN (nst_methods
);
8182 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8183 cls_methods
= TREE_CHAIN (cls_methods
);
8185 fprintf (fp
, "\n@end");
8188 /* Demangle function for Objective-C */
8190 objc_demangle (mangled
)
8191 const char *mangled
;
8193 char *demangled
, *cp
;
8195 if (mangled
[0] == '_' &&
8196 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8199 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8200 if (mangled
[1] == 'i')
8201 *cp
++ = '-'; /* for instance method */
8203 *cp
++ = '+'; /* for class method */
8204 *cp
++ = '['; /* opening left brace */
8205 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8206 while (*cp
&& *cp
== '_')
8207 cp
++; /* skip any initial underbars in class name */
8208 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8211 free(demangled
); /* not mangled name */
8214 if (cp
[1] == '_') /* easy case: no category name */
8216 *cp
++ = ' '; /* replace two '_' with one ' ' */
8217 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8221 *cp
++ = '('; /* less easy case: category name */
8222 cp
= strchr(cp
, '_');
8225 free(demangled
); /* not mangled name */
8229 *cp
++ = ' '; /* overwriting 1st char of method name... */
8230 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8232 while (*cp
&& *cp
== '_')
8233 cp
++; /* skip any initial underbars in method name */
8236 *cp
= ':'; /* replace remaining '_' with ':' */
8237 *cp
++ = ']'; /* closing right brace */
8238 *cp
++ = 0; /* string terminator */
8242 return mangled
; /* not an objc mangled name */
8246 objc_printable_name (decl
, kind
)
8248 int kind ATTRIBUTE_UNUSED
;
8250 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8256 /* Add the special tree codes of Objective C to the tables. */
8258 #define LAST_CODE LAST_C_TREE_CODE
8260 gcc_obstack_init (&util_obstack
);
8261 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8263 memcpy (tree_code_type
+ (int) LAST_CODE
,
8264 objc_tree_code_type
,
8265 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8266 memcpy (tree_code_length
+ (int) LAST_CODE
,
8267 objc_tree_code_length
,
8268 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8269 memcpy (tree_code_name
+ (int) LAST_CODE
,
8270 objc_tree_code_name
,
8271 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8273 errbuf
= (char *)xmalloc (BUFSIZE
);
8275 synth_module_prologue ();
8277 /* Change the default error function */
8278 save_lang_status
= &push_c_function_context
;
8279 restore_lang_status
= &pop_c_function_context
;
8280 mark_lang_status
= &mark_c_function_context
;
8281 decl_printable_name
= objc_printable_name
;
8282 lang_expand_expr
= c_expand_expr
;
8283 lang_expand_decl_stmt
= c_expand_decl_stmt
;
8289 struct imp_entry
*impent
;
8291 /* The internally generated initializers appear to have missing braces.
8292 Don't warn about this. */
8293 int save_warn_missing_braces
= warn_missing_braces
;
8294 warn_missing_braces
= 0;
8296 /* A missing @end may not be detected by the parser. */
8297 if (objc_implementation_context
)
8299 warning ("`@end' missing in implementation context");
8300 finish_class (implementation_context
);
8301 objc_ivar_chain
= NULL_TREE
;
8302 objc_implementation_context
= NULL_TREE
;
8305 generate_forward_declaration_to_string_table ();
8307 #ifdef OBJC_PROLOGUE
8311 /* Process the static instances here because initialization of objc_symtab
8313 if (objc_static_instances
)
8314 generate_static_references ();
8316 if (implementation_context
|| class_names_chain
8317 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8318 generate_objc_symtab_decl ();
8320 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8322 implementation_context
= impent
->imp_context
;
8323 implementation_template
= impent
->imp_template
;
8325 UOBJC_CLASS_decl
= impent
->class_decl
;
8326 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8328 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8330 /* all of the following reference the string pool... */
8331 generate_ivar_lists ();
8332 generate_dispatch_tables ();
8333 generate_shared_structures ();
8337 generate_dispatch_tables ();
8338 generate_category (implementation_context
);
8342 /* If we are using an array of selectors, we must always
8343 finish up the array decl even if no selectors were used. */
8344 if (! flag_next_runtime
|| sel_ref_chain
)
8345 build_selector_translation_table ();
8348 generate_protocols ();
8350 if (implementation_context
|| class_names_chain
|| objc_static_instances
8351 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8353 /* Arrange for Objc data structures to be initialized at run time. */
8354 rtx init_sym
= build_module_descriptor ();
8355 if (init_sym
&& targetm
.have_ctors_dtors
)
8356 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8359 /* Dump the class references. This forces the appropriate classes
8360 to be linked into the executable image, preserving unix archive
8361 semantics. This can be removed when we move to a more dynamically
8362 linked environment. */
8364 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8366 handle_class_ref (chain
);
8367 if (TREE_PURPOSE (chain
))
8368 generate_classref_translation_entry (chain
);
8371 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8372 handle_impent (impent
);
8374 /* Dump the string table last. */
8376 generate_strings ();
8378 if (flag_gen_declaration
)
8380 add_class (implementation_context
);
8381 dump_interface (gen_declaration_file
, implementation_context
);
8389 /* Run through the selector hash tables and print a warning for any
8390 selector which has multiple methods. */
8392 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8393 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8396 tree meth
= hsh
->key
;
8397 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8401 warning ("potential selector conflict for method `%s'",
8402 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8403 warn_with_method ("found", type
, meth
);
8404 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8405 warn_with_method ("found", type
, loop
->value
);
8408 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8409 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8412 tree meth
= hsh
->key
;
8413 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8417 warning ("potential selector conflict for method `%s'",
8418 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8419 warn_with_method ("found", type
, meth
);
8420 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8421 warn_with_method ("found", type
, loop
->value
);
8425 warn_missing_braces
= save_warn_missing_braces
;
8428 /* Subroutines of finish_objc. */
8431 generate_classref_translation_entry (chain
)
8434 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8437 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8439 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8440 expr
= build_c_cast (type
, expr
); /* cast! */
8442 name
= DECL_NAME (TREE_PURPOSE (chain
));
8444 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8446 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8447 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8449 /* The decl that is returned from start_decl is the one that we
8450 forward declared in build_class_reference. */
8451 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8452 DECL_CONTEXT (decl
) = NULL_TREE
;
8453 finish_decl (decl
, expr
, NULL_TREE
);
8458 handle_class_ref (chain
)
8461 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8462 char *string
= (char *) alloca (strlen (name
) + 30);
8466 sprintf (string
, "%sobjc_class_name_%s",
8467 (flag_next_runtime
? "." : "__"), name
);
8469 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8470 if (flag_next_runtime
)
8472 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8477 /* Make a decl for this name, so we can use its address in a tree. */
8478 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8479 DECL_EXTERNAL (decl
) = 1;
8480 TREE_PUBLIC (decl
) = 1;
8483 rest_of_decl_compilation (decl
, 0, 0, 0);
8485 /* Make a decl for the address. */
8486 sprintf (string
, "%sobjc_class_ref_%s",
8487 (flag_next_runtime
? "." : "__"), name
);
8488 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8489 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8490 DECL_INITIAL (decl
) = exp
;
8491 TREE_STATIC (decl
) = 1;
8494 rest_of_decl_compilation (decl
, 0, 0, 0);
8498 handle_impent (impent
)
8499 struct imp_entry
*impent
;
8503 implementation_context
= impent
->imp_context
;
8504 implementation_template
= impent
->imp_template
;
8506 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8508 const char *class_name
=
8509 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8511 string
= (char *) alloca (strlen (class_name
) + 30);
8513 sprintf (string
, "*%sobjc_class_name_%s",
8514 (flag_next_runtime
? "." : "__"), class_name
);
8516 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8518 const char *class_name
=
8519 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8520 const char *class_super_name
=
8521 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8523 string
= (char *) alloca (strlen (class_name
)
8524 + strlen (class_super_name
) + 30);
8526 /* Do the same for categories. Even though no references to
8527 these symbols are generated automatically by the compiler, it
8528 gives you a handle to pull them into an archive by hand. */
8529 sprintf (string
, "*%sobjc_category_name_%s_%s",
8530 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8535 #ifdef ASM_DECLARE_CLASS_REFERENCE
8536 if (flag_next_runtime
)
8538 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8543 /* (Should this be a routine in varasm.c?) */
8544 readonly_data_section ();
8545 assemble_global (string
);
8546 assemble_align (UNITS_PER_WORD
);
8547 assemble_label (string
);
8548 assemble_zeros (UNITS_PER_WORD
);
8552 print_lang_statistics ()
8557 ggc_mark_imp_list (arg
)
8560 struct imp_entry
*impent
;
8562 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8564 ggc_mark_tree (impent
->imp_context
);
8565 ggc_mark_tree (impent
->imp_template
);
8566 ggc_mark_tree (impent
->class_decl
);
8567 ggc_mark_tree (impent
->meta_decl
);
8572 ggc_mark_hash_table (arg
)
8575 hash
*hash_table
= *(hash
**)arg
;
8580 if (hash_table
== NULL
)
8582 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8583 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8585 ggc_mark_tree (hst
->key
);
8586 for (list
= hst
->list
; list
; list
= list
->next
)
8587 ggc_mark_tree (list
->value
);
8591 /* Add GC roots for variables local to this file. */
8593 objc_act_parse_init ()
8595 ggc_add_tree_root (&objc_ellipsis_node
, 1);
8596 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8597 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8598 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8599 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8602 /* Look up ID as an instance variable. */
8604 lookup_objc_ivar (id
)
8609 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8610 /* we have a message to super */
8611 return get_super_receiver ();
8612 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8614 if (is_private (decl
))
8615 return error_mark_node
;
8617 return build_ivar_reference (id
);