1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000, 2001 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
40 - OBJC_INT_SELECTORS */
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
87 /* Define the special tree codes that we use. */
89 /* Table indexed by tree code giving a string containing a character
90 classifying the tree code. Possibilities are
91 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
95 static const char objc_tree_code_type
[] = {
97 #include "objc-tree.def"
101 /* Table indexed by tree code giving number of expression
102 operands beyond the fixed part of the node structure.
103 Not used for types or decls. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
107 static const int objc_tree_code_length
[] = {
109 #include "objc-tree.def"
113 /* Names of tree components.
114 Used for printing out the tree and error messages. */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
117 static const char * const objc_tree_code_name
[] = {
119 #include "objc-tree.def"
123 /* Set up for use of obstacks. */
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
130 /* This obstack is used to accumulate the encoding of a data type. */
131 static struct obstack util_obstack
;
132 /* This points to the beginning of obstack contents,
133 so we can free the whole contents. */
136 /* for encode_method_def */
139 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
140 #define PROTOCOL_VERSION 2
142 #define OBJC_ENCODE_INLINE_DEFS 0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
145 /*** Private Interface (procedures) ***/
147 /* Used by compile_file. */
149 static void init_objc
PARAMS ((void));
150 static void finish_objc
PARAMS ((void));
151 static void objc_post_options
PARAMS ((void));
153 /* Code generation. */
155 static void synth_module_prologue
PARAMS ((void));
156 static tree build_constructor
PARAMS ((tree
, tree
));
157 static const char *build_module_descriptor
PARAMS ((void));
158 static tree init_module_descriptor
PARAMS ((tree
));
159 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
161 static void generate_strings
PARAMS ((void));
162 static tree get_proto_encoding
PARAMS ((tree
));
163 static void build_selector_translation_table
PARAMS ((void));
164 static tree build_ivar_chain
PARAMS ((tree
, int));
166 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
168 static tree build_ivar_template
PARAMS ((void));
169 static tree build_method_template
PARAMS ((void));
170 static tree build_private_template
PARAMS ((tree
));
171 static void build_class_template
PARAMS ((void));
172 static void build_selector_template
PARAMS ((void));
173 static void build_category_template
PARAMS ((void));
174 static tree build_super_template
PARAMS ((void));
175 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
177 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
180 static void synth_forward_declarations
PARAMS ((void));
181 static void generate_ivar_lists
PARAMS ((void));
182 static void generate_dispatch_tables
PARAMS ((void));
183 static void generate_shared_structures
PARAMS ((void));
184 static tree generate_protocol_list
PARAMS ((tree
));
185 static void generate_forward_declaration_to_string_table
PARAMS ((void));
186 static void build_protocol_reference
PARAMS ((tree
));
189 static tree init_selector
PARAMS ((int));
191 static tree build_keyword_selector
PARAMS ((tree
));
192 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
194 static void generate_static_references
PARAMS ((void));
195 static int check_methods_accessible
PARAMS ((tree
, tree
,
197 static void encode_aggregate_within
PARAMS ((tree
, int, int,
199 static const char *objc_demangle
PARAMS ((const char *));
200 static const char *objc_printable_name
PARAMS ((tree
, int));
201 static void objc_expand_function_end
PARAMS ((void));
203 /* Misc. bookkeeping */
205 typedef struct hashed_entry
*hash
;
206 typedef struct hashed_attribute
*attr
;
208 struct hashed_attribute
220 static void hash_init
PARAMS ((void));
221 static void hash_enter
PARAMS ((hash
*, tree
));
222 static hash hash_lookup
PARAMS ((hash
*, tree
));
223 static void hash_add_attr
PARAMS ((hash
, tree
));
224 static tree lookup_method
PARAMS ((tree
, tree
));
225 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
226 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
227 static tree add_class
PARAMS ((tree
));
228 static void add_category
PARAMS ((tree
, tree
));
232 class_names
, /* class, category, protocol, module names */
233 meth_var_names
, /* method and variable names */
234 meth_var_types
/* method and variable type descriptors */
237 static tree add_objc_string
PARAMS ((tree
,
238 enum string_section
));
239 static tree get_objc_string_decl
PARAMS ((tree
,
240 enum string_section
));
241 static tree build_objc_string_decl
PARAMS ((enum string_section
));
242 static tree build_selector_reference_decl
PARAMS ((void));
244 /* Protocol additions. */
246 static tree add_protocol
PARAMS ((tree
));
247 static tree lookup_protocol
PARAMS ((tree
));
248 static tree lookup_and_install_protocols
PARAMS ((tree
));
252 static void encode_type_qualifiers
PARAMS ((tree
));
253 static void encode_pointer
PARAMS ((tree
, int, int));
254 static void encode_array
PARAMS ((tree
, int, int));
255 static void encode_aggregate
PARAMS ((tree
, int, int));
256 static void encode_bitfield
PARAMS ((int));
257 static void encode_type
PARAMS ((tree
, int, int));
258 static void encode_field_decl
PARAMS ((tree
, int, int));
260 static void really_start_method
PARAMS ((tree
, tree
));
261 static int comp_method_with_proto
PARAMS ((tree
, tree
));
262 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
263 static tree get_arg_type_list
PARAMS ((tree
, int, int));
264 static tree expr_last
PARAMS ((tree
));
266 /* Utilities for debugging and error diagnostics. */
268 static void warn_with_method
PARAMS ((const char *, int, tree
));
269 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
270 static char *gen_method_decl
PARAMS ((tree
, char *));
271 static char *gen_declaration
PARAMS ((tree
, char *));
272 static char *gen_declarator
PARAMS ((tree
, char *,
274 static int is_complex_decl
PARAMS ((tree
));
275 static void adorn_decl
PARAMS ((tree
, char *));
276 static void dump_interface
PARAMS ((FILE *, tree
));
278 /* Everything else. */
280 static tree define_decl
PARAMS ((tree
, tree
));
281 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
282 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
283 static tree create_builtin_decl
PARAMS ((enum tree_code
,
284 tree
, const char *));
285 static tree my_build_string
PARAMS ((int, const char *));
286 static void build_objc_symtab_template
PARAMS ((void));
287 static tree init_def_list
PARAMS ((tree
));
288 static tree init_objc_symtab
PARAMS ((tree
));
289 static void forward_declare_categories
PARAMS ((void));
290 static void generate_objc_symtab_decl
PARAMS ((void));
291 static tree build_selector
PARAMS ((tree
));
293 static tree build_msg_pool_reference
PARAMS ((int));
295 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
296 static tree build_selector_reference
PARAMS ((tree
));
297 static tree build_class_reference_decl
PARAMS ((void));
298 static void add_class_reference
PARAMS ((tree
));
299 static tree objc_copy_list
PARAMS ((tree
, tree
*));
300 static tree build_protocol_template
PARAMS ((void));
301 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
302 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
303 static tree build_method_prototype_template
PARAMS ((void));
304 static int forwarding_offset
PARAMS ((tree
));
305 static tree encode_method_prototype
PARAMS ((tree
, tree
));
306 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
308 static void generate_method_descriptors
PARAMS ((tree
));
309 static tree build_tmp_function_decl
PARAMS ((void));
310 static void hack_method_prototype
PARAMS ((tree
, tree
));
311 static void generate_protocol_references
PARAMS ((tree
));
312 static void generate_protocols
PARAMS ((void));
313 static void check_ivars
PARAMS ((tree
, tree
));
314 static tree build_ivar_list_template
PARAMS ((tree
, int));
315 static tree build_method_list_template
PARAMS ((tree
, int));
316 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
317 static tree generate_ivars_list
PARAMS ((tree
, const char *,
319 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
320 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
322 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
323 tree
, int, tree
, tree
,
325 static void generate_category
PARAMS ((tree
));
326 static int is_objc_type_qualifier
PARAMS ((tree
));
327 static tree adjust_type_for_id_default
PARAMS ((tree
));
328 static tree check_duplicates
PARAMS ((hash
));
329 static tree receiver_is_class_object
PARAMS ((tree
));
330 static int check_methods
PARAMS ((tree
, tree
, int));
331 static int conforms_to_protocol
PARAMS ((tree
, tree
));
332 static void check_protocols
PARAMS ((tree
, const char *,
334 static tree encode_method_def
PARAMS ((tree
));
335 static void gen_declspecs
PARAMS ((tree
, char *, int));
336 static void generate_classref_translation_entry
PARAMS ((tree
));
337 static void handle_class_ref
PARAMS ((tree
));
338 static void generate_struct_by_value_array
PARAMS ((void))
340 static void objc_act_parse_init
PARAMS ((void));
341 static void ggc_mark_imp_list
PARAMS ((void *));
342 static void ggc_mark_hash_table
PARAMS ((void *));
344 /*** Private Interface (data) ***/
346 /* Reserved tag definitions. */
349 #define TAG_OBJECT "objc_object"
350 #define TAG_CLASS "objc_class"
351 #define TAG_SUPER "objc_super"
352 #define TAG_SELECTOR "objc_selector"
354 #define UTAG_CLASS "_objc_class"
355 #define UTAG_IVAR "_objc_ivar"
356 #define UTAG_IVAR_LIST "_objc_ivar_list"
357 #define UTAG_METHOD "_objc_method"
358 #define UTAG_METHOD_LIST "_objc_method_list"
359 #define UTAG_CATEGORY "_objc_category"
360 #define UTAG_MODULE "_objc_module"
361 #define UTAG_STATICS "_objc_statics"
362 #define UTAG_SYMTAB "_objc_symtab"
363 #define UTAG_SUPER "_objc_super"
364 #define UTAG_SELECTOR "_objc_selector"
366 #define UTAG_PROTOCOL "_objc_protocol"
367 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
368 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
369 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
371 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
372 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
374 static const char *constant_string_class_name
= NULL
;
376 static const char *TAG_GETCLASS
;
377 static const char *TAG_GETMETACLASS
;
378 static const char *TAG_MSGSEND
;
379 static const char *TAG_MSGSENDSUPER
;
380 static const char *TAG_EXECCLASS
;
382 /* Set by `continue_class' and checked by `is_public'. */
384 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
385 #define TYPED_OBJECT(type) \
386 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
388 tree objc_ellipsis_node
;
393 OCTI_STATIC_NST_DECL
,
399 OCTI_UMSG_SUPER_DECL
,
401 OCTI_GET_MCLASS_DECL
,
415 OCTI_CLS_NAMES_CHAIN
,
416 OCTI_METH_VAR_NAMES_CHAIN
,
417 OCTI_METH_VAR_TYPES_CHAIN
,
439 OCTI_UUCLS_SUPER_REF
,
457 static tree objc_global_trees
[OCTI_MAX
];
459 /* List of classes with list of their static instances. */
460 #define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
462 /* The declaration of the array administrating the static instances. */
463 #define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
465 /* Some commonly used instances of "identifier_node". */
467 #define self_id objc_global_trees[OCTI_SELF_ID]
468 #define ucmd_id objc_global_trees[OCTI_UCMD_ID]
469 #define unused_list objc_global_trees[OCTI_UNUSED_LIST]
471 #define self_decl objc_global_trees[OCTI_SELF_DECL]
472 #define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
473 #define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
474 #define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
475 #define objc_get_meta_class_decl \
476 objc_global_trees[OCTI_GET_MCLASS_DECL]
478 #define super_type objc_global_trees[OCTI_SUPER_TYPE]
479 #define selector_type objc_global_trees[OCTI_SEL_TYPE]
480 #define id_type objc_global_trees[OCTI_ID_TYPE]
481 #define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
482 #define instance_type objc_global_trees[OCTI_NST_TYPE]
483 #define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
485 /* Type checking macros. */
487 #define IS_ID(TYPE) \
488 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
489 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
490 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
491 #define IS_SUPER(TYPE) \
492 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
494 #define class_chain objc_global_trees[OCTI_CLS_CHAIN]
495 #define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
496 #define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
497 #define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
499 /* Chains to manage selectors that are referenced and defined in the
502 #define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
503 #define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
505 /* Chains to manage uniquing of strings. */
507 #define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
508 #define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
509 #define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
511 /* Hash tables to manage the global pool of method prototypes. */
513 static hash
*nst_method_hash_list
= 0;
514 static hash
*cls_method_hash_list
= 0;
516 /* Backend data declarations. */
518 #define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
519 #define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
520 #define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
521 #define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
522 #define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
523 #define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
524 #define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
525 #define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
526 #define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
527 #define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
529 /* The following are used when compiling a class implementation.
530 implementation_template will normally be an interface, however if
531 none exists this will be equal to implementation_context...it is
532 set in start_class. */
534 #define implementation_context objc_global_trees[OCTI_IMPL_CTX]
535 #define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
539 struct imp_entry
*next
;
542 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
543 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
546 static void handle_impent
PARAMS ((struct imp_entry
*));
548 static struct imp_entry
*imp_list
= 0;
549 static int imp_count
= 0; /* `@implementation' */
550 static int cat_count
= 0; /* `@category' */
552 #define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
553 #define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
554 #define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
555 #define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
556 #define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
557 #define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
558 #define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
560 #define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
561 #define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
562 #define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
563 #define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
564 #define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
565 #define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
567 #define objc_object_id objc_global_trees[OCTI_OBJ_ID]
568 #define objc_class_id objc_global_trees[OCTI_CLS_ID]
569 #define objc_id_id objc_global_trees[OCTI_ID_ID]
570 #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
571 #define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
572 #define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
574 #define method_context objc_global_trees[OCTI_METH_CTX]
575 static int method_slot
= 0; /* Used by start_method_def, */
579 static char *errbuf
; /* Buffer for error diagnostics */
581 /* Data imported from tree.c. */
583 extern enum debug_info_type write_symbols
;
585 /* Data imported from toplev.c. */
587 extern const char *dump_base_name
;
589 /* Generate code for GNU or NeXT runtime environment. */
591 #ifdef NEXT_OBJC_RUNTIME
592 int flag_next_runtime
= 1;
594 int flag_next_runtime
= 0;
597 int flag_typed_selectors
;
599 /* Open and close the file for outputting class declarations, if requested. */
601 int flag_gen_declaration
= 0;
603 FILE *gen_declaration_file
;
605 /* Warn if multiple methods are seen for the same selector, but with
606 different argument types. */
608 int warn_selector
= 0;
610 /* Warn if methods required by a protocol are not implemented in the
611 class adopting it. When turned off, methods inherited to that
612 class are also considered implemented */
614 int flag_warn_protocol
= 1;
616 /* Tells "encode_pointer/encode_aggregate" whether we are generating
617 type descriptors for instance variables (as opposed to methods).
618 Type descriptors for instance variables contain more information
619 than methods (for static typing and embedded structures). This
620 was added to support features being planned for dbkit2. */
622 static int generating_instance_variables
= 0;
624 /* Tells the compiler that this is a special run. Do not perform
625 any compiling, instead we are to test some platform dependent
626 features and output a C header file with appropriate definitions. */
628 static int print_struct_values
= 0;
630 /* Each front end provides its own. */
631 struct lang_hooks lang_hooks
= {objc_post_options
};
633 /* Post-switch processing. */
639 /* Some platforms pass small structures through registers versus through
640 an invisible pointer. Determine at what size structure is the
641 transition point between the two possibilities. */
644 generate_struct_by_value_array ()
647 tree field_decl
, field_decl_chain
;
649 int aggregate_in_mem
[32];
652 /* Presumbaly no platform passes 32 byte structures in a register. */
653 for (i
= 1; i
< 32; i
++)
657 /* Create an unnamed struct that has `i' character components */
658 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
660 strcpy (buffer
, "c1");
661 field_decl
= create_builtin_decl (FIELD_DECL
,
664 field_decl_chain
= field_decl
;
666 for (j
= 1; j
< i
; j
++)
668 sprintf (buffer
, "c%d", j
+ 1);
669 field_decl
= create_builtin_decl (FIELD_DECL
,
672 chainon (field_decl_chain
, field_decl
);
674 finish_struct (type
, field_decl_chain
, NULL_TREE
);
676 aggregate_in_mem
[i
] = aggregate_value_p (type
);
677 if (!aggregate_in_mem
[i
])
681 /* We found some structures that are returned in registers instead of memory
682 so output the necessary data. */
685 for (i
= 31; i
>= 0; i
--)
686 if (!aggregate_in_mem
[i
])
688 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
690 /* The first member of the structure is always 0 because we don't handle
691 structures with 0 members */
692 printf ("static int struct_forward_array[] = {\n 0");
694 for (j
= 1; j
<= i
; j
++)
695 printf (", %d", aggregate_in_mem
[j
]);
705 parse_in
= cpp_create_reader (CLK_OBJC
);
706 c_language
= clk_objective_c
;
712 /* Force the line number back to 0; check_newline will have
713 raised it to 1, which will make the builtin functions appear
714 not to be built in. */
717 c_common_lang_init ();
719 /* If gen_declaration desired, open the output file. */
720 if (flag_gen_declaration
)
722 register char * const dumpname
= concat (dumpname
, ".decl", NULL
);
723 gen_declaration_file
= fopen (dumpname
, "w");
724 if (gen_declaration_file
== 0)
725 pfatal_with_name (dumpname
);
729 if (flag_next_runtime
)
731 TAG_GETCLASS
= "objc_getClass";
732 TAG_GETMETACLASS
= "objc_getMetaClass";
733 TAG_MSGSEND
= "objc_msgSend";
734 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
735 TAG_EXECCLASS
= "__objc_execClass";
739 TAG_GETCLASS
= "objc_get_class";
740 TAG_GETMETACLASS
= "objc_get_meta_class";
741 TAG_MSGSEND
= "objc_msg_lookup";
742 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
743 TAG_EXECCLASS
= "__objc_exec_class";
744 flag_typed_selectors
= 1;
747 objc_ellipsis_node
= make_node (ERROR_MARK
);
751 if (print_struct_values
)
752 generate_struct_by_value_array ();
754 objc_act_parse_init ();
761 finish_objc (); /* Objective-C finalization */
763 if (gen_declaration_file
)
764 fclose (gen_declaration_file
);
779 lang_decode_option (argc
, argv
)
783 const char *p
= argv
[0];
785 if (!strcmp (p
, "-gen-decls"))
786 flag_gen_declaration
= 1;
787 else if (!strcmp (p
, "-Wselector"))
789 else if (!strcmp (p
, "-Wno-selector"))
791 else if (!strcmp (p
, "-Wprotocol"))
792 flag_warn_protocol
= 1;
793 else if (!strcmp (p
, "-Wno-protocol"))
794 flag_warn_protocol
= 0;
795 else if (!strcmp (p
, "-fgnu-runtime"))
796 flag_next_runtime
= 0;
797 else if (!strcmp (p
, "-fno-next-runtime"))
798 flag_next_runtime
= 0;
799 else if (!strcmp (p
, "-fno-gnu-runtime"))
800 flag_next_runtime
= 1;
801 else if (!strcmp (p
, "-fnext-runtime"))
802 flag_next_runtime
= 1;
803 else if (!strcmp (p
, "-print-objc-runtime-info"))
804 print_struct_values
= 1;
805 #define CSTSTRCLASS "-fconstant-string-class="
806 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
807 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
808 error ("no class name specified as argument to -fconstant-string-class");
809 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
813 return c_decode_option (argc
, argv
);
818 /* used by print-tree.c */
821 lang_print_xnode (file
, node
, indent
)
822 FILE *file ATTRIBUTE_UNUSED
;
823 tree node ATTRIBUTE_UNUSED
;
824 int indent ATTRIBUTE_UNUSED
;
830 define_decl (declarator
, declspecs
)
834 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
835 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
839 /* Return 1 if LHS and RHS are compatible types for assignment or
840 various other operations. Return 0 if they are incompatible, and
841 return -1 if we choose to not decide. When the operation is
842 REFLEXIVE, check for compatibility in either direction.
844 For statically typed objects, an assignment of the form `a' = `b'
848 `a' and `b' are the same class type, or
849 `a' and `b' are of class types A and B such that B is a descendant of A. */
852 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
856 return objc_comptypes (lhs
, rhs
, reflexive
);
860 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
868 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
870 p
= TREE_VALUE (rproto
);
872 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
874 if ((fnd
= lookup_method (class_meth
875 ? PROTOCOL_CLS_METHODS (p
)
876 : PROTOCOL_NST_METHODS (p
), sel_name
)))
878 else if (PROTOCOL_LIST (p
))
879 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
880 sel_name
, class_meth
);
884 ; /* An identifier...if we could not find a protocol. */
895 lookup_protocol_in_reflist (rproto_list
, lproto
)
901 /* Make sure the protocol is support by the object on the rhs. */
902 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
905 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
907 p
= TREE_VALUE (rproto
);
909 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
914 else if (PROTOCOL_LIST (p
))
915 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
924 ; /* An identifier...if we could not find a protocol. */
930 /* Return 1 if LHS and RHS are compatible types for assignment
931 or various other operations. Return 0 if they are incompatible,
932 and return -1 if we choose to not decide. When the operation
933 is REFLEXIVE, check for compatibility in either direction. */
936 objc_comptypes (lhs
, rhs
, reflexive
)
941 /* New clause for protocols. */
943 if (TREE_CODE (lhs
) == POINTER_TYPE
944 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
945 && TREE_CODE (rhs
) == POINTER_TYPE
946 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
948 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
949 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
953 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
954 tree rproto
, rproto_list
;
959 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
961 /* Make sure the protocol is supported by the object
963 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
965 p
= TREE_VALUE (lproto
);
966 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
969 warning ("object does not conform to the `%s' protocol",
970 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
973 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
975 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
978 /* Make sure the protocol is supported by the object
980 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
982 p
= TREE_VALUE (lproto
);
984 rinter
= lookup_interface (rname
);
986 while (rinter
&& !rproto
)
990 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
991 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
993 /* Check for protocols adopted by categories. */
994 cat
= CLASS_CATEGORY_LIST (rinter
);
995 while (cat
&& !rproto
)
997 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
998 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
1000 cat
= CLASS_CATEGORY_LIST (cat
);
1003 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
1007 warning ("class `%s' does not implement the `%s' protocol",
1008 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
1009 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1013 /* May change...based on whether there was any mismatch */
1016 else if (rhs_is_proto
)
1017 /* Lhs is not a protocol...warn if it is statically typed */
1018 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
1021 /* Defer to comptypes .*/
1025 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
1026 ; /* Fall thru. This is the case we have been handling all along */
1028 /* Defer to comptypes. */
1031 /* `id' = `<class> *', `<class> *' = `id' */
1033 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
1034 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
1037 /* `id' = `Class', `Class' = `id' */
1039 else if ((TYPE_NAME (lhs
) == objc_object_id
1040 && TYPE_NAME (rhs
) == objc_class_id
)
1041 || (TYPE_NAME (lhs
) == objc_class_id
1042 && TYPE_NAME (rhs
) == objc_object_id
))
1045 /* `<class> *' = `<class> *' */
1047 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1049 tree lname
= TYPE_NAME (lhs
);
1050 tree rname
= TYPE_NAME (rhs
);
1056 /* If the left hand side is a super class of the right hand side,
1058 for (inter
= lookup_interface (rname
); inter
;
1059 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1060 if (lname
== CLASS_SUPER_NAME (inter
))
1063 /* Allow the reverse when reflexive. */
1065 for (inter
= lookup_interface (lname
); inter
;
1066 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1067 if (rname
== CLASS_SUPER_NAME (inter
))
1073 /* Defer to comptypes. */
1077 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1080 objc_check_decl (decl
)
1083 tree type
= TREE_TYPE (decl
);
1085 if (TREE_CODE (type
) == RECORD_TYPE
1086 && TREE_STATIC_TEMPLATE (type
)
1087 && type
!= constant_string_type
)
1089 error_with_decl (decl
, "`%s' cannot be statically allocated");
1090 fatal ("statically allocated objects not supported");
1095 maybe_objc_check_decl (decl
)
1098 objc_check_decl (decl
);
1101 /* Implement static typing. At this point, we know we have an interface. */
1104 get_static_reference (interface
, protocols
)
1108 tree type
= xref_tag (RECORD_TYPE
, interface
);
1112 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1114 t
= copy_node (type
);
1115 TYPE_BINFO (t
) = make_tree_vec (2);
1117 /* Add this type to the chain of variants of TYPE. */
1118 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1119 TYPE_NEXT_VARIANT (m
) = t
;
1121 /* Look up protocols and install in lang specific list. */
1122 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1124 /* This forces a new pointer type to be created later
1125 (in build_pointer_type)...so that the new template
1126 we just created will actually be used...what a hack! */
1127 if (TYPE_POINTER_TO (t
))
1128 TYPE_POINTER_TO (t
) = 0;
1137 get_object_reference (protocols
)
1140 tree type_decl
= lookup_name (objc_id_id
);
1143 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1145 type
= TREE_TYPE (type_decl
);
1146 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1147 warning ("Unexpected type for `id' (%s)",
1148 gen_declaration (type
, errbuf
));
1151 fatal ("Undefined type `id', please import <objc/objc.h>");
1153 /* This clause creates a new pointer type that is qualified with
1154 the protocol specification...this info is used later to do more
1155 elaborate type checking. */
1159 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1161 t
= copy_node (type
);
1162 TYPE_BINFO (t
) = make_tree_vec (2);
1164 /* Add this type to the chain of variants of TYPE. */
1165 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1166 TYPE_NEXT_VARIANT (m
) = t
;
1168 /* Look up protocols...and install in lang specific list */
1169 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1171 /* This forces a new pointer type to be created later
1172 (in build_pointer_type)...so that the new template
1173 we just created will actually be used...what a hack! */
1174 if (TYPE_POINTER_TO (t
))
1175 TYPE_POINTER_TO (t
) = NULL
;
1183 lookup_and_install_protocols (protocols
)
1188 tree return_value
= protocols
;
1190 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1192 tree ident
= TREE_VALUE (proto
);
1193 tree p
= lookup_protocol (ident
);
1197 error ("Cannot find protocol declaration for `%s'",
1198 IDENTIFIER_POINTER (ident
));
1200 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1202 return_value
= TREE_CHAIN (proto
);
1206 /* Replace identifier with actual protocol node. */
1207 TREE_VALUE (proto
) = p
;
1212 return return_value
;
1215 /* Create and push a decl for a built-in external variable or field NAME.
1217 TYPE is its data type. */
1220 create_builtin_decl (code
, type
, name
)
1221 enum tree_code code
;
1225 tree decl
= build_decl (code
, get_identifier (name
), type
);
1227 if (code
== VAR_DECL
)
1229 TREE_STATIC (decl
) = 1;
1230 make_decl_rtl (decl
, 0, 1);
1234 DECL_ARTIFICIAL (decl
) = 1;
1238 /* Purpose: "play" parser, creating/installing representations
1239 of the declarations that are required by Objective-C.
1243 type_spec--------->sc_spec
1244 (tree_list) (tree_list)
1247 identifier_node identifier_node */
1250 synth_module_prologue ()
1255 /* Defined in `objc.h' */
1256 objc_object_id
= get_identifier (TAG_OBJECT
);
1258 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1260 id_type
= build_pointer_type (objc_object_reference
);
1262 objc_id_id
= get_identifier (TYPE_ID
);
1263 objc_class_id
= get_identifier (TAG_CLASS
);
1265 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1266 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1267 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1269 /* Declare type of selector-objects that represent an operation name. */
1271 #ifdef OBJC_INT_SELECTORS
1272 /* `unsigned int' */
1273 selector_type
= unsigned_type_node
;
1275 /* `struct objc_selector *' */
1277 = build_pointer_type (xref_tag (RECORD_TYPE
,
1278 get_identifier (TAG_SELECTOR
)));
1279 #endif /* not OBJC_INT_SELECTORS */
1281 /* Forward declare type, or else the prototype for msgSendSuper will
1284 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1285 get_identifier (TAG_SUPER
)));
1288 /* id objc_msgSend (id, SEL, ...); */
1291 = build_function_type (id_type
,
1292 tree_cons (NULL_TREE
, id_type
,
1293 tree_cons (NULL_TREE
, selector_type
,
1296 if (! flag_next_runtime
)
1298 umsg_decl
= build_decl (FUNCTION_DECL
,
1299 get_identifier (TAG_MSGSEND
), temp_type
);
1300 DECL_EXTERNAL (umsg_decl
) = 1;
1301 TREE_PUBLIC (umsg_decl
) = 1;
1302 DECL_INLINE (umsg_decl
) = 1;
1303 DECL_ARTIFICIAL (umsg_decl
) = 1;
1305 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1306 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1308 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1309 pushdecl (umsg_decl
);
1312 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1314 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1317 = build_function_type (id_type
,
1318 tree_cons (NULL_TREE
, super_p
,
1319 tree_cons (NULL_TREE
, selector_type
,
1322 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1323 temp_type
, 0, NOT_BUILT_IN
, 0);
1325 /* id objc_getClass (const char *); */
1327 temp_type
= build_function_type (id_type
,
1328 tree_cons (NULL_TREE
,
1329 const_string_type_node
,
1330 tree_cons (NULL_TREE
, void_type_node
,
1334 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1336 /* id objc_getMetaClass (const char *); */
1338 objc_get_meta_class_decl
1339 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1341 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1343 if (! flag_next_runtime
)
1345 if (flag_typed_selectors
)
1347 /* Suppress outputting debug symbols, because
1348 dbxout_init hasn'r been called yet. */
1349 enum debug_info_type save_write_symbols
= write_symbols
;
1350 write_symbols
= NO_DEBUG
;
1352 build_selector_template ();
1353 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1355 write_symbols
= save_write_symbols
;
1358 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1360 layout_type (temp_type
);
1361 UOBJC_SELECTOR_TABLE_decl
1362 = create_builtin_decl (VAR_DECL
, temp_type
,
1363 "_OBJC_SELECTOR_TABLE");
1365 /* Avoid warning when not sending messages. */
1366 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1369 generate_forward_declaration_to_string_table ();
1371 /* Forward declare constant_string_id and constant_string_type. */
1372 if (!constant_string_class_name
)
1373 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1375 constant_string_id
= get_identifier (constant_string_class_name
);
1376 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1379 /* Custom build_string which sets TREE_TYPE! */
1382 my_build_string (len
, str
)
1387 tree a_string
= build_string (len
, str
);
1389 /* Some code from combine_strings, which is local to c-parse.y. */
1390 if (TREE_TYPE (a_string
) == int_array_type_node
)
1393 TREE_TYPE (a_string
)
1394 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1395 build_index_type (build_int_2 (len
- 1, 0)));
1397 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1398 TREE_STATIC (a_string
) = 1;
1403 /* Given a chain of STRING_CST's, build a static instance of
1404 NXConstanString which points at the concatenation of those strings.
1405 We place the string object in the __string_objects section of the
1406 __OBJC segment. The Objective-C runtime will initialize the isa
1407 pointers of the string objects to point at the NXConstandString class
1411 build_objc_string_object (strings
)
1414 tree string
, initlist
, constructor
;
1417 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1419 error ("Cannot find interface declaration for `%s'",
1420 IDENTIFIER_POINTER (constant_string_id
));
1421 return error_mark_node
;
1424 add_class_reference (constant_string_id
);
1426 string
= combine_strings (strings
);
1427 TREE_SET_CODE (string
, STRING_CST
);
1428 length
= TREE_STRING_LENGTH (string
) - 1;
1430 /* & ((NXConstantString) {0, string, length}) */
1432 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1434 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1436 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1437 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1439 if (!flag_next_runtime
)
1442 = objc_add_static_instance (constructor
, constant_string_type
);
1445 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1448 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1451 objc_add_static_instance (constructor
, class_decl
)
1452 tree constructor
, class_decl
;
1454 static int num_static_inst
;
1458 /* Find the list of static instances for the CLASS_DECL. Create one if
1460 for (chain
= &objc_static_instances
;
1461 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1462 chain
= &TREE_CHAIN (*chain
));
1465 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1466 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1469 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1470 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1471 DECL_COMMON (decl
) = 1;
1472 TREE_STATIC (decl
) = 1;
1473 DECL_ARTIFICIAL (decl
) = 1;
1474 pushdecl_top_level (decl
);
1475 rest_of_decl_compilation (decl
, 0, 1, 0);
1477 /* Do this here so it gets output later instead of possibly
1478 inside something else we are writing. */
1479 DECL_INITIAL (decl
) = constructor
;
1481 /* Add the DECL to the head of this CLASS' list. */
1482 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1487 /* Build a static constant CONSTRUCTOR
1488 with type TYPE and elements ELTS. */
1491 build_constructor (type
, elts
)
1494 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1496 TREE_CONSTANT (constructor
) = 1;
1497 TREE_STATIC (constructor
) = 1;
1498 TREE_READONLY (constructor
) = 1;
1503 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1505 /* Predefine the following data type:
1513 void *defs[cls_def_cnt + cat_def_cnt];
1517 build_objc_symtab_template ()
1519 tree field_decl
, field_decl_chain
, index
;
1521 objc_symtab_template
1522 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1524 /* long sel_ref_cnt; */
1526 field_decl
= create_builtin_decl (FIELD_DECL
,
1527 long_integer_type_node
,
1529 field_decl_chain
= field_decl
;
1533 field_decl
= create_builtin_decl (FIELD_DECL
,
1534 build_pointer_type (selector_type
),
1536 chainon (field_decl_chain
, field_decl
);
1538 /* short cls_def_cnt; */
1540 field_decl
= create_builtin_decl (FIELD_DECL
,
1541 short_integer_type_node
,
1543 chainon (field_decl_chain
, field_decl
);
1545 /* short cat_def_cnt; */
1547 field_decl
= create_builtin_decl (FIELD_DECL
,
1548 short_integer_type_node
,
1550 chainon (field_decl_chain
, field_decl
);
1552 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1554 if (!flag_next_runtime
)
1555 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1557 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1558 imp_count
== 0 && cat_count
== 0
1560 field_decl
= create_builtin_decl (FIELD_DECL
,
1561 build_array_type (ptr_type_node
, index
),
1563 chainon (field_decl_chain
, field_decl
);
1565 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1568 /* Create the initial value for the `defs' field of _objc_symtab.
1569 This is a CONSTRUCTOR. */
1572 init_def_list (type
)
1575 tree expr
, initlist
= NULL_TREE
;
1576 struct imp_entry
*impent
;
1579 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1581 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1583 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1584 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1589 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1591 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1593 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1594 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1598 if (!flag_next_runtime
)
1600 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1603 if (static_instances_decl
)
1604 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1606 expr
= build_int_2 (0, 0);
1608 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1611 return build_constructor (type
, nreverse (initlist
));
1614 /* Construct the initial value for all of _objc_symtab. */
1617 init_objc_symtab (type
)
1622 /* sel_ref_cnt = { ..., 5, ... } */
1624 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1626 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1628 if (flag_next_runtime
|| ! sel_ref_chain
)
1629 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1631 initlist
= tree_cons (NULL_TREE
,
1632 build_unary_op (ADDR_EXPR
,
1633 UOBJC_SELECTOR_TABLE_decl
, 1),
1636 /* cls_def_cnt = { ..., 5, ... } */
1638 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1640 /* cat_def_cnt = { ..., 5, ... } */
1642 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1644 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1646 if (imp_count
|| cat_count
|| static_instances_decl
)
1649 tree field
= TYPE_FIELDS (type
);
1650 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1652 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1656 return build_constructor (type
, nreverse (initlist
));
1659 /* Push forward-declarations of all the categories
1660 so that init_def_list can use them in a CONSTRUCTOR. */
1663 forward_declare_categories ()
1665 struct imp_entry
*impent
;
1666 tree sav
= implementation_context
;
1668 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1670 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1672 /* Set an invisible arg to synth_id_with_class_suffix. */
1673 implementation_context
= impent
->imp_context
;
1675 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1676 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1679 implementation_context
= sav
;
1682 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1683 and initialized appropriately. */
1686 generate_objc_symtab_decl ()
1690 if (!objc_category_template
)
1691 build_category_template ();
1693 /* forward declare categories */
1695 forward_declare_categories ();
1697 if (!objc_symtab_template
)
1698 build_objc_symtab_template ();
1700 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1702 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1703 tree_cons (NULL_TREE
,
1704 objc_symtab_template
, sc_spec
),
1706 NULL_TREE
, NULL_TREE
);
1708 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1709 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1710 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1711 finish_decl (UOBJC_SYMBOLS_decl
,
1712 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1717 init_module_descriptor (type
)
1720 tree initlist
, expr
;
1722 /* version = { 1, ... } */
1724 expr
= build_int_2 (OBJC_VERSION
, 0);
1725 initlist
= build_tree_list (NULL_TREE
, expr
);
1727 /* size = { ..., sizeof (struct objc_module), ... } */
1729 expr
= size_in_bytes (objc_module_template
);
1730 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1732 /* name = { ..., "foo.m", ... } */
1734 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1735 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1737 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1739 if (UOBJC_SYMBOLS_decl
)
1740 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1742 expr
= build_int_2 (0, 0);
1743 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1745 return build_constructor (type
, nreverse (initlist
));
1748 /* Write out the data structures to describe Objective C classes defined.
1749 If appropriate, compile and output a setup function to initialize them.
1750 Return a string which is the name of a function to call to initialize
1751 the Objective C data structures for this file (and perhaps for other files
1754 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1757 build_module_descriptor ()
1759 tree decl_specs
, field_decl
, field_decl_chain
;
1761 objc_module_template
1762 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1766 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1767 field_decl
= get_identifier ("version");
1769 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1770 field_decl_chain
= field_decl
;
1774 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1775 field_decl
= get_identifier ("size");
1777 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1778 chainon (field_decl_chain
, field_decl
);
1782 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1783 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1785 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1786 chainon (field_decl_chain
, field_decl
);
1788 /* struct objc_symtab *symtab; */
1790 decl_specs
= get_identifier (UTAG_SYMTAB
);
1791 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1792 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1794 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1795 chainon (field_decl_chain
, field_decl
);
1797 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1799 /* Create an instance of "objc_module". */
1801 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1802 build_tree_list (NULL_TREE
,
1803 ridpointers
[(int) RID_STATIC
]));
1805 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1806 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1808 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1809 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1810 finish_decl (UOBJC_MODULES_decl
,
1811 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1814 /* Mark the decl to avoid "defined but not used" warning. */
1815 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1817 /* Generate a constructor call for the module descriptor.
1818 This code was generated by reading the grammar rules
1819 of c-parse.in; Therefore, it may not be the most efficient
1820 way of generating the requisite code. */
1822 if (flag_next_runtime
)
1826 tree parms
, function_decl
, decelerator
, void_list_node_1
;
1828 tree init_function_name
= get_file_function_name ('I');
1830 /* Declare void __objc_execClass (void *); */
1832 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1834 = build_function_type (void_type_node
,
1835 tree_cons (NULL_TREE
, ptr_type_node
,
1837 function_decl
= build_decl (FUNCTION_DECL
,
1838 get_identifier (TAG_EXECCLASS
),
1840 DECL_EXTERNAL (function_decl
) = 1;
1841 DECL_ARTIFICIAL (function_decl
) = 1;
1842 TREE_PUBLIC (function_decl
) = 1;
1844 pushdecl (function_decl
);
1845 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1848 = build_tree_list (NULL_TREE
,
1849 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1850 decelerator
= build_function_call (function_decl
, parms
);
1852 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1854 start_function (void_list_node_1
,
1855 build_parse_node (CALL_EXPR
, init_function_name
,
1856 /* This has the format of the output
1857 of get_parm_info. */
1858 tree_cons (NULL_TREE
, NULL_TREE
,
1861 NULL_TREE
, NULL_TREE
);
1862 #if 0 /* This should be turned back on later
1863 for the systems where collect is not needed. */
1864 /* Make these functions nonglobal
1865 so each file can use the same name. */
1866 TREE_PUBLIC (current_function_decl
) = 0;
1868 TREE_USED (current_function_decl
) = 1;
1869 store_parm_decls ();
1871 assemble_external (function_decl
);
1872 c_expand_expr_stmt (decelerator
);
1874 TREE_PUBLIC (current_function_decl
) = 1;
1876 function_decl
= current_function_decl
;
1877 finish_function (0);
1879 /* Return the name of the constructor function. */
1880 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1884 /* extern const char _OBJC_STRINGS[]; */
1887 generate_forward_declaration_to_string_table ()
1889 tree sc_spec
, decl_specs
, expr_decl
;
1891 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1892 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1895 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1897 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1900 /* Return the DECL of the string IDENT in the SECTION. */
1903 get_objc_string_decl (ident
, section
)
1905 enum string_section section
;
1909 if (section
== class_names
)
1910 chain
= class_names_chain
;
1911 else if (section
== meth_var_names
)
1912 chain
= meth_var_names_chain
;
1913 else if (section
== meth_var_types
)
1914 chain
= meth_var_types_chain
;
1918 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1919 if (TREE_VALUE (chain
) == ident
)
1920 return (TREE_PURPOSE (chain
));
1926 /* Output references to all statically allocated objects. Return the DECL
1927 for the array built. */
1930 generate_static_references ()
1932 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1933 tree class_name
, class, decl
, initlist
;
1934 tree cl_chain
, in_chain
, type
;
1935 int num_inst
, num_class
;
1938 if (flag_next_runtime
)
1941 for (cl_chain
= objc_static_instances
, num_class
= 0;
1942 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1944 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1945 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1947 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1948 ident
= get_identifier (buf
);
1950 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1951 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1952 build_tree_list (NULL_TREE
,
1953 ridpointers
[(int) RID_STATIC
]));
1954 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1955 DECL_CONTEXT (decl
) = 0;
1956 DECL_ARTIFICIAL (decl
) = 1;
1958 /* Output {class_name, ...}. */
1959 class = TREE_VALUE (cl_chain
);
1960 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1961 initlist
= build_tree_list (NULL_TREE
,
1962 build_unary_op (ADDR_EXPR
, class_name
, 1));
1964 /* Output {..., instance, ...}. */
1965 for (in_chain
= TREE_PURPOSE (cl_chain
);
1966 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1968 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1969 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1972 /* Output {..., NULL}. */
1973 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1975 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1976 finish_decl (decl
, expr
, NULL_TREE
);
1977 TREE_USED (decl
) = 1;
1979 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1980 decl
= build_decl (VAR_DECL
, ident
, type
);
1981 make_decl_rtl (decl
, 0, 1);
1982 TREE_USED (decl
) = 1;
1984 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1987 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1988 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1989 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1990 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1991 build_tree_list (NULL_TREE
,
1992 ridpointers
[(int) RID_STATIC
]));
1993 static_instances_decl
1994 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1995 TREE_USED (static_instances_decl
) = 1;
1996 DECL_CONTEXT (static_instances_decl
) = 0;
1997 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1998 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
2000 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
2003 /* Output all strings. */
2008 tree sc_spec
, decl_specs
, expr_decl
;
2009 tree chain
, string_expr
;
2012 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2014 string
= TREE_VALUE (chain
);
2015 decl
= TREE_PURPOSE (chain
);
2017 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2018 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2019 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2020 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2021 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2022 IDENTIFIER_POINTER (string
));
2023 finish_decl (decl
, string_expr
, NULL_TREE
);
2026 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2028 string
= TREE_VALUE (chain
);
2029 decl
= TREE_PURPOSE (chain
);
2031 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2032 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2033 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2034 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2035 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2036 IDENTIFIER_POINTER (string
));
2037 finish_decl (decl
, string_expr
, NULL_TREE
);
2040 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2042 string
= TREE_VALUE (chain
);
2043 decl
= TREE_PURPOSE (chain
);
2045 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2046 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2047 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2048 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2049 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2050 IDENTIFIER_POINTER (string
));
2051 finish_decl (decl
, string_expr
, NULL_TREE
);
2056 build_selector_reference_decl ()
2062 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2064 ident
= get_identifier (buf
);
2066 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2067 DECL_EXTERNAL (decl
) = 1;
2068 TREE_PUBLIC (decl
) = 1;
2069 TREE_USED (decl
) = 1;
2070 TREE_READONLY (decl
) = 1;
2071 DECL_ARTIFICIAL (decl
) = 1;
2072 DECL_CONTEXT (decl
) = 0;
2074 make_decl_rtl (decl
, 0, 1);
2075 pushdecl_top_level (decl
);
2080 /* Just a handy wrapper for add_objc_string. */
2083 build_selector (ident
)
2086 tree expr
= add_objc_string (ident
, meth_var_names
);
2087 if (flag_typed_selectors
)
2090 return build_c_cast (selector_type
, expr
); /* cast! */
2093 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2094 The cast stops the compiler from issuing the following message:
2095 grok.m: warning: initialization of non-const * pointer from const *
2096 grok.m: warning: initialization between incompatible pointer types. */
2100 build_msg_pool_reference (offset
)
2103 tree expr
= build_int_2 (offset
, 0);
2106 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2107 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2109 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2110 ridpointers
[(int) RID_CHAR
]),
2111 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2112 TREE_TYPE (expr
) = groktypename (cast
);
2117 init_selector (offset
)
2120 tree expr
= build_msg_pool_reference (offset
);
2121 TREE_TYPE (expr
) = selector_type
;
2127 build_selector_translation_table ()
2129 tree sc_spec
, decl_specs
;
2130 tree chain
, initlist
= NULL_TREE
;
2132 tree decl
= NULL_TREE
, var_decl
, name
;
2134 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2138 expr
= build_selector (TREE_VALUE (chain
));
2140 if (flag_next_runtime
)
2142 name
= DECL_NAME (TREE_PURPOSE (chain
));
2144 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2146 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2147 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2151 /* The `decl' that is returned from start_decl is the one that we
2152 forward declared in `build_selector_reference' */
2153 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2156 /* add one for the '\0' character */
2157 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2159 if (flag_next_runtime
)
2160 finish_decl (decl
, expr
, NULL_TREE
);
2163 if (flag_typed_selectors
)
2165 tree eltlist
= NULL_TREE
;
2166 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2167 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2168 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2169 expr
= build_constructor (objc_selector_template
,
2170 nreverse (eltlist
));
2172 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2177 if (! flag_next_runtime
)
2179 /* Cause the variable and its initial value to be actually output. */
2180 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2181 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2182 /* NULL terminate the list and fix the decl for output. */
2183 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2184 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2185 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2186 nreverse (initlist
));
2187 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2188 current_function_decl
= NULL_TREE
;
2193 get_proto_encoding (proto
)
2201 if (! METHOD_ENCODING (proto
))
2203 tmp_decl
= build_tmp_function_decl ();
2204 hack_method_prototype (proto
, tmp_decl
);
2205 encoding
= encode_method_prototype (proto
, tmp_decl
);
2206 METHOD_ENCODING (proto
) = encoding
;
2209 encoding
= METHOD_ENCODING (proto
);
2211 return add_objc_string (encoding
, meth_var_types
);
2214 return build_int_2 (0, 0);
2217 /* sel_ref_chain is a list whose "value" fields will be instances of
2218 identifier_node that represent the selector. */
2221 build_typed_selector_reference (ident
, proto
)
2224 tree
*chain
= &sel_ref_chain
;
2230 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2231 goto return_at_index
;
2234 chain
= &TREE_CHAIN (*chain
);
2237 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2240 expr
= build_unary_op (ADDR_EXPR
,
2241 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2242 build_int_2 (index
, 0)),
2244 return build_c_cast (selector_type
, expr
);
2248 build_selector_reference (ident
)
2251 tree
*chain
= &sel_ref_chain
;
2257 if (TREE_VALUE (*chain
) == ident
)
2258 return (flag_next_runtime
2259 ? TREE_PURPOSE (*chain
)
2260 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2261 build_int_2 (index
, 0)));
2264 chain
= &TREE_CHAIN (*chain
);
2267 expr
= build_selector_reference_decl ();
2269 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2271 return (flag_next_runtime
2273 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2274 build_int_2 (index
, 0)));
2278 build_class_reference_decl ()
2284 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2286 ident
= get_identifier (buf
);
2288 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2289 DECL_EXTERNAL (decl
) = 1;
2290 TREE_PUBLIC (decl
) = 1;
2291 TREE_USED (decl
) = 1;
2292 TREE_READONLY (decl
) = 1;
2293 DECL_CONTEXT (decl
) = 0;
2294 DECL_ARTIFICIAL (decl
) = 1;
2296 make_decl_rtl (decl
, 0, 1);
2297 pushdecl_top_level (decl
);
2302 /* Create a class reference, but don't create a variable to reference
2306 add_class_reference (ident
)
2311 if ((chain
= cls_ref_chain
))
2316 if (ident
== TREE_VALUE (chain
))
2320 chain
= TREE_CHAIN (chain
);
2324 /* Append to the end of the list */
2325 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2328 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2331 /* Get a class reference, creating it if necessary. Also create the
2332 reference variable. */
2335 get_class_reference (ident
)
2338 if (flag_next_runtime
)
2343 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2344 if (TREE_VALUE (*chain
) == ident
)
2346 if (! TREE_PURPOSE (*chain
))
2347 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2349 return TREE_PURPOSE (*chain
);
2352 decl
= build_class_reference_decl ();
2353 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2360 add_class_reference (ident
);
2362 params
= build_tree_list (NULL_TREE
,
2363 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2364 IDENTIFIER_POINTER (ident
)));
2366 assemble_external (objc_get_class_decl
);
2367 return build_function_call (objc_get_class_decl
, params
);
2371 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2372 of identifier_node that represent the selector. It returns the
2373 offset of the selector from the beginning of the _OBJC_STRINGS
2374 pool. This offset is typically used by init_selector during code
2377 For each string section we have a chain which maps identifier nodes
2378 to decls for the strings. */
2381 add_objc_string (ident
, section
)
2383 enum string_section section
;
2387 if (section
== class_names
)
2388 chain
= &class_names_chain
;
2389 else if (section
== meth_var_names
)
2390 chain
= &meth_var_names_chain
;
2391 else if (section
== meth_var_types
)
2392 chain
= &meth_var_types_chain
;
2398 if (TREE_VALUE (*chain
) == ident
)
2399 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2401 chain
= &TREE_CHAIN (*chain
);
2404 decl
= build_objc_string_decl (section
);
2406 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2408 return build_unary_op (ADDR_EXPR
, decl
, 1);
2412 build_objc_string_decl (section
)
2413 enum string_section section
;
2417 static int class_names_idx
= 0;
2418 static int meth_var_names_idx
= 0;
2419 static int meth_var_types_idx
= 0;
2421 if (section
== class_names
)
2422 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2423 else if (section
== meth_var_names
)
2424 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2425 else if (section
== meth_var_types
)
2426 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2428 ident
= get_identifier (buf
);
2430 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2431 DECL_EXTERNAL (decl
) = 1;
2432 TREE_PUBLIC (decl
) = 1;
2433 TREE_USED (decl
) = 1;
2434 TREE_READONLY (decl
) = 1;
2435 TREE_CONSTANT (decl
) = 1;
2436 DECL_CONTEXT (decl
) = 0;
2437 DECL_ARTIFICIAL (decl
) = 1;
2439 make_decl_rtl (decl
, 0, 1);
2440 pushdecl_top_level (decl
);
2447 objc_declare_alias (alias_ident
, class_ident
)
2451 if (is_class_name (class_ident
) != class_ident
)
2452 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2453 else if (is_class_name (alias_ident
))
2454 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2456 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2460 objc_declare_class (ident_list
)
2465 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2467 tree ident
= TREE_VALUE (list
);
2470 if ((decl
= lookup_name (ident
)))
2472 error ("`%s' redeclared as different kind of symbol",
2473 IDENTIFIER_POINTER (ident
));
2474 error_with_decl (decl
, "previous declaration of `%s'");
2477 if (! is_class_name (ident
))
2479 tree record
= xref_tag (RECORD_TYPE
, ident
);
2480 TREE_STATIC_TEMPLATE (record
) = 1;
2481 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2487 is_class_name (ident
)
2492 if (lookup_interface (ident
))
2495 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2497 if (ident
== TREE_VALUE (chain
))
2501 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2503 if (ident
== TREE_VALUE (chain
))
2504 return TREE_PURPOSE (chain
);
2511 lookup_interface (ident
)
2516 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2518 if (ident
== CLASS_NAME (chain
))
2525 objc_copy_list (list
, head
)
2529 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2533 tail
= copy_node (list
);
2535 /* The following statement fixes a bug when inheriting instance
2536 variables that are declared to be bitfields. finish_struct
2537 expects to find the width of the bitfield in DECL_INITIAL. */
2538 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2539 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2541 newlist
= chainon (newlist
, tail
);
2542 list
= TREE_CHAIN (list
);
2549 /* Used by: build_private_template, get_class_ivars, and
2550 continue_class. COPY is 1 when called from @defs. In this case
2551 copy all fields. Otherwise don't copy leaf ivars since we rely on
2552 them being side-effected exactly once by finish_struct. */
2555 build_ivar_chain (interface
, copy
)
2559 tree my_name
, super_name
, ivar_chain
;
2561 my_name
= CLASS_NAME (interface
);
2562 super_name
= CLASS_SUPER_NAME (interface
);
2564 /* Possibly copy leaf ivars. */
2566 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2568 ivar_chain
= CLASS_IVARS (interface
);
2573 tree super_interface
= lookup_interface (super_name
);
2575 if (!super_interface
)
2577 /* fatal did not work with 2 args...should fix */
2578 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2579 IDENTIFIER_POINTER (super_name
),
2580 IDENTIFIER_POINTER (my_name
));
2581 exit (FATAL_EXIT_CODE
);
2584 if (super_interface
== interface
)
2586 fatal ("Circular inheritance in interface declaration for `%s'",
2587 IDENTIFIER_POINTER (super_name
));
2590 interface
= super_interface
;
2591 my_name
= CLASS_NAME (interface
);
2592 super_name
= CLASS_SUPER_NAME (interface
);
2594 op1
= CLASS_IVARS (interface
);
2597 tree head
, tail
= objc_copy_list (op1
, &head
);
2599 /* Prepend super class ivars...make a copy of the list, we
2600 do not want to alter the original. */
2601 TREE_CHAIN (tail
) = ivar_chain
;
2608 /* struct <classname> {
2609 struct objc_class *isa;
2614 build_private_template (class)
2619 if (CLASS_STATIC_TEMPLATE (class))
2621 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2622 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2626 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2628 ivar_context
= build_ivar_chain (class, 0);
2630 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2632 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2634 /* mark this record as class template - for class type checking */
2635 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2639 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2641 build1 (INDIRECT_REF
, NULL_TREE
,
2644 return ivar_context
;
2647 /* Begin code generation for protocols... */
2649 /* struct objc_protocol {
2650 char *protocol_name;
2651 struct objc_protocol **protocol_list;
2652 struct objc_method_desc *instance_methods;
2653 struct objc_method_desc *class_methods;
2657 build_protocol_template ()
2659 tree decl_specs
, field_decl
, field_decl_chain
;
2662 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2664 /* struct objc_class *isa; */
2666 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2667 get_identifier (UTAG_CLASS
)));
2668 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2670 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2671 field_decl_chain
= field_decl
;
2673 /* char *protocol_name; */
2675 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2677 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2679 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2680 chainon (field_decl_chain
, field_decl
);
2682 /* struct objc_protocol **protocol_list; */
2684 decl_specs
= build_tree_list (NULL_TREE
, template);
2686 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2687 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2689 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2690 chainon (field_decl_chain
, field_decl
);
2692 /* struct objc_method_list *instance_methods; */
2695 = build_tree_list (NULL_TREE
,
2696 xref_tag (RECORD_TYPE
,
2697 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2699 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2701 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2702 chainon (field_decl_chain
, field_decl
);
2704 /* struct objc_method_list *class_methods; */
2707 = build_tree_list (NULL_TREE
,
2708 xref_tag (RECORD_TYPE
,
2709 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2711 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2713 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2714 chainon (field_decl_chain
, field_decl
);
2716 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2720 build_descriptor_table_initializer (type
, entries
)
2724 tree initlist
= NULL_TREE
;
2728 tree eltlist
= NULL_TREE
;
2731 = tree_cons (NULL_TREE
,
2732 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2734 = tree_cons (NULL_TREE
,
2735 add_objc_string (METHOD_ENCODING (entries
),
2740 = tree_cons (NULL_TREE
,
2741 build_constructor (type
, nreverse (eltlist
)), initlist
);
2743 entries
= TREE_CHAIN (entries
);
2747 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2750 /* struct objc_method_prototype_list {
2752 struct objc_method_prototype {
2759 build_method_prototype_list_template (list_type
, size
)
2763 tree objc_ivar_list_record
;
2764 tree decl_specs
, field_decl
, field_decl_chain
;
2766 /* Generate an unnamed struct definition. */
2768 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2770 /* int method_count; */
2772 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2773 field_decl
= get_identifier ("method_count");
2776 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2777 field_decl_chain
= field_decl
;
2779 /* struct objc_method method_list[]; */
2781 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2782 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2783 build_int_2 (size
, 0));
2786 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2787 chainon (field_decl_chain
, field_decl
);
2789 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2791 return objc_ivar_list_record
;
2795 build_method_prototype_template ()
2798 tree decl_specs
, field_decl
, field_decl_chain
;
2801 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2803 #ifdef OBJC_INT_SELECTORS
2804 /* unsigned int _cmd; */
2806 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2807 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2808 field_decl
= get_identifier ("_cmd");
2809 #else /* OBJC_INT_SELECTORS */
2810 /* struct objc_selector *_cmd; */
2811 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2812 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2813 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2814 #endif /* OBJC_INT_SELECTORS */
2817 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2818 field_decl_chain
= field_decl
;
2820 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2822 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2824 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2825 chainon (field_decl_chain
, field_decl
);
2827 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2829 return proto_record
;
2832 /* True if last call to forwarding_offset yielded a register offset. */
2833 static int offset_is_register
;
2836 forwarding_offset (parm
)
2839 int offset_in_bytes
;
2841 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2843 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2845 /* ??? Here we assume that the parm address is indexed
2846 off the frame pointer or arg pointer.
2847 If that is not true, we produce meaningless results,
2848 but do not crash. */
2849 if (GET_CODE (addr
) == PLUS
2850 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2851 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2853 offset_in_bytes
= 0;
2855 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2856 offset_is_register
= 0;
2858 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2860 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2861 offset_in_bytes
= apply_args_register_offset (regno
);
2862 offset_is_register
= 1;
2867 /* This is the case where the parm is passed as an int or double
2868 and it is converted to a char, short or float and stored back
2869 in the parmlist. In this case, describe the parm
2870 with the variable's declared type, and adjust the address
2871 if the least significant bytes (which we are using) are not
2873 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2874 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2875 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2877 return offset_in_bytes
;
2881 encode_method_prototype (method_decl
, func_decl
)
2888 HOST_WIDE_INT max_parm_end
= 0;
2892 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2893 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2896 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2897 obstack_object_size (&util_obstack
),
2898 OBJC_ENCODE_INLINE_DEFS
);
2901 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2902 parms
= TREE_CHAIN (parms
))
2904 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2905 + int_size_in_bytes (TREE_TYPE (parms
)));
2907 if (!offset_is_register
&& max_parm_end
< parm_end
)
2908 max_parm_end
= parm_end
;
2911 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2913 sprintf (buf
, "%d", stack_size
);
2914 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2916 user_args
= METHOD_SEL_ARGS (method_decl
);
2918 /* Argument types. */
2919 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2920 parms
= TREE_CHAIN (parms
), i
++)
2922 /* Process argument qualifiers for user supplied arguments. */
2925 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2926 user_args
= TREE_CHAIN (user_args
);
2930 encode_type (TREE_TYPE (parms
),
2931 obstack_object_size (&util_obstack
),
2932 OBJC_ENCODE_INLINE_DEFS
);
2934 /* Compute offset. */
2935 sprintf (buf
, "%d", forwarding_offset (parms
));
2937 /* Indicate register. */
2938 if (offset_is_register
)
2939 obstack_1grow (&util_obstack
, '+');
2941 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2944 obstack_1grow (&util_obstack
, '\0');
2945 result
= get_identifier (obstack_finish (&util_obstack
));
2946 obstack_free (&util_obstack
, util_firstobj
);
2951 generate_descriptor_table (type
, name
, size
, list
, proto
)
2958 tree sc_spec
, decl_specs
, decl
, initlist
;
2960 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2961 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2963 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2964 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2966 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2967 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2969 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2976 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2979 static tree objc_method_prototype_template
;
2980 tree initlist
, chain
, method_list_template
;
2981 tree cast
, variable_length_type
;
2984 if (!objc_method_prototype_template
)
2986 objc_method_prototype_template
= build_method_prototype_template ();
2987 ggc_add_tree_root (&objc_method_prototype_template
, 1);
2990 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2991 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2993 variable_length_type
= groktypename (cast
);
2995 chain
= PROTOCOL_CLS_METHODS (protocol
);
2998 size
= list_length (chain
);
3000 method_list_template
3001 = build_method_prototype_list_template (objc_method_prototype_template
,
3005 = build_descriptor_table_initializer (objc_method_prototype_template
,
3008 UOBJC_CLASS_METHODS_decl
3009 = generate_descriptor_table (method_list_template
,
3010 "_OBJC_PROTOCOL_CLASS_METHODS",
3011 size
, initlist
, protocol
);
3012 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3015 UOBJC_CLASS_METHODS_decl
= 0;
3017 chain
= PROTOCOL_NST_METHODS (protocol
);
3020 size
= list_length (chain
);
3022 method_list_template
3023 = build_method_prototype_list_template (objc_method_prototype_template
,
3026 = build_descriptor_table_initializer (objc_method_prototype_template
,
3029 UOBJC_INSTANCE_METHODS_decl
3030 = generate_descriptor_table (method_list_template
,
3031 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3032 size
, initlist
, protocol
);
3033 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3036 UOBJC_INSTANCE_METHODS_decl
= 0;
3040 build_tmp_function_decl ()
3042 tree decl_specs
, expr_decl
, parms
;
3046 /* struct objc_object *objc_xxx (id, SEL, ...); */
3048 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3049 push_parm_decl (build_tree_list
3050 (build_tree_list (decl_specs
,
3051 build1 (INDIRECT_REF
, NULL_TREE
,
3053 build_tree_list (NULL_TREE
, NULL_TREE
)));
3055 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3056 get_identifier (TAG_SELECTOR
)));
3057 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3059 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3060 build_tree_list (NULL_TREE
, NULL_TREE
)));
3061 parms
= get_parm_info (0);
3064 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3065 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3066 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3067 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3069 return define_decl (expr_decl
, decl_specs
);
3073 hack_method_prototype (nst_methods
, tmp_decl
)
3080 /* Hack to avoid problem with static typing of self arg. */
3081 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3082 start_method_def (nst_methods
);
3083 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3085 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
3086 parms
= get_parm_info (0); /* we have a `, ...' */
3088 parms
= get_parm_info (1); /* place a `void_at_end' */
3090 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3092 /* Usually called from store_parm_decls -> init_function_start. */
3094 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3095 current_function_decl
= tmp_decl
;
3098 /* Code taken from start_function. */
3099 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3100 /* Promote the value to int before returning it. */
3101 if (TREE_CODE (restype
) == INTEGER_TYPE
3102 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3103 restype
= integer_type_node
;
3104 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3107 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3108 DECL_CONTEXT (parm
) = tmp_decl
;
3110 init_function_start (tmp_decl
, "objc-act", 0);
3112 /* Typically called from expand_function_start for function definitions. */
3113 assign_parms (tmp_decl
);
3115 /* install return type */
3116 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3121 generate_protocol_references (plist
)
3126 /* Forward declare protocols referenced. */
3127 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3129 tree proto
= TREE_VALUE (lproto
);
3131 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3132 && PROTOCOL_NAME (proto
))
3134 if (! PROTOCOL_FORWARD_DECL (proto
))
3135 build_protocol_reference (proto
);
3137 if (PROTOCOL_LIST (proto
))
3138 generate_protocol_references (PROTOCOL_LIST (proto
));
3144 generate_protocols ()
3146 tree p
, tmp_decl
, encoding
;
3147 tree sc_spec
, decl_specs
, decl
;
3148 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3151 tmp_decl
= build_tmp_function_decl ();
3153 if (! objc_protocol_template
)
3154 objc_protocol_template
= build_protocol_template ();
3156 /* If a protocol was directly referenced, pull in indirect references. */
3157 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3158 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3159 generate_protocol_references (PROTOCOL_LIST (p
));
3161 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3163 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3164 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3166 /* If protocol wasn't referenced, don't generate any code. */
3167 if (! PROTOCOL_FORWARD_DECL (p
))
3170 /* Make sure we link in the Protocol class. */
3171 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3175 if (! METHOD_ENCODING (nst_methods
))
3177 hack_method_prototype (nst_methods
, tmp_decl
);
3178 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3179 METHOD_ENCODING (nst_methods
) = encoding
;
3181 nst_methods
= TREE_CHAIN (nst_methods
);
3186 if (! METHOD_ENCODING (cls_methods
))
3188 hack_method_prototype (cls_methods
, tmp_decl
);
3189 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3190 METHOD_ENCODING (cls_methods
) = encoding
;
3193 cls_methods
= TREE_CHAIN (cls_methods
);
3195 generate_method_descriptors (p
);
3197 if (PROTOCOL_LIST (p
))
3198 refs_decl
= generate_protocol_list (p
);
3202 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3204 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3206 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3208 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3209 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3211 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3217 (build_tree_list (build_tree_list (NULL_TREE
,
3218 objc_protocol_template
),
3219 build1 (INDIRECT_REF
, NULL_TREE
,
3220 build1 (INDIRECT_REF
, NULL_TREE
,
3223 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3224 TREE_TYPE (refs_expr
) = cast_type2
;
3227 refs_expr
= build_int_2 (0, 0);
3229 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3230 by generate_method_descriptors, which is called above. */
3231 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3232 protocol_name_expr
, refs_expr
,
3233 UOBJC_INSTANCE_METHODS_decl
,
3234 UOBJC_CLASS_METHODS_decl
);
3235 finish_decl (decl
, initlist
, NULL_TREE
);
3237 /* Mark the decl as used to avoid "defined but not used" warning. */
3238 TREE_USED (decl
) = 1;
3243 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3244 instance_methods
, class_methods
)
3248 tree instance_methods
;
3251 tree initlist
= NULL_TREE
, expr
;
3254 cast_type
= groktypename
3256 (build_tree_list (NULL_TREE
,
3257 xref_tag (RECORD_TYPE
,
3258 get_identifier (UTAG_CLASS
))),
3259 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3261 /* Filling the "isa" in with one allows the runtime system to
3262 detect that the version change...should remove before final release. */
3264 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3265 TREE_TYPE (expr
) = cast_type
;
3266 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3267 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3268 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3270 if (!instance_methods
)
3271 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3274 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3275 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3279 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3282 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3283 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3286 return build_constructor (type
, nreverse (initlist
));
3289 /* struct objc_category {
3290 char *category_name;
3292 struct objc_method_list *instance_methods;
3293 struct objc_method_list *class_methods;
3294 struct objc_protocol_list *protocols;
3298 build_category_template ()
3300 tree decl_specs
, field_decl
, field_decl_chain
;
3302 objc_category_template
= start_struct (RECORD_TYPE
,
3303 get_identifier (UTAG_CATEGORY
));
3304 /* char *category_name; */
3306 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3308 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3310 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3311 field_decl_chain
= field_decl
;
3313 /* char *class_name; */
3315 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3316 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3318 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3319 chainon (field_decl_chain
, field_decl
);
3321 /* struct objc_method_list *instance_methods; */
3323 decl_specs
= build_tree_list (NULL_TREE
,
3324 xref_tag (RECORD_TYPE
,
3325 get_identifier (UTAG_METHOD_LIST
)));
3327 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3329 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3330 chainon (field_decl_chain
, field_decl
);
3332 /* struct objc_method_list *class_methods; */
3334 decl_specs
= build_tree_list (NULL_TREE
,
3335 xref_tag (RECORD_TYPE
,
3336 get_identifier (UTAG_METHOD_LIST
)));
3338 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3340 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3341 chainon (field_decl_chain
, field_decl
);
3343 /* struct objc_protocol **protocol_list; */
3345 decl_specs
= build_tree_list (NULL_TREE
,
3346 xref_tag (RECORD_TYPE
,
3347 get_identifier (UTAG_PROTOCOL
)));
3349 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3350 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3352 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3353 chainon (field_decl_chain
, field_decl
);
3355 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3358 /* struct objc_selector {
3364 build_selector_template ()
3367 tree decl_specs
, field_decl
, field_decl_chain
;
3369 objc_selector_template
3370 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3374 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3375 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3377 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3378 field_decl_chain
= field_decl
;
3380 /* char *sel_type; */
3382 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3383 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3385 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3386 chainon (field_decl_chain
, field_decl
);
3388 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3391 /* struct objc_class {
3392 struct objc_class *isa;
3393 struct objc_class *super_class;
3398 struct objc_ivar_list *ivars;
3399 struct objc_method_list *methods;
3400 if (flag_next_runtime)
3401 struct objc_cache *cache;
3403 struct sarray *dtable;
3404 struct objc_class *subclass_list;
3405 struct objc_class *sibling_class;
3407 struct objc_protocol_list *protocols;
3408 void *gc_object_type;
3412 build_class_template ()
3414 tree decl_specs
, field_decl
, field_decl_chain
;
3417 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3419 /* struct objc_class *isa; */
3421 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3422 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3424 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3425 field_decl_chain
= field_decl
;
3427 /* struct objc_class *super_class; */
3429 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3431 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3433 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3434 chainon (field_decl_chain
, field_decl
);
3438 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3439 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3441 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3442 chainon (field_decl_chain
, field_decl
);
3446 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3447 field_decl
= get_identifier ("version");
3449 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3450 chainon (field_decl_chain
, field_decl
);
3454 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3455 field_decl
= get_identifier ("info");
3457 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3458 chainon (field_decl_chain
, field_decl
);
3460 /* long instance_size; */
3462 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3463 field_decl
= get_identifier ("instance_size");
3465 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3466 chainon (field_decl_chain
, field_decl
);
3468 /* struct objc_ivar_list *ivars; */
3470 decl_specs
= build_tree_list (NULL_TREE
,
3471 xref_tag (RECORD_TYPE
,
3472 get_identifier (UTAG_IVAR_LIST
)));
3473 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3475 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3476 chainon (field_decl_chain
, field_decl
);
3478 /* struct objc_method_list *methods; */
3480 decl_specs
= build_tree_list (NULL_TREE
,
3481 xref_tag (RECORD_TYPE
,
3482 get_identifier (UTAG_METHOD_LIST
)));
3483 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3485 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3486 chainon (field_decl_chain
, field_decl
);
3488 if (flag_next_runtime
)
3490 /* struct objc_cache *cache; */
3492 decl_specs
= build_tree_list (NULL_TREE
,
3493 xref_tag (RECORD_TYPE
,
3494 get_identifier ("objc_cache")));
3495 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3496 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3497 decl_specs
, NULL_TREE
);
3498 chainon (field_decl_chain
, field_decl
);
3502 /* struct sarray *dtable; */
3504 decl_specs
= build_tree_list (NULL_TREE
,
3505 xref_tag (RECORD_TYPE
,
3506 get_identifier ("sarray")));
3507 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3508 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3509 decl_specs
, NULL_TREE
);
3510 chainon (field_decl_chain
, field_decl
);
3512 /* struct objc_class *subclass_list; */
3514 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3516 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3517 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3518 decl_specs
, NULL_TREE
);
3519 chainon (field_decl_chain
, field_decl
);
3521 /* struct objc_class *sibling_class; */
3523 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3525 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3526 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3527 decl_specs
, NULL_TREE
);
3528 chainon (field_decl_chain
, field_decl
);
3531 /* struct objc_protocol **protocol_list; */
3533 decl_specs
= build_tree_list (NULL_TREE
,
3534 xref_tag (RECORD_TYPE
,
3535 get_identifier (UTAG_PROTOCOL
)));
3537 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3539 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3540 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3541 decl_specs
, NULL_TREE
);
3542 chainon (field_decl_chain
, field_decl
);
3546 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3547 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3549 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3550 chainon (field_decl_chain
, field_decl
);
3552 /* void *gc_object_type; */
3554 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3555 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3557 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3558 chainon (field_decl_chain
, field_decl
);
3560 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3563 /* Generate appropriate forward declarations for an implementation. */
3566 synth_forward_declarations ()
3568 tree sc_spec
, decl_specs
, an_id
;
3570 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3572 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3574 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3575 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3576 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3577 TREE_USED (UOBJC_CLASS_decl
) = 1;
3578 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3580 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3582 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3583 implementation_context
);
3585 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3586 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3587 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3589 /* Pre-build the following entities - for speed/convenience. */
3591 an_id
= get_identifier ("super_class");
3592 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3593 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3597 error_with_ivar (message
, decl
, rawdecl
)
3598 const char *message
;
3604 report_error_function (DECL_SOURCE_FILE (decl
));
3606 fprintf (stderr
, "%s:%d: ",
3607 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3608 memset (errbuf
, 0, BUFSIZE
);
3609 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3612 #define USERTYPE(t) \
3613 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3614 || TREE_CODE (t) == ENUMERAL_TYPE)
3617 check_ivars (inter
, imp
)
3621 tree intdecls
= CLASS_IVARS (inter
);
3622 tree impdecls
= CLASS_IVARS (imp
);
3623 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3624 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3630 if (intdecls
== 0 && impdecls
== 0)
3632 if (intdecls
== 0 || impdecls
== 0)
3634 error ("inconsistent instance variable specification");
3638 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3640 if (!comptypes (t1
, t2
))
3642 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3644 error_with_ivar ("conflicting instance variable type",
3645 impdecls
, rawimpdecls
);
3646 error_with_ivar ("previous declaration of",
3647 intdecls
, rawintdecls
);
3649 else /* both the type and the name don't match */
3651 error ("inconsistent instance variable specification");
3656 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3658 error_with_ivar ("conflicting instance variable name",
3659 impdecls
, rawimpdecls
);
3660 error_with_ivar ("previous declaration of",
3661 intdecls
, rawintdecls
);
3664 intdecls
= TREE_CHAIN (intdecls
);
3665 impdecls
= TREE_CHAIN (impdecls
);
3666 rawintdecls
= TREE_CHAIN (rawintdecls
);
3667 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3671 /* Set super_type to the data type node for struct objc_super *,
3672 first defining struct objc_super itself.
3673 This needs to be done just once per compilation. */
3676 build_super_template ()
3678 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3680 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3682 /* struct objc_object *self; */
3684 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3685 field_decl
= get_identifier ("self");
3686 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3687 field_decl
= grokfield (input_filename
, lineno
,
3688 field_decl
, decl_specs
, NULL_TREE
);
3689 field_decl_chain
= field_decl
;
3691 /* struct objc_class *class; */
3693 decl_specs
= get_identifier (UTAG_CLASS
);
3694 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3695 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3697 field_decl
= grokfield (input_filename
, lineno
,
3698 field_decl
, decl_specs
, NULL_TREE
);
3699 chainon (field_decl_chain
, field_decl
);
3701 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3703 /* `struct objc_super *' */
3704 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3706 build1 (INDIRECT_REF
,
3707 NULL_TREE
, NULL_TREE
)));
3711 /* struct objc_ivar {
3718 build_ivar_template ()
3720 tree objc_ivar_id
, objc_ivar_record
;
3721 tree decl_specs
, field_decl
, field_decl_chain
;
3723 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3724 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3726 /* char *ivar_name; */
3728 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3729 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3731 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3732 decl_specs
, NULL_TREE
);
3733 field_decl_chain
= field_decl
;
3735 /* char *ivar_type; */
3737 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3738 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3740 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3741 decl_specs
, NULL_TREE
);
3742 chainon (field_decl_chain
, field_decl
);
3744 /* int ivar_offset; */
3746 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3747 field_decl
= get_identifier ("ivar_offset");
3749 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3750 decl_specs
, NULL_TREE
);
3751 chainon (field_decl_chain
, field_decl
);
3753 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3755 return objc_ivar_record
;
3760 struct objc_ivar ivar_list[ivar_count];
3764 build_ivar_list_template (list_type
, size
)
3768 tree objc_ivar_list_record
;
3769 tree decl_specs
, field_decl
, field_decl_chain
;
3771 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3773 /* int ivar_count; */
3775 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3776 field_decl
= get_identifier ("ivar_count");
3778 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3779 decl_specs
, NULL_TREE
);
3780 field_decl_chain
= field_decl
;
3782 /* struct objc_ivar ivar_list[]; */
3784 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3785 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3786 build_int_2 (size
, 0));
3788 field_decl
= grokfield (input_filename
, lineno
,
3789 field_decl
, decl_specs
, NULL_TREE
);
3790 chainon (field_decl_chain
, field_decl
);
3792 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3794 return objc_ivar_list_record
;
3800 struct objc_method method_list[method_count];
3804 build_method_list_template (list_type
, size
)
3808 tree objc_ivar_list_record
;
3809 tree decl_specs
, field_decl
, field_decl_chain
;
3811 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3813 /* int method_next; */
3818 xref_tag (RECORD_TYPE
,
3819 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3821 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3822 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3823 decl_specs
, NULL_TREE
);
3824 field_decl_chain
= field_decl
;
3826 /* int method_count; */
3828 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3829 field_decl
= get_identifier ("method_count");
3831 field_decl
= grokfield (input_filename
, lineno
,
3832 field_decl
, decl_specs
, NULL_TREE
);
3833 chainon (field_decl_chain
, field_decl
);
3835 /* struct objc_method method_list[]; */
3837 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3838 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3839 build_int_2 (size
, 0));
3841 field_decl
= grokfield (input_filename
, lineno
,
3842 field_decl
, decl_specs
, NULL_TREE
);
3843 chainon (field_decl_chain
, field_decl
);
3845 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3847 return objc_ivar_list_record
;
3851 build_ivar_list_initializer (type
, field_decl
)
3855 tree initlist
= NULL_TREE
;
3859 tree ivar
= NULL_TREE
;
3862 if (DECL_NAME (field_decl
))
3863 ivar
= tree_cons (NULL_TREE
,
3864 add_objc_string (DECL_NAME (field_decl
),
3868 /* Unnamed bit-field ivar (yuck). */
3869 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3872 encode_field_decl (field_decl
,
3873 obstack_object_size (&util_obstack
),
3874 OBJC_ENCODE_DONT_INLINE_DEFS
);
3876 /* Null terminate string. */
3877 obstack_1grow (&util_obstack
, 0);
3881 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3884 obstack_free (&util_obstack
, util_firstobj
);
3887 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3888 initlist
= tree_cons (NULL_TREE
,
3889 build_constructor (type
, nreverse (ivar
)),
3892 field_decl
= TREE_CHAIN (field_decl
);
3896 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3900 generate_ivars_list (type
, name
, size
, list
)
3906 tree sc_spec
, decl_specs
, decl
, initlist
;
3908 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3909 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3911 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3912 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3914 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3915 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3918 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3925 generate_ivar_lists ()
3927 tree initlist
, ivar_list_template
, chain
;
3928 tree cast
, variable_length_type
;
3931 generating_instance_variables
= 1;
3933 if (!objc_ivar_template
)
3934 objc_ivar_template
= build_ivar_template ();
3938 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3939 get_identifier (UTAG_IVAR_LIST
))),
3941 variable_length_type
= groktypename (cast
);
3943 /* Only generate class variables for the root of the inheritance
3944 hierarchy since these will be the same for every class. */
3946 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3947 && (chain
= TYPE_FIELDS (objc_class_template
)))
3949 size
= list_length (chain
);
3951 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3952 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3954 UOBJC_CLASS_VARIABLES_decl
3955 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3957 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3960 UOBJC_CLASS_VARIABLES_decl
= 0;
3962 chain
= CLASS_IVARS (implementation_template
);
3965 size
= list_length (chain
);
3966 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3967 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3969 UOBJC_INSTANCE_VARIABLES_decl
3970 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3972 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3975 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3977 generating_instance_variables
= 0;
3981 build_dispatch_table_initializer (type
, entries
)
3985 tree initlist
= NULL_TREE
;
3989 tree elemlist
= NULL_TREE
;
3991 elemlist
= tree_cons (NULL_TREE
,
3992 build_selector (METHOD_SEL_NAME (entries
)),
3995 elemlist
= tree_cons (NULL_TREE
,
3996 add_objc_string (METHOD_ENCODING (entries
),
4000 elemlist
= tree_cons (NULL_TREE
,
4001 build_unary_op (ADDR_EXPR
,
4002 METHOD_DEFINITION (entries
), 1),
4005 initlist
= tree_cons (NULL_TREE
,
4006 build_constructor (type
, nreverse (elemlist
)),
4009 entries
= TREE_CHAIN (entries
);
4013 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4016 /* To accomplish method prototyping without generating all kinds of
4017 inane warnings, the definition of the dispatch table entries were
4020 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4022 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4025 build_method_template ()
4028 tree decl_specs
, field_decl
, field_decl_chain
;
4030 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4032 #ifdef OBJC_INT_SELECTORS
4033 /* unsigned int _cmd; */
4034 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
4036 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
4037 field_decl
= get_identifier ("_cmd");
4038 #else /* not OBJC_INT_SELECTORS */
4039 /* struct objc_selector *_cmd; */
4040 decl_specs
= tree_cons (NULL_TREE
,
4041 xref_tag (RECORD_TYPE
,
4042 get_identifier (TAG_SELECTOR
)),
4044 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4045 #endif /* not OBJC_INT_SELECTORS */
4047 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4048 decl_specs
, NULL_TREE
);
4049 field_decl_chain
= field_decl
;
4051 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4052 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4053 get_identifier ("method_types"));
4054 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4055 decl_specs
, NULL_TREE
);
4056 chainon (field_decl_chain
, field_decl
);
4060 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4061 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4062 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4063 decl_specs
, NULL_TREE
);
4064 chainon (field_decl_chain
, field_decl
);
4066 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4073 generate_dispatch_table (type
, name
, size
, list
)
4079 tree sc_spec
, decl_specs
, decl
, initlist
;
4081 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4082 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4084 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4085 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4087 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4088 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4089 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4092 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4099 generate_dispatch_tables ()
4101 tree initlist
, chain
, method_list_template
;
4102 tree cast
, variable_length_type
;
4105 if (!objc_method_template
)
4106 objc_method_template
= build_method_template ();
4110 (build_tree_list (NULL_TREE
,
4111 xref_tag (RECORD_TYPE
,
4112 get_identifier (UTAG_METHOD_LIST
))),
4115 variable_length_type
= groktypename (cast
);
4117 chain
= CLASS_CLS_METHODS (implementation_context
);
4120 size
= list_length (chain
);
4122 method_list_template
4123 = build_method_list_template (objc_method_template
, size
);
4125 = build_dispatch_table_initializer (objc_method_template
, chain
);
4127 UOBJC_CLASS_METHODS_decl
4128 = generate_dispatch_table (method_list_template
,
4129 ((TREE_CODE (implementation_context
)
4130 == CLASS_IMPLEMENTATION_TYPE
)
4131 ? "_OBJC_CLASS_METHODS"
4132 : "_OBJC_CATEGORY_CLASS_METHODS"),
4134 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4137 UOBJC_CLASS_METHODS_decl
= 0;
4139 chain
= CLASS_NST_METHODS (implementation_context
);
4142 size
= list_length (chain
);
4144 method_list_template
4145 = build_method_list_template (objc_method_template
, size
);
4147 = build_dispatch_table_initializer (objc_method_template
, chain
);
4149 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4150 UOBJC_INSTANCE_METHODS_decl
4151 = generate_dispatch_table (method_list_template
,
4152 "_OBJC_INSTANCE_METHODS",
4155 /* We have a category. */
4156 UOBJC_INSTANCE_METHODS_decl
4157 = generate_dispatch_table (method_list_template
,
4158 "_OBJC_CATEGORY_INSTANCE_METHODS",
4160 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4163 UOBJC_INSTANCE_METHODS_decl
= 0;
4167 generate_protocol_list (i_or_p
)
4170 tree initlist
, decl_specs
, sc_spec
;
4171 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4175 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4176 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4177 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4178 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4179 plist
= PROTOCOL_LIST (i_or_p
);
4183 cast_type
= groktypename
4185 (build_tree_list (NULL_TREE
,
4186 xref_tag (RECORD_TYPE
,
4187 get_identifier (UTAG_PROTOCOL
))),
4188 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4191 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4192 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4193 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4196 /* Build initializer. */
4197 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4199 e
= build_int_2 (size
, 0);
4200 TREE_TYPE (e
) = cast_type
;
4201 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4203 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4205 tree pval
= TREE_VALUE (lproto
);
4207 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4208 && PROTOCOL_FORWARD_DECL (pval
))
4210 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4211 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4215 /* static struct objc_protocol *refs[n]; */
4217 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4218 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4219 get_identifier (UTAG_PROTOCOL
)),
4222 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4223 expr_decl
= build_nt (ARRAY_REF
,
4224 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4226 build_int_2 (size
+ 2, 0));
4227 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4228 expr_decl
= build_nt (ARRAY_REF
,
4229 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4231 build_int_2 (size
+ 2, 0));
4232 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4234 = build_nt (ARRAY_REF
,
4235 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4237 build_int_2 (size
+ 2, 0));
4241 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4243 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4245 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4246 nreverse (initlist
)),
4253 build_category_initializer (type
, cat_name
, class_name
,
4254 instance_methods
, class_methods
, protocol_list
)
4258 tree instance_methods
;
4262 tree initlist
= NULL_TREE
, expr
;
4264 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4265 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4267 if (!instance_methods
)
4268 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4271 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4272 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4275 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4278 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4279 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4282 /* protocol_list = */
4284 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4287 tree cast_type2
= groktypename
4289 (build_tree_list (NULL_TREE
,
4290 xref_tag (RECORD_TYPE
,
4291 get_identifier (UTAG_PROTOCOL
))),
4292 build1 (INDIRECT_REF
, NULL_TREE
,
4293 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4295 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4296 TREE_TYPE (expr
) = cast_type2
;
4297 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4300 return build_constructor (type
, nreverse (initlist
));
4303 /* struct objc_class {
4304 struct objc_class *isa;
4305 struct objc_class *super_class;
4310 struct objc_ivar_list *ivars;
4311 struct objc_method_list *methods;
4312 if (flag_next_runtime)
4313 struct objc_cache *cache;
4315 struct sarray *dtable;
4316 struct objc_class *subclass_list;
4317 struct objc_class *sibling_class;
4319 struct objc_protocol_list *protocols;
4320 void *gc_object_type;
4324 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4325 dispatch_table
, ivar_list
, protocol_list
)
4332 tree dispatch_table
;
4336 tree initlist
= NULL_TREE
, expr
;
4339 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4342 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4345 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4348 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4351 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4353 /* instance_size = */
4354 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4356 /* objc_ivar_list = */
4358 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4361 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4362 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4365 /* objc_method_list = */
4366 if (!dispatch_table
)
4367 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4370 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4371 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4374 if (flag_next_runtime
)
4375 /* method_cache = */
4376 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4380 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4382 /* subclass_list = */
4383 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4385 /* sibling_class = */
4386 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4389 /* protocol_list = */
4390 if (! protocol_list
)
4391 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4397 (build_tree_list (NULL_TREE
,
4398 xref_tag (RECORD_TYPE
,
4399 get_identifier (UTAG_PROTOCOL
))),
4400 build1 (INDIRECT_REF
, NULL_TREE
,
4401 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4403 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4404 TREE_TYPE (expr
) = cast_type2
;
4405 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4408 /* gc_object_type = NULL */
4409 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4411 return build_constructor (type
, nreverse (initlist
));
4414 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4417 generate_category (cat
)
4420 tree sc_spec
, decl_specs
, decl
;
4421 tree initlist
, cat_name_expr
, class_name_expr
;
4422 tree protocol_decl
, category
;
4424 add_class_reference (CLASS_NAME (cat
));
4425 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4427 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4429 category
= CLASS_CATEGORY_LIST (implementation_template
);
4431 /* find the category interface from the class it is associated with */
4434 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4436 category
= CLASS_CATEGORY_LIST (category
);
4439 if (category
&& CLASS_PROTOCOL_LIST (category
))
4441 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4442 protocol_decl
= generate_protocol_list (category
);
4447 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4448 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4450 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4451 implementation_context
),
4452 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4454 initlist
= build_category_initializer (TREE_TYPE (decl
),
4455 cat_name_expr
, class_name_expr
,
4456 UOBJC_INSTANCE_METHODS_decl
,
4457 UOBJC_CLASS_METHODS_decl
,
4460 TREE_USED (decl
) = 1;
4461 finish_decl (decl
, initlist
, NULL_TREE
);
4464 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4465 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4468 generate_shared_structures ()
4470 tree sc_spec
, decl_specs
, decl
;
4471 tree name_expr
, super_expr
, root_expr
;
4472 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4473 tree cast_type
, initlist
, protocol_decl
;
4475 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4478 add_class_reference (my_super_id
);
4480 /* Compute "my_root_id" - this is required for code generation.
4481 the "isa" for all meta class structures points to the root of
4482 the inheritance hierarchy (e.g. "__Object")... */
4483 my_root_id
= my_super_id
;
4486 tree my_root_int
= lookup_interface (my_root_id
);
4488 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4489 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4496 /* No super class. */
4497 my_root_id
= CLASS_NAME (implementation_template
);
4500 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4501 objc_class_template
),
4502 build1 (INDIRECT_REF
,
4503 NULL_TREE
, NULL_TREE
)));
4505 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4508 /* Install class `isa' and `super' pointers at runtime. */
4511 super_expr
= add_objc_string (my_super_id
, class_names
);
4512 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4515 super_expr
= build_int_2 (0, 0);
4517 root_expr
= add_objc_string (my_root_id
, class_names
);
4518 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4520 if (CLASS_PROTOCOL_LIST (implementation_template
))
4522 generate_protocol_references
4523 (CLASS_PROTOCOL_LIST (implementation_template
));
4524 protocol_decl
= generate_protocol_list (implementation_template
);
4529 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4531 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4532 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4534 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4535 NULL_TREE
, NULL_TREE
);
4538 = build_shared_structure_initializer
4540 root_expr
, super_expr
, name_expr
,
4541 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4543 UOBJC_CLASS_METHODS_decl
,
4544 UOBJC_CLASS_VARIABLES_decl
,
4547 finish_decl (decl
, initlist
, NULL_TREE
);
4549 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4551 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4552 NULL_TREE
, NULL_TREE
);
4555 = build_shared_structure_initializer
4557 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4558 super_expr
, name_expr
,
4559 convert (integer_type_node
,
4560 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4561 (implementation_template
))),
4563 UOBJC_INSTANCE_METHODS_decl
,
4564 UOBJC_INSTANCE_VARIABLES_decl
,
4567 finish_decl (decl
, initlist
, NULL_TREE
);
4571 synth_id_with_class_suffix (preamble
, ctxt
)
4572 const char *preamble
;
4576 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4577 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4579 const char *class_name
4580 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4581 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4582 sprintf (string
, "%s_%s", preamble
,
4583 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4585 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4586 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4588 /* We have a category. */
4589 const char *class_name
4590 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4591 const char *class_super_name
4592 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4593 string
= (char *) alloca (strlen (preamble
)
4594 + strlen (class_name
)
4595 + strlen (class_super_name
)
4597 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4599 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4601 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4603 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4604 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4609 return get_identifier (string
);
4613 is_objc_type_qualifier (node
)
4616 return (TREE_CODE (node
) == IDENTIFIER_NODE
4617 && (node
== ridpointers
[(int) RID_CONST
]
4618 || node
== ridpointers
[(int) RID_VOLATILE
]
4619 || node
== ridpointers
[(int) RID_IN
]
4620 || node
== ridpointers
[(int) RID_OUT
]
4621 || node
== ridpointers
[(int) RID_INOUT
]
4622 || node
== ridpointers
[(int) RID_BYCOPY
]
4623 || node
== ridpointers
[(int) RID_BYREF
]
4624 || node
== ridpointers
[(int) RID_ONEWAY
]));
4627 /* If type is empty or only type qualifiers are present, add default
4628 type of id (otherwise grokdeclarator will default to int). */
4631 adjust_type_for_id_default (type
)
4634 tree declspecs
, chain
;
4637 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4638 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4640 declspecs
= TREE_PURPOSE (type
);
4642 /* Determine if a typespec is present. */
4643 for (chain
= declspecs
;
4645 chain
= TREE_CHAIN (chain
))
4647 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4651 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4653 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4658 selector ':' '(' typename ')' identifier
4661 Transform an Objective-C keyword argument into
4662 the C equivalent parameter declarator.
4664 In: key_name, an "identifier_node" (optional).
4665 arg_type, a "tree_list" (optional).
4666 arg_name, an "identifier_node".
4668 Note: It would be really nice to strongly type the preceding
4669 arguments in the function prototype; however, then I
4670 could not use the "accessor" macros defined in "tree.h".
4672 Out: an instance of "keyword_decl". */
4675 build_keyword_decl (key_name
, arg_type
, arg_name
)
4682 /* If no type is specified, default to "id". */
4683 arg_type
= adjust_type_for_id_default (arg_type
);
4685 keyword_decl
= make_node (KEYWORD_DECL
);
4687 TREE_TYPE (keyword_decl
) = arg_type
;
4688 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4689 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4691 return keyword_decl
;
4694 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4697 build_keyword_selector (selector
)
4701 tree key_chain
, key_name
;
4704 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4706 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4707 key_name
= KEYWORD_KEY_NAME (key_chain
);
4708 else if (TREE_CODE (selector
) == TREE_LIST
)
4709 key_name
= TREE_PURPOSE (key_chain
);
4714 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4716 /* Just a ':' arg. */
4720 buf
= (char *)alloca (len
+ 1);
4721 memset (buf
, 0, len
+ 1);
4723 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4725 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4726 key_name
= KEYWORD_KEY_NAME (key_chain
);
4727 else if (TREE_CODE (selector
) == TREE_LIST
)
4728 key_name
= TREE_PURPOSE (key_chain
);
4733 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4737 return get_identifier (buf
);
4740 /* Used for declarations and definitions. */
4743 build_method_decl (code
, ret_type
, selector
, add_args
)
4744 enum tree_code code
;
4751 /* If no type is specified, default to "id". */
4752 ret_type
= adjust_type_for_id_default (ret_type
);
4754 method_decl
= make_node (code
);
4755 TREE_TYPE (method_decl
) = ret_type
;
4757 /* If we have a keyword selector, create an identifier_node that
4758 represents the full selector name (`:' included)... */
4759 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4761 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4762 METHOD_SEL_ARGS (method_decl
) = selector
;
4763 METHOD_ADD_ARGS (method_decl
) = add_args
;
4767 METHOD_SEL_NAME (method_decl
) = selector
;
4768 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4769 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4775 #define METHOD_DEF 0
4776 #define METHOD_REF 1
4778 /* Used by `build_message_expr' and `comp_method_types'. Return an
4779 argument list for method METH. CONTEXT is either METHOD_DEF or
4780 METHOD_REF, saying whether we are trying to define a method or call
4781 one. SUPERFLAG says this is for a send to super; this makes a
4782 difference for the NeXT calling sequence in which the lookup and
4783 the method call are done together. */
4786 get_arg_type_list (meth
, context
, superflag
)
4793 /* Receiver type. */
4794 if (flag_next_runtime
&& superflag
)
4795 arglist
= build_tree_list (NULL_TREE
, super_type
);
4796 else if (context
== METHOD_DEF
)
4797 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4799 arglist
= build_tree_list (NULL_TREE
, id_type
);
4801 /* Selector type - will eventually change to `int'. */
4802 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4804 /* Build a list of argument types. */
4805 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4807 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4808 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4811 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4812 /* We have a `, ...' immediately following the selector,
4813 finalize the arglist...simulate get_parm_info (0). */
4815 else if (METHOD_ADD_ARGS (meth
))
4817 /* we have a variable length selector */
4818 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4819 chainon (arglist
, add_arg_list
);
4822 /* finalize the arglist...simulate get_parm_info (1) */
4823 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4829 check_duplicates (hsh
)
4832 tree meth
= NULL_TREE
;
4840 /* We have two methods with the same name and different types. */
4842 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4844 warning ("multiple declarations for method `%s'",
4845 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4847 warn_with_method ("using", type
, meth
);
4848 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4849 warn_with_method ("also found", type
, loop
->value
);
4855 /* If RECEIVER is a class reference, return the identifier node for the
4856 referenced class. RECEIVER is created by get_class_reference, so we
4857 check the exact form created depending on which runtimes are used. */
4860 receiver_is_class_object (receiver
)
4863 tree chain
, exp
, arg
;
4864 if (flag_next_runtime
)
4866 /* The receiver is a variable created by build_class_reference_decl. */
4867 if (TREE_CODE (receiver
) == VAR_DECL
4868 && TREE_TYPE (receiver
) == objc_class_type
)
4869 /* Look up the identifier. */
4870 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4871 if (TREE_PURPOSE (chain
) == receiver
)
4872 return TREE_VALUE (chain
);
4876 /* The receiver is a function call that returns an id. Check if
4877 it is a call to objc_getClass, if so, pick up the class name. */
4878 if ((exp
= TREE_OPERAND (receiver
, 0))
4879 && TREE_CODE (exp
) == ADDR_EXPR
4880 && (exp
= TREE_OPERAND (exp
, 0))
4881 && TREE_CODE (exp
) == FUNCTION_DECL
4882 && exp
== objc_get_class_decl
4883 /* we have a call to objc_getClass! */
4884 && (arg
= TREE_OPERAND (receiver
, 1))
4885 && TREE_CODE (arg
) == TREE_LIST
4886 && (arg
= TREE_VALUE (arg
)))
4889 if (TREE_CODE (arg
) == ADDR_EXPR
4890 && (arg
= TREE_OPERAND (arg
, 0))
4891 && TREE_CODE (arg
) == STRING_CST
)
4892 /* Finally, we have the class name. */
4893 return get_identifier (TREE_STRING_POINTER (arg
));
4899 /* If we are currently building a message expr, this holds
4900 the identifier of the selector of the message. This is
4901 used when printing warnings about argument mismatches. */
4903 static tree building_objc_message_expr
= 0;
4906 maybe_building_objc_message_expr ()
4908 return building_objc_message_expr
;
4911 /* Construct an expression for sending a message.
4912 MESS has the object to send to in TREE_PURPOSE
4913 and the argument list (including selector) in TREE_VALUE.
4915 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4916 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4919 build_message_expr (mess
)
4922 tree receiver
= TREE_PURPOSE (mess
);
4923 tree selector
, self_object
;
4924 tree rtype
, sel_name
;
4925 tree args
= TREE_VALUE (mess
);
4926 tree method_params
= NULL_TREE
;
4927 tree method_prototype
= NULL_TREE
;
4929 int statically_typed
= 0, statically_allocated
= 0;
4930 tree class_ident
= 0;
4932 /* 1 if this is sending to the superclass. */
4935 if (TREE_CODE (receiver
) == ERROR_MARK
)
4936 return error_mark_node
;
4938 /* Determine receiver type. */
4939 rtype
= TREE_TYPE (receiver
);
4940 super
= IS_SUPER (rtype
);
4944 if (TREE_STATIC_TEMPLATE (rtype
))
4945 statically_allocated
= 1;
4946 else if (TREE_CODE (rtype
) == POINTER_TYPE
4947 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4948 statically_typed
= 1;
4949 else if ((flag_next_runtime
4950 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4951 && (class_ident
= receiver_is_class_object (receiver
)))
4953 else if (! IS_ID (rtype
)
4954 /* Allow any type that matches objc_class_type. */
4955 && ! comptypes (rtype
, objc_class_type
))
4957 memset (errbuf
, 0, BUFSIZE
);
4958 warning ("invalid receiver type `%s'",
4959 gen_declaration (rtype
, errbuf
));
4962 if (statically_allocated
)
4963 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4965 /* Don't evaluate the receiver twice. */
4966 receiver
= save_expr (receiver
);
4967 self_object
= receiver
;
4970 /* If sending to `super', use current self as the object. */
4971 self_object
= self_decl
;
4973 /* Obtain the full selector name. */
4975 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4976 /* A unary selector. */
4978 else if (TREE_CODE (args
) == TREE_LIST
)
4979 sel_name
= build_keyword_selector (args
);
4983 /* Build the parameter list to give to the method. */
4985 method_params
= NULL_TREE
;
4986 if (TREE_CODE (args
) == TREE_LIST
)
4988 tree chain
= args
, prev
= NULL_TREE
;
4990 /* We have a keyword selector--check for comma expressions. */
4993 tree element
= TREE_VALUE (chain
);
4995 /* We have a comma expression, must collapse... */
4996 if (TREE_CODE (element
) == TREE_LIST
)
4999 TREE_CHAIN (prev
) = element
;
5004 chain
= TREE_CHAIN (chain
);
5006 method_params
= args
;
5009 /* Determine operation return type. */
5011 if (IS_SUPER (rtype
))
5015 if (CLASS_SUPER_NAME (implementation_template
))
5018 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5020 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5021 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5023 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5025 if (iface
&& !method_prototype
)
5026 warning ("`%s' does not respond to `%s'",
5027 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5028 IDENTIFIER_POINTER (sel_name
));
5032 error ("no super class declared in interface for `%s'",
5033 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5034 return error_mark_node
;
5038 else if (statically_allocated
)
5040 tree ctype
= TREE_TYPE (rtype
);
5041 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5044 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5046 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5048 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5051 if (!method_prototype
)
5052 warning ("`%s' does not respond to `%s'",
5053 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5054 IDENTIFIER_POINTER (sel_name
));
5056 else if (statically_typed
)
5058 tree ctype
= TREE_TYPE (rtype
);
5060 /* `self' is now statically_typed. All methods should be visible
5061 within the context of the implementation. */
5062 if (implementation_context
5063 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5066 = lookup_instance_method_static (implementation_template
,
5069 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5071 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5074 if (! method_prototype
5075 && implementation_template
!= implementation_context
)
5076 /* The method is not published in the interface. Check
5079 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5086 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5087 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5089 if (! method_prototype
)
5091 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5094 = lookup_method_in_protocol_list (protocol_list
,
5099 if (!method_prototype
)
5100 warning ("`%s' does not respond to `%s'",
5101 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5102 IDENTIFIER_POINTER (sel_name
));
5104 else if (class_ident
)
5106 if (implementation_context
5107 && CLASS_NAME (implementation_context
) == class_ident
)
5110 = lookup_class_method_static (implementation_template
, sel_name
);
5112 if (!method_prototype
5113 && implementation_template
!= implementation_context
)
5114 /* The method is not published in the interface. Check
5117 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5124 if ((iface
= lookup_interface (class_ident
)))
5125 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5128 if (!method_prototype
)
5130 warning ("cannot find class (factory) method.");
5131 warning ("return type for `%s' defaults to id",
5132 IDENTIFIER_POINTER (sel_name
));
5135 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5137 /* An anonymous object that has been qualified with a protocol. */
5139 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5141 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5144 if (!method_prototype
)
5148 warning ("method `%s' not implemented by protocol.",
5149 IDENTIFIER_POINTER (sel_name
));
5151 /* Try and find the method signature in the global pools. */
5153 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5154 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5156 if (!(method_prototype
= check_duplicates (hsh
)))
5157 warning ("return type defaults to id");
5164 /* We think we have an instance...loophole: extern id Object; */
5165 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5167 /* For various loopholes, like sending messages to self in a
5169 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5171 method_prototype
= check_duplicates (hsh
);
5172 if (!method_prototype
)
5174 warning ("cannot find method.");
5175 warning ("return type for `%s' defaults to id",
5176 IDENTIFIER_POINTER (sel_name
));
5180 /* Save the selector name for printing error messages. */
5181 building_objc_message_expr
= sel_name
;
5183 /* Build the parameters list for looking up the method.
5184 These are the object itself and the selector. */
5186 if (flag_typed_selectors
)
5187 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5189 selector
= build_selector_reference (sel_name
);
5191 retval
= build_objc_method_call (super
, method_prototype
,
5192 receiver
, self_object
,
5193 selector
, method_params
);
5195 building_objc_message_expr
= 0;
5200 /* Build a tree expression to send OBJECT the operation SELECTOR,
5201 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5202 assuming the method has prototype METHOD_PROTOTYPE.
5203 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5204 Use METHOD_PARAMS as list of args to pass to the method.
5205 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5208 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5209 selector
, method_params
)
5211 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5213 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5214 tree rcv_p
= (super_flag
5215 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5216 get_identifier (TAG_SUPER
)))
5219 if (flag_next_runtime
)
5221 if (! method_prototype
)
5223 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5224 tree_cons (NULL_TREE
, selector
,
5226 assemble_external (sender
);
5227 return build_function_call (sender
, method_params
);
5231 /* This is a real kludge, but it is used only for the Next.
5232 Clobber the data type of SENDER temporarily to accept
5233 all the arguments for this operation, and to return
5234 whatever this operation returns. */
5235 tree arglist
= NULL_TREE
;
5238 /* Save the proper contents of SENDER's data type. */
5239 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5240 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5242 /* Install this method's argument types. */
5243 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5245 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5247 /* Install this method's return type. */
5248 TREE_TYPE (TREE_TYPE (sender
))
5249 = groktypename (TREE_TYPE (method_prototype
));
5251 /* Call SENDER with all the parameters. This will do type
5252 checking using the arg types for this method. */
5253 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5254 tree_cons (NULL_TREE
, selector
,
5256 assemble_external (sender
);
5257 retval
= build_function_call (sender
, method_params
);
5259 /* Restore SENDER's return/argument types. */
5260 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5261 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5267 /* This is the portable way.
5268 First call the lookup function to get a pointer to the method,
5269 then cast the pointer, then call it with the method arguments. */
5272 /* Avoid trouble since we may evaluate each of these twice. */
5273 object
= save_expr (object
);
5274 selector
= save_expr (selector
);
5276 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5278 assemble_external (sender
);
5280 = build_function_call (sender
,
5281 tree_cons (NULL_TREE
, lookup_object
,
5282 tree_cons (NULL_TREE
, selector
,
5285 /* If we have a method prototype, construct the data type this
5286 method needs, and cast what we got from SENDER into a pointer
5288 if (method_prototype
)
5290 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5292 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5293 tree fake_function_type
= build_function_type (valtype
, arglist
);
5294 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5298 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5300 /* Pass the object to the method. */
5301 assemble_external (method
);
5302 return build_function_call (method
,
5303 tree_cons (NULL_TREE
, object
,
5304 tree_cons (NULL_TREE
, selector
,
5310 build_protocol_reference (p
)
5313 tree decl
, ident
, ptype
;
5315 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5317 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5319 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5320 objc_protocol_template
),
5323 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5324 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5327 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5328 DECL_EXTERNAL (decl
) = 1;
5329 TREE_PUBLIC (decl
) = 1;
5330 TREE_USED (decl
) = 1;
5331 DECL_ARTIFICIAL (decl
) = 1;
5333 make_decl_rtl (decl
, 0, 1);
5334 pushdecl_top_level (decl
);
5337 PROTOCOL_FORWARD_DECL (p
) = decl
;
5341 build_protocol_expr (protoname
)
5345 tree p
= lookup_protocol (protoname
);
5349 error ("Cannot find protocol declaration for `%s'",
5350 IDENTIFIER_POINTER (protoname
));
5351 return error_mark_node
;
5354 if (!PROTOCOL_FORWARD_DECL (p
))
5355 build_protocol_reference (p
);
5357 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5359 TREE_TYPE (expr
) = protocol_type
;
5365 build_selector_expr (selnamelist
)
5370 /* Obtain the full selector name. */
5371 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5372 /* A unary selector. */
5373 selname
= selnamelist
;
5374 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5375 selname
= build_keyword_selector (selnamelist
);
5379 if (flag_typed_selectors
)
5380 return build_typed_selector_reference (selname
, 0);
5382 return build_selector_reference (selname
);
5386 build_encode_expr (type
)
5392 encode_type (type
, obstack_object_size (&util_obstack
),
5393 OBJC_ENCODE_INLINE_DEFS
);
5394 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5395 string
= obstack_finish (&util_obstack
);
5397 /* Synthesize a string that represents the encoded struct/union. */
5398 result
= my_build_string (strlen (string
) + 1, string
);
5399 obstack_free (&util_obstack
, util_firstobj
);
5404 build_ivar_reference (id
)
5407 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5409 /* Historically, a class method that produced objects (factory
5410 method) would assign `self' to the instance that it
5411 allocated. This would effectively turn the class method into
5412 an instance method. Following this assignment, the instance
5413 variables could be accessed. That practice, while safe,
5414 violates the simple rule that a class method should not refer
5415 to an instance variable. It's better to catch the cases
5416 where this is done unknowingly than to support the above
5418 warning ("instance variable `%s' accessed in class method",
5419 IDENTIFIER_POINTER (id
));
5420 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5423 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5426 #define HASH_ALLOC_LIST_SIZE 170
5427 #define ATTR_ALLOC_LIST_SIZE 170
5428 #define SIZEHASHTABLE 257
5431 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5436 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5437 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5439 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5440 perror ("unable to allocate space in objc-tree.c");
5445 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5447 nst_method_hash_list
[i
] = 0;
5448 cls_method_hash_list
[i
] = 0;
5454 hash_enter (hashlist
, method
)
5458 static hash hash_alloc_list
= 0;
5459 static int hash_alloc_index
= 0;
5461 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5463 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5465 hash_alloc_index
= 0;
5466 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5467 * HASH_ALLOC_LIST_SIZE
);
5468 if (! hash_alloc_list
)
5469 perror ("unable to allocate in objc-tree.c");
5471 obj
= &hash_alloc_list
[hash_alloc_index
++];
5473 obj
->next
= hashlist
[slot
];
5476 hashlist
[slot
] = obj
; /* append to front */
5480 hash_lookup (hashlist
, sel_name
)
5486 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5490 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5493 target
= target
->next
;
5499 hash_add_attr (entry
, value
)
5503 static attr attr_alloc_list
= 0;
5504 static int attr_alloc_index
= 0;
5507 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5509 attr_alloc_index
= 0;
5510 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5511 * ATTR_ALLOC_LIST_SIZE
);
5512 if (! attr_alloc_list
)
5513 perror ("unable to allocate in objc-tree.c");
5515 obj
= &attr_alloc_list
[attr_alloc_index
++];
5516 obj
->next
= entry
->list
;
5519 entry
->list
= obj
; /* append to front */
5523 lookup_method (mchain
, method
)
5529 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5532 key
= METHOD_SEL_NAME (method
);
5536 if (METHOD_SEL_NAME (mchain
) == key
)
5538 mchain
= TREE_CHAIN (mchain
);
5544 lookup_instance_method_static (interface
, ident
)
5548 tree inter
= interface
;
5549 tree chain
= CLASS_NST_METHODS (inter
);
5550 tree meth
= NULL_TREE
;
5554 if ((meth
= lookup_method (chain
, ident
)))
5557 if (CLASS_CATEGORY_LIST (inter
))
5559 tree category
= CLASS_CATEGORY_LIST (inter
);
5560 chain
= CLASS_NST_METHODS (category
);
5564 if ((meth
= lookup_method (chain
, ident
)))
5567 /* Check for instance methods in protocols in categories. */
5568 if (CLASS_PROTOCOL_LIST (category
))
5570 if ((meth
= (lookup_method_in_protocol_list
5571 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5575 if ((category
= CLASS_CATEGORY_LIST (category
)))
5576 chain
= CLASS_NST_METHODS (category
);
5581 if (CLASS_PROTOCOL_LIST (inter
))
5583 if ((meth
= (lookup_method_in_protocol_list
5584 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5588 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5589 chain
= CLASS_NST_METHODS (inter
);
5597 lookup_class_method_static (interface
, ident
)
5601 tree inter
= interface
;
5602 tree chain
= CLASS_CLS_METHODS (inter
);
5603 tree meth
= NULL_TREE
;
5604 tree root_inter
= NULL_TREE
;
5608 if ((meth
= lookup_method (chain
, ident
)))
5611 if (CLASS_CATEGORY_LIST (inter
))
5613 tree category
= CLASS_CATEGORY_LIST (inter
);
5614 chain
= CLASS_CLS_METHODS (category
);
5618 if ((meth
= lookup_method (chain
, ident
)))
5621 /* Check for class methods in protocols in categories. */
5622 if (CLASS_PROTOCOL_LIST (category
))
5624 if ((meth
= (lookup_method_in_protocol_list
5625 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5629 if ((category
= CLASS_CATEGORY_LIST (category
)))
5630 chain
= CLASS_CLS_METHODS (category
);
5635 /* Check for class methods in protocols. */
5636 if (CLASS_PROTOCOL_LIST (inter
))
5638 if ((meth
= (lookup_method_in_protocol_list
5639 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5644 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5645 chain
= CLASS_CLS_METHODS (inter
);
5649 /* Simulate wrap around. */
5650 return lookup_instance_method_static (root_inter
, ident
);
5654 add_class_method (class, method
)
5661 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5663 /* put method on list in reverse order */
5664 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5665 CLASS_CLS_METHODS (class) = method
;
5669 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5670 error ("duplicate definition of class method `%s'.",
5671 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5674 /* Check types; if different, complain. */
5675 if (!comp_proto_with_proto (method
, mth
))
5676 error ("duplicate declaration of class method `%s'.",
5677 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5681 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5683 /* Install on a global chain. */
5684 hash_enter (cls_method_hash_list
, method
);
5688 /* Check types; if different, add to a list. */
5689 if (!comp_proto_with_proto (method
, hsh
->key
))
5690 hash_add_attr (hsh
, method
);
5696 add_instance_method (class, method
)
5703 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5705 /* Put method on list in reverse order. */
5706 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5707 CLASS_NST_METHODS (class) = method
;
5711 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5712 error ("duplicate definition of instance method `%s'.",
5713 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5716 /* Check types; if different, complain. */
5717 if (!comp_proto_with_proto (method
, mth
))
5718 error ("duplicate declaration of instance method `%s'.",
5719 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5723 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5725 /* Install on a global chain. */
5726 hash_enter (nst_method_hash_list
, method
);
5730 /* Check types; if different, add to a list. */
5731 if (!comp_proto_with_proto (method
, hsh
->key
))
5732 hash_add_attr (hsh
, method
);
5741 /* Put interfaces on list in reverse order. */
5742 TREE_CHAIN (class) = interface_chain
;
5743 interface_chain
= class;
5744 return interface_chain
;
5748 add_category (class, category
)
5752 /* Put categories on list in reverse order. */
5753 tree cat
= CLASS_CATEGORY_LIST (class);
5757 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5758 warning ("duplicate interface declaration for category `%s(%s)'",
5759 IDENTIFIER_POINTER (CLASS_NAME (class)),
5760 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5761 cat
= CLASS_CATEGORY_LIST (cat
);
5764 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5765 CLASS_CATEGORY_LIST (class) = category
;
5768 /* Called after parsing each instance variable declaration. Necessary to
5769 preserve typedefs and implement public/private...
5771 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5774 add_instance_variable (class, public, declarator
, declspecs
, width
)
5781 tree field_decl
, raw_decl
;
5783 raw_decl
= build_tree_list (declspecs
, declarator
);
5785 if (CLASS_RAW_IVARS (class))
5786 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5788 CLASS_RAW_IVARS (class) = raw_decl
;
5790 field_decl
= grokfield (input_filename
, lineno
,
5791 declarator
, declspecs
, width
);
5793 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5797 TREE_PUBLIC (field_decl
) = 0;
5798 TREE_PRIVATE (field_decl
) = 0;
5799 TREE_PROTECTED (field_decl
) = 1;
5803 TREE_PUBLIC (field_decl
) = 1;
5804 TREE_PRIVATE (field_decl
) = 0;
5805 TREE_PROTECTED (field_decl
) = 0;
5809 TREE_PUBLIC (field_decl
) = 0;
5810 TREE_PRIVATE (field_decl
) = 1;
5811 TREE_PROTECTED (field_decl
) = 0;
5816 if (CLASS_IVARS (class))
5817 chainon (CLASS_IVARS (class), field_decl
);
5819 CLASS_IVARS (class) = field_decl
;
5825 is_ivar (decl_chain
, ident
)
5829 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5830 if (DECL_NAME (decl_chain
) == ident
)
5835 /* True if the ivar is private and we are not in its implementation. */
5841 if (TREE_PRIVATE (decl
)
5842 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5844 error ("instance variable `%s' is declared private",
5845 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5852 /* We have an instance variable reference;, check to see if it is public. */
5855 is_public (expr
, identifier
)
5859 tree basetype
= TREE_TYPE (expr
);
5860 enum tree_code code
= TREE_CODE (basetype
);
5863 if (code
== RECORD_TYPE
)
5865 if (TREE_STATIC_TEMPLATE (basetype
))
5867 if (!lookup_interface (TYPE_NAME (basetype
)))
5869 error ("Cannot find interface declaration for `%s'",
5870 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5874 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5876 if (TREE_PUBLIC (decl
))
5879 /* Important difference between the Stepstone translator:
5880 all instance variables should be public within the context
5881 of the implementation. */
5882 if (implementation_context
5883 && (((TREE_CODE (implementation_context
)
5884 == CLASS_IMPLEMENTATION_TYPE
)
5885 || (TREE_CODE (implementation_context
)
5886 == CATEGORY_IMPLEMENTATION_TYPE
))
5887 && (CLASS_NAME (implementation_context
)
5888 == TYPE_NAME (basetype
))))
5889 return ! is_private (decl
);
5891 error ("instance variable `%s' is declared %s",
5892 IDENTIFIER_POINTER (identifier
),
5893 TREE_PRIVATE (decl
) ? "private" : "protected");
5898 else if (implementation_context
&& (basetype
== objc_object_reference
))
5900 TREE_TYPE (expr
) = uprivate_record
;
5901 warning ("static access to object of type `id'");
5908 /* Implement @defs (<classname>) within struct bodies. */
5911 get_class_ivars (interface
)
5914 return build_ivar_chain (interface
, 1);
5917 /* Make sure all entries in CHAIN are also in LIST. */
5920 check_methods (chain
, list
, mtype
)
5929 if (!lookup_method (list
, chain
))
5933 if (TREE_CODE (implementation_context
)
5934 == CLASS_IMPLEMENTATION_TYPE
)
5935 warning ("incomplete implementation of class `%s'",
5936 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5937 else if (TREE_CODE (implementation_context
)
5938 == CATEGORY_IMPLEMENTATION_TYPE
)
5939 warning ("incomplete implementation of category `%s'",
5940 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5944 warning ("method definition for `%c%s' not found",
5945 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5948 chain
= TREE_CHAIN (chain
);
5955 conforms_to_protocol (class, protocol
)
5961 tree p
= CLASS_PROTOCOL_LIST (class);
5963 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5968 tree super
= (CLASS_SUPER_NAME (class)
5969 ? lookup_interface (CLASS_SUPER_NAME (class))
5971 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5976 protocol
= TREE_CHAIN (protocol
);
5982 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5983 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5986 check_methods_accessible (chain
, context
, mtype
)
5993 tree base_context
= context
;
5997 context
= base_context
;
6001 list
= CLASS_CLS_METHODS (context
);
6003 list
= CLASS_NST_METHODS (context
);
6005 if (lookup_method (list
, chain
))
6008 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6009 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6010 context
= (CLASS_SUPER_NAME (context
)
6011 ? lookup_interface (CLASS_SUPER_NAME (context
))
6014 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6015 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6016 context
= (CLASS_NAME (context
)
6017 ? lookup_interface (CLASS_NAME (context
))
6023 if (context
== NULL_TREE
)
6027 if (TREE_CODE (implementation_context
)
6028 == CLASS_IMPLEMENTATION_TYPE
)
6029 warning ("incomplete implementation of class `%s'",
6031 (CLASS_NAME (implementation_context
)));
6032 else if (TREE_CODE (implementation_context
)
6033 == CATEGORY_IMPLEMENTATION_TYPE
)
6034 warning ("incomplete implementation of category `%s'",
6036 (CLASS_SUPER_NAME (implementation_context
)));
6039 warning ("method definition for `%c%s' not found",
6040 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6043 chain
= TREE_CHAIN (chain
); /* next method... */
6049 check_protocols (proto_list
, type
, name
)
6054 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6056 tree p
= TREE_VALUE (proto_list
);
6058 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6062 /* Ensure that all protocols have bodies. */
6063 if (flag_warn_protocol
) {
6064 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6065 CLASS_CLS_METHODS (implementation_context
),
6067 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6068 CLASS_NST_METHODS (implementation_context
),
6071 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6072 implementation_context
,
6074 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6075 implementation_context
,
6080 warning ("%s `%s' does not fully implement the `%s' protocol",
6081 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6086 ; /* An identifier if we could not find a protocol. */
6089 /* Check protocols recursively. */
6090 if (PROTOCOL_LIST (p
))
6093 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6094 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6095 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6100 /* Make sure that the class CLASS_NAME is defined
6101 CODE says which kind of thing CLASS_NAME ought to be.
6102 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6103 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6106 start_class (code
, class_name
, super_name
, protocol_list
)
6107 enum tree_code code
;
6114 class = make_node (code
);
6115 TYPE_BINFO (class) = make_tree_vec (5);
6117 CLASS_NAME (class) = class_name
;
6118 CLASS_SUPER_NAME (class) = super_name
;
6119 CLASS_CLS_METHODS (class) = NULL_TREE
;
6121 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6123 error ("`%s' redeclared as different kind of symbol",
6124 IDENTIFIER_POINTER (class_name
));
6125 error_with_decl (decl
, "previous declaration of `%s'");
6128 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6131 static tree implemented_classes
= 0;
6132 tree chain
= implemented_classes
;
6133 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6134 if (TREE_VALUE (chain
) == class_name
)
6136 error ("reimplementation of class `%s'",
6137 IDENTIFIER_POINTER (class_name
));
6138 return error_mark_node
;
6140 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6141 implemented_classes
);
6144 /* Pre-build the following entities - for speed/convenience. */
6146 self_id
= get_identifier ("self");
6148 ucmd_id
= get_identifier ("_cmd");
6151 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6152 if (!objc_super_template
)
6153 objc_super_template
= build_super_template ();
6155 /* Reset for multiple classes per file. */
6158 implementation_context
= class;
6160 /* Lookup the interface for this implementation. */
6162 if (!(implementation_template
= lookup_interface (class_name
)))
6164 warning ("Cannot find interface declaration for `%s'",
6165 IDENTIFIER_POINTER (class_name
));
6166 add_class (implementation_template
= implementation_context
);
6169 /* If a super class has been specified in the implementation,
6170 insure it conforms to the one specified in the interface. */
6173 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6175 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6177 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6178 error ("conflicting super class name `%s'",
6179 IDENTIFIER_POINTER (super_name
));
6180 error ("previous declaration of `%s'", name
);
6183 else if (! super_name
)
6185 CLASS_SUPER_NAME (implementation_context
)
6186 = CLASS_SUPER_NAME (implementation_template
);
6190 else if (code
== CLASS_INTERFACE_TYPE
)
6192 if (lookup_interface (class_name
))
6193 warning ("duplicate interface declaration for class `%s'",
6194 IDENTIFIER_POINTER (class_name
));
6199 CLASS_PROTOCOL_LIST (class)
6200 = lookup_and_install_protocols (protocol_list
);
6203 else if (code
== CATEGORY_INTERFACE_TYPE
)
6205 tree class_category_is_assoc_with
;
6207 /* For a category, class_name is really the name of the class that
6208 the following set of methods will be associated with. We must
6209 find the interface so that can derive the objects template. */
6211 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6213 error ("Cannot find interface declaration for `%s'",
6214 IDENTIFIER_POINTER (class_name
));
6215 exit (FATAL_EXIT_CODE
);
6218 add_category (class_category_is_assoc_with
, class);
6221 CLASS_PROTOCOL_LIST (class)
6222 = lookup_and_install_protocols (protocol_list
);
6225 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6227 /* Pre-build the following entities for speed/convenience. */
6229 self_id
= get_identifier ("self");
6231 ucmd_id
= get_identifier ("_cmd");
6234 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6235 if (!objc_super_template
)
6236 objc_super_template
= build_super_template ();
6238 /* Reset for multiple classes per file. */
6241 implementation_context
= class;
6243 /* For a category, class_name is really the name of the class that
6244 the following set of methods will be associated with. We must
6245 find the interface so that can derive the objects template. */
6247 if (!(implementation_template
= lookup_interface (class_name
)))
6249 error ("Cannot find interface declaration for `%s'",
6250 IDENTIFIER_POINTER (class_name
));
6251 exit (FATAL_EXIT_CODE
);
6258 continue_class (class)
6261 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6262 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6264 struct imp_entry
*imp_entry
;
6267 /* Check consistency of the instance variables. */
6269 if (CLASS_IVARS (class))
6270 check_ivars (implementation_template
, class);
6272 /* code generation */
6274 ivar_context
= build_private_template (implementation_template
);
6276 if (!objc_class_template
)
6277 build_class_template ();
6280 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6281 perror ("unable to allocate in objc-tree.c");
6283 imp_entry
->next
= imp_list
;
6284 imp_entry
->imp_context
= class;
6285 imp_entry
->imp_template
= implementation_template
;
6287 synth_forward_declarations ();
6288 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6289 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6291 /* Append to front and increment count. */
6292 imp_list
= imp_entry
;
6293 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6298 return ivar_context
;
6301 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6303 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6305 if (!TYPE_FIELDS (record
))
6307 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6308 CLASS_STATIC_TEMPLATE (class) = record
;
6310 /* Mark this record as a class template for static typing. */
6311 TREE_STATIC_TEMPLATE (record
) = 1;
6318 return error_mark_node
;
6321 /* This is called once we see the "@end" in an interface/implementation. */
6324 finish_class (class)
6327 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6329 /* All code generation is done in finish_objc. */
6331 if (implementation_template
!= implementation_context
)
6333 /* Ensure that all method listed in the interface contain bodies. */
6334 check_methods (CLASS_CLS_METHODS (implementation_template
),
6335 CLASS_CLS_METHODS (implementation_context
), '+');
6336 check_methods (CLASS_NST_METHODS (implementation_template
),
6337 CLASS_NST_METHODS (implementation_context
), '-');
6339 if (CLASS_PROTOCOL_LIST (implementation_template
))
6340 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6342 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6346 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6348 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6350 /* Find the category interface from the class it is associated with. */
6353 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6355 category
= CLASS_CATEGORY_LIST (category
);
6360 /* Ensure all method listed in the interface contain bodies. */
6361 check_methods (CLASS_CLS_METHODS (category
),
6362 CLASS_CLS_METHODS (implementation_context
), '+');
6363 check_methods (CLASS_NST_METHODS (category
),
6364 CLASS_NST_METHODS (implementation_context
), '-');
6366 if (CLASS_PROTOCOL_LIST (category
))
6367 check_protocols (CLASS_PROTOCOL_LIST (category
),
6369 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6373 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6376 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6377 char *string
= (char *) alloca (strlen (class_name
) + 3);
6379 /* extern struct objc_object *_<my_name>; */
6381 sprintf (string
, "_%s", class_name
);
6383 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6384 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6385 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6391 add_protocol (protocol
)
6394 /* Put protocol on list in reverse order. */
6395 TREE_CHAIN (protocol
) = protocol_chain
;
6396 protocol_chain
= protocol
;
6397 return protocol_chain
;
6401 lookup_protocol (ident
)
6406 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6408 if (ident
== PROTOCOL_NAME (chain
))
6416 start_protocol (code
, name
, list
)
6417 enum tree_code code
;
6423 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6424 if (!objc_protocol_template
)
6425 objc_protocol_template
= build_protocol_template ();
6427 protocol
= make_node (code
);
6428 TYPE_BINFO (protocol
) = make_tree_vec (2);
6430 PROTOCOL_NAME (protocol
) = name
;
6431 PROTOCOL_LIST (protocol
) = list
;
6433 lookup_and_install_protocols (list
);
6435 if (lookup_protocol (name
))
6436 warning ("duplicate declaration for protocol `%s'",
6437 IDENTIFIER_POINTER (name
));
6439 add_protocol (protocol
);
6441 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6447 finish_protocol (protocol
)
6448 tree protocol ATTRIBUTE_UNUSED
;
6453 /* "Encode" a data type into a string, which grows in util_obstack.
6454 ??? What is the FORMAT? Someone please document this! */
6457 encode_type_qualifiers (declspecs
)
6462 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6464 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6465 obstack_1grow (&util_obstack
, 'r');
6466 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6467 obstack_1grow (&util_obstack
, 'n');
6468 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6469 obstack_1grow (&util_obstack
, 'N');
6470 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6471 obstack_1grow (&util_obstack
, 'o');
6472 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6473 obstack_1grow (&util_obstack
, 'O');
6474 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6475 obstack_1grow (&util_obstack
, 'R');
6476 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6477 obstack_1grow (&util_obstack
, 'V');
6481 /* Encode a pointer type. */
6484 encode_pointer (type
, curtype
, format
)
6489 tree pointer_to
= TREE_TYPE (type
);
6491 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6493 if (TYPE_NAME (pointer_to
)
6494 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6496 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6498 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6500 obstack_1grow (&util_obstack
, '@');
6503 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6505 if (generating_instance_variables
)
6507 obstack_1grow (&util_obstack
, '@');
6508 obstack_1grow (&util_obstack
, '"');
6509 obstack_grow (&util_obstack
, name
, strlen (name
));
6510 obstack_1grow (&util_obstack
, '"');
6515 obstack_1grow (&util_obstack
, '@');
6519 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6521 obstack_1grow (&util_obstack
, '#');
6524 #ifndef OBJC_INT_SELECTORS
6525 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6527 obstack_1grow (&util_obstack
, ':');
6530 #endif /* OBJC_INT_SELECTORS */
6533 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6534 && TYPE_MODE (pointer_to
) == QImode
)
6536 obstack_1grow (&util_obstack
, '*');
6540 /* We have a type that does not get special treatment. */
6542 /* NeXT extension */
6543 obstack_1grow (&util_obstack
, '^');
6544 encode_type (pointer_to
, curtype
, format
);
6548 encode_array (type
, curtype
, format
)
6553 tree an_int_cst
= TYPE_SIZE (type
);
6554 tree array_of
= TREE_TYPE (type
);
6557 /* An incomplete array is treated like a pointer. */
6558 if (an_int_cst
== NULL
)
6560 encode_pointer (type
, curtype
, format
);
6564 sprintf (buffer
, "[%ld",
6565 (long) (TREE_INT_CST_LOW (an_int_cst
)
6566 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6568 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6569 encode_type (array_of
, curtype
, format
);
6570 obstack_1grow (&util_obstack
, ']');
6575 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6582 if (obstack_object_size (&util_obstack
) > 0
6583 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6585 tree name
= TYPE_NAME (type
);
6587 /* we have a reference; this is a NeXT extension. */
6589 if (obstack_object_size (&util_obstack
) - curtype
== 1
6590 && format
== OBJC_ENCODE_INLINE_DEFS
)
6592 /* Output format of struct for first level only. */
6593 tree fields
= TYPE_FIELDS (type
);
6595 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6597 obstack_1grow (&util_obstack
, left
);
6598 obstack_grow (&util_obstack
,
6599 IDENTIFIER_POINTER (name
),
6600 strlen (IDENTIFIER_POINTER (name
)));
6601 obstack_1grow (&util_obstack
, '=');
6605 obstack_1grow (&util_obstack
, left
);
6606 obstack_grow (&util_obstack
, "?=", 2);
6609 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6610 encode_field_decl (fields
, curtype
, format
);
6612 obstack_1grow (&util_obstack
, right
);
6615 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6617 obstack_1grow (&util_obstack
, left
);
6618 obstack_grow (&util_obstack
,
6619 IDENTIFIER_POINTER (name
),
6620 strlen (IDENTIFIER_POINTER (name
)));
6621 obstack_1grow (&util_obstack
, right
);
6626 /* We have an untagged structure or a typedef. */
6627 obstack_1grow (&util_obstack
, left
);
6628 obstack_1grow (&util_obstack
, '?');
6629 obstack_1grow (&util_obstack
, right
);
6635 tree name
= TYPE_NAME (type
);
6636 tree fields
= TYPE_FIELDS (type
);
6638 if (format
== OBJC_ENCODE_INLINE_DEFS
6639 || generating_instance_variables
)
6641 obstack_1grow (&util_obstack
, left
);
6642 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6643 obstack_grow (&util_obstack
,
6644 IDENTIFIER_POINTER (name
),
6645 strlen (IDENTIFIER_POINTER (name
)));
6647 obstack_1grow (&util_obstack
, '?');
6649 obstack_1grow (&util_obstack
, '=');
6651 for (; fields
; fields
= TREE_CHAIN (fields
))
6653 if (generating_instance_variables
)
6655 tree fname
= DECL_NAME (fields
);
6657 obstack_1grow (&util_obstack
, '"');
6658 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6660 obstack_grow (&util_obstack
,
6661 IDENTIFIER_POINTER (fname
),
6662 strlen (IDENTIFIER_POINTER (fname
)));
6665 obstack_1grow (&util_obstack
, '"');
6668 encode_field_decl (fields
, curtype
, format
);
6671 obstack_1grow (&util_obstack
, right
);
6676 obstack_1grow (&util_obstack
, left
);
6677 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6678 obstack_grow (&util_obstack
,
6679 IDENTIFIER_POINTER (name
),
6680 strlen (IDENTIFIER_POINTER (name
)));
6682 /* We have an untagged structure or a typedef. */
6683 obstack_1grow (&util_obstack
, '?');
6685 obstack_1grow (&util_obstack
, right
);
6691 encode_aggregate (type
, curtype
, format
)
6696 enum tree_code code
= TREE_CODE (type
);
6702 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6707 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6712 obstack_1grow (&util_obstack
, 'i');
6720 /* Support bitfields. The current version of Objective-C does not support
6721 them. The string will consist of one or more "b:n"'s where n is an
6722 integer describing the width of the bitfield. Currently, classes in
6723 the kit implement a method "-(char *)describeBitfieldStruct:" that
6724 simulates this. If they do not implement this method, the archiver
6725 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6726 according to the GNU compiler. After looking at the "kit", it appears
6727 that all classes currently rely on this default behavior, rather than
6728 hand generating this string (which is tedious). */
6731 encode_bitfield (width
)
6735 sprintf (buffer
, "b%d", width
);
6736 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6739 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6742 encode_type (type
, curtype
, format
)
6747 enum tree_code code
= TREE_CODE (type
);
6749 if (code
== INTEGER_TYPE
)
6751 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6753 /* Unsigned integer types. */
6755 if (TYPE_MODE (type
) == QImode
)
6756 obstack_1grow (&util_obstack
, 'C');
6757 else if (TYPE_MODE (type
) == HImode
)
6758 obstack_1grow (&util_obstack
, 'S');
6759 else if (TYPE_MODE (type
) == SImode
)
6761 if (type
== long_unsigned_type_node
)
6762 obstack_1grow (&util_obstack
, 'L');
6764 obstack_1grow (&util_obstack
, 'I');
6766 else if (TYPE_MODE (type
) == DImode
)
6767 obstack_1grow (&util_obstack
, 'Q');
6771 /* Signed integer types. */
6773 if (TYPE_MODE (type
) == QImode
)
6774 obstack_1grow (&util_obstack
, 'c');
6775 else if (TYPE_MODE (type
) == HImode
)
6776 obstack_1grow (&util_obstack
, 's');
6777 else if (TYPE_MODE (type
) == SImode
)
6779 if (type
== long_integer_type_node
)
6780 obstack_1grow (&util_obstack
, 'l');
6782 obstack_1grow (&util_obstack
, 'i');
6785 else if (TYPE_MODE (type
) == DImode
)
6786 obstack_1grow (&util_obstack
, 'q');
6790 else if (code
== REAL_TYPE
)
6792 /* Floating point types. */
6794 if (TYPE_MODE (type
) == SFmode
)
6795 obstack_1grow (&util_obstack
, 'f');
6796 else if (TYPE_MODE (type
) == DFmode
6797 || TYPE_MODE (type
) == TFmode
)
6798 obstack_1grow (&util_obstack
, 'd');
6801 else if (code
== VOID_TYPE
)
6802 obstack_1grow (&util_obstack
, 'v');
6804 else if (code
== ARRAY_TYPE
)
6805 encode_array (type
, curtype
, format
);
6807 else if (code
== POINTER_TYPE
)
6808 encode_pointer (type
, curtype
, format
);
6810 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6811 encode_aggregate (type
, curtype
, format
);
6813 else if (code
== FUNCTION_TYPE
) /* '?' */
6814 obstack_1grow (&util_obstack
, '?');
6818 encode_complete_bitfield (int position
, tree type
, int size
)
6820 enum tree_code code
= TREE_CODE (type
);
6822 char charType
= '?';
6824 if (code
== INTEGER_TYPE
)
6826 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6828 /* Unsigned integer types. */
6830 if (TYPE_MODE (type
) == QImode
)
6832 else if (TYPE_MODE (type
) == HImode
)
6834 else if (TYPE_MODE (type
) == SImode
)
6836 if (type
== long_unsigned_type_node
)
6841 else if (TYPE_MODE (type
) == DImode
)
6846 /* Signed integer types. */
6848 if (TYPE_MODE (type
) == QImode
)
6850 else if (TYPE_MODE (type
) == HImode
)
6852 else if (TYPE_MODE (type
) == SImode
)
6854 if (type
== long_integer_type_node
)
6860 else if (TYPE_MODE (type
) == DImode
)
6868 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6869 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6873 encode_field_decl (field_decl
, curtype
, format
)
6880 type
= TREE_TYPE (field_decl
);
6882 /* If this field is obviously a bitfield, or is a bitfield that has been
6883 clobbered to look like a ordinary integer mode, go ahead and generate
6884 the bitfield typing information. */
6885 if (flag_next_runtime
)
6887 if (DECL_BIT_FIELD (field_decl
))
6888 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6890 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6894 if (DECL_BIT_FIELD (field_decl
))
6895 encode_complete_bitfield (int_bit_position (field_decl
),
6896 DECL_BIT_FIELD_TYPE (field_decl
),
6897 tree_low_cst (DECL_SIZE (field_decl
), 1));
6899 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6904 expr_last (complex_expr
)
6910 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6911 complex_expr
= next
;
6913 return complex_expr
;
6916 /* The selector of the current method,
6917 or NULL if we aren't compiling a method. */
6920 maybe_objc_method_name (decl
)
6921 tree decl ATTRIBUTE_UNUSED
;
6924 return METHOD_SEL_NAME (method_context
);
6929 /* Transform a method definition into a function definition as follows:
6930 - synthesize the first two arguments, "self" and "_cmd". */
6933 start_method_def (method
)
6938 /* Required to implement _msgSuper. */
6939 method_context
= method
;
6940 UOBJC_SUPER_decl
= NULL_TREE
;
6942 /* Must be called BEFORE start_function. */
6945 /* Generate prototype declarations for arguments..."new-style". */
6947 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
6948 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6950 /* Really a `struct objc_class *'. However, we allow people to
6951 assign to self, which changes its type midstream. */
6952 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6954 push_parm_decl (build_tree_list
6955 (build_tree_list (decl_specs
,
6956 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6957 build_tree_list (unused_list
, NULL_TREE
)));
6959 #ifdef OBJC_INT_SELECTORS
6960 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
6961 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
6962 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
6963 build_tree_list (unused_list
, NULL_TREE
)));
6964 #else /* not OBJC_INT_SELECTORS */
6965 decl_specs
= build_tree_list (NULL_TREE
,
6966 xref_tag (RECORD_TYPE
,
6967 get_identifier (TAG_SELECTOR
)));
6968 push_parm_decl (build_tree_list
6969 (build_tree_list (decl_specs
,
6970 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6971 build_tree_list (unused_list
, NULL_TREE
)));
6972 #endif /* not OBJC_INT_SELECTORS */
6974 /* Generate argument declarations if a keyword_decl. */
6975 if (METHOD_SEL_ARGS (method
))
6977 tree arglist
= METHOD_SEL_ARGS (method
);
6980 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6981 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6985 tree last_expr
= expr_last (arg_decl
);
6987 /* Unite the abstract decl with its name. */
6988 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6989 push_parm_decl (build_tree_list
6990 (build_tree_list (arg_spec
, arg_decl
),
6991 build_tree_list (NULL_TREE
, NULL_TREE
)));
6993 /* Unhook: restore the abstract declarator. */
6994 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6998 push_parm_decl (build_tree_list
6999 (build_tree_list (arg_spec
,
7000 KEYWORD_ARG_NAME (arglist
)),
7001 build_tree_list (NULL_TREE
, NULL_TREE
)));
7003 arglist
= TREE_CHAIN (arglist
);
7008 if (METHOD_ADD_ARGS (method
) != NULL_TREE
7009 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7011 /* We have a variable length selector - in "prototype" format. */
7012 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7015 /* This must be done prior to calling pushdecl. pushdecl is
7016 going to change our chain on us. */
7017 tree nextkey
= TREE_CHAIN (akey
);
7025 warn_with_method (message
, mtype
, method
)
7026 const char *message
;
7030 if (count_error (1) == 0)
7033 report_error_function (DECL_SOURCE_FILE (method
));
7035 fprintf (stderr
, "%s:%d: warning: ",
7036 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7037 memset (errbuf
, 0, BUFSIZE
);
7038 fprintf (stderr
, "%s `%c%s'\n",
7039 message
, mtype
, gen_method_decl (method
, errbuf
));
7042 /* Return 1 if METHOD is consistent with PROTO. */
7045 comp_method_with_proto (method
, proto
)
7048 static tree function_type
= 0;
7050 /* Create a function_type node once. */
7053 function_type
= make_node (FUNCTION_TYPE
);
7054 ggc_add_tree_root (&function_type
, 1);
7057 /* Install argument types - normally set by build_function_type. */
7058 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7060 /* install return type */
7061 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7063 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7066 /* Return 1 if PROTO1 is consistent with PROTO2. */
7069 comp_proto_with_proto (proto0
, proto1
)
7070 tree proto0
, proto1
;
7072 static tree function_type
[2];
7074 /* Create a couple function_type node's once. */
7075 if (!function_type
[0])
7077 function_type
[0] = make_node (FUNCTION_TYPE
);
7078 function_type
[1] = make_node (FUNCTION_TYPE
);
7079 ggc_add_tree_root (function_type
, 2);
7082 /* Install argument types; normally set by build_function_type. */
7083 TYPE_ARG_TYPES (function_type
[0]) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7084 TYPE_ARG_TYPES (function_type
[1]) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7086 /* Install return type. */
7087 TREE_TYPE (function_type
[0]) = groktypename (TREE_TYPE (proto0
));
7088 TREE_TYPE (function_type
[1]) = groktypename (TREE_TYPE (proto1
));
7090 return comptypes (function_type
[0], function_type
[1]);
7093 /* - Generate an identifier for the function. the format is "_n_cls",
7094 where 1 <= n <= nMethods, and cls is the name the implementation we
7096 - Install the return type from the method declaration.
7097 - If we have a prototype, check for type consistency. */
7100 really_start_method (method
, parmlist
)
7101 tree method
, parmlist
;
7103 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7104 tree method_decl
, method_id
;
7105 const char *sel_name
, *class_name
, *cat_name
;
7108 /* Synth the storage class & assemble the return type. */
7109 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7110 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7111 decl_specs
= chainon (sc_spec
, ret_spec
);
7113 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7114 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7115 cat_name
= ((TREE_CODE (implementation_context
)
7116 == CLASS_IMPLEMENTATION_TYPE
)
7118 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7121 /* Make sure this is big enough for any plausible method label. */
7122 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7123 + (cat_name
? strlen (cat_name
) : 0));
7125 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7126 class_name
, cat_name
, sel_name
, method_slot
);
7128 method_id
= get_identifier (buf
);
7130 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7132 /* Check the declarator portion of the return type for the method. */
7133 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7135 /* Unite the complex decl (specified in the abstract decl) with the
7136 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7137 tree save_expr
= expr_last (ret_decl
);
7139 TREE_OPERAND (save_expr
, 0) = method_decl
;
7140 method_decl
= ret_decl
;
7142 /* Fool the parser into thinking it is starting a function. */
7143 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7145 /* Unhook: this has the effect of restoring the abstract declarator. */
7146 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7151 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7153 /* Fool the parser into thinking it is starting a function. */
7154 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7156 /* Unhook: this has the effect of restoring the abstract declarator. */
7157 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7160 METHOD_DEFINITION (method
) = current_function_decl
;
7162 if (implementation_template
!= implementation_context
)
7166 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7167 proto
= lookup_instance_method_static (implementation_template
,
7168 METHOD_SEL_NAME (method
));
7170 proto
= lookup_class_method_static (implementation_template
,
7171 METHOD_SEL_NAME (method
));
7173 if (proto
&& ! comp_method_with_proto (method
, proto
))
7175 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7177 warn_with_method ("conflicting types for", type
, method
);
7178 warn_with_method ("previous declaration of", type
, proto
);
7183 /* The following routine is always called...this "architecture" is to
7184 accommodate "old-style" variable length selectors.
7186 - a:a b:b // prototype ; id c; id d; // old-style. */
7189 continue_method_def ()
7193 if (METHOD_ADD_ARGS (method_context
) == objc_ellipsis_node
)
7194 /* We have a `, ...' immediately following the selector. */
7195 parmlist
= get_parm_info (0);
7197 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7199 /* Set self_decl from the first argument...this global is used by
7200 build_ivar_reference calling build_indirect_ref. */
7201 self_decl
= TREE_PURPOSE (parmlist
);
7204 really_start_method (method_context
, parmlist
);
7205 store_parm_decls ();
7208 /* Called by the parser, from the `pushlevel' production. */
7213 if (!UOBJC_SUPER_decl
)
7215 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7216 build_tree_list (NULL_TREE
,
7217 objc_super_template
),
7218 0, NULL_TREE
, NULL_TREE
);
7220 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7222 /* This prevents `unused variable' warnings when compiling with -Wall. */
7223 TREE_USED (UOBJC_SUPER_decl
) = 1;
7224 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7228 /* _n_Method (id self, SEL sel, ...)
7230 struct objc_super _S;
7231 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7235 get_super_receiver ()
7239 tree super_expr
, super_expr_list
;
7241 /* Set receiver to self. */
7242 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7243 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7244 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7246 /* Set class to begin searching. */
7247 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7248 get_identifier ("class"));
7250 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7252 /* [_cls, __cls]Super are "pre-built" in
7253 synth_forward_declarations. */
7255 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7256 ((TREE_CODE (method_context
)
7257 == INSTANCE_METHOD_DECL
)
7259 : uucls_super_ref
));
7263 /* We have a category. */
7265 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7270 error ("no super class declared in interface for `%s'",
7271 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7272 return error_mark_node
;
7275 if (flag_next_runtime
)
7277 super_class
= get_class_reference (super_name
);
7278 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7280 = build_component_ref (build_indirect_ref (super_class
, "->"),
7281 get_identifier ("isa"));
7285 add_class_reference (super_name
);
7286 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7287 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7288 assemble_external (super_class
);
7290 = build_function_call
7294 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7295 IDENTIFIER_POINTER (super_name
))));
7298 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7299 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7302 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7304 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7305 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7307 return build_compound_expr (super_expr_list
);
7311 error ("[super ...] must appear in a method context");
7312 return error_mark_node
;
7317 encode_method_def (func_decl
)
7322 HOST_WIDE_INT max_parm_end
= 0;
7327 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7328 obstack_object_size (&util_obstack
),
7329 OBJC_ENCODE_INLINE_DEFS
);
7332 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7333 parms
= TREE_CHAIN (parms
))
7335 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7336 + int_size_in_bytes (TREE_TYPE (parms
)));
7338 if (! offset_is_register
&& parm_end
> max_parm_end
)
7339 max_parm_end
= parm_end
;
7342 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7344 sprintf (buffer
, "%d", stack_size
);
7345 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7347 /* Argument types. */
7348 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7349 parms
= TREE_CHAIN (parms
))
7352 encode_type (TREE_TYPE (parms
),
7353 obstack_object_size (&util_obstack
),
7354 OBJC_ENCODE_INLINE_DEFS
);
7356 /* Compute offset. */
7357 sprintf (buffer
, "%d", forwarding_offset (parms
));
7359 /* Indicate register. */
7360 if (offset_is_register
)
7361 obstack_1grow (&util_obstack
, '+');
7363 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7366 obstack_1grow (&util_obstack
, 0);
7367 result
= get_identifier (obstack_finish (&util_obstack
));
7368 obstack_free (&util_obstack
, util_firstobj
);
7373 objc_expand_function_end ()
7375 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7379 finish_method_def ()
7381 lang_expand_function_end
= objc_expand_function_end
;
7382 finish_function (0);
7383 lang_expand_function_end
= NULL
;
7385 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7386 since the optimizer may find "may be used before set" errors. */
7387 method_context
= NULL_TREE
;
7392 lang_report_error_function (decl
)
7397 fprintf (stderr
, "In method `%s'\n",
7398 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7408 is_complex_decl (type
)
7411 return (TREE_CODE (type
) == ARRAY_TYPE
7412 || TREE_CODE (type
) == FUNCTION_TYPE
7413 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7417 /* Code to convert a decl node into text for a declaration in C. */
7419 static char tmpbuf
[256];
7422 adorn_decl (decl
, str
)
7426 enum tree_code code
= TREE_CODE (decl
);
7428 if (code
== ARRAY_REF
)
7430 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7432 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7433 sprintf (str
+ strlen (str
), "[%ld]",
7434 (long) TREE_INT_CST_LOW (an_int_cst
));
7439 else if (code
== ARRAY_TYPE
)
7441 tree an_int_cst
= TYPE_SIZE (decl
);
7442 tree array_of
= TREE_TYPE (decl
);
7444 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7445 sprintf (str
+ strlen (str
), "[%ld]",
7446 (long) (TREE_INT_CST_LOW (an_int_cst
)
7447 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7452 else if (code
== CALL_EXPR
)
7454 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7459 gen_declaration (chain
, str
);
7460 chain
= TREE_CHAIN (chain
);
7467 else if (code
== FUNCTION_TYPE
)
7469 tree chain
= TYPE_ARG_TYPES (decl
);
7472 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7474 gen_declaration (TREE_VALUE (chain
), str
);
7475 chain
= TREE_CHAIN (chain
);
7476 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7482 else if (code
== INDIRECT_REF
)
7484 strcpy (tmpbuf
, "*");
7485 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7489 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7491 chain
= TREE_CHAIN (chain
))
7493 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7495 strcat (tmpbuf
, " ");
7496 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7500 strcat (tmpbuf
, " ");
7502 strcat (tmpbuf
, str
);
7503 strcpy (str
, tmpbuf
);
7506 else if (code
== POINTER_TYPE
)
7508 strcpy (tmpbuf
, "*");
7509 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7511 if (TREE_READONLY (decl
))
7512 strcat (tmpbuf
, " const");
7513 if (TYPE_VOLATILE (decl
))
7514 strcat (tmpbuf
, " volatile");
7516 strcat (tmpbuf
, " ");
7518 strcat (tmpbuf
, str
);
7519 strcpy (str
, tmpbuf
);
7524 gen_declarator (decl
, buf
, name
)
7531 enum tree_code code
= TREE_CODE (decl
);
7541 op
= TREE_OPERAND (decl
, 0);
7543 /* We have a pointer to a function or array...(*)(), (*)[] */
7544 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7545 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7548 str
= gen_declarator (op
, buf
, name
);
7552 strcpy (tmpbuf
, "(");
7553 strcat (tmpbuf
, str
);
7554 strcat (tmpbuf
, ")");
7555 strcpy (str
, tmpbuf
);
7558 adorn_decl (decl
, str
);
7567 /* This clause is done iteratively rather than recursively. */
7570 op
= (is_complex_decl (TREE_TYPE (decl
))
7571 ? TREE_TYPE (decl
) : NULL_TREE
);
7573 adorn_decl (decl
, str
);
7575 /* We have a pointer to a function or array...(*)(), (*)[] */
7576 if (code
== POINTER_TYPE
7577 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7578 || TREE_CODE (op
) == ARRAY_TYPE
))
7580 strcpy (tmpbuf
, "(");
7581 strcat (tmpbuf
, str
);
7582 strcat (tmpbuf
, ")");
7583 strcpy (str
, tmpbuf
);
7586 decl
= (is_complex_decl (TREE_TYPE (decl
))
7587 ? TREE_TYPE (decl
) : NULL_TREE
);
7590 while (decl
&& (code
= TREE_CODE (decl
)))
7595 case IDENTIFIER_NODE
:
7596 /* Will only happen if we are processing a "raw" expr-decl. */
7597 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7608 /* We have an abstract declarator or a _DECL node. */
7616 gen_declspecs (declspecs
, buf
, raw
)
7625 for (chain
= nreverse (copy_list (declspecs
));
7626 chain
; chain
= TREE_CHAIN (chain
))
7628 tree aspec
= TREE_VALUE (chain
);
7630 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7631 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7632 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7634 if (TYPE_NAME (aspec
))
7636 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7638 if (! TREE_STATIC_TEMPLATE (aspec
))
7639 strcat (buf
, "struct ");
7640 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7645 tree chain
= protocol_list
;
7652 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7653 chain
= TREE_CHAIN (chain
);
7662 strcat (buf
, "untagged struct");
7665 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7667 if (TYPE_NAME (aspec
))
7669 if (! TREE_STATIC_TEMPLATE (aspec
))
7670 strcat (buf
, "union ");
7671 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7674 strcat (buf
, "untagged union");
7677 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7679 if (TYPE_NAME (aspec
))
7681 if (! TREE_STATIC_TEMPLATE (aspec
))
7682 strcat (buf
, "enum ");
7683 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7686 strcat (buf
, "untagged enum");
7689 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7690 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7692 else if (IS_ID (aspec
))
7694 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7699 tree chain
= protocol_list
;
7706 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7707 chain
= TREE_CHAIN (chain
);
7714 if (TREE_CHAIN (chain
))
7720 /* Type qualifiers. */
7721 if (TREE_READONLY (declspecs
))
7722 strcat (buf
, "const ");
7723 if (TYPE_VOLATILE (declspecs
))
7724 strcat (buf
, "volatile ");
7726 switch (TREE_CODE (declspecs
))
7728 /* Type specifiers. */
7731 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7733 /* Signed integer types. */
7735 if (declspecs
== short_integer_type_node
)
7736 strcat (buf
, "short int ");
7737 else if (declspecs
== integer_type_node
)
7738 strcat (buf
, "int ");
7739 else if (declspecs
== long_integer_type_node
)
7740 strcat (buf
, "long int ");
7741 else if (declspecs
== long_long_integer_type_node
)
7742 strcat (buf
, "long long int ");
7743 else if (declspecs
== signed_char_type_node
7744 || declspecs
== char_type_node
)
7745 strcat (buf
, "char ");
7747 /* Unsigned integer types. */
7749 else if (declspecs
== short_unsigned_type_node
)
7750 strcat (buf
, "unsigned short ");
7751 else if (declspecs
== unsigned_type_node
)
7752 strcat (buf
, "unsigned int ");
7753 else if (declspecs
== long_unsigned_type_node
)
7754 strcat (buf
, "unsigned long ");
7755 else if (declspecs
== long_long_unsigned_type_node
)
7756 strcat (buf
, "unsigned long long ");
7757 else if (declspecs
== unsigned_char_type_node
)
7758 strcat (buf
, "unsigned char ");
7762 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7764 if (declspecs
== float_type_node
)
7765 strcat (buf
, "float ");
7766 else if (declspecs
== double_type_node
)
7767 strcat (buf
, "double ");
7768 else if (declspecs
== long_double_type_node
)
7769 strcat (buf
, "long double ");
7773 if (TYPE_NAME (declspecs
)
7774 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7776 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7778 if (! TREE_STATIC_TEMPLATE (declspecs
))
7779 strcat (buf
, "struct ");
7780 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7784 tree chain
= protocol_list
;
7791 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7792 chain
= TREE_CHAIN (chain
);
7801 strcat (buf
, "untagged struct");
7807 if (TYPE_NAME (declspecs
)
7808 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7810 strcat (buf
, "union ");
7811 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7816 strcat (buf
, "untagged union ");
7820 if (TYPE_NAME (declspecs
)
7821 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7823 strcat (buf
, "enum ");
7824 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7829 strcat (buf
, "untagged enum ");
7833 strcat (buf
, "void ");
7838 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7843 tree chain
= protocol_list
;
7850 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7851 chain
= TREE_CHAIN (chain
);
7868 gen_declaration (atype_or_adecl
, buf
)
7869 tree atype_or_adecl
;
7874 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7876 tree declspecs
; /* "identifier_node", "record_type" */
7877 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7879 /* We have a "raw", abstract declarator (typename). */
7880 declarator
= TREE_VALUE (atype_or_adecl
);
7881 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7883 gen_declspecs (declspecs
, buf
, 1);
7887 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7894 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7895 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7897 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7898 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7899 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7900 atype
= TREE_TYPE (atype_or_adecl
);
7902 /* Assume we have a *_type node. */
7903 atype
= atype_or_adecl
;
7905 if (is_complex_decl (atype
))
7909 /* Get the declaration specifier; it is at the end of the list. */
7910 declarator
= chain
= atype
;
7912 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7913 while (is_complex_decl (chain
));
7920 declarator
= NULL_TREE
;
7923 gen_declspecs (declspecs
, buf
, 0);
7925 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7926 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7927 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7929 const char *decl_name
=
7930 (DECL_NAME (atype_or_adecl
)
7931 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7936 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7939 else if (decl_name
[0])
7942 strcat (buf
, decl_name
);
7945 else if (declarator
)
7948 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7955 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7958 gen_method_decl (method
, buf
)
7964 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7967 gen_declaration (TREE_TYPE (method
), buf
);
7971 chain
= METHOD_SEL_ARGS (method
);
7974 /* We have a chain of keyword_decls. */
7977 if (KEYWORD_KEY_NAME (chain
))
7978 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7981 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7984 gen_declaration (TREE_TYPE (chain
), buf
);
7988 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7989 if ((chain
= TREE_CHAIN (chain
)))
7994 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7995 strcat (buf
, ", ...");
7996 else if (METHOD_ADD_ARGS (method
))
7998 /* We have a tree list node as generate by get_parm_info. */
7999 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8001 /* Know we have a chain of parm_decls. */
8005 gen_declaration (chain
, buf
);
8006 chain
= TREE_CHAIN (chain
);
8012 /* We have a unary selector. */
8013 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8021 dump_interface (fp
, chain
)
8025 char *buf
= (char *)xmalloc (256);
8026 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8027 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8028 tree nst_methods
= CLASS_NST_METHODS (chain
);
8029 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8031 fprintf (fp
, "\n@interface %s", my_name
);
8033 if (CLASS_SUPER_NAME (chain
))
8035 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8036 fprintf (fp
, " : %s\n", super_name
);
8043 fprintf (fp
, "{\n");
8046 memset (buf
, 0, 256);
8047 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8048 ivar_decls
= TREE_CHAIN (ivar_decls
);
8051 fprintf (fp
, "}\n");
8056 memset (buf
, 0, 256);
8057 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8058 nst_methods
= TREE_CHAIN (nst_methods
);
8063 memset (buf
, 0, 256);
8064 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8065 cls_methods
= TREE_CHAIN (cls_methods
);
8067 fprintf (fp
, "\n@end");
8070 /* Demangle function for Objective-C */
8072 objc_demangle (mangled
)
8073 const char *mangled
;
8075 char *demangled
, *cp
;
8077 if (mangled
[0] == '_' &&
8078 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8081 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8082 if (mangled
[1] == 'i')
8083 *cp
++ = '-'; /* for instance method */
8085 *cp
++ = '+'; /* for class method */
8086 *cp
++ = '['; /* opening left brace */
8087 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8088 while (*cp
&& *cp
== '_')
8089 cp
++; /* skip any initial underbars in class name */
8090 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8093 free(demangled
); /* not mangled name */
8096 if (cp
[1] == '_') /* easy case: no category name */
8098 *cp
++ = ' '; /* replace two '_' with one ' ' */
8099 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8103 *cp
++ = '('; /* less easy case: category name */
8104 cp
= strchr(cp
, '_');
8107 free(demangled
); /* not mangled name */
8111 *cp
++ = ' '; /* overwriting 1st char of method name... */
8112 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8114 while (*cp
&& *cp
== '_')
8115 cp
++; /* skip any initial underbars in method name */
8118 *cp
= ':'; /* replace remaining '_' with ':' */
8119 *cp
++ = ']'; /* closing right brace */
8120 *cp
++ = 0; /* string terminator */
8124 return mangled
; /* not an objc mangled name */
8128 objc_printable_name (decl
, kind
)
8130 int kind ATTRIBUTE_UNUSED
;
8132 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8138 /* Add the special tree codes of Objective C to the tables. */
8140 #define LAST_CODE LAST_C_TREE_CODE
8142 gcc_obstack_init (&util_obstack
);
8143 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8145 memcpy (tree_code_type
+ (int) LAST_CODE
,
8146 objc_tree_code_type
,
8147 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8148 memcpy (tree_code_length
+ (int) LAST_CODE
,
8149 objc_tree_code_length
,
8150 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8151 memcpy (tree_code_name
+ (int) LAST_CODE
,
8152 objc_tree_code_name
,
8153 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8155 errbuf
= (char *)xmalloc (BUFSIZE
);
8157 synth_module_prologue ();
8159 /* Change the default error function */
8160 decl_printable_name
= objc_printable_name
;
8161 lang_expand_expr
= c_expand_expr
;
8162 lang_expand_decl_stmt
= c_expand_decl_stmt
;
8168 struct imp_entry
*impent
;
8170 /* The internally generated initializers appear to have missing braces.
8171 Don't warn about this. */
8172 int save_warn_missing_braces
= warn_missing_braces
;
8173 warn_missing_braces
= 0;
8175 generate_forward_declaration_to_string_table ();
8177 #ifdef OBJC_PROLOGUE
8181 /* Process the static instances here because initialization of objc_symtab
8183 if (objc_static_instances
)
8184 generate_static_references ();
8186 if (implementation_context
|| class_names_chain
8187 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8188 generate_objc_symtab_decl ();
8190 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8192 implementation_context
= impent
->imp_context
;
8193 implementation_template
= impent
->imp_template
;
8195 UOBJC_CLASS_decl
= impent
->class_decl
;
8196 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8198 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8200 /* all of the following reference the string pool... */
8201 generate_ivar_lists ();
8202 generate_dispatch_tables ();
8203 generate_shared_structures ();
8207 generate_dispatch_tables ();
8208 generate_category (implementation_context
);
8212 /* If we are using an array of selectors, we must always
8213 finish up the array decl even if no selectors were used. */
8214 if (! flag_next_runtime
|| sel_ref_chain
)
8215 build_selector_translation_table ();
8218 generate_protocols ();
8220 if (implementation_context
|| class_names_chain
|| objc_static_instances
8221 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8223 /* Arrange for Objc data structures to be initialized at run time. */
8224 const char *init_name
= build_module_descriptor ();
8226 assemble_constructor (init_name
);
8229 /* Dump the class references. This forces the appropriate classes
8230 to be linked into the executable image, preserving unix archive
8231 semantics. This can be removed when we move to a more dynamically
8232 linked environment. */
8234 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8236 handle_class_ref (chain
);
8237 if (TREE_PURPOSE (chain
))
8238 generate_classref_translation_entry (chain
);
8241 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8242 handle_impent (impent
);
8244 /* Dump the string table last. */
8246 generate_strings ();
8248 if (flag_gen_declaration
)
8250 add_class (implementation_context
);
8251 dump_interface (gen_declaration_file
, implementation_context
);
8259 /* Run through the selector hash tables and print a warning for any
8260 selector which has multiple methods. */
8262 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8263 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8266 tree meth
= hsh
->key
;
8267 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8271 warning ("potential selector conflict for method `%s'",
8272 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8273 warn_with_method ("found", type
, meth
);
8274 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8275 warn_with_method ("found", type
, loop
->value
);
8278 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8279 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8282 tree meth
= hsh
->key
;
8283 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8287 warning ("potential selector conflict for method `%s'",
8288 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8289 warn_with_method ("found", type
, meth
);
8290 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8291 warn_with_method ("found", type
, loop
->value
);
8295 warn_missing_braces
= save_warn_missing_braces
;
8298 /* Subroutines of finish_objc. */
8301 generate_classref_translation_entry (chain
)
8304 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8307 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8309 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8310 expr
= build_c_cast (type
, expr
); /* cast! */
8312 name
= DECL_NAME (TREE_PURPOSE (chain
));
8314 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8316 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8317 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8319 /* The decl that is returned from start_decl is the one that we
8320 forward declared in build_class_reference. */
8321 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8322 finish_decl (decl
, expr
, NULL_TREE
);
8327 handle_class_ref (chain
)
8330 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8331 if (! flag_next_runtime
)
8334 char *string
= (char *) alloca (strlen (name
) + 30);
8337 sprintf (string
, "%sobjc_class_name_%s",
8338 (flag_next_runtime
? "." : "__"), name
);
8340 /* Make a decl for this name, so we can use its address in a tree. */
8341 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8342 DECL_EXTERNAL (decl
) = 1;
8343 TREE_PUBLIC (decl
) = 1;
8346 rest_of_decl_compilation (decl
, 0, 0, 0);
8348 /* Make following constant read-only (why not)? */
8349 readonly_data_section ();
8351 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8353 /* Align the section properly. */
8354 assemble_constant_align (exp
);
8356 /* Inform the assembler about this new external thing. */
8357 assemble_external (decl
);
8359 /* Output a constant to reference this address. */
8360 output_constant (exp
, int_size_in_bytes (string_type_node
));
8364 /* This overreliance on our assembler (i.e. lack of portability)
8365 should be dealt with at some point. The GNU strategy (above)
8366 won't work either, but it is a start. */
8367 char *string
= (char *) alloca (strlen (name
) + 30);
8368 sprintf (string
, ".reference .objc_class_name_%s", name
);
8369 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8374 handle_impent (impent
)
8375 struct imp_entry
*impent
;
8377 implementation_context
= impent
->imp_context
;
8378 implementation_template
= impent
->imp_template
;
8380 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8382 const char *class_name
=
8383 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8384 char *string
= (char *) alloca (strlen (class_name
) + 30);
8386 if (flag_next_runtime
)
8388 /* Grossly unportable.
8389 People should know better than to assume
8390 such things about assembler syntax! */
8391 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8392 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8394 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8395 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8400 sprintf (string
, "%sobjc_class_name_%s",
8401 (flag_next_runtime
? "." : "__"), class_name
);
8402 assemble_global (string
);
8403 assemble_label (string
);
8407 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8409 const char *class_name
=
8410 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8411 const char *class_super_name
=
8412 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8413 char *string
= (char *) alloca (strlen (class_name
)
8414 + strlen (class_super_name
) + 30);
8416 /* Do the same for categories. Even though no references to these
8417 symbols are generated automatically by the compiler, it gives
8418 you a handle to pull them into an archive by hand. */
8419 if (flag_next_runtime
)
8421 /* Grossly unportable. */
8422 sprintf (string
, ".objc_category_name_%s_%s=0",
8423 class_name
, class_super_name
);
8424 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8426 sprintf (string
, ".globl .objc_category_name_%s_%s",
8427 class_name
, class_super_name
);
8428 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8433 sprintf (string
, "%sobjc_category_name_%s_%s",
8434 (flag_next_runtime
? "." : "__"),
8435 class_name
, class_super_name
);
8436 assemble_global (string
);
8437 assemble_label (string
);
8448 char *buf
= (char *)xmalloc (256);
8450 { /* dump function prototypes */
8451 tree loop
= UOBJC_MODULES_decl
;
8453 fprintf (fp
, "\n\nfunction prototypes:\n");
8456 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8458 /* We have a function definition: generate prototype. */
8459 memset (errbuf
, 0, BUFSIZE
);
8460 gen_declaration (loop
, errbuf
);
8461 fprintf (fp
, "%s;\n", errbuf
);
8463 loop
= TREE_CHAIN (loop
);
8467 /* Dump global chains. */
8469 int i
, index
= 0, offset
= 0;
8472 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8474 if (hashlist
= nst_method_hash_list
[i
])
8476 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8479 memset (buf
, 0, 256);
8480 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8481 hashlist
= hashlist
->next
;
8487 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8489 if (hashlist
= cls_method_hash_list
[i
])
8491 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8494 memset (buf
, 0, 256);
8495 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8496 hashlist
= hashlist
->next
;
8502 fprintf (fp
, "\nsel_refdef_chain:\n");
8503 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8505 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8506 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8508 /* add one for the '\0' character */
8509 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8512 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8518 print_lang_statistics ()
8523 ggc_mark_imp_list (arg
)
8526 struct imp_entry
*impent
;
8528 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8530 ggc_mark_tree (impent
->imp_context
);
8531 ggc_mark_tree (impent
->imp_template
);
8532 ggc_mark_tree (impent
->class_decl
);
8533 ggc_mark_tree (impent
->meta_decl
);
8538 ggc_mark_hash_table (arg
)
8541 hash
*hash_table
= *(hash
**)arg
;
8546 if (hash_table
== NULL
)
8548 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8549 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8551 ggc_mark_tree (hst
->key
);
8552 for (list
= hst
->list
; list
; list
= list
->next
)
8553 ggc_mark_tree (list
->value
);
8557 /* Add GC roots for variables local to this file. */
8559 objc_act_parse_init ()
8561 ggc_add_tree_root (&objc_ellipsis_node
, 1);
8562 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8563 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8564 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8565 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8568 /* Look up ID as an instance variable. */
8570 lookup_objc_ivar (id
)
8575 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8576 /* we have a message to super */
8577 return get_super_receiver ();
8578 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8580 if (is_private (decl
))
8581 return error_mark_node
;
8583 return build_ivar_reference (id
);
8589 /* Parser callbacks. */
8591 forget_protocol_qualifiers ()
8593 C_IS_RESERVED_WORD (ridpointers
[(int) RID_IN
]) = 0;
8594 C_IS_RESERVED_WORD (ridpointers
[(int) RID_OUT
]) = 0;
8595 C_IS_RESERVED_WORD (ridpointers
[(int) RID_INOUT
]) = 0;
8596 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYCOPY
]) = 0;
8597 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYREF
]) = 0;
8598 C_IS_RESERVED_WORD (ridpointers
[(int) RID_ONEWAY
]) = 0;
8602 remember_protocol_qualifiers ()
8604 C_IS_RESERVED_WORD (ridpointers
[(int) RID_IN
]) = 1;
8605 C_IS_RESERVED_WORD (ridpointers
[(int) RID_OUT
]) = 1;
8606 C_IS_RESERVED_WORD (ridpointers
[(int) RID_INOUT
]) = 1;
8607 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYCOPY
]) = 1;
8608 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYREF
]) = 1;
8609 C_IS_RESERVED_WORD (ridpointers
[(int) RID_ONEWAY
]) = 1;