1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
40 - OBJC_INT_SELECTORS */
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
87 /* Define the special tree codes that we use. */
89 /* Table indexed by tree code giving a string containing a character
90 classifying the tree code. Possibilities are
91 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
95 static const char objc_tree_code_type
[] = {
97 #include "objc-tree.def"
101 /* Table indexed by tree code giving number of expression
102 operands beyond the fixed part of the node structure.
103 Not used for types or decls. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
107 static const int objc_tree_code_length
[] = {
109 #include "objc-tree.def"
113 /* Names of tree components.
114 Used for printing out the tree and error messages. */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
117 static const char * const objc_tree_code_name
[] = {
119 #include "objc-tree.def"
123 /* Set up for use of obstacks. */
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
130 /* This obstack is used to accumulate the encoding of a data type. */
131 static struct obstack util_obstack
;
132 /* This points to the beginning of obstack contents,
133 so we can free the whole contents. */
136 /* for encode_method_def */
139 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
140 #define PROTOCOL_VERSION 2
142 #define OBJC_ENCODE_INLINE_DEFS 0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
145 /*** Private Interface (procedures) ***/
147 /* Used by compile_file. */
149 static void init_objc
PARAMS ((void));
150 static void finish_objc
PARAMS ((void));
152 /* Code generation. */
154 static void synth_module_prologue
PARAMS ((void));
155 static tree build_constructor
PARAMS ((tree
, tree
));
156 static const char *build_module_descriptor
PARAMS ((void));
157 static tree init_module_descriptor
PARAMS ((tree
));
158 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
160 static void generate_strings
PARAMS ((void));
161 static tree get_proto_encoding
PARAMS ((tree
));
162 static void build_selector_translation_table
PARAMS ((void));
163 static tree build_ivar_chain
PARAMS ((tree
, int));
165 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
167 static tree build_ivar_template
PARAMS ((void));
168 static tree build_method_template
PARAMS ((void));
169 static tree build_private_template
PARAMS ((tree
));
170 static void build_class_template
PARAMS ((void));
171 static void build_selector_template
PARAMS ((void));
172 static void build_category_template
PARAMS ((void));
173 static tree build_super_template
PARAMS ((void));
174 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
176 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
179 static void synth_forward_declarations
PARAMS ((void));
180 static void generate_ivar_lists
PARAMS ((void));
181 static void generate_dispatch_tables
PARAMS ((void));
182 static void generate_shared_structures
PARAMS ((void));
183 static tree generate_protocol_list
PARAMS ((tree
));
184 static void generate_forward_declaration_to_string_table
PARAMS ((void));
185 static void build_protocol_reference
PARAMS ((tree
));
188 static tree init_selector
PARAMS ((int));
190 static tree build_keyword_selector
PARAMS ((tree
));
191 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
193 static void generate_static_references
PARAMS ((void));
194 static int check_methods_accessible
PARAMS ((tree
, tree
,
196 static void encode_aggregate_within
PARAMS ((tree
, int, int,
198 static const char *objc_demangle
PARAMS ((const char *));
199 static const char *objc_printable_name
PARAMS ((tree
, int));
200 static void objc_expand_function_end
PARAMS ((void));
202 /* Misc. bookkeeping */
204 typedef struct hashed_entry
*hash
;
205 typedef struct hashed_attribute
*attr
;
207 struct hashed_attribute
219 static void hash_init
PARAMS ((void));
220 static void hash_enter
PARAMS ((hash
*, tree
));
221 static hash hash_lookup
PARAMS ((hash
*, tree
));
222 static void hash_add_attr
PARAMS ((hash
, tree
));
223 static tree lookup_method
PARAMS ((tree
, tree
));
224 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
225 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
226 static tree add_class
PARAMS ((tree
));
227 static void add_category
PARAMS ((tree
, tree
));
231 class_names
, /* class, category, protocol, module names */
232 meth_var_names
, /* method and variable names */
233 meth_var_types
/* method and variable type descriptors */
236 static tree add_objc_string
PARAMS ((tree
,
237 enum string_section
));
238 static tree get_objc_string_decl
PARAMS ((tree
,
239 enum string_section
));
240 static tree build_objc_string_decl
PARAMS ((enum string_section
));
241 static tree build_selector_reference_decl
PARAMS ((void));
243 /* Protocol additions. */
245 static tree add_protocol
PARAMS ((tree
));
246 static tree lookup_protocol
PARAMS ((tree
));
247 static tree lookup_and_install_protocols
PARAMS ((tree
));
251 static void encode_type_qualifiers
PARAMS ((tree
));
252 static void encode_pointer
PARAMS ((tree
, int, int));
253 static void encode_array
PARAMS ((tree
, int, int));
254 static void encode_aggregate
PARAMS ((tree
, int, int));
255 static void encode_bitfield
PARAMS ((int));
256 static void encode_type
PARAMS ((tree
, int, int));
257 static void encode_field_decl
PARAMS ((tree
, int, int));
259 static void really_start_method
PARAMS ((tree
, tree
));
260 static int comp_method_with_proto
PARAMS ((tree
, tree
));
261 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
262 static tree get_arg_type_list
PARAMS ((tree
, int, int));
263 static tree expr_last
PARAMS ((tree
));
265 /* Utilities for debugging and error diagnostics. */
267 static void warn_with_method
PARAMS ((const char *, int, tree
));
268 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
269 static char *gen_method_decl
PARAMS ((tree
, char *));
270 static char *gen_declaration
PARAMS ((tree
, char *));
271 static char *gen_declarator
PARAMS ((tree
, char *,
273 static int is_complex_decl
PARAMS ((tree
));
274 static void adorn_decl
PARAMS ((tree
, char *));
275 static void dump_interface
PARAMS ((FILE *, tree
));
277 /* Everything else. */
279 static tree define_decl
PARAMS ((tree
, tree
));
280 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
281 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
282 static tree create_builtin_decl
PARAMS ((enum tree_code
,
283 tree
, const char *));
284 static tree my_build_string
PARAMS ((int, const char *));
285 static void build_objc_symtab_template
PARAMS ((void));
286 static tree init_def_list
PARAMS ((tree
));
287 static tree init_objc_symtab
PARAMS ((tree
));
288 static void forward_declare_categories
PARAMS ((void));
289 static void generate_objc_symtab_decl
PARAMS ((void));
290 static tree build_selector
PARAMS ((tree
));
292 static tree build_msg_pool_reference
PARAMS ((int));
294 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
295 static tree build_selector_reference
PARAMS ((tree
));
296 static tree build_class_reference_decl
PARAMS ((void));
297 static void add_class_reference
PARAMS ((tree
));
298 static tree objc_copy_list
PARAMS ((tree
, tree
*));
299 static tree build_protocol_template
PARAMS ((void));
300 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
301 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
302 static tree build_method_prototype_template
PARAMS ((void));
303 static int forwarding_offset
PARAMS ((tree
));
304 static tree encode_method_prototype
PARAMS ((tree
, tree
));
305 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
307 static void generate_method_descriptors
PARAMS ((tree
));
308 static tree build_tmp_function_decl
PARAMS ((void));
309 static void hack_method_prototype
PARAMS ((tree
, tree
));
310 static void generate_protocol_references
PARAMS ((tree
));
311 static void generate_protocols
PARAMS ((void));
312 static void check_ivars
PARAMS ((tree
, tree
));
313 static tree build_ivar_list_template
PARAMS ((tree
, int));
314 static tree build_method_list_template
PARAMS ((tree
, int));
315 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
316 static tree generate_ivars_list
PARAMS ((tree
, const char *,
318 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
319 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
321 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
322 tree
, int, tree
, tree
,
324 static void generate_category
PARAMS ((tree
));
325 static int is_objc_type_qualifier
PARAMS ((tree
));
326 static tree adjust_type_for_id_default
PARAMS ((tree
));
327 static tree check_duplicates
PARAMS ((hash
));
328 static tree receiver_is_class_object
PARAMS ((tree
));
329 static int check_methods
PARAMS ((tree
, tree
, int));
330 static int conforms_to_protocol
PARAMS ((tree
, tree
));
331 static void check_protocols
PARAMS ((tree
, const char *,
333 static tree encode_method_def
PARAMS ((tree
));
334 static void gen_declspecs
PARAMS ((tree
, char *, int));
335 static void generate_classref_translation_entry
PARAMS ((tree
));
336 static void handle_class_ref
PARAMS ((tree
));
337 static void generate_struct_by_value_array
PARAMS ((void))
339 static void objc_act_parse_init
PARAMS ((void));
340 static void ggc_mark_imp_list
PARAMS ((void *));
341 static void ggc_mark_hash_table
PARAMS ((void *));
343 /*** Private Interface (data) ***/
345 /* Reserved tag definitions. */
348 #define TAG_OBJECT "objc_object"
349 #define TAG_CLASS "objc_class"
350 #define TAG_SUPER "objc_super"
351 #define TAG_SELECTOR "objc_selector"
353 #define UTAG_CLASS "_objc_class"
354 #define UTAG_IVAR "_objc_ivar"
355 #define UTAG_IVAR_LIST "_objc_ivar_list"
356 #define UTAG_METHOD "_objc_method"
357 #define UTAG_METHOD_LIST "_objc_method_list"
358 #define UTAG_CATEGORY "_objc_category"
359 #define UTAG_MODULE "_objc_module"
360 #define UTAG_STATICS "_objc_statics"
361 #define UTAG_SYMTAB "_objc_symtab"
362 #define UTAG_SUPER "_objc_super"
363 #define UTAG_SELECTOR "_objc_selector"
365 #define UTAG_PROTOCOL "_objc_protocol"
366 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
367 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
368 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
370 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
371 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
373 static const char *constant_string_class_name
= NULL
;
375 static const char *TAG_GETCLASS
;
376 static const char *TAG_GETMETACLASS
;
377 static const char *TAG_MSGSEND
;
378 static const char *TAG_MSGSENDSUPER
;
379 static const char *TAG_EXECCLASS
;
381 /* Set by `continue_class' and checked by `is_public'. */
383 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
384 #define TYPED_OBJECT(type) \
385 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
387 tree objc_ellipsis_node
;
392 OCTI_STATIC_NST_DECL
,
398 OCTI_UMSG_SUPER_DECL
,
400 OCTI_GET_MCLASS_DECL
,
414 OCTI_CLS_NAMES_CHAIN
,
415 OCTI_METH_VAR_NAMES_CHAIN
,
416 OCTI_METH_VAR_TYPES_CHAIN
,
438 OCTI_UUCLS_SUPER_REF
,
456 static tree objc_global_trees
[OCTI_MAX
];
458 /* List of classes with list of their static instances. */
459 #define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
461 /* The declaration of the array administrating the static instances. */
462 #define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
464 /* Some commonly used instances of "identifier_node". */
466 #define self_id objc_global_trees[OCTI_SELF_ID]
467 #define ucmd_id objc_global_trees[OCTI_UCMD_ID]
468 #define unused_list objc_global_trees[OCTI_UNUSED_LIST]
470 #define self_decl objc_global_trees[OCTI_SELF_DECL]
471 #define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
472 #define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
473 #define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
474 #define objc_get_meta_class_decl \
475 objc_global_trees[OCTI_GET_MCLASS_DECL]
477 #define super_type objc_global_trees[OCTI_SUPER_TYPE]
478 #define selector_type objc_global_trees[OCTI_SEL_TYPE]
479 #define id_type objc_global_trees[OCTI_ID_TYPE]
480 #define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
481 #define instance_type objc_global_trees[OCTI_NST_TYPE]
482 #define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
484 /* Type checking macros. */
486 #define IS_ID(TYPE) \
487 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
488 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
489 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
490 #define IS_SUPER(TYPE) \
491 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
493 #define class_chain objc_global_trees[OCTI_CLS_CHAIN]
494 #define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
495 #define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
496 #define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
498 /* Chains to manage selectors that are referenced and defined in the
501 #define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
502 #define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
504 /* Chains to manage uniquing of strings. */
506 #define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
507 #define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
508 #define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
510 /* Hash tables to manage the global pool of method prototypes. */
512 static hash
*nst_method_hash_list
= 0;
513 static hash
*cls_method_hash_list
= 0;
515 /* Backend data declarations. */
517 #define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
518 #define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
519 #define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
520 #define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
521 #define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
522 #define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
523 #define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
524 #define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
525 #define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
526 #define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
528 /* The following are used when compiling a class implementation.
529 implementation_template will normally be an interface, however if
530 none exists this will be equal to implementation_context...it is
531 set in start_class. */
533 #define implementation_context objc_global_trees[OCTI_IMPL_CTX]
534 #define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
538 struct imp_entry
*next
;
541 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
542 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
545 static void handle_impent
PARAMS ((struct imp_entry
*));
547 static struct imp_entry
*imp_list
= 0;
548 static int imp_count
= 0; /* `@implementation' */
549 static int cat_count
= 0; /* `@category' */
551 #define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
552 #define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
553 #define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
554 #define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
555 #define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
556 #define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
557 #define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
559 #define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
560 #define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
561 #define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
562 #define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
563 #define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
564 #define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
566 #define objc_object_id objc_global_trees[OCTI_OBJ_ID]
567 #define objc_class_id objc_global_trees[OCTI_CLS_ID]
568 #define objc_id_id objc_global_trees[OCTI_ID_ID]
569 #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
570 #define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
571 #define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
573 #define method_context objc_global_trees[OCTI_METH_CTX]
574 static int method_slot
= 0; /* Used by start_method_def, */
578 static char *errbuf
; /* Buffer for error diagnostics */
580 /* Data imported from tree.c. */
582 extern enum debug_info_type write_symbols
;
584 /* Data imported from toplev.c. */
586 extern const char *dump_base_name
;
588 /* Generate code for GNU or NeXT runtime environment. */
590 #ifdef NEXT_OBJC_RUNTIME
591 int flag_next_runtime
= 1;
593 int flag_next_runtime
= 0;
596 int flag_typed_selectors
;
598 /* Open and close the file for outputting class declarations, if requested. */
600 int flag_gen_declaration
= 0;
602 FILE *gen_declaration_file
;
604 /* Warn if multiple methods are seen for the same selector, but with
605 different argument types. */
607 int warn_selector
= 0;
609 /* Warn if methods required by a protocol are not implemented in the
610 class adopting it. When turned off, methods inherited to that
611 class are also considered implemented */
613 int flag_warn_protocol
= 1;
615 /* Tells "encode_pointer/encode_aggregate" whether we are generating
616 type descriptors for instance variables (as opposed to methods).
617 Type descriptors for instance variables contain more information
618 than methods (for static typing and embedded structures). This
619 was added to support features being planned for dbkit2. */
621 static int generating_instance_variables
= 0;
623 /* Tells the compiler that this is a special run. Do not perform
624 any compiling, instead we are to test some platform dependent
625 features and output a C header file with appropriate definitions. */
627 static int print_struct_values
= 0;
629 /* Some platforms pass small structures through registers versus through
630 an invisible pointer. Determine at what size structure is the
631 transition point between the two possibilities. */
634 generate_struct_by_value_array ()
637 tree field_decl
, field_decl_chain
;
639 int aggregate_in_mem
[32];
642 /* Presumbaly no platform passes 32 byte structures in a register. */
643 for (i
= 1; i
< 32; i
++)
647 /* Create an unnamed struct that has `i' character components */
648 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
650 strcpy (buffer
, "c1");
651 field_decl
= create_builtin_decl (FIELD_DECL
,
654 field_decl_chain
= field_decl
;
656 for (j
= 1; j
< i
; j
++)
658 sprintf (buffer
, "c%d", j
+ 1);
659 field_decl
= create_builtin_decl (FIELD_DECL
,
662 chainon (field_decl_chain
, field_decl
);
664 finish_struct (type
, field_decl_chain
, NULL_TREE
);
666 aggregate_in_mem
[i
] = aggregate_value_p (type
);
667 if (!aggregate_in_mem
[i
])
671 /* We found some structures that are returned in registers instead of memory
672 so output the necessary data. */
675 for (i
= 31; i
>= 0; i
--)
676 if (!aggregate_in_mem
[i
])
678 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
680 /* The first member of the structure is always 0 because we don't handle
681 structures with 0 members */
682 printf ("static int struct_forward_array[] = {\n 0");
684 for (j
= 1; j
<= i
; j
++)
685 printf (", %d", aggregate_in_mem
[j
]);
695 parse_in
= cpp_create_reader (CLK_OBJC
);
696 c_language
= clk_objective_c
;
702 /* Force the line number back to 0; check_newline will have
703 raised it to 1, which will make the builtin functions appear
704 not to be built in. */
707 /* If gen_declaration desired, open the output file. */
708 if (flag_gen_declaration
)
710 register char * const dumpname
= concat (dumpname
, ".decl", NULL
);
711 gen_declaration_file
= fopen (dumpname
, "w");
712 if (gen_declaration_file
== 0)
713 pfatal_with_name (dumpname
);
717 if (flag_next_runtime
)
719 TAG_GETCLASS
= "objc_getClass";
720 TAG_GETMETACLASS
= "objc_getMetaClass";
721 TAG_MSGSEND
= "objc_msgSend";
722 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
723 TAG_EXECCLASS
= "__objc_execClass";
727 TAG_GETCLASS
= "objc_get_class";
728 TAG_GETMETACLASS
= "objc_get_meta_class";
729 TAG_MSGSEND
= "objc_msg_lookup";
730 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
731 TAG_EXECCLASS
= "__objc_exec_class";
732 flag_typed_selectors
= 1;
735 objc_ellipsis_node
= make_node (ERROR_MARK
);
739 if (print_struct_values
)
740 generate_struct_by_value_array ();
742 objc_act_parse_init ();
749 finish_objc (); /* Objective-C finalization */
751 if (gen_declaration_file
)
752 fclose (gen_declaration_file
);
767 lang_decode_option (argc
, argv
)
771 const char *p
= argv
[0];
773 if (!strcmp (p
, "-gen-decls"))
774 flag_gen_declaration
= 1;
775 else if (!strcmp (p
, "-Wselector"))
777 else if (!strcmp (p
, "-Wno-selector"))
779 else if (!strcmp (p
, "-Wprotocol"))
780 flag_warn_protocol
= 1;
781 else if (!strcmp (p
, "-Wno-protocol"))
782 flag_warn_protocol
= 0;
783 else if (!strcmp (p
, "-fgnu-runtime"))
784 flag_next_runtime
= 0;
785 else if (!strcmp (p
, "-fno-next-runtime"))
786 flag_next_runtime
= 0;
787 else if (!strcmp (p
, "-fno-gnu-runtime"))
788 flag_next_runtime
= 1;
789 else if (!strcmp (p
, "-fnext-runtime"))
790 flag_next_runtime
= 1;
791 else if (!strcmp (p
, "-print-objc-runtime-info"))
792 print_struct_values
= 1;
793 #define CSTSTRCLASS "-fconstant-string-class="
794 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
795 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
796 error ("no class name specified as argument to -fconstant-string-class");
797 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
801 return c_decode_option (argc
, argv
);
806 /* used by print-tree.c */
809 lang_print_xnode (file
, node
, indent
)
810 FILE *file ATTRIBUTE_UNUSED
;
811 tree node ATTRIBUTE_UNUSED
;
812 int indent ATTRIBUTE_UNUSED
;
818 define_decl (declarator
, declspecs
)
822 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
823 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
827 /* Return 1 if LHS and RHS are compatible types for assignment or
828 various other operations. Return 0 if they are incompatible, and
829 return -1 if we choose to not decide. When the operation is
830 REFLEXIVE, check for compatibility in either direction.
832 For statically typed objects, an assignment of the form `a' = `b'
836 `a' and `b' are the same class type, or
837 `a' and `b' are of class types A and B such that B is a descendant of A. */
840 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
844 return objc_comptypes (lhs
, rhs
, reflexive
);
848 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
856 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
858 p
= TREE_VALUE (rproto
);
860 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
862 if ((fnd
= lookup_method (class_meth
863 ? PROTOCOL_CLS_METHODS (p
)
864 : PROTOCOL_NST_METHODS (p
), sel_name
)))
866 else if (PROTOCOL_LIST (p
))
867 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
868 sel_name
, class_meth
);
872 ; /* An identifier...if we could not find a protocol. */
883 lookup_protocol_in_reflist (rproto_list
, lproto
)
889 /* Make sure the protocol is support by the object on the rhs. */
890 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
893 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
895 p
= TREE_VALUE (rproto
);
897 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
902 else if (PROTOCOL_LIST (p
))
903 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
912 ; /* An identifier...if we could not find a protocol. */
918 /* Return 1 if LHS and RHS are compatible types for assignment
919 or various other operations. Return 0 if they are incompatible,
920 and return -1 if we choose to not decide. When the operation
921 is REFLEXIVE, check for compatibility in either direction. */
924 objc_comptypes (lhs
, rhs
, reflexive
)
929 /* New clause for protocols. */
931 if (TREE_CODE (lhs
) == POINTER_TYPE
932 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
933 && TREE_CODE (rhs
) == POINTER_TYPE
934 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
936 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
937 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
941 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
942 tree rproto
, rproto_list
;
947 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
949 /* Make sure the protocol is supported by the object
951 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
953 p
= TREE_VALUE (lproto
);
954 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
957 warning ("object does not conform to the `%s' protocol",
958 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
961 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
963 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
966 /* Make sure the protocol is supported by the object
968 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
970 p
= TREE_VALUE (lproto
);
972 rinter
= lookup_interface (rname
);
974 while (rinter
&& !rproto
)
978 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
979 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
981 /* Check for protocols adopted by categories. */
982 cat
= CLASS_CATEGORY_LIST (rinter
);
983 while (cat
&& !rproto
)
985 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
986 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
988 cat
= CLASS_CATEGORY_LIST (cat
);
991 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
995 warning ("class `%s' does not implement the `%s' protocol",
996 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
997 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1001 /* May change...based on whether there was any mismatch */
1004 else if (rhs_is_proto
)
1005 /* Lhs is not a protocol...warn if it is statically typed */
1006 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
1009 /* Defer to comptypes .*/
1013 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
1014 ; /* Fall thru. This is the case we have been handling all along */
1016 /* Defer to comptypes. */
1019 /* `id' = `<class> *', `<class> *' = `id' */
1021 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
1022 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
1025 /* `id' = `Class', `Class' = `id' */
1027 else if ((TYPE_NAME (lhs
) == objc_object_id
1028 && TYPE_NAME (rhs
) == objc_class_id
)
1029 || (TYPE_NAME (lhs
) == objc_class_id
1030 && TYPE_NAME (rhs
) == objc_object_id
))
1033 /* `<class> *' = `<class> *' */
1035 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1037 tree lname
= TYPE_NAME (lhs
);
1038 tree rname
= TYPE_NAME (rhs
);
1044 /* If the left hand side is a super class of the right hand side,
1046 for (inter
= lookup_interface (rname
); inter
;
1047 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1048 if (lname
== CLASS_SUPER_NAME (inter
))
1051 /* Allow the reverse when reflexive. */
1053 for (inter
= lookup_interface (lname
); inter
;
1054 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1055 if (rname
== CLASS_SUPER_NAME (inter
))
1061 /* Defer to comptypes. */
1065 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1068 objc_check_decl (decl
)
1071 tree type
= TREE_TYPE (decl
);
1073 if (TREE_CODE (type
) == RECORD_TYPE
1074 && TREE_STATIC_TEMPLATE (type
)
1075 && type
!= constant_string_type
)
1077 error_with_decl (decl
, "`%s' cannot be statically allocated");
1078 fatal ("statically allocated objects not supported");
1083 maybe_objc_check_decl (decl
)
1086 objc_check_decl (decl
);
1089 /* Implement static typing. At this point, we know we have an interface. */
1092 get_static_reference (interface
, protocols
)
1096 tree type
= xref_tag (RECORD_TYPE
, interface
);
1100 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1102 t
= copy_node (type
);
1103 TYPE_BINFO (t
) = make_tree_vec (2);
1105 /* Add this type to the chain of variants of TYPE. */
1106 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1107 TYPE_NEXT_VARIANT (m
) = t
;
1109 /* Look up protocols and install in lang specific list. */
1110 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1112 /* This forces a new pointer type to be created later
1113 (in build_pointer_type)...so that the new template
1114 we just created will actually be used...what a hack! */
1115 if (TYPE_POINTER_TO (t
))
1116 TYPE_POINTER_TO (t
) = 0;
1125 get_object_reference (protocols
)
1128 tree type_decl
= lookup_name (objc_id_id
);
1131 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1133 type
= TREE_TYPE (type_decl
);
1134 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1135 warning ("Unexpected type for `id' (%s)",
1136 gen_declaration (type
, errbuf
));
1139 fatal ("Undefined type `id', please import <objc/objc.h>");
1141 /* This clause creates a new pointer type that is qualified with
1142 the protocol specification...this info is used later to do more
1143 elaborate type checking. */
1147 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1149 t
= copy_node (type
);
1150 TYPE_BINFO (t
) = make_tree_vec (2);
1152 /* Add this type to the chain of variants of TYPE. */
1153 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1154 TYPE_NEXT_VARIANT (m
) = t
;
1156 /* Look up protocols...and install in lang specific list */
1157 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1159 /* This forces a new pointer type to be created later
1160 (in build_pointer_type)...so that the new template
1161 we just created will actually be used...what a hack! */
1162 if (TYPE_POINTER_TO (t
))
1163 TYPE_POINTER_TO (t
) = NULL
;
1171 lookup_and_install_protocols (protocols
)
1176 tree return_value
= protocols
;
1178 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1180 tree ident
= TREE_VALUE (proto
);
1181 tree p
= lookup_protocol (ident
);
1185 error ("Cannot find protocol declaration for `%s'",
1186 IDENTIFIER_POINTER (ident
));
1188 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1190 return_value
= TREE_CHAIN (proto
);
1194 /* Replace identifier with actual protocol node. */
1195 TREE_VALUE (proto
) = p
;
1200 return return_value
;
1203 /* Create and push a decl for a built-in external variable or field NAME.
1205 TYPE is its data type. */
1208 create_builtin_decl (code
, type
, name
)
1209 enum tree_code code
;
1213 tree decl
= build_decl (code
, get_identifier (name
), type
);
1215 if (code
== VAR_DECL
)
1217 TREE_STATIC (decl
) = 1;
1218 make_decl_rtl (decl
, 0, 1);
1222 DECL_ARTIFICIAL (decl
) = 1;
1226 /* Purpose: "play" parser, creating/installing representations
1227 of the declarations that are required by Objective-C.
1231 type_spec--------->sc_spec
1232 (tree_list) (tree_list)
1235 identifier_node identifier_node */
1238 synth_module_prologue ()
1243 /* Defined in `objc.h' */
1244 objc_object_id
= get_identifier (TAG_OBJECT
);
1246 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1248 id_type
= build_pointer_type (objc_object_reference
);
1250 objc_id_id
= get_identifier (TYPE_ID
);
1251 objc_class_id
= get_identifier (TAG_CLASS
);
1253 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1254 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1255 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1257 /* Declare type of selector-objects that represent an operation name. */
1259 #ifdef OBJC_INT_SELECTORS
1260 /* `unsigned int' */
1261 selector_type
= unsigned_type_node
;
1263 /* `struct objc_selector *' */
1265 = build_pointer_type (xref_tag (RECORD_TYPE
,
1266 get_identifier (TAG_SELECTOR
)));
1267 #endif /* not OBJC_INT_SELECTORS */
1269 /* Forward declare type, or else the prototype for msgSendSuper will
1272 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1273 get_identifier (TAG_SUPER
)));
1276 /* id objc_msgSend (id, SEL, ...); */
1279 = build_function_type (id_type
,
1280 tree_cons (NULL_TREE
, id_type
,
1281 tree_cons (NULL_TREE
, selector_type
,
1284 if (! flag_next_runtime
)
1286 umsg_decl
= build_decl (FUNCTION_DECL
,
1287 get_identifier (TAG_MSGSEND
), temp_type
);
1288 DECL_EXTERNAL (umsg_decl
) = 1;
1289 TREE_PUBLIC (umsg_decl
) = 1;
1290 DECL_INLINE (umsg_decl
) = 1;
1291 DECL_ARTIFICIAL (umsg_decl
) = 1;
1293 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1294 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1296 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1297 pushdecl (umsg_decl
);
1300 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1302 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1305 = build_function_type (id_type
,
1306 tree_cons (NULL_TREE
, super_p
,
1307 tree_cons (NULL_TREE
, selector_type
,
1310 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1311 temp_type
, 0, NOT_BUILT_IN
, 0);
1313 /* id objc_getClass (const char *); */
1315 temp_type
= build_function_type (id_type
,
1316 tree_cons (NULL_TREE
,
1317 const_string_type_node
,
1318 tree_cons (NULL_TREE
, void_type_node
,
1322 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1324 /* id objc_getMetaClass (const char *); */
1326 objc_get_meta_class_decl
1327 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1329 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1331 if (! flag_next_runtime
)
1333 if (flag_typed_selectors
)
1335 /* Suppress outputting debug symbols, because
1336 dbxout_init hasn'r been called yet. */
1337 enum debug_info_type save_write_symbols
= write_symbols
;
1338 write_symbols
= NO_DEBUG
;
1340 build_selector_template ();
1341 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1343 write_symbols
= save_write_symbols
;
1346 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1348 layout_type (temp_type
);
1349 UOBJC_SELECTOR_TABLE_decl
1350 = create_builtin_decl (VAR_DECL
, temp_type
,
1351 "_OBJC_SELECTOR_TABLE");
1353 /* Avoid warning when not sending messages. */
1354 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1357 generate_forward_declaration_to_string_table ();
1359 /* Forward declare constant_string_id and constant_string_type. */
1360 if (!constant_string_class_name
)
1361 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1363 constant_string_id
= get_identifier (constant_string_class_name
);
1364 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1367 /* Custom build_string which sets TREE_TYPE! */
1370 my_build_string (len
, str
)
1375 tree a_string
= build_string (len
, str
);
1377 /* Some code from combine_strings, which is local to c-parse.y. */
1378 if (TREE_TYPE (a_string
) == int_array_type_node
)
1381 TREE_TYPE (a_string
)
1382 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1383 build_index_type (build_int_2 (len
- 1, 0)));
1385 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1386 TREE_STATIC (a_string
) = 1;
1391 /* Given a chain of STRING_CST's, build a static instance of
1392 NXConstanString which points at the concatenation of those strings.
1393 We place the string object in the __string_objects section of the
1394 __OBJC segment. The Objective-C runtime will initialize the isa
1395 pointers of the string objects to point at the NXConstandString class
1399 build_objc_string_object (strings
)
1402 tree string
, initlist
, constructor
;
1405 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1407 error ("Cannot find interface declaration for `%s'",
1408 IDENTIFIER_POINTER (constant_string_id
));
1409 return error_mark_node
;
1412 add_class_reference (constant_string_id
);
1414 string
= combine_strings (strings
);
1415 TREE_SET_CODE (string
, STRING_CST
);
1416 length
= TREE_STRING_LENGTH (string
) - 1;
1418 /* & ((NXConstantString) {0, string, length}) */
1420 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1422 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1424 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1425 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1427 if (!flag_next_runtime
)
1430 = objc_add_static_instance (constructor
, constant_string_type
);
1433 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1436 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1439 objc_add_static_instance (constructor
, class_decl
)
1440 tree constructor
, class_decl
;
1442 static int num_static_inst
;
1446 /* Find the list of static instances for the CLASS_DECL. Create one if
1448 for (chain
= &objc_static_instances
;
1449 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1450 chain
= &TREE_CHAIN (*chain
));
1453 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1454 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1457 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1458 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1459 DECL_COMMON (decl
) = 1;
1460 TREE_STATIC (decl
) = 1;
1461 DECL_ARTIFICIAL (decl
) = 1;
1462 pushdecl_top_level (decl
);
1463 rest_of_decl_compilation (decl
, 0, 1, 0);
1465 /* Do this here so it gets output later instead of possibly
1466 inside something else we are writing. */
1467 DECL_INITIAL (decl
) = constructor
;
1469 /* Add the DECL to the head of this CLASS' list. */
1470 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1475 /* Build a static constant CONSTRUCTOR
1476 with type TYPE and elements ELTS. */
1479 build_constructor (type
, elts
)
1482 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1484 TREE_CONSTANT (constructor
) = 1;
1485 TREE_STATIC (constructor
) = 1;
1486 TREE_READONLY (constructor
) = 1;
1491 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1493 /* Predefine the following data type:
1501 void *defs[cls_def_cnt + cat_def_cnt];
1505 build_objc_symtab_template ()
1507 tree field_decl
, field_decl_chain
, index
;
1509 objc_symtab_template
1510 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1512 /* long sel_ref_cnt; */
1514 field_decl
= create_builtin_decl (FIELD_DECL
,
1515 long_integer_type_node
,
1517 field_decl_chain
= field_decl
;
1521 field_decl
= create_builtin_decl (FIELD_DECL
,
1522 build_pointer_type (selector_type
),
1524 chainon (field_decl_chain
, field_decl
);
1526 /* short cls_def_cnt; */
1528 field_decl
= create_builtin_decl (FIELD_DECL
,
1529 short_integer_type_node
,
1531 chainon (field_decl_chain
, field_decl
);
1533 /* short cat_def_cnt; */
1535 field_decl
= create_builtin_decl (FIELD_DECL
,
1536 short_integer_type_node
,
1538 chainon (field_decl_chain
, field_decl
);
1540 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1542 if (!flag_next_runtime
)
1543 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1545 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1546 imp_count
== 0 && cat_count
== 0
1548 field_decl
= create_builtin_decl (FIELD_DECL
,
1549 build_array_type (ptr_type_node
, index
),
1551 chainon (field_decl_chain
, field_decl
);
1553 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1556 /* Create the initial value for the `defs' field of _objc_symtab.
1557 This is a CONSTRUCTOR. */
1560 init_def_list (type
)
1563 tree expr
, initlist
= NULL_TREE
;
1564 struct imp_entry
*impent
;
1567 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1569 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1571 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1572 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1577 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1579 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1581 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1582 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1586 if (!flag_next_runtime
)
1588 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1591 if (static_instances_decl
)
1592 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1594 expr
= build_int_2 (0, 0);
1596 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1599 return build_constructor (type
, nreverse (initlist
));
1602 /* Construct the initial value for all of _objc_symtab. */
1605 init_objc_symtab (type
)
1610 /* sel_ref_cnt = { ..., 5, ... } */
1612 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1614 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1616 if (flag_next_runtime
|| ! sel_ref_chain
)
1617 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1619 initlist
= tree_cons (NULL_TREE
,
1620 build_unary_op (ADDR_EXPR
,
1621 UOBJC_SELECTOR_TABLE_decl
, 1),
1624 /* cls_def_cnt = { ..., 5, ... } */
1626 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1628 /* cat_def_cnt = { ..., 5, ... } */
1630 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1632 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1634 if (imp_count
|| cat_count
|| static_instances_decl
)
1637 tree field
= TYPE_FIELDS (type
);
1638 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1640 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1644 return build_constructor (type
, nreverse (initlist
));
1647 /* Push forward-declarations of all the categories
1648 so that init_def_list can use them in a CONSTRUCTOR. */
1651 forward_declare_categories ()
1653 struct imp_entry
*impent
;
1654 tree sav
= implementation_context
;
1656 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1658 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1660 /* Set an invisible arg to synth_id_with_class_suffix. */
1661 implementation_context
= impent
->imp_context
;
1663 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1664 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1667 implementation_context
= sav
;
1670 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1671 and initialized appropriately. */
1674 generate_objc_symtab_decl ()
1678 if (!objc_category_template
)
1679 build_category_template ();
1681 /* forward declare categories */
1683 forward_declare_categories ();
1685 if (!objc_symtab_template
)
1686 build_objc_symtab_template ();
1688 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1690 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1691 tree_cons (NULL_TREE
,
1692 objc_symtab_template
, sc_spec
),
1694 NULL_TREE
, NULL_TREE
);
1696 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1697 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1698 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1699 finish_decl (UOBJC_SYMBOLS_decl
,
1700 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1705 init_module_descriptor (type
)
1708 tree initlist
, expr
;
1710 /* version = { 1, ... } */
1712 expr
= build_int_2 (OBJC_VERSION
, 0);
1713 initlist
= build_tree_list (NULL_TREE
, expr
);
1715 /* size = { ..., sizeof (struct objc_module), ... } */
1717 expr
= size_in_bytes (objc_module_template
);
1718 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1720 /* name = { ..., "foo.m", ... } */
1722 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1723 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1725 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1727 if (UOBJC_SYMBOLS_decl
)
1728 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1730 expr
= build_int_2 (0, 0);
1731 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1733 return build_constructor (type
, nreverse (initlist
));
1736 /* Write out the data structures to describe Objective C classes defined.
1737 If appropriate, compile and output a setup function to initialize them.
1738 Return a string which is the name of a function to call to initialize
1739 the Objective C data structures for this file (and perhaps for other files
1742 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1745 build_module_descriptor ()
1747 tree decl_specs
, field_decl
, field_decl_chain
;
1749 objc_module_template
1750 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1754 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1755 field_decl
= get_identifier ("version");
1757 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1758 field_decl_chain
= field_decl
;
1762 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1763 field_decl
= get_identifier ("size");
1765 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1766 chainon (field_decl_chain
, field_decl
);
1770 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1771 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1773 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1774 chainon (field_decl_chain
, field_decl
);
1776 /* struct objc_symtab *symtab; */
1778 decl_specs
= get_identifier (UTAG_SYMTAB
);
1779 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1780 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1782 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1783 chainon (field_decl_chain
, field_decl
);
1785 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1787 /* Create an instance of "objc_module". */
1789 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1790 build_tree_list (NULL_TREE
,
1791 ridpointers
[(int) RID_STATIC
]));
1793 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1794 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1796 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1797 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1798 finish_decl (UOBJC_MODULES_decl
,
1799 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1802 /* Mark the decl to avoid "defined but not used" warning. */
1803 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1805 /* Generate a constructor call for the module descriptor.
1806 This code was generated by reading the grammar rules
1807 of c-parse.in; Therefore, it may not be the most efficient
1808 way of generating the requisite code. */
1810 if (flag_next_runtime
)
1814 tree parms
, function_decl
, decelerator
, void_list_node_1
;
1816 tree init_function_name
= get_file_function_name ('I');
1818 /* Declare void __objc_execClass (void *); */
1820 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1822 = build_function_type (void_type_node
,
1823 tree_cons (NULL_TREE
, ptr_type_node
,
1825 function_decl
= build_decl (FUNCTION_DECL
,
1826 get_identifier (TAG_EXECCLASS
),
1828 DECL_EXTERNAL (function_decl
) = 1;
1829 DECL_ARTIFICIAL (function_decl
) = 1;
1830 TREE_PUBLIC (function_decl
) = 1;
1832 pushdecl (function_decl
);
1833 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1836 = build_tree_list (NULL_TREE
,
1837 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1838 decelerator
= build_function_call (function_decl
, parms
);
1840 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1842 start_function (void_list_node_1
,
1843 build_parse_node (CALL_EXPR
, init_function_name
,
1844 /* This has the format of the output
1845 of get_parm_info. */
1846 tree_cons (NULL_TREE
, NULL_TREE
,
1849 NULL_TREE
, NULL_TREE
);
1850 #if 0 /* This should be turned back on later
1851 for the systems where collect is not needed. */
1852 /* Make these functions nonglobal
1853 so each file can use the same name. */
1854 TREE_PUBLIC (current_function_decl
) = 0;
1856 TREE_USED (current_function_decl
) = 1;
1857 store_parm_decls ();
1859 assemble_external (function_decl
);
1860 c_expand_expr_stmt (decelerator
);
1862 TREE_PUBLIC (current_function_decl
) = 1;
1864 function_decl
= current_function_decl
;
1865 finish_function (0);
1867 /* Return the name of the constructor function. */
1868 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1872 /* extern const char _OBJC_STRINGS[]; */
1875 generate_forward_declaration_to_string_table ()
1877 tree sc_spec
, decl_specs
, expr_decl
;
1879 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1880 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1883 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1885 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1888 /* Return the DECL of the string IDENT in the SECTION. */
1891 get_objc_string_decl (ident
, section
)
1893 enum string_section section
;
1897 if (section
== class_names
)
1898 chain
= class_names_chain
;
1899 else if (section
== meth_var_names
)
1900 chain
= meth_var_names_chain
;
1901 else if (section
== meth_var_types
)
1902 chain
= meth_var_types_chain
;
1906 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1907 if (TREE_VALUE (chain
) == ident
)
1908 return (TREE_PURPOSE (chain
));
1914 /* Output references to all statically allocated objects. Return the DECL
1915 for the array built. */
1918 generate_static_references ()
1920 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1921 tree class_name
, class, decl
, initlist
;
1922 tree cl_chain
, in_chain
, type
;
1923 int num_inst
, num_class
;
1926 if (flag_next_runtime
)
1929 for (cl_chain
= objc_static_instances
, num_class
= 0;
1930 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1932 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1933 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1935 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1936 ident
= get_identifier (buf
);
1938 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1939 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1940 build_tree_list (NULL_TREE
,
1941 ridpointers
[(int) RID_STATIC
]));
1942 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1943 DECL_CONTEXT (decl
) = 0;
1944 DECL_ARTIFICIAL (decl
) = 1;
1946 /* Output {class_name, ...}. */
1947 class = TREE_VALUE (cl_chain
);
1948 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1949 initlist
= build_tree_list (NULL_TREE
,
1950 build_unary_op (ADDR_EXPR
, class_name
, 1));
1952 /* Output {..., instance, ...}. */
1953 for (in_chain
= TREE_PURPOSE (cl_chain
);
1954 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1956 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1957 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1960 /* Output {..., NULL}. */
1961 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1963 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1964 finish_decl (decl
, expr
, NULL_TREE
);
1965 TREE_USED (decl
) = 1;
1967 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1968 decl
= build_decl (VAR_DECL
, ident
, type
);
1969 make_decl_rtl (decl
, 0, 1);
1970 TREE_USED (decl
) = 1;
1972 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1975 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1976 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1977 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1978 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1979 build_tree_list (NULL_TREE
,
1980 ridpointers
[(int) RID_STATIC
]));
1981 static_instances_decl
1982 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1983 TREE_USED (static_instances_decl
) = 1;
1984 DECL_CONTEXT (static_instances_decl
) = 0;
1985 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1986 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1988 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1991 /* Output all strings. */
1996 tree sc_spec
, decl_specs
, expr_decl
;
1997 tree chain
, string_expr
;
2000 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2002 string
= TREE_VALUE (chain
);
2003 decl
= TREE_PURPOSE (chain
);
2005 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2006 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2007 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2008 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2009 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2010 IDENTIFIER_POINTER (string
));
2011 finish_decl (decl
, string_expr
, NULL_TREE
);
2014 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2016 string
= TREE_VALUE (chain
);
2017 decl
= TREE_PURPOSE (chain
);
2019 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2020 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2021 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2022 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2023 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2024 IDENTIFIER_POINTER (string
));
2025 finish_decl (decl
, string_expr
, NULL_TREE
);
2028 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2030 string
= TREE_VALUE (chain
);
2031 decl
= TREE_PURPOSE (chain
);
2033 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2034 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2035 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2036 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2037 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2038 IDENTIFIER_POINTER (string
));
2039 finish_decl (decl
, string_expr
, NULL_TREE
);
2044 build_selector_reference_decl ()
2050 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2052 ident
= get_identifier (buf
);
2054 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2055 DECL_EXTERNAL (decl
) = 1;
2056 TREE_PUBLIC (decl
) = 1;
2057 TREE_USED (decl
) = 1;
2058 TREE_READONLY (decl
) = 1;
2059 DECL_ARTIFICIAL (decl
) = 1;
2060 DECL_CONTEXT (decl
) = 0;
2062 make_decl_rtl (decl
, 0, 1);
2063 pushdecl_top_level (decl
);
2068 /* Just a handy wrapper for add_objc_string. */
2071 build_selector (ident
)
2074 tree expr
= add_objc_string (ident
, meth_var_names
);
2075 if (flag_typed_selectors
)
2078 return build_c_cast (selector_type
, expr
); /* cast! */
2081 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2082 The cast stops the compiler from issuing the following message:
2083 grok.m: warning: initialization of non-const * pointer from const *
2084 grok.m: warning: initialization between incompatible pointer types. */
2088 build_msg_pool_reference (offset
)
2091 tree expr
= build_int_2 (offset
, 0);
2094 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2095 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2097 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2098 ridpointers
[(int) RID_CHAR
]),
2099 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2100 TREE_TYPE (expr
) = groktypename (cast
);
2105 init_selector (offset
)
2108 tree expr
= build_msg_pool_reference (offset
);
2109 TREE_TYPE (expr
) = selector_type
;
2115 build_selector_translation_table ()
2117 tree sc_spec
, decl_specs
;
2118 tree chain
, initlist
= NULL_TREE
;
2120 tree decl
= NULL_TREE
, var_decl
, name
;
2122 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2126 expr
= build_selector (TREE_VALUE (chain
));
2128 if (flag_next_runtime
)
2130 name
= DECL_NAME (TREE_PURPOSE (chain
));
2132 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2134 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2135 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2139 /* The `decl' that is returned from start_decl is the one that we
2140 forward declared in `build_selector_reference' */
2141 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2144 /* add one for the '\0' character */
2145 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2147 if (flag_next_runtime
)
2148 finish_decl (decl
, expr
, NULL_TREE
);
2151 if (flag_typed_selectors
)
2153 tree eltlist
= NULL_TREE
;
2154 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2155 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2156 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2157 expr
= build_constructor (objc_selector_template
,
2158 nreverse (eltlist
));
2160 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2165 if (! flag_next_runtime
)
2167 /* Cause the variable and its initial value to be actually output. */
2168 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2169 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2170 /* NULL terminate the list and fix the decl for output. */
2171 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2172 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2173 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2174 nreverse (initlist
));
2175 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2176 current_function_decl
= NULL_TREE
;
2181 get_proto_encoding (proto
)
2189 if (! METHOD_ENCODING (proto
))
2191 tmp_decl
= build_tmp_function_decl ();
2192 hack_method_prototype (proto
, tmp_decl
);
2193 encoding
= encode_method_prototype (proto
, tmp_decl
);
2194 METHOD_ENCODING (proto
) = encoding
;
2197 encoding
= METHOD_ENCODING (proto
);
2199 return add_objc_string (encoding
, meth_var_types
);
2202 return build_int_2 (0, 0);
2205 /* sel_ref_chain is a list whose "value" fields will be instances of
2206 identifier_node that represent the selector. */
2209 build_typed_selector_reference (ident
, proto
)
2212 tree
*chain
= &sel_ref_chain
;
2218 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2219 goto return_at_index
;
2222 chain
= &TREE_CHAIN (*chain
);
2225 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2228 expr
= build_unary_op (ADDR_EXPR
,
2229 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2230 build_int_2 (index
, 0)),
2232 return build_c_cast (selector_type
, expr
);
2236 build_selector_reference (ident
)
2239 tree
*chain
= &sel_ref_chain
;
2245 if (TREE_VALUE (*chain
) == ident
)
2246 return (flag_next_runtime
2247 ? TREE_PURPOSE (*chain
)
2248 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2249 build_int_2 (index
, 0)));
2252 chain
= &TREE_CHAIN (*chain
);
2255 expr
= build_selector_reference_decl ();
2257 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2259 return (flag_next_runtime
2261 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2262 build_int_2 (index
, 0)));
2266 build_class_reference_decl ()
2272 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2274 ident
= get_identifier (buf
);
2276 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2277 DECL_EXTERNAL (decl
) = 1;
2278 TREE_PUBLIC (decl
) = 1;
2279 TREE_USED (decl
) = 1;
2280 TREE_READONLY (decl
) = 1;
2281 DECL_CONTEXT (decl
) = 0;
2282 DECL_ARTIFICIAL (decl
) = 1;
2284 make_decl_rtl (decl
, 0, 1);
2285 pushdecl_top_level (decl
);
2290 /* Create a class reference, but don't create a variable to reference
2294 add_class_reference (ident
)
2299 if ((chain
= cls_ref_chain
))
2304 if (ident
== TREE_VALUE (chain
))
2308 chain
= TREE_CHAIN (chain
);
2312 /* Append to the end of the list */
2313 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2316 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2319 /* Get a class reference, creating it if necessary. Also create the
2320 reference variable. */
2323 get_class_reference (ident
)
2326 if (flag_next_runtime
)
2331 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2332 if (TREE_VALUE (*chain
) == ident
)
2334 if (! TREE_PURPOSE (*chain
))
2335 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2337 return TREE_PURPOSE (*chain
);
2340 decl
= build_class_reference_decl ();
2341 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2348 add_class_reference (ident
);
2350 params
= build_tree_list (NULL_TREE
,
2351 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2352 IDENTIFIER_POINTER (ident
)));
2354 assemble_external (objc_get_class_decl
);
2355 return build_function_call (objc_get_class_decl
, params
);
2359 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2360 of identifier_node that represent the selector. It returns the
2361 offset of the selector from the beginning of the _OBJC_STRINGS
2362 pool. This offset is typically used by init_selector during code
2365 For each string section we have a chain which maps identifier nodes
2366 to decls for the strings. */
2369 add_objc_string (ident
, section
)
2371 enum string_section section
;
2375 if (section
== class_names
)
2376 chain
= &class_names_chain
;
2377 else if (section
== meth_var_names
)
2378 chain
= &meth_var_names_chain
;
2379 else if (section
== meth_var_types
)
2380 chain
= &meth_var_types_chain
;
2386 if (TREE_VALUE (*chain
) == ident
)
2387 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2389 chain
= &TREE_CHAIN (*chain
);
2392 decl
= build_objc_string_decl (section
);
2394 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2396 return build_unary_op (ADDR_EXPR
, decl
, 1);
2400 build_objc_string_decl (section
)
2401 enum string_section section
;
2405 static int class_names_idx
= 0;
2406 static int meth_var_names_idx
= 0;
2407 static int meth_var_types_idx
= 0;
2409 if (section
== class_names
)
2410 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2411 else if (section
== meth_var_names
)
2412 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2413 else if (section
== meth_var_types
)
2414 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2416 ident
= get_identifier (buf
);
2418 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2419 DECL_EXTERNAL (decl
) = 1;
2420 TREE_PUBLIC (decl
) = 1;
2421 TREE_USED (decl
) = 1;
2422 TREE_READONLY (decl
) = 1;
2423 TREE_CONSTANT (decl
) = 1;
2424 DECL_CONTEXT (decl
) = 0;
2425 DECL_ARTIFICIAL (decl
) = 1;
2427 make_decl_rtl (decl
, 0, 1);
2428 pushdecl_top_level (decl
);
2435 objc_declare_alias (alias_ident
, class_ident
)
2439 if (is_class_name (class_ident
) != class_ident
)
2440 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2441 else if (is_class_name (alias_ident
))
2442 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2444 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2448 objc_declare_class (ident_list
)
2453 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2455 tree ident
= TREE_VALUE (list
);
2458 if ((decl
= lookup_name (ident
)))
2460 error ("`%s' redeclared as different kind of symbol",
2461 IDENTIFIER_POINTER (ident
));
2462 error_with_decl (decl
, "previous declaration of `%s'");
2465 if (! is_class_name (ident
))
2467 tree record
= xref_tag (RECORD_TYPE
, ident
);
2468 TREE_STATIC_TEMPLATE (record
) = 1;
2469 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2475 is_class_name (ident
)
2480 if (lookup_interface (ident
))
2483 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2485 if (ident
== TREE_VALUE (chain
))
2489 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2491 if (ident
== TREE_VALUE (chain
))
2492 return TREE_PURPOSE (chain
);
2499 lookup_interface (ident
)
2504 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2506 if (ident
== CLASS_NAME (chain
))
2513 objc_copy_list (list
, head
)
2517 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2521 tail
= copy_node (list
);
2523 /* The following statement fixes a bug when inheriting instance
2524 variables that are declared to be bitfields. finish_struct
2525 expects to find the width of the bitfield in DECL_INITIAL. */
2526 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2527 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2529 newlist
= chainon (newlist
, tail
);
2530 list
= TREE_CHAIN (list
);
2537 /* Used by: build_private_template, get_class_ivars, and
2538 continue_class. COPY is 1 when called from @defs. In this case
2539 copy all fields. Otherwise don't copy leaf ivars since we rely on
2540 them being side-effected exactly once by finish_struct. */
2543 build_ivar_chain (interface
, copy
)
2547 tree my_name
, super_name
, ivar_chain
;
2549 my_name
= CLASS_NAME (interface
);
2550 super_name
= CLASS_SUPER_NAME (interface
);
2552 /* Possibly copy leaf ivars. */
2554 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2556 ivar_chain
= CLASS_IVARS (interface
);
2561 tree super_interface
= lookup_interface (super_name
);
2563 if (!super_interface
)
2565 /* fatal did not work with 2 args...should fix */
2566 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2567 IDENTIFIER_POINTER (super_name
),
2568 IDENTIFIER_POINTER (my_name
));
2569 exit (FATAL_EXIT_CODE
);
2572 if (super_interface
== interface
)
2574 fatal ("Circular inheritance in interface declaration for `%s'",
2575 IDENTIFIER_POINTER (super_name
));
2578 interface
= super_interface
;
2579 my_name
= CLASS_NAME (interface
);
2580 super_name
= CLASS_SUPER_NAME (interface
);
2582 op1
= CLASS_IVARS (interface
);
2585 tree head
, tail
= objc_copy_list (op1
, &head
);
2587 /* Prepend super class ivars...make a copy of the list, we
2588 do not want to alter the original. */
2589 TREE_CHAIN (tail
) = ivar_chain
;
2596 /* struct <classname> {
2597 struct objc_class *isa;
2602 build_private_template (class)
2607 if (CLASS_STATIC_TEMPLATE (class))
2609 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2610 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2614 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2616 ivar_context
= build_ivar_chain (class, 0);
2618 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2620 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2622 /* mark this record as class template - for class type checking */
2623 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2627 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2629 build1 (INDIRECT_REF
, NULL_TREE
,
2632 return ivar_context
;
2635 /* Begin code generation for protocols... */
2637 /* struct objc_protocol {
2638 char *protocol_name;
2639 struct objc_protocol **protocol_list;
2640 struct objc_method_desc *instance_methods;
2641 struct objc_method_desc *class_methods;
2645 build_protocol_template ()
2647 tree decl_specs
, field_decl
, field_decl_chain
;
2650 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2652 /* struct objc_class *isa; */
2654 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2655 get_identifier (UTAG_CLASS
)));
2656 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2658 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2659 field_decl_chain
= field_decl
;
2661 /* char *protocol_name; */
2663 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2665 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2667 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2668 chainon (field_decl_chain
, field_decl
);
2670 /* struct objc_protocol **protocol_list; */
2672 decl_specs
= build_tree_list (NULL_TREE
, template);
2674 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2675 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2677 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2678 chainon (field_decl_chain
, field_decl
);
2680 /* struct objc_method_list *instance_methods; */
2683 = build_tree_list (NULL_TREE
,
2684 xref_tag (RECORD_TYPE
,
2685 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2687 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2689 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2690 chainon (field_decl_chain
, field_decl
);
2692 /* struct objc_method_list *class_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 ("class_methods"));
2701 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2702 chainon (field_decl_chain
, field_decl
);
2704 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2708 build_descriptor_table_initializer (type
, entries
)
2712 tree initlist
= NULL_TREE
;
2716 tree eltlist
= NULL_TREE
;
2719 = tree_cons (NULL_TREE
,
2720 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2722 = tree_cons (NULL_TREE
,
2723 add_objc_string (METHOD_ENCODING (entries
),
2728 = tree_cons (NULL_TREE
,
2729 build_constructor (type
, nreverse (eltlist
)), initlist
);
2731 entries
= TREE_CHAIN (entries
);
2735 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2738 /* struct objc_method_prototype_list {
2740 struct objc_method_prototype {
2747 build_method_prototype_list_template (list_type
, size
)
2751 tree objc_ivar_list_record
;
2752 tree decl_specs
, field_decl
, field_decl_chain
;
2754 /* Generate an unnamed struct definition. */
2756 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2758 /* int method_count; */
2760 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2761 field_decl
= get_identifier ("method_count");
2764 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2765 field_decl_chain
= field_decl
;
2767 /* struct objc_method method_list[]; */
2769 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2770 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2771 build_int_2 (size
, 0));
2774 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2775 chainon (field_decl_chain
, field_decl
);
2777 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2779 return objc_ivar_list_record
;
2783 build_method_prototype_template ()
2786 tree decl_specs
, field_decl
, field_decl_chain
;
2789 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2791 #ifdef OBJC_INT_SELECTORS
2792 /* unsigned int _cmd; */
2794 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2795 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2796 field_decl
= get_identifier ("_cmd");
2797 #else /* OBJC_INT_SELECTORS */
2798 /* struct objc_selector *_cmd; */
2799 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2800 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2801 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2802 #endif /* OBJC_INT_SELECTORS */
2805 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2806 field_decl_chain
= field_decl
;
2808 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2810 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2812 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2813 chainon (field_decl_chain
, field_decl
);
2815 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2817 return proto_record
;
2820 /* True if last call to forwarding_offset yielded a register offset. */
2821 static int offset_is_register
;
2824 forwarding_offset (parm
)
2827 int offset_in_bytes
;
2829 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2831 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2833 /* ??? Here we assume that the parm address is indexed
2834 off the frame pointer or arg pointer.
2835 If that is not true, we produce meaningless results,
2836 but do not crash. */
2837 if (GET_CODE (addr
) == PLUS
2838 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2839 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2841 offset_in_bytes
= 0;
2843 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2844 offset_is_register
= 0;
2846 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2848 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2849 offset_in_bytes
= apply_args_register_offset (regno
);
2850 offset_is_register
= 1;
2855 /* This is the case where the parm is passed as an int or double
2856 and it is converted to a char, short or float and stored back
2857 in the parmlist. In this case, describe the parm
2858 with the variable's declared type, and adjust the address
2859 if the least significant bytes (which we are using) are not
2861 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2862 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2863 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2865 return offset_in_bytes
;
2869 encode_method_prototype (method_decl
, func_decl
)
2876 HOST_WIDE_INT max_parm_end
= 0;
2880 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2881 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2884 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2885 obstack_object_size (&util_obstack
),
2886 OBJC_ENCODE_INLINE_DEFS
);
2889 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2890 parms
= TREE_CHAIN (parms
))
2892 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2893 + int_size_in_bytes (TREE_TYPE (parms
)));
2895 if (!offset_is_register
&& max_parm_end
< parm_end
)
2896 max_parm_end
= parm_end
;
2899 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2901 sprintf (buf
, "%d", stack_size
);
2902 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2904 user_args
= METHOD_SEL_ARGS (method_decl
);
2906 /* Argument types. */
2907 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2908 parms
= TREE_CHAIN (parms
), i
++)
2910 /* Process argument qualifiers for user supplied arguments. */
2913 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2914 user_args
= TREE_CHAIN (user_args
);
2918 encode_type (TREE_TYPE (parms
),
2919 obstack_object_size (&util_obstack
),
2920 OBJC_ENCODE_INLINE_DEFS
);
2922 /* Compute offset. */
2923 sprintf (buf
, "%d", forwarding_offset (parms
));
2925 /* Indicate register. */
2926 if (offset_is_register
)
2927 obstack_1grow (&util_obstack
, '+');
2929 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2932 obstack_1grow (&util_obstack
, '\0');
2933 result
= get_identifier (obstack_finish (&util_obstack
));
2934 obstack_free (&util_obstack
, util_firstobj
);
2939 generate_descriptor_table (type
, name
, size
, list
, proto
)
2946 tree sc_spec
, decl_specs
, decl
, initlist
;
2948 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2949 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2951 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2952 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2954 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2955 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2957 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2964 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2967 static tree objc_method_prototype_template
;
2968 tree initlist
, chain
, method_list_template
;
2969 tree cast
, variable_length_type
;
2972 if (!objc_method_prototype_template
)
2974 objc_method_prototype_template
= build_method_prototype_template ();
2975 ggc_add_tree_root (&objc_method_prototype_template
, 1);
2978 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2979 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2981 variable_length_type
= groktypename (cast
);
2983 chain
= PROTOCOL_CLS_METHODS (protocol
);
2986 size
= list_length (chain
);
2988 method_list_template
2989 = build_method_prototype_list_template (objc_method_prototype_template
,
2993 = build_descriptor_table_initializer (objc_method_prototype_template
,
2996 UOBJC_CLASS_METHODS_decl
2997 = generate_descriptor_table (method_list_template
,
2998 "_OBJC_PROTOCOL_CLASS_METHODS",
2999 size
, initlist
, protocol
);
3000 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3003 UOBJC_CLASS_METHODS_decl
= 0;
3005 chain
= PROTOCOL_NST_METHODS (protocol
);
3008 size
= list_length (chain
);
3010 method_list_template
3011 = build_method_prototype_list_template (objc_method_prototype_template
,
3014 = build_descriptor_table_initializer (objc_method_prototype_template
,
3017 UOBJC_INSTANCE_METHODS_decl
3018 = generate_descriptor_table (method_list_template
,
3019 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3020 size
, initlist
, protocol
);
3021 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3024 UOBJC_INSTANCE_METHODS_decl
= 0;
3028 build_tmp_function_decl ()
3030 tree decl_specs
, expr_decl
, parms
;
3034 /* struct objc_object *objc_xxx (id, SEL, ...); */
3036 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3037 push_parm_decl (build_tree_list
3038 (build_tree_list (decl_specs
,
3039 build1 (INDIRECT_REF
, NULL_TREE
,
3041 build_tree_list (NULL_TREE
, NULL_TREE
)));
3043 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3044 get_identifier (TAG_SELECTOR
)));
3045 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3047 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3048 build_tree_list (NULL_TREE
, NULL_TREE
)));
3049 parms
= get_parm_info (0);
3052 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3053 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3054 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3055 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3057 return define_decl (expr_decl
, decl_specs
);
3061 hack_method_prototype (nst_methods
, tmp_decl
)
3068 /* Hack to avoid problem with static typing of self arg. */
3069 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3070 start_method_def (nst_methods
);
3071 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3073 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
3074 parms
= get_parm_info (0); /* we have a `, ...' */
3076 parms
= get_parm_info (1); /* place a `void_at_end' */
3078 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3080 /* Usually called from store_parm_decls -> init_function_start. */
3082 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3083 current_function_decl
= tmp_decl
;
3086 /* Code taken from start_function. */
3087 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3088 /* Promote the value to int before returning it. */
3089 if (TREE_CODE (restype
) == INTEGER_TYPE
3090 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3091 restype
= integer_type_node
;
3092 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3095 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3096 DECL_CONTEXT (parm
) = tmp_decl
;
3098 init_function_start (tmp_decl
, "objc-act", 0);
3100 /* Typically called from expand_function_start for function definitions. */
3101 assign_parms (tmp_decl
);
3103 /* install return type */
3104 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3109 generate_protocol_references (plist
)
3114 /* Forward declare protocols referenced. */
3115 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3117 tree proto
= TREE_VALUE (lproto
);
3119 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3120 && PROTOCOL_NAME (proto
))
3122 if (! PROTOCOL_FORWARD_DECL (proto
))
3123 build_protocol_reference (proto
);
3125 if (PROTOCOL_LIST (proto
))
3126 generate_protocol_references (PROTOCOL_LIST (proto
));
3132 generate_protocols ()
3134 tree p
, tmp_decl
, encoding
;
3135 tree sc_spec
, decl_specs
, decl
;
3136 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3139 tmp_decl
= build_tmp_function_decl ();
3141 if (! objc_protocol_template
)
3142 objc_protocol_template
= build_protocol_template ();
3144 /* If a protocol was directly referenced, pull in indirect references. */
3145 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3146 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3147 generate_protocol_references (PROTOCOL_LIST (p
));
3149 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3151 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3152 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3154 /* If protocol wasn't referenced, don't generate any code. */
3155 if (! PROTOCOL_FORWARD_DECL (p
))
3158 /* Make sure we link in the Protocol class. */
3159 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3163 if (! METHOD_ENCODING (nst_methods
))
3165 hack_method_prototype (nst_methods
, tmp_decl
);
3166 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3167 METHOD_ENCODING (nst_methods
) = encoding
;
3169 nst_methods
= TREE_CHAIN (nst_methods
);
3174 if (! METHOD_ENCODING (cls_methods
))
3176 hack_method_prototype (cls_methods
, tmp_decl
);
3177 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3178 METHOD_ENCODING (cls_methods
) = encoding
;
3181 cls_methods
= TREE_CHAIN (cls_methods
);
3183 generate_method_descriptors (p
);
3185 if (PROTOCOL_LIST (p
))
3186 refs_decl
= generate_protocol_list (p
);
3190 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3192 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3194 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3196 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3197 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3199 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3205 (build_tree_list (build_tree_list (NULL_TREE
,
3206 objc_protocol_template
),
3207 build1 (INDIRECT_REF
, NULL_TREE
,
3208 build1 (INDIRECT_REF
, NULL_TREE
,
3211 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3212 TREE_TYPE (refs_expr
) = cast_type2
;
3215 refs_expr
= build_int_2 (0, 0);
3217 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3218 by generate_method_descriptors, which is called above. */
3219 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3220 protocol_name_expr
, refs_expr
,
3221 UOBJC_INSTANCE_METHODS_decl
,
3222 UOBJC_CLASS_METHODS_decl
);
3223 finish_decl (decl
, initlist
, NULL_TREE
);
3225 /* Mark the decl as used to avoid "defined but not used" warning. */
3226 TREE_USED (decl
) = 1;
3231 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3232 instance_methods
, class_methods
)
3236 tree instance_methods
;
3239 tree initlist
= NULL_TREE
, expr
;
3242 cast_type
= groktypename
3244 (build_tree_list (NULL_TREE
,
3245 xref_tag (RECORD_TYPE
,
3246 get_identifier (UTAG_CLASS
))),
3247 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3249 /* Filling the "isa" in with one allows the runtime system to
3250 detect that the version change...should remove before final release. */
3252 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3253 TREE_TYPE (expr
) = cast_type
;
3254 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3255 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3256 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3258 if (!instance_methods
)
3259 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3262 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3263 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3267 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3270 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3271 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3274 return build_constructor (type
, nreverse (initlist
));
3277 /* struct objc_category {
3278 char *category_name;
3280 struct objc_method_list *instance_methods;
3281 struct objc_method_list *class_methods;
3282 struct objc_protocol_list *protocols;
3286 build_category_template ()
3288 tree decl_specs
, field_decl
, field_decl_chain
;
3290 objc_category_template
= start_struct (RECORD_TYPE
,
3291 get_identifier (UTAG_CATEGORY
));
3292 /* char *category_name; */
3294 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3296 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3298 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3299 field_decl_chain
= field_decl
;
3301 /* char *class_name; */
3303 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3304 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3306 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3307 chainon (field_decl_chain
, field_decl
);
3309 /* struct objc_method_list *instance_methods; */
3311 decl_specs
= build_tree_list (NULL_TREE
,
3312 xref_tag (RECORD_TYPE
,
3313 get_identifier (UTAG_METHOD_LIST
)));
3315 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3317 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3318 chainon (field_decl_chain
, field_decl
);
3320 /* struct objc_method_list *class_methods; */
3322 decl_specs
= build_tree_list (NULL_TREE
,
3323 xref_tag (RECORD_TYPE
,
3324 get_identifier (UTAG_METHOD_LIST
)));
3326 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3328 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3329 chainon (field_decl_chain
, field_decl
);
3331 /* struct objc_protocol **protocol_list; */
3333 decl_specs
= build_tree_list (NULL_TREE
,
3334 xref_tag (RECORD_TYPE
,
3335 get_identifier (UTAG_PROTOCOL
)));
3337 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3338 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3340 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3341 chainon (field_decl_chain
, field_decl
);
3343 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3346 /* struct objc_selector {
3352 build_selector_template ()
3355 tree decl_specs
, field_decl
, field_decl_chain
;
3357 objc_selector_template
3358 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3362 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3363 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3365 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3366 field_decl_chain
= field_decl
;
3368 /* char *sel_type; */
3370 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3371 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3373 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3374 chainon (field_decl_chain
, field_decl
);
3376 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3379 /* struct objc_class {
3380 struct objc_class *isa;
3381 struct objc_class *super_class;
3386 struct objc_ivar_list *ivars;
3387 struct objc_method_list *methods;
3388 if (flag_next_runtime)
3389 struct objc_cache *cache;
3391 struct sarray *dtable;
3392 struct objc_class *subclass_list;
3393 struct objc_class *sibling_class;
3395 struct objc_protocol_list *protocols;
3396 void *gc_object_type;
3400 build_class_template ()
3402 tree decl_specs
, field_decl
, field_decl_chain
;
3405 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3407 /* struct objc_class *isa; */
3409 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3410 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3412 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3413 field_decl_chain
= field_decl
;
3415 /* struct objc_class *super_class; */
3417 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3419 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3421 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3422 chainon (field_decl_chain
, field_decl
);
3426 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3427 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3429 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3430 chainon (field_decl_chain
, field_decl
);
3434 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3435 field_decl
= get_identifier ("version");
3437 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3438 chainon (field_decl_chain
, field_decl
);
3442 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3443 field_decl
= get_identifier ("info");
3445 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3446 chainon (field_decl_chain
, field_decl
);
3448 /* long instance_size; */
3450 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3451 field_decl
= get_identifier ("instance_size");
3453 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3454 chainon (field_decl_chain
, field_decl
);
3456 /* struct objc_ivar_list *ivars; */
3458 decl_specs
= build_tree_list (NULL_TREE
,
3459 xref_tag (RECORD_TYPE
,
3460 get_identifier (UTAG_IVAR_LIST
)));
3461 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3463 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3464 chainon (field_decl_chain
, field_decl
);
3466 /* struct objc_method_list *methods; */
3468 decl_specs
= build_tree_list (NULL_TREE
,
3469 xref_tag (RECORD_TYPE
,
3470 get_identifier (UTAG_METHOD_LIST
)));
3471 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3473 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3474 chainon (field_decl_chain
, field_decl
);
3476 if (flag_next_runtime
)
3478 /* struct objc_cache *cache; */
3480 decl_specs
= build_tree_list (NULL_TREE
,
3481 xref_tag (RECORD_TYPE
,
3482 get_identifier ("objc_cache")));
3483 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3484 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3485 decl_specs
, NULL_TREE
);
3486 chainon (field_decl_chain
, field_decl
);
3490 /* struct sarray *dtable; */
3492 decl_specs
= build_tree_list (NULL_TREE
,
3493 xref_tag (RECORD_TYPE
,
3494 get_identifier ("sarray")));
3495 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3496 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3497 decl_specs
, NULL_TREE
);
3498 chainon (field_decl_chain
, field_decl
);
3500 /* struct objc_class *subclass_list; */
3502 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3504 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3505 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3506 decl_specs
, NULL_TREE
);
3507 chainon (field_decl_chain
, field_decl
);
3509 /* struct objc_class *sibling_class; */
3511 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3513 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3514 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3515 decl_specs
, NULL_TREE
);
3516 chainon (field_decl_chain
, field_decl
);
3519 /* struct objc_protocol **protocol_list; */
3521 decl_specs
= build_tree_list (NULL_TREE
,
3522 xref_tag (RECORD_TYPE
,
3523 get_identifier (UTAG_PROTOCOL
)));
3525 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3527 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3528 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3529 decl_specs
, NULL_TREE
);
3530 chainon (field_decl_chain
, field_decl
);
3534 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3535 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3537 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3538 chainon (field_decl_chain
, field_decl
);
3540 /* void *gc_object_type; */
3542 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3543 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3545 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3546 chainon (field_decl_chain
, field_decl
);
3548 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3551 /* Generate appropriate forward declarations for an implementation. */
3554 synth_forward_declarations ()
3556 tree sc_spec
, decl_specs
, an_id
;
3558 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3560 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3562 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3563 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3564 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3565 TREE_USED (UOBJC_CLASS_decl
) = 1;
3566 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3568 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3570 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3571 implementation_context
);
3573 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3574 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3575 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3577 /* Pre-build the following entities - for speed/convenience. */
3579 an_id
= get_identifier ("super_class");
3580 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3581 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3585 error_with_ivar (message
, decl
, rawdecl
)
3586 const char *message
;
3592 report_error_function (DECL_SOURCE_FILE (decl
));
3594 fprintf (stderr
, "%s:%d: ",
3595 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3596 memset (errbuf
, 0, BUFSIZE
);
3597 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3600 #define USERTYPE(t) \
3601 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3602 || TREE_CODE (t) == ENUMERAL_TYPE)
3605 check_ivars (inter
, imp
)
3609 tree intdecls
= CLASS_IVARS (inter
);
3610 tree impdecls
= CLASS_IVARS (imp
);
3611 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3612 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3618 if (intdecls
== 0 && impdecls
== 0)
3620 if (intdecls
== 0 || impdecls
== 0)
3622 error ("inconsistent instance variable specification");
3626 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3628 if (!comptypes (t1
, t2
))
3630 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3632 error_with_ivar ("conflicting instance variable type",
3633 impdecls
, rawimpdecls
);
3634 error_with_ivar ("previous declaration of",
3635 intdecls
, rawintdecls
);
3637 else /* both the type and the name don't match */
3639 error ("inconsistent instance variable specification");
3644 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3646 error_with_ivar ("conflicting instance variable name",
3647 impdecls
, rawimpdecls
);
3648 error_with_ivar ("previous declaration of",
3649 intdecls
, rawintdecls
);
3652 intdecls
= TREE_CHAIN (intdecls
);
3653 impdecls
= TREE_CHAIN (impdecls
);
3654 rawintdecls
= TREE_CHAIN (rawintdecls
);
3655 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3659 /* Set super_type to the data type node for struct objc_super *,
3660 first defining struct objc_super itself.
3661 This needs to be done just once per compilation. */
3664 build_super_template ()
3666 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3668 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3670 /* struct objc_object *self; */
3672 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3673 field_decl
= get_identifier ("self");
3674 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3675 field_decl
= grokfield (input_filename
, lineno
,
3676 field_decl
, decl_specs
, NULL_TREE
);
3677 field_decl_chain
= field_decl
;
3679 /* struct objc_class *class; */
3681 decl_specs
= get_identifier (UTAG_CLASS
);
3682 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3683 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3685 field_decl
= grokfield (input_filename
, lineno
,
3686 field_decl
, decl_specs
, NULL_TREE
);
3687 chainon (field_decl_chain
, field_decl
);
3689 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3691 /* `struct objc_super *' */
3692 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3694 build1 (INDIRECT_REF
,
3695 NULL_TREE
, NULL_TREE
)));
3699 /* struct objc_ivar {
3706 build_ivar_template ()
3708 tree objc_ivar_id
, objc_ivar_record
;
3709 tree decl_specs
, field_decl
, field_decl_chain
;
3711 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3712 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3714 /* char *ivar_name; */
3716 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3717 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3719 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3720 decl_specs
, NULL_TREE
);
3721 field_decl_chain
= field_decl
;
3723 /* char *ivar_type; */
3725 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3726 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3728 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3729 decl_specs
, NULL_TREE
);
3730 chainon (field_decl_chain
, field_decl
);
3732 /* int ivar_offset; */
3734 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3735 field_decl
= get_identifier ("ivar_offset");
3737 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3738 decl_specs
, NULL_TREE
);
3739 chainon (field_decl_chain
, field_decl
);
3741 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3743 return objc_ivar_record
;
3748 struct objc_ivar ivar_list[ivar_count];
3752 build_ivar_list_template (list_type
, size
)
3756 tree objc_ivar_list_record
;
3757 tree decl_specs
, field_decl
, field_decl_chain
;
3759 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3761 /* int ivar_count; */
3763 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3764 field_decl
= get_identifier ("ivar_count");
3766 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3767 decl_specs
, NULL_TREE
);
3768 field_decl_chain
= field_decl
;
3770 /* struct objc_ivar ivar_list[]; */
3772 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3773 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3774 build_int_2 (size
, 0));
3776 field_decl
= grokfield (input_filename
, lineno
,
3777 field_decl
, decl_specs
, NULL_TREE
);
3778 chainon (field_decl_chain
, field_decl
);
3780 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3782 return objc_ivar_list_record
;
3788 struct objc_method method_list[method_count];
3792 build_method_list_template (list_type
, size
)
3796 tree objc_ivar_list_record
;
3797 tree decl_specs
, field_decl
, field_decl_chain
;
3799 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3801 /* int method_next; */
3806 xref_tag (RECORD_TYPE
,
3807 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3809 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3810 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3811 decl_specs
, NULL_TREE
);
3812 field_decl_chain
= field_decl
;
3814 /* int method_count; */
3816 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3817 field_decl
= get_identifier ("method_count");
3819 field_decl
= grokfield (input_filename
, lineno
,
3820 field_decl
, decl_specs
, NULL_TREE
);
3821 chainon (field_decl_chain
, field_decl
);
3823 /* struct objc_method method_list[]; */
3825 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3826 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3827 build_int_2 (size
, 0));
3829 field_decl
= grokfield (input_filename
, lineno
,
3830 field_decl
, decl_specs
, NULL_TREE
);
3831 chainon (field_decl_chain
, field_decl
);
3833 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3835 return objc_ivar_list_record
;
3839 build_ivar_list_initializer (type
, field_decl
)
3843 tree initlist
= NULL_TREE
;
3847 tree ivar
= NULL_TREE
;
3850 if (DECL_NAME (field_decl
))
3851 ivar
= tree_cons (NULL_TREE
,
3852 add_objc_string (DECL_NAME (field_decl
),
3856 /* Unnamed bit-field ivar (yuck). */
3857 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3860 encode_field_decl (field_decl
,
3861 obstack_object_size (&util_obstack
),
3862 OBJC_ENCODE_DONT_INLINE_DEFS
);
3864 /* Null terminate string. */
3865 obstack_1grow (&util_obstack
, 0);
3869 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3872 obstack_free (&util_obstack
, util_firstobj
);
3875 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3876 initlist
= tree_cons (NULL_TREE
,
3877 build_constructor (type
, nreverse (ivar
)),
3880 field_decl
= TREE_CHAIN (field_decl
);
3884 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3888 generate_ivars_list (type
, name
, size
, list
)
3894 tree sc_spec
, decl_specs
, decl
, initlist
;
3896 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3897 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3899 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3900 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3902 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3903 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3906 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3913 generate_ivar_lists ()
3915 tree initlist
, ivar_list_template
, chain
;
3916 tree cast
, variable_length_type
;
3919 generating_instance_variables
= 1;
3921 if (!objc_ivar_template
)
3922 objc_ivar_template
= build_ivar_template ();
3926 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3927 get_identifier (UTAG_IVAR_LIST
))),
3929 variable_length_type
= groktypename (cast
);
3931 /* Only generate class variables for the root of the inheritance
3932 hierarchy since these will be the same for every class. */
3934 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3935 && (chain
= TYPE_FIELDS (objc_class_template
)))
3937 size
= list_length (chain
);
3939 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3940 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3942 UOBJC_CLASS_VARIABLES_decl
3943 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3945 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3948 UOBJC_CLASS_VARIABLES_decl
= 0;
3950 chain
= CLASS_IVARS (implementation_template
);
3953 size
= list_length (chain
);
3954 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3955 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3957 UOBJC_INSTANCE_VARIABLES_decl
3958 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3960 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3963 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3965 generating_instance_variables
= 0;
3969 build_dispatch_table_initializer (type
, entries
)
3973 tree initlist
= NULL_TREE
;
3977 tree elemlist
= NULL_TREE
;
3979 elemlist
= tree_cons (NULL_TREE
,
3980 build_selector (METHOD_SEL_NAME (entries
)),
3983 elemlist
= tree_cons (NULL_TREE
,
3984 add_objc_string (METHOD_ENCODING (entries
),
3988 elemlist
= tree_cons (NULL_TREE
,
3989 build_unary_op (ADDR_EXPR
,
3990 METHOD_DEFINITION (entries
), 1),
3993 initlist
= tree_cons (NULL_TREE
,
3994 build_constructor (type
, nreverse (elemlist
)),
3997 entries
= TREE_CHAIN (entries
);
4001 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4004 /* To accomplish method prototyping without generating all kinds of
4005 inane warnings, the definition of the dispatch table entries were
4008 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4010 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4013 build_method_template ()
4016 tree decl_specs
, field_decl
, field_decl_chain
;
4018 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4020 #ifdef OBJC_INT_SELECTORS
4021 /* unsigned int _cmd; */
4022 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
4024 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
4025 field_decl
= get_identifier ("_cmd");
4026 #else /* not OBJC_INT_SELECTORS */
4027 /* struct objc_selector *_cmd; */
4028 decl_specs
= tree_cons (NULL_TREE
,
4029 xref_tag (RECORD_TYPE
,
4030 get_identifier (TAG_SELECTOR
)),
4032 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4033 #endif /* not OBJC_INT_SELECTORS */
4035 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4036 decl_specs
, NULL_TREE
);
4037 field_decl_chain
= field_decl
;
4039 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4040 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4041 get_identifier ("method_types"));
4042 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4043 decl_specs
, NULL_TREE
);
4044 chainon (field_decl_chain
, field_decl
);
4048 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4049 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4050 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4051 decl_specs
, NULL_TREE
);
4052 chainon (field_decl_chain
, field_decl
);
4054 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4061 generate_dispatch_table (type
, name
, size
, list
)
4067 tree sc_spec
, decl_specs
, decl
, initlist
;
4069 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4070 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4072 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4073 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4075 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4076 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4077 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4080 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4087 generate_dispatch_tables ()
4089 tree initlist
, chain
, method_list_template
;
4090 tree cast
, variable_length_type
;
4093 if (!objc_method_template
)
4094 objc_method_template
= build_method_template ();
4098 (build_tree_list (NULL_TREE
,
4099 xref_tag (RECORD_TYPE
,
4100 get_identifier (UTAG_METHOD_LIST
))),
4103 variable_length_type
= groktypename (cast
);
4105 chain
= CLASS_CLS_METHODS (implementation_context
);
4108 size
= list_length (chain
);
4110 method_list_template
4111 = build_method_list_template (objc_method_template
, size
);
4113 = build_dispatch_table_initializer (objc_method_template
, chain
);
4115 UOBJC_CLASS_METHODS_decl
4116 = generate_dispatch_table (method_list_template
,
4117 ((TREE_CODE (implementation_context
)
4118 == CLASS_IMPLEMENTATION_TYPE
)
4119 ? "_OBJC_CLASS_METHODS"
4120 : "_OBJC_CATEGORY_CLASS_METHODS"),
4122 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4125 UOBJC_CLASS_METHODS_decl
= 0;
4127 chain
= CLASS_NST_METHODS (implementation_context
);
4130 size
= list_length (chain
);
4132 method_list_template
4133 = build_method_list_template (objc_method_template
, size
);
4135 = build_dispatch_table_initializer (objc_method_template
, chain
);
4137 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4138 UOBJC_INSTANCE_METHODS_decl
4139 = generate_dispatch_table (method_list_template
,
4140 "_OBJC_INSTANCE_METHODS",
4143 /* We have a category. */
4144 UOBJC_INSTANCE_METHODS_decl
4145 = generate_dispatch_table (method_list_template
,
4146 "_OBJC_CATEGORY_INSTANCE_METHODS",
4148 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4151 UOBJC_INSTANCE_METHODS_decl
= 0;
4155 generate_protocol_list (i_or_p
)
4158 tree initlist
, decl_specs
, sc_spec
;
4159 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4163 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4164 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4165 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4166 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4167 plist
= PROTOCOL_LIST (i_or_p
);
4171 cast_type
= groktypename
4173 (build_tree_list (NULL_TREE
,
4174 xref_tag (RECORD_TYPE
,
4175 get_identifier (UTAG_PROTOCOL
))),
4176 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4179 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4180 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4181 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4184 /* Build initializer. */
4185 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4187 e
= build_int_2 (size
, 0);
4188 TREE_TYPE (e
) = cast_type
;
4189 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4191 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4193 tree pval
= TREE_VALUE (lproto
);
4195 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4196 && PROTOCOL_FORWARD_DECL (pval
))
4198 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4199 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4203 /* static struct objc_protocol *refs[n]; */
4205 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4206 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4207 get_identifier (UTAG_PROTOCOL
)),
4210 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4211 expr_decl
= build_nt (ARRAY_REF
,
4212 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4214 build_int_2 (size
+ 2, 0));
4215 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4216 expr_decl
= build_nt (ARRAY_REF
,
4217 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4219 build_int_2 (size
+ 2, 0));
4220 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4222 = build_nt (ARRAY_REF
,
4223 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4225 build_int_2 (size
+ 2, 0));
4229 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4231 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4233 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4234 nreverse (initlist
)),
4241 build_category_initializer (type
, cat_name
, class_name
,
4242 instance_methods
, class_methods
, protocol_list
)
4246 tree instance_methods
;
4250 tree initlist
= NULL_TREE
, expr
;
4252 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4253 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4255 if (!instance_methods
)
4256 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4259 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4260 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4263 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4266 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4267 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4270 /* protocol_list = */
4272 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4275 tree cast_type2
= groktypename
4277 (build_tree_list (NULL_TREE
,
4278 xref_tag (RECORD_TYPE
,
4279 get_identifier (UTAG_PROTOCOL
))),
4280 build1 (INDIRECT_REF
, NULL_TREE
,
4281 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4283 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4284 TREE_TYPE (expr
) = cast_type2
;
4285 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4288 return build_constructor (type
, nreverse (initlist
));
4291 /* struct objc_class {
4292 struct objc_class *isa;
4293 struct objc_class *super_class;
4298 struct objc_ivar_list *ivars;
4299 struct objc_method_list *methods;
4300 if (flag_next_runtime)
4301 struct objc_cache *cache;
4303 struct sarray *dtable;
4304 struct objc_class *subclass_list;
4305 struct objc_class *sibling_class;
4307 struct objc_protocol_list *protocols;
4308 void *gc_object_type;
4312 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4313 dispatch_table
, ivar_list
, protocol_list
)
4320 tree dispatch_table
;
4324 tree initlist
= NULL_TREE
, expr
;
4327 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4330 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4333 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4336 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4339 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4341 /* instance_size = */
4342 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4344 /* objc_ivar_list = */
4346 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4349 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4350 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4353 /* objc_method_list = */
4354 if (!dispatch_table
)
4355 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4358 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4359 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4362 if (flag_next_runtime
)
4363 /* method_cache = */
4364 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4368 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4370 /* subclass_list = */
4371 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4373 /* sibling_class = */
4374 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4377 /* protocol_list = */
4378 if (! protocol_list
)
4379 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4385 (build_tree_list (NULL_TREE
,
4386 xref_tag (RECORD_TYPE
,
4387 get_identifier (UTAG_PROTOCOL
))),
4388 build1 (INDIRECT_REF
, NULL_TREE
,
4389 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4391 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4392 TREE_TYPE (expr
) = cast_type2
;
4393 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4396 /* gc_object_type = NULL */
4397 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4399 return build_constructor (type
, nreverse (initlist
));
4402 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4405 generate_category (cat
)
4408 tree sc_spec
, decl_specs
, decl
;
4409 tree initlist
, cat_name_expr
, class_name_expr
;
4410 tree protocol_decl
, category
;
4412 add_class_reference (CLASS_NAME (cat
));
4413 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4415 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4417 category
= CLASS_CATEGORY_LIST (implementation_template
);
4419 /* find the category interface from the class it is associated with */
4422 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4424 category
= CLASS_CATEGORY_LIST (category
);
4427 if (category
&& CLASS_PROTOCOL_LIST (category
))
4429 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4430 protocol_decl
= generate_protocol_list (category
);
4435 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4436 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4438 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4439 implementation_context
),
4440 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4442 initlist
= build_category_initializer (TREE_TYPE (decl
),
4443 cat_name_expr
, class_name_expr
,
4444 UOBJC_INSTANCE_METHODS_decl
,
4445 UOBJC_CLASS_METHODS_decl
,
4448 TREE_USED (decl
) = 1;
4449 finish_decl (decl
, initlist
, NULL_TREE
);
4452 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4453 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4456 generate_shared_structures ()
4458 tree sc_spec
, decl_specs
, decl
;
4459 tree name_expr
, super_expr
, root_expr
;
4460 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4461 tree cast_type
, initlist
, protocol_decl
;
4463 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4466 add_class_reference (my_super_id
);
4468 /* Compute "my_root_id" - this is required for code generation.
4469 the "isa" for all meta class structures points to the root of
4470 the inheritance hierarchy (e.g. "__Object")... */
4471 my_root_id
= my_super_id
;
4474 tree my_root_int
= lookup_interface (my_root_id
);
4476 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4477 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4484 /* No super class. */
4485 my_root_id
= CLASS_NAME (implementation_template
);
4488 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4489 objc_class_template
),
4490 build1 (INDIRECT_REF
,
4491 NULL_TREE
, NULL_TREE
)));
4493 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4496 /* Install class `isa' and `super' pointers at runtime. */
4499 super_expr
= add_objc_string (my_super_id
, class_names
);
4500 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4503 super_expr
= build_int_2 (0, 0);
4505 root_expr
= add_objc_string (my_root_id
, class_names
);
4506 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4508 if (CLASS_PROTOCOL_LIST (implementation_template
))
4510 generate_protocol_references
4511 (CLASS_PROTOCOL_LIST (implementation_template
));
4512 protocol_decl
= generate_protocol_list (implementation_template
);
4517 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4519 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4520 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4522 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4523 NULL_TREE
, NULL_TREE
);
4526 = build_shared_structure_initializer
4528 root_expr
, super_expr
, name_expr
,
4529 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4531 UOBJC_CLASS_METHODS_decl
,
4532 UOBJC_CLASS_VARIABLES_decl
,
4535 finish_decl (decl
, initlist
, NULL_TREE
);
4537 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4539 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4540 NULL_TREE
, NULL_TREE
);
4543 = build_shared_structure_initializer
4545 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4546 super_expr
, name_expr
,
4547 convert (integer_type_node
,
4548 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4549 (implementation_template
))),
4551 UOBJC_INSTANCE_METHODS_decl
,
4552 UOBJC_INSTANCE_VARIABLES_decl
,
4555 finish_decl (decl
, initlist
, NULL_TREE
);
4559 synth_id_with_class_suffix (preamble
, ctxt
)
4560 const char *preamble
;
4564 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4565 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4567 const char *class_name
4568 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4569 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4570 sprintf (string
, "%s_%s", preamble
,
4571 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4573 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4574 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4576 /* We have a category. */
4577 const char *class_name
4578 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4579 const char *class_super_name
4580 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4581 string
= (char *) alloca (strlen (preamble
)
4582 + strlen (class_name
)
4583 + strlen (class_super_name
)
4585 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4587 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4589 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4591 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4592 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4597 return get_identifier (string
);
4601 is_objc_type_qualifier (node
)
4604 return (TREE_CODE (node
) == IDENTIFIER_NODE
4605 && (node
== ridpointers
[(int) RID_CONST
]
4606 || node
== ridpointers
[(int) RID_VOLATILE
]
4607 || node
== ridpointers
[(int) RID_IN
]
4608 || node
== ridpointers
[(int) RID_OUT
]
4609 || node
== ridpointers
[(int) RID_INOUT
]
4610 || node
== ridpointers
[(int) RID_BYCOPY
]
4611 || node
== ridpointers
[(int) RID_BYREF
]
4612 || node
== ridpointers
[(int) RID_ONEWAY
]));
4615 /* If type is empty or only type qualifiers are present, add default
4616 type of id (otherwise grokdeclarator will default to int). */
4619 adjust_type_for_id_default (type
)
4622 tree declspecs
, chain
;
4625 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4626 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4628 declspecs
= TREE_PURPOSE (type
);
4630 /* Determine if a typespec is present. */
4631 for (chain
= declspecs
;
4633 chain
= TREE_CHAIN (chain
))
4635 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4639 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4641 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4646 selector ':' '(' typename ')' identifier
4649 Transform an Objective-C keyword argument into
4650 the C equivalent parameter declarator.
4652 In: key_name, an "identifier_node" (optional).
4653 arg_type, a "tree_list" (optional).
4654 arg_name, an "identifier_node".
4656 Note: It would be really nice to strongly type the preceding
4657 arguments in the function prototype; however, then I
4658 could not use the "accessor" macros defined in "tree.h".
4660 Out: an instance of "keyword_decl". */
4663 build_keyword_decl (key_name
, arg_type
, arg_name
)
4670 /* If no type is specified, default to "id". */
4671 arg_type
= adjust_type_for_id_default (arg_type
);
4673 keyword_decl
= make_node (KEYWORD_DECL
);
4675 TREE_TYPE (keyword_decl
) = arg_type
;
4676 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4677 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4679 return keyword_decl
;
4682 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4685 build_keyword_selector (selector
)
4689 tree key_chain
, key_name
;
4692 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4694 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4695 key_name
= KEYWORD_KEY_NAME (key_chain
);
4696 else if (TREE_CODE (selector
) == TREE_LIST
)
4697 key_name
= TREE_PURPOSE (key_chain
);
4702 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4704 /* Just a ':' arg. */
4708 buf
= (char *)alloca (len
+ 1);
4709 memset (buf
, 0, len
+ 1);
4711 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4713 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4714 key_name
= KEYWORD_KEY_NAME (key_chain
);
4715 else if (TREE_CODE (selector
) == TREE_LIST
)
4716 key_name
= TREE_PURPOSE (key_chain
);
4721 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4725 return get_identifier (buf
);
4728 /* Used for declarations and definitions. */
4731 build_method_decl (code
, ret_type
, selector
, add_args
)
4732 enum tree_code code
;
4739 /* If no type is specified, default to "id". */
4740 ret_type
= adjust_type_for_id_default (ret_type
);
4742 method_decl
= make_node (code
);
4743 TREE_TYPE (method_decl
) = ret_type
;
4745 /* If we have a keyword selector, create an identifier_node that
4746 represents the full selector name (`:' included)... */
4747 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4749 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4750 METHOD_SEL_ARGS (method_decl
) = selector
;
4751 METHOD_ADD_ARGS (method_decl
) = add_args
;
4755 METHOD_SEL_NAME (method_decl
) = selector
;
4756 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4757 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4763 #define METHOD_DEF 0
4764 #define METHOD_REF 1
4766 /* Used by `build_message_expr' and `comp_method_types'. Return an
4767 argument list for method METH. CONTEXT is either METHOD_DEF or
4768 METHOD_REF, saying whether we are trying to define a method or call
4769 one. SUPERFLAG says this is for a send to super; this makes a
4770 difference for the NeXT calling sequence in which the lookup and
4771 the method call are done together. */
4774 get_arg_type_list (meth
, context
, superflag
)
4781 /* Receiver type. */
4782 if (flag_next_runtime
&& superflag
)
4783 arglist
= build_tree_list (NULL_TREE
, super_type
);
4784 else if (context
== METHOD_DEF
)
4785 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4787 arglist
= build_tree_list (NULL_TREE
, id_type
);
4789 /* Selector type - will eventually change to `int'. */
4790 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4792 /* Build a list of argument types. */
4793 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4795 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4796 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4799 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4800 /* We have a `, ...' immediately following the selector,
4801 finalize the arglist...simulate get_parm_info (0). */
4803 else if (METHOD_ADD_ARGS (meth
))
4805 /* we have a variable length selector */
4806 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4807 chainon (arglist
, add_arg_list
);
4810 /* finalize the arglist...simulate get_parm_info (1) */
4811 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4817 check_duplicates (hsh
)
4820 tree meth
= NULL_TREE
;
4828 /* We have two methods with the same name and different types. */
4830 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4832 warning ("multiple declarations for method `%s'",
4833 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4835 warn_with_method ("using", type
, meth
);
4836 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4837 warn_with_method ("also found", type
, loop
->value
);
4843 /* If RECEIVER is a class reference, return the identifier node for the
4844 referenced class. RECEIVER is created by get_class_reference, so we
4845 check the exact form created depending on which runtimes are used. */
4848 receiver_is_class_object (receiver
)
4851 tree chain
, exp
, arg
;
4852 if (flag_next_runtime
)
4854 /* The receiver is a variable created by build_class_reference_decl. */
4855 if (TREE_CODE (receiver
) == VAR_DECL
4856 && TREE_TYPE (receiver
) == objc_class_type
)
4857 /* Look up the identifier. */
4858 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4859 if (TREE_PURPOSE (chain
) == receiver
)
4860 return TREE_VALUE (chain
);
4864 /* The receiver is a function call that returns an id. Check if
4865 it is a call to objc_getClass, if so, pick up the class name. */
4866 if ((exp
= TREE_OPERAND (receiver
, 0))
4867 && TREE_CODE (exp
) == ADDR_EXPR
4868 && (exp
= TREE_OPERAND (exp
, 0))
4869 && TREE_CODE (exp
) == FUNCTION_DECL
4870 && exp
== objc_get_class_decl
4871 /* we have a call to objc_getClass! */
4872 && (arg
= TREE_OPERAND (receiver
, 1))
4873 && TREE_CODE (arg
) == TREE_LIST
4874 && (arg
= TREE_VALUE (arg
)))
4877 if (TREE_CODE (arg
) == ADDR_EXPR
4878 && (arg
= TREE_OPERAND (arg
, 0))
4879 && TREE_CODE (arg
) == STRING_CST
)
4880 /* Finally, we have the class name. */
4881 return get_identifier (TREE_STRING_POINTER (arg
));
4887 /* If we are currently building a message expr, this holds
4888 the identifier of the selector of the message. This is
4889 used when printing warnings about argument mismatches. */
4891 static tree building_objc_message_expr
= 0;
4894 maybe_building_objc_message_expr ()
4896 return building_objc_message_expr
;
4899 /* Construct an expression for sending a message.
4900 MESS has the object to send to in TREE_PURPOSE
4901 and the argument list (including selector) in TREE_VALUE.
4903 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4904 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4907 build_message_expr (mess
)
4910 tree receiver
= TREE_PURPOSE (mess
);
4911 tree selector
, self_object
;
4912 tree rtype
, sel_name
;
4913 tree args
= TREE_VALUE (mess
);
4914 tree method_params
= NULL_TREE
;
4915 tree method_prototype
= NULL_TREE
;
4917 int statically_typed
= 0, statically_allocated
= 0;
4918 tree class_ident
= 0;
4920 /* 1 if this is sending to the superclass. */
4923 if (TREE_CODE (receiver
) == ERROR_MARK
)
4924 return error_mark_node
;
4926 /* Determine receiver type. */
4927 rtype
= TREE_TYPE (receiver
);
4928 super
= IS_SUPER (rtype
);
4932 if (TREE_STATIC_TEMPLATE (rtype
))
4933 statically_allocated
= 1;
4934 else if (TREE_CODE (rtype
) == POINTER_TYPE
4935 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4936 statically_typed
= 1;
4937 else if ((flag_next_runtime
4938 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4939 && (class_ident
= receiver_is_class_object (receiver
)))
4941 else if (! IS_ID (rtype
)
4942 /* Allow any type that matches objc_class_type. */
4943 && ! comptypes (rtype
, objc_class_type
))
4945 memset (errbuf
, 0, BUFSIZE
);
4946 warning ("invalid receiver type `%s'",
4947 gen_declaration (rtype
, errbuf
));
4950 if (statically_allocated
)
4951 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4953 /* Don't evaluate the receiver twice. */
4954 receiver
= save_expr (receiver
);
4955 self_object
= receiver
;
4958 /* If sending to `super', use current self as the object. */
4959 self_object
= self_decl
;
4961 /* Obtain the full selector name. */
4963 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4964 /* A unary selector. */
4966 else if (TREE_CODE (args
) == TREE_LIST
)
4967 sel_name
= build_keyword_selector (args
);
4971 /* Build the parameter list to give to the method. */
4973 method_params
= NULL_TREE
;
4974 if (TREE_CODE (args
) == TREE_LIST
)
4976 tree chain
= args
, prev
= NULL_TREE
;
4978 /* We have a keyword selector--check for comma expressions. */
4981 tree element
= TREE_VALUE (chain
);
4983 /* We have a comma expression, must collapse... */
4984 if (TREE_CODE (element
) == TREE_LIST
)
4987 TREE_CHAIN (prev
) = element
;
4992 chain
= TREE_CHAIN (chain
);
4994 method_params
= args
;
4997 /* Determine operation return type. */
4999 if (IS_SUPER (rtype
))
5003 if (CLASS_SUPER_NAME (implementation_template
))
5006 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5008 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5009 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5011 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5013 if (iface
&& !method_prototype
)
5014 warning ("`%s' does not respond to `%s'",
5015 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5016 IDENTIFIER_POINTER (sel_name
));
5020 error ("no super class declared in interface for `%s'",
5021 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5022 return error_mark_node
;
5026 else if (statically_allocated
)
5028 tree ctype
= TREE_TYPE (rtype
);
5029 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5032 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5034 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5036 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5039 if (!method_prototype
)
5040 warning ("`%s' does not respond to `%s'",
5041 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5042 IDENTIFIER_POINTER (sel_name
));
5044 else if (statically_typed
)
5046 tree ctype
= TREE_TYPE (rtype
);
5048 /* `self' is now statically_typed. All methods should be visible
5049 within the context of the implementation. */
5050 if (implementation_context
5051 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5054 = lookup_instance_method_static (implementation_template
,
5057 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5059 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5062 if (! method_prototype
5063 && implementation_template
!= implementation_context
)
5064 /* The method is not published in the interface. Check
5067 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5074 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5075 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5077 if (! method_prototype
)
5079 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5082 = lookup_method_in_protocol_list (protocol_list
,
5087 if (!method_prototype
)
5088 warning ("`%s' does not respond to `%s'",
5089 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5090 IDENTIFIER_POINTER (sel_name
));
5092 else if (class_ident
)
5094 if (implementation_context
5095 && CLASS_NAME (implementation_context
) == class_ident
)
5098 = lookup_class_method_static (implementation_template
, sel_name
);
5100 if (!method_prototype
5101 && implementation_template
!= implementation_context
)
5102 /* The method is not published in the interface. Check
5105 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5112 if ((iface
= lookup_interface (class_ident
)))
5113 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5116 if (!method_prototype
)
5118 warning ("cannot find class (factory) method.");
5119 warning ("return type for `%s' defaults to id",
5120 IDENTIFIER_POINTER (sel_name
));
5123 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5125 /* An anonymous object that has been qualified with a protocol. */
5127 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5129 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5132 if (!method_prototype
)
5136 warning ("method `%s' not implemented by protocol.",
5137 IDENTIFIER_POINTER (sel_name
));
5139 /* Try and find the method signature in the global pools. */
5141 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5142 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5144 if (!(method_prototype
= check_duplicates (hsh
)))
5145 warning ("return type defaults to id");
5152 /* We think we have an instance...loophole: extern id Object; */
5153 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5155 /* For various loopholes, like sending messages to self in a
5157 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5159 method_prototype
= check_duplicates (hsh
);
5160 if (!method_prototype
)
5162 warning ("cannot find method.");
5163 warning ("return type for `%s' defaults to id",
5164 IDENTIFIER_POINTER (sel_name
));
5168 /* Save the selector name for printing error messages. */
5169 building_objc_message_expr
= sel_name
;
5171 /* Build the parameters list for looking up the method.
5172 These are the object itself and the selector. */
5174 if (flag_typed_selectors
)
5175 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5177 selector
= build_selector_reference (sel_name
);
5179 retval
= build_objc_method_call (super
, method_prototype
,
5180 receiver
, self_object
,
5181 selector
, method_params
);
5183 building_objc_message_expr
= 0;
5188 /* Build a tree expression to send OBJECT the operation SELECTOR,
5189 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5190 assuming the method has prototype METHOD_PROTOTYPE.
5191 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5192 Use METHOD_PARAMS as list of args to pass to the method.
5193 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5196 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5197 selector
, method_params
)
5199 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5201 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5202 tree rcv_p
= (super_flag
5203 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5204 get_identifier (TAG_SUPER
)))
5207 if (flag_next_runtime
)
5209 if (! method_prototype
)
5211 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5212 tree_cons (NULL_TREE
, selector
,
5214 assemble_external (sender
);
5215 return build_function_call (sender
, method_params
);
5219 /* This is a real kludge, but it is used only for the Next.
5220 Clobber the data type of SENDER temporarily to accept
5221 all the arguments for this operation, and to return
5222 whatever this operation returns. */
5223 tree arglist
= NULL_TREE
;
5226 /* Save the proper contents of SENDER's data type. */
5227 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5228 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5230 /* Install this method's argument types. */
5231 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5233 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5235 /* Install this method's return type. */
5236 TREE_TYPE (TREE_TYPE (sender
))
5237 = groktypename (TREE_TYPE (method_prototype
));
5239 /* Call SENDER with all the parameters. This will do type
5240 checking using the arg types for this method. */
5241 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5242 tree_cons (NULL_TREE
, selector
,
5244 assemble_external (sender
);
5245 retval
= build_function_call (sender
, method_params
);
5247 /* Restore SENDER's return/argument types. */
5248 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5249 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5255 /* This is the portable way.
5256 First call the lookup function to get a pointer to the method,
5257 then cast the pointer, then call it with the method arguments. */
5260 /* Avoid trouble since we may evaluate each of these twice. */
5261 object
= save_expr (object
);
5262 selector
= save_expr (selector
);
5264 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5266 assemble_external (sender
);
5268 = build_function_call (sender
,
5269 tree_cons (NULL_TREE
, lookup_object
,
5270 tree_cons (NULL_TREE
, selector
,
5273 /* If we have a method prototype, construct the data type this
5274 method needs, and cast what we got from SENDER into a pointer
5276 if (method_prototype
)
5278 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5280 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5281 tree fake_function_type
= build_function_type (valtype
, arglist
);
5282 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5286 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5288 /* Pass the object to the method. */
5289 assemble_external (method
);
5290 return build_function_call (method
,
5291 tree_cons (NULL_TREE
, object
,
5292 tree_cons (NULL_TREE
, selector
,
5298 build_protocol_reference (p
)
5301 tree decl
, ident
, ptype
;
5303 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5305 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5307 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5308 objc_protocol_template
),
5311 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5312 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5315 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5316 DECL_EXTERNAL (decl
) = 1;
5317 TREE_PUBLIC (decl
) = 1;
5318 TREE_USED (decl
) = 1;
5319 DECL_ARTIFICIAL (decl
) = 1;
5321 make_decl_rtl (decl
, 0, 1);
5322 pushdecl_top_level (decl
);
5325 PROTOCOL_FORWARD_DECL (p
) = decl
;
5329 build_protocol_expr (protoname
)
5333 tree p
= lookup_protocol (protoname
);
5337 error ("Cannot find protocol declaration for `%s'",
5338 IDENTIFIER_POINTER (protoname
));
5339 return error_mark_node
;
5342 if (!PROTOCOL_FORWARD_DECL (p
))
5343 build_protocol_reference (p
);
5345 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5347 TREE_TYPE (expr
) = protocol_type
;
5353 build_selector_expr (selnamelist
)
5358 /* Obtain the full selector name. */
5359 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5360 /* A unary selector. */
5361 selname
= selnamelist
;
5362 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5363 selname
= build_keyword_selector (selnamelist
);
5367 if (flag_typed_selectors
)
5368 return build_typed_selector_reference (selname
, 0);
5370 return build_selector_reference (selname
);
5374 build_encode_expr (type
)
5380 encode_type (type
, obstack_object_size (&util_obstack
),
5381 OBJC_ENCODE_INLINE_DEFS
);
5382 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5383 string
= obstack_finish (&util_obstack
);
5385 /* Synthesize a string that represents the encoded struct/union. */
5386 result
= my_build_string (strlen (string
) + 1, string
);
5387 obstack_free (&util_obstack
, util_firstobj
);
5392 build_ivar_reference (id
)
5395 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5397 /* Historically, a class method that produced objects (factory
5398 method) would assign `self' to the instance that it
5399 allocated. This would effectively turn the class method into
5400 an instance method. Following this assignment, the instance
5401 variables could be accessed. That practice, while safe,
5402 violates the simple rule that a class method should not refer
5403 to an instance variable. It's better to catch the cases
5404 where this is done unknowingly than to support the above
5406 warning ("instance variable `%s' accessed in class method",
5407 IDENTIFIER_POINTER (id
));
5408 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5411 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5414 #define HASH_ALLOC_LIST_SIZE 170
5415 #define ATTR_ALLOC_LIST_SIZE 170
5416 #define SIZEHASHTABLE 257
5419 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5424 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5425 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5427 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5428 perror ("unable to allocate space in objc-tree.c");
5433 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5435 nst_method_hash_list
[i
] = 0;
5436 cls_method_hash_list
[i
] = 0;
5442 hash_enter (hashlist
, method
)
5446 static hash hash_alloc_list
= 0;
5447 static int hash_alloc_index
= 0;
5449 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5451 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5453 hash_alloc_index
= 0;
5454 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5455 * HASH_ALLOC_LIST_SIZE
);
5456 if (! hash_alloc_list
)
5457 perror ("unable to allocate in objc-tree.c");
5459 obj
= &hash_alloc_list
[hash_alloc_index
++];
5461 obj
->next
= hashlist
[slot
];
5464 hashlist
[slot
] = obj
; /* append to front */
5468 hash_lookup (hashlist
, sel_name
)
5474 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5478 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5481 target
= target
->next
;
5487 hash_add_attr (entry
, value
)
5491 static attr attr_alloc_list
= 0;
5492 static int attr_alloc_index
= 0;
5495 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5497 attr_alloc_index
= 0;
5498 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5499 * ATTR_ALLOC_LIST_SIZE
);
5500 if (! attr_alloc_list
)
5501 perror ("unable to allocate in objc-tree.c");
5503 obj
= &attr_alloc_list
[attr_alloc_index
++];
5504 obj
->next
= entry
->list
;
5507 entry
->list
= obj
; /* append to front */
5511 lookup_method (mchain
, method
)
5517 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5520 key
= METHOD_SEL_NAME (method
);
5524 if (METHOD_SEL_NAME (mchain
) == key
)
5526 mchain
= TREE_CHAIN (mchain
);
5532 lookup_instance_method_static (interface
, ident
)
5536 tree inter
= interface
;
5537 tree chain
= CLASS_NST_METHODS (inter
);
5538 tree meth
= NULL_TREE
;
5542 if ((meth
= lookup_method (chain
, ident
)))
5545 if (CLASS_CATEGORY_LIST (inter
))
5547 tree category
= CLASS_CATEGORY_LIST (inter
);
5548 chain
= CLASS_NST_METHODS (category
);
5552 if ((meth
= lookup_method (chain
, ident
)))
5555 /* Check for instance methods in protocols in categories. */
5556 if (CLASS_PROTOCOL_LIST (category
))
5558 if ((meth
= (lookup_method_in_protocol_list
5559 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5563 if ((category
= CLASS_CATEGORY_LIST (category
)))
5564 chain
= CLASS_NST_METHODS (category
);
5569 if (CLASS_PROTOCOL_LIST (inter
))
5571 if ((meth
= (lookup_method_in_protocol_list
5572 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5576 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5577 chain
= CLASS_NST_METHODS (inter
);
5585 lookup_class_method_static (interface
, ident
)
5589 tree inter
= interface
;
5590 tree chain
= CLASS_CLS_METHODS (inter
);
5591 tree meth
= NULL_TREE
;
5592 tree root_inter
= NULL_TREE
;
5596 if ((meth
= lookup_method (chain
, ident
)))
5599 if (CLASS_CATEGORY_LIST (inter
))
5601 tree category
= CLASS_CATEGORY_LIST (inter
);
5602 chain
= CLASS_CLS_METHODS (category
);
5606 if ((meth
= lookup_method (chain
, ident
)))
5609 /* Check for class methods in protocols in categories. */
5610 if (CLASS_PROTOCOL_LIST (category
))
5612 if ((meth
= (lookup_method_in_protocol_list
5613 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5617 if ((category
= CLASS_CATEGORY_LIST (category
)))
5618 chain
= CLASS_CLS_METHODS (category
);
5623 /* Check for class methods in protocols. */
5624 if (CLASS_PROTOCOL_LIST (inter
))
5626 if ((meth
= (lookup_method_in_protocol_list
5627 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5632 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5633 chain
= CLASS_CLS_METHODS (inter
);
5637 /* Simulate wrap around. */
5638 return lookup_instance_method_static (root_inter
, ident
);
5642 add_class_method (class, method
)
5649 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5651 /* put method on list in reverse order */
5652 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5653 CLASS_CLS_METHODS (class) = method
;
5657 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5658 error ("duplicate definition of class method `%s'.",
5659 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5662 /* Check types; if different, complain. */
5663 if (!comp_proto_with_proto (method
, mth
))
5664 error ("duplicate declaration of class method `%s'.",
5665 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5669 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5671 /* Install on a global chain. */
5672 hash_enter (cls_method_hash_list
, method
);
5676 /* Check types; if different, add to a list. */
5677 if (!comp_proto_with_proto (method
, hsh
->key
))
5678 hash_add_attr (hsh
, method
);
5684 add_instance_method (class, method
)
5691 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5693 /* Put method on list in reverse order. */
5694 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5695 CLASS_NST_METHODS (class) = method
;
5699 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5700 error ("duplicate definition of instance method `%s'.",
5701 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5704 /* Check types; if different, complain. */
5705 if (!comp_proto_with_proto (method
, mth
))
5706 error ("duplicate declaration of instance method `%s'.",
5707 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5711 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5713 /* Install on a global chain. */
5714 hash_enter (nst_method_hash_list
, method
);
5718 /* Check types; if different, add to a list. */
5719 if (!comp_proto_with_proto (method
, hsh
->key
))
5720 hash_add_attr (hsh
, method
);
5729 /* Put interfaces on list in reverse order. */
5730 TREE_CHAIN (class) = interface_chain
;
5731 interface_chain
= class;
5732 return interface_chain
;
5736 add_category (class, category
)
5740 /* Put categories on list in reverse order. */
5741 tree cat
= CLASS_CATEGORY_LIST (class);
5745 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5746 warning ("duplicate interface declaration for category `%s(%s)'",
5747 IDENTIFIER_POINTER (CLASS_NAME (class)),
5748 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5749 cat
= CLASS_CATEGORY_LIST (cat
);
5752 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5753 CLASS_CATEGORY_LIST (class) = category
;
5756 /* Called after parsing each instance variable declaration. Necessary to
5757 preserve typedefs and implement public/private...
5759 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5762 add_instance_variable (class, public, declarator
, declspecs
, width
)
5769 tree field_decl
, raw_decl
;
5771 raw_decl
= build_tree_list (declspecs
, declarator
);
5773 if (CLASS_RAW_IVARS (class))
5774 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5776 CLASS_RAW_IVARS (class) = raw_decl
;
5778 field_decl
= grokfield (input_filename
, lineno
,
5779 declarator
, declspecs
, width
);
5781 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5785 TREE_PUBLIC (field_decl
) = 0;
5786 TREE_PRIVATE (field_decl
) = 0;
5787 TREE_PROTECTED (field_decl
) = 1;
5791 TREE_PUBLIC (field_decl
) = 1;
5792 TREE_PRIVATE (field_decl
) = 0;
5793 TREE_PROTECTED (field_decl
) = 0;
5797 TREE_PUBLIC (field_decl
) = 0;
5798 TREE_PRIVATE (field_decl
) = 1;
5799 TREE_PROTECTED (field_decl
) = 0;
5804 if (CLASS_IVARS (class))
5805 chainon (CLASS_IVARS (class), field_decl
);
5807 CLASS_IVARS (class) = field_decl
;
5813 is_ivar (decl_chain
, ident
)
5817 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5818 if (DECL_NAME (decl_chain
) == ident
)
5823 /* True if the ivar is private and we are not in its implementation. */
5829 if (TREE_PRIVATE (decl
)
5830 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5832 error ("instance variable `%s' is declared private",
5833 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5840 /* We have an instance variable reference;, check to see if it is public. */
5843 is_public (expr
, identifier
)
5847 tree basetype
= TREE_TYPE (expr
);
5848 enum tree_code code
= TREE_CODE (basetype
);
5851 if (code
== RECORD_TYPE
)
5853 if (TREE_STATIC_TEMPLATE (basetype
))
5855 if (!lookup_interface (TYPE_NAME (basetype
)))
5857 error ("Cannot find interface declaration for `%s'",
5858 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5862 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5864 if (TREE_PUBLIC (decl
))
5867 /* Important difference between the Stepstone translator:
5868 all instance variables should be public within the context
5869 of the implementation. */
5870 if (implementation_context
5871 && (((TREE_CODE (implementation_context
)
5872 == CLASS_IMPLEMENTATION_TYPE
)
5873 || (TREE_CODE (implementation_context
)
5874 == CATEGORY_IMPLEMENTATION_TYPE
))
5875 && (CLASS_NAME (implementation_context
)
5876 == TYPE_NAME (basetype
))))
5877 return ! is_private (decl
);
5879 error ("instance variable `%s' is declared %s",
5880 IDENTIFIER_POINTER (identifier
),
5881 TREE_PRIVATE (decl
) ? "private" : "protected");
5886 else if (implementation_context
&& (basetype
== objc_object_reference
))
5888 TREE_TYPE (expr
) = uprivate_record
;
5889 warning ("static access to object of type `id'");
5896 /* Implement @defs (<classname>) within struct bodies. */
5899 get_class_ivars (interface
)
5902 return build_ivar_chain (interface
, 1);
5905 /* Make sure all entries in CHAIN are also in LIST. */
5908 check_methods (chain
, list
, mtype
)
5917 if (!lookup_method (list
, chain
))
5921 if (TREE_CODE (implementation_context
)
5922 == CLASS_IMPLEMENTATION_TYPE
)
5923 warning ("incomplete implementation of class `%s'",
5924 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5925 else if (TREE_CODE (implementation_context
)
5926 == CATEGORY_IMPLEMENTATION_TYPE
)
5927 warning ("incomplete implementation of category `%s'",
5928 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5932 warning ("method definition for `%c%s' not found",
5933 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5936 chain
= TREE_CHAIN (chain
);
5943 conforms_to_protocol (class, protocol
)
5949 tree p
= CLASS_PROTOCOL_LIST (class);
5951 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5956 tree super
= (CLASS_SUPER_NAME (class)
5957 ? lookup_interface (CLASS_SUPER_NAME (class))
5959 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5964 protocol
= TREE_CHAIN (protocol
);
5970 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5971 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5974 check_methods_accessible (chain
, context
, mtype
)
5981 tree base_context
= context
;
5985 context
= base_context
;
5989 list
= CLASS_CLS_METHODS (context
);
5991 list
= CLASS_NST_METHODS (context
);
5993 if (lookup_method (list
, chain
))
5996 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5997 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5998 context
= (CLASS_SUPER_NAME (context
)
5999 ? lookup_interface (CLASS_SUPER_NAME (context
))
6002 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6003 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6004 context
= (CLASS_NAME (context
)
6005 ? lookup_interface (CLASS_NAME (context
))
6011 if (context
== NULL_TREE
)
6015 if (TREE_CODE (implementation_context
)
6016 == CLASS_IMPLEMENTATION_TYPE
)
6017 warning ("incomplete implementation of class `%s'",
6019 (CLASS_NAME (implementation_context
)));
6020 else if (TREE_CODE (implementation_context
)
6021 == CATEGORY_IMPLEMENTATION_TYPE
)
6022 warning ("incomplete implementation of category `%s'",
6024 (CLASS_SUPER_NAME (implementation_context
)));
6027 warning ("method definition for `%c%s' not found",
6028 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6031 chain
= TREE_CHAIN (chain
); /* next method... */
6037 check_protocols (proto_list
, type
, name
)
6042 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6044 tree p
= TREE_VALUE (proto_list
);
6046 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6050 /* Ensure that all protocols have bodies. */
6051 if (flag_warn_protocol
) {
6052 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6053 CLASS_CLS_METHODS (implementation_context
),
6055 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6056 CLASS_NST_METHODS (implementation_context
),
6059 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6060 implementation_context
,
6062 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6063 implementation_context
,
6068 warning ("%s `%s' does not fully implement the `%s' protocol",
6069 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6074 ; /* An identifier if we could not find a protocol. */
6077 /* Check protocols recursively. */
6078 if (PROTOCOL_LIST (p
))
6081 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6082 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6083 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6088 /* Make sure that the class CLASS_NAME is defined
6089 CODE says which kind of thing CLASS_NAME ought to be.
6090 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6091 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6094 start_class (code
, class_name
, super_name
, protocol_list
)
6095 enum tree_code code
;
6102 class = make_node (code
);
6103 TYPE_BINFO (class) = make_tree_vec (5);
6105 CLASS_NAME (class) = class_name
;
6106 CLASS_SUPER_NAME (class) = super_name
;
6107 CLASS_CLS_METHODS (class) = NULL_TREE
;
6109 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6111 error ("`%s' redeclared as different kind of symbol",
6112 IDENTIFIER_POINTER (class_name
));
6113 error_with_decl (decl
, "previous declaration of `%s'");
6116 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6119 static tree implemented_classes
= 0;
6120 tree chain
= implemented_classes
;
6121 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6122 if (TREE_VALUE (chain
) == class_name
)
6124 error ("reimplementation of class `%s'",
6125 IDENTIFIER_POINTER (class_name
));
6126 return error_mark_node
;
6128 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6129 implemented_classes
);
6132 /* Pre-build the following entities - for speed/convenience. */
6134 self_id
= get_identifier ("self");
6136 ucmd_id
= get_identifier ("_cmd");
6139 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6140 if (!objc_super_template
)
6141 objc_super_template
= build_super_template ();
6143 /* Reset for multiple classes per file. */
6146 implementation_context
= class;
6148 /* Lookup the interface for this implementation. */
6150 if (!(implementation_template
= lookup_interface (class_name
)))
6152 warning ("Cannot find interface declaration for `%s'",
6153 IDENTIFIER_POINTER (class_name
));
6154 add_class (implementation_template
= implementation_context
);
6157 /* If a super class has been specified in the implementation,
6158 insure it conforms to the one specified in the interface. */
6161 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6163 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6165 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6166 error ("conflicting super class name `%s'",
6167 IDENTIFIER_POINTER (super_name
));
6168 error ("previous declaration of `%s'", name
);
6171 else if (! super_name
)
6173 CLASS_SUPER_NAME (implementation_context
)
6174 = CLASS_SUPER_NAME (implementation_template
);
6178 else if (code
== CLASS_INTERFACE_TYPE
)
6180 if (lookup_interface (class_name
))
6181 warning ("duplicate interface declaration for class `%s'",
6182 IDENTIFIER_POINTER (class_name
));
6187 CLASS_PROTOCOL_LIST (class)
6188 = lookup_and_install_protocols (protocol_list
);
6191 else if (code
== CATEGORY_INTERFACE_TYPE
)
6193 tree class_category_is_assoc_with
;
6195 /* For a category, class_name is really the name of the class that
6196 the following set of methods will be associated with. We must
6197 find the interface so that can derive the objects template. */
6199 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6201 error ("Cannot find interface declaration for `%s'",
6202 IDENTIFIER_POINTER (class_name
));
6203 exit (FATAL_EXIT_CODE
);
6206 add_category (class_category_is_assoc_with
, class);
6209 CLASS_PROTOCOL_LIST (class)
6210 = lookup_and_install_protocols (protocol_list
);
6213 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6215 /* Pre-build the following entities for speed/convenience. */
6217 self_id
= get_identifier ("self");
6219 ucmd_id
= get_identifier ("_cmd");
6222 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6223 if (!objc_super_template
)
6224 objc_super_template
= build_super_template ();
6226 /* Reset for multiple classes per file. */
6229 implementation_context
= class;
6231 /* For a category, class_name is really the name of the class that
6232 the following set of methods will be associated with. We must
6233 find the interface so that can derive the objects template. */
6235 if (!(implementation_template
= lookup_interface (class_name
)))
6237 error ("Cannot find interface declaration for `%s'",
6238 IDENTIFIER_POINTER (class_name
));
6239 exit (FATAL_EXIT_CODE
);
6246 continue_class (class)
6249 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6250 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6252 struct imp_entry
*imp_entry
;
6255 /* Check consistency of the instance variables. */
6257 if (CLASS_IVARS (class))
6258 check_ivars (implementation_template
, class);
6260 /* code generation */
6262 ivar_context
= build_private_template (implementation_template
);
6264 if (!objc_class_template
)
6265 build_class_template ();
6268 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6269 perror ("unable to allocate in objc-tree.c");
6271 imp_entry
->next
= imp_list
;
6272 imp_entry
->imp_context
= class;
6273 imp_entry
->imp_template
= implementation_template
;
6275 synth_forward_declarations ();
6276 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6277 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6279 /* Append to front and increment count. */
6280 imp_list
= imp_entry
;
6281 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6286 return ivar_context
;
6289 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6291 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6293 if (!TYPE_FIELDS (record
))
6295 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6296 CLASS_STATIC_TEMPLATE (class) = record
;
6298 /* Mark this record as a class template for static typing. */
6299 TREE_STATIC_TEMPLATE (record
) = 1;
6306 return error_mark_node
;
6309 /* This is called once we see the "@end" in an interface/implementation. */
6312 finish_class (class)
6315 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6317 /* All code generation is done in finish_objc. */
6319 if (implementation_template
!= implementation_context
)
6321 /* Ensure that all method listed in the interface contain bodies. */
6322 check_methods (CLASS_CLS_METHODS (implementation_template
),
6323 CLASS_CLS_METHODS (implementation_context
), '+');
6324 check_methods (CLASS_NST_METHODS (implementation_template
),
6325 CLASS_NST_METHODS (implementation_context
), '-');
6327 if (CLASS_PROTOCOL_LIST (implementation_template
))
6328 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6330 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6334 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6336 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6338 /* Find the category interface from the class it is associated with. */
6341 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6343 category
= CLASS_CATEGORY_LIST (category
);
6348 /* Ensure all method listed in the interface contain bodies. */
6349 check_methods (CLASS_CLS_METHODS (category
),
6350 CLASS_CLS_METHODS (implementation_context
), '+');
6351 check_methods (CLASS_NST_METHODS (category
),
6352 CLASS_NST_METHODS (implementation_context
), '-');
6354 if (CLASS_PROTOCOL_LIST (category
))
6355 check_protocols (CLASS_PROTOCOL_LIST (category
),
6357 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6361 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6364 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6365 char *string
= (char *) alloca (strlen (class_name
) + 3);
6367 /* extern struct objc_object *_<my_name>; */
6369 sprintf (string
, "_%s", class_name
);
6371 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6372 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6373 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6379 add_protocol (protocol
)
6382 /* Put protocol on list in reverse order. */
6383 TREE_CHAIN (protocol
) = protocol_chain
;
6384 protocol_chain
= protocol
;
6385 return protocol_chain
;
6389 lookup_protocol (ident
)
6394 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6396 if (ident
== PROTOCOL_NAME (chain
))
6404 start_protocol (code
, name
, list
)
6405 enum tree_code code
;
6411 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6412 if (!objc_protocol_template
)
6413 objc_protocol_template
= build_protocol_template ();
6415 protocol
= make_node (code
);
6416 TYPE_BINFO (protocol
) = make_tree_vec (2);
6418 PROTOCOL_NAME (protocol
) = name
;
6419 PROTOCOL_LIST (protocol
) = list
;
6421 lookup_and_install_protocols (list
);
6423 if (lookup_protocol (name
))
6424 warning ("duplicate declaration for protocol `%s'",
6425 IDENTIFIER_POINTER (name
));
6427 add_protocol (protocol
);
6429 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6435 finish_protocol (protocol
)
6436 tree protocol ATTRIBUTE_UNUSED
;
6441 /* "Encode" a data type into a string, which grows in util_obstack.
6442 ??? What is the FORMAT? Someone please document this! */
6445 encode_type_qualifiers (declspecs
)
6450 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6452 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6453 obstack_1grow (&util_obstack
, 'r');
6454 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6455 obstack_1grow (&util_obstack
, 'n');
6456 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6457 obstack_1grow (&util_obstack
, 'N');
6458 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6459 obstack_1grow (&util_obstack
, 'o');
6460 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6461 obstack_1grow (&util_obstack
, 'O');
6462 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6463 obstack_1grow (&util_obstack
, 'R');
6464 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6465 obstack_1grow (&util_obstack
, 'V');
6469 /* Encode a pointer type. */
6472 encode_pointer (type
, curtype
, format
)
6477 tree pointer_to
= TREE_TYPE (type
);
6479 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6481 if (TYPE_NAME (pointer_to
)
6482 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6484 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6486 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6488 obstack_1grow (&util_obstack
, '@');
6491 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6493 if (generating_instance_variables
)
6495 obstack_1grow (&util_obstack
, '@');
6496 obstack_1grow (&util_obstack
, '"');
6497 obstack_grow (&util_obstack
, name
, strlen (name
));
6498 obstack_1grow (&util_obstack
, '"');
6503 obstack_1grow (&util_obstack
, '@');
6507 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6509 obstack_1grow (&util_obstack
, '#');
6512 #ifndef OBJC_INT_SELECTORS
6513 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6515 obstack_1grow (&util_obstack
, ':');
6518 #endif /* OBJC_INT_SELECTORS */
6521 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6522 && TYPE_MODE (pointer_to
) == QImode
)
6524 obstack_1grow (&util_obstack
, '*');
6528 /* We have a type that does not get special treatment. */
6530 /* NeXT extension */
6531 obstack_1grow (&util_obstack
, '^');
6532 encode_type (pointer_to
, curtype
, format
);
6536 encode_array (type
, curtype
, format
)
6541 tree an_int_cst
= TYPE_SIZE (type
);
6542 tree array_of
= TREE_TYPE (type
);
6545 /* An incomplete array is treated like a pointer. */
6546 if (an_int_cst
== NULL
)
6548 encode_pointer (type
, curtype
, format
);
6552 sprintf (buffer
, "[%ld",
6553 (long) (TREE_INT_CST_LOW (an_int_cst
)
6554 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6556 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6557 encode_type (array_of
, curtype
, format
);
6558 obstack_1grow (&util_obstack
, ']');
6563 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6570 if (obstack_object_size (&util_obstack
) > 0
6571 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6573 tree name
= TYPE_NAME (type
);
6575 /* we have a reference; this is a NeXT extension. */
6577 if (obstack_object_size (&util_obstack
) - curtype
== 1
6578 && format
== OBJC_ENCODE_INLINE_DEFS
)
6580 /* Output format of struct for first level only. */
6581 tree fields
= TYPE_FIELDS (type
);
6583 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6585 obstack_1grow (&util_obstack
, left
);
6586 obstack_grow (&util_obstack
,
6587 IDENTIFIER_POINTER (name
),
6588 strlen (IDENTIFIER_POINTER (name
)));
6589 obstack_1grow (&util_obstack
, '=');
6593 obstack_1grow (&util_obstack
, left
);
6594 obstack_grow (&util_obstack
, "?=", 2);
6597 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6598 encode_field_decl (fields
, curtype
, format
);
6600 obstack_1grow (&util_obstack
, right
);
6603 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6605 obstack_1grow (&util_obstack
, left
);
6606 obstack_grow (&util_obstack
,
6607 IDENTIFIER_POINTER (name
),
6608 strlen (IDENTIFIER_POINTER (name
)));
6609 obstack_1grow (&util_obstack
, right
);
6614 /* We have an untagged structure or a typedef. */
6615 obstack_1grow (&util_obstack
, left
);
6616 obstack_1grow (&util_obstack
, '?');
6617 obstack_1grow (&util_obstack
, right
);
6623 tree name
= TYPE_NAME (type
);
6624 tree fields
= TYPE_FIELDS (type
);
6626 if (format
== OBJC_ENCODE_INLINE_DEFS
6627 || generating_instance_variables
)
6629 obstack_1grow (&util_obstack
, left
);
6630 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6631 obstack_grow (&util_obstack
,
6632 IDENTIFIER_POINTER (name
),
6633 strlen (IDENTIFIER_POINTER (name
)));
6635 obstack_1grow (&util_obstack
, '?');
6637 obstack_1grow (&util_obstack
, '=');
6639 for (; fields
; fields
= TREE_CHAIN (fields
))
6641 if (generating_instance_variables
)
6643 tree fname
= DECL_NAME (fields
);
6645 obstack_1grow (&util_obstack
, '"');
6646 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6648 obstack_grow (&util_obstack
,
6649 IDENTIFIER_POINTER (fname
),
6650 strlen (IDENTIFIER_POINTER (fname
)));
6653 obstack_1grow (&util_obstack
, '"');
6656 encode_field_decl (fields
, curtype
, format
);
6659 obstack_1grow (&util_obstack
, right
);
6664 obstack_1grow (&util_obstack
, left
);
6665 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6666 obstack_grow (&util_obstack
,
6667 IDENTIFIER_POINTER (name
),
6668 strlen (IDENTIFIER_POINTER (name
)));
6670 /* We have an untagged structure or a typedef. */
6671 obstack_1grow (&util_obstack
, '?');
6673 obstack_1grow (&util_obstack
, right
);
6679 encode_aggregate (type
, curtype
, format
)
6684 enum tree_code code
= TREE_CODE (type
);
6690 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6695 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6700 obstack_1grow (&util_obstack
, 'i');
6708 /* Support bitfields. The current version of Objective-C does not support
6709 them. The string will consist of one or more "b:n"'s where n is an
6710 integer describing the width of the bitfield. Currently, classes in
6711 the kit implement a method "-(char *)describeBitfieldStruct:" that
6712 simulates this. If they do not implement this method, the archiver
6713 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6714 according to the GNU compiler. After looking at the "kit", it appears
6715 that all classes currently rely on this default behavior, rather than
6716 hand generating this string (which is tedious). */
6719 encode_bitfield (width
)
6723 sprintf (buffer
, "b%d", width
);
6724 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6727 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6730 encode_type (type
, curtype
, format
)
6735 enum tree_code code
= TREE_CODE (type
);
6737 if (code
== INTEGER_TYPE
)
6739 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6741 /* Unsigned integer types. */
6743 if (TYPE_MODE (type
) == QImode
)
6744 obstack_1grow (&util_obstack
, 'C');
6745 else if (TYPE_MODE (type
) == HImode
)
6746 obstack_1grow (&util_obstack
, 'S');
6747 else if (TYPE_MODE (type
) == SImode
)
6749 if (type
== long_unsigned_type_node
)
6750 obstack_1grow (&util_obstack
, 'L');
6752 obstack_1grow (&util_obstack
, 'I');
6754 else if (TYPE_MODE (type
) == DImode
)
6755 obstack_1grow (&util_obstack
, 'Q');
6759 /* Signed integer types. */
6761 if (TYPE_MODE (type
) == QImode
)
6762 obstack_1grow (&util_obstack
, 'c');
6763 else if (TYPE_MODE (type
) == HImode
)
6764 obstack_1grow (&util_obstack
, 's');
6765 else if (TYPE_MODE (type
) == SImode
)
6767 if (type
== long_integer_type_node
)
6768 obstack_1grow (&util_obstack
, 'l');
6770 obstack_1grow (&util_obstack
, 'i');
6773 else if (TYPE_MODE (type
) == DImode
)
6774 obstack_1grow (&util_obstack
, 'q');
6778 else if (code
== REAL_TYPE
)
6780 /* Floating point types. */
6782 if (TYPE_MODE (type
) == SFmode
)
6783 obstack_1grow (&util_obstack
, 'f');
6784 else if (TYPE_MODE (type
) == DFmode
6785 || TYPE_MODE (type
) == TFmode
)
6786 obstack_1grow (&util_obstack
, 'd');
6789 else if (code
== VOID_TYPE
)
6790 obstack_1grow (&util_obstack
, 'v');
6792 else if (code
== ARRAY_TYPE
)
6793 encode_array (type
, curtype
, format
);
6795 else if (code
== POINTER_TYPE
)
6796 encode_pointer (type
, curtype
, format
);
6798 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6799 encode_aggregate (type
, curtype
, format
);
6801 else if (code
== FUNCTION_TYPE
) /* '?' */
6802 obstack_1grow (&util_obstack
, '?');
6806 encode_complete_bitfield (int position
, tree type
, int size
)
6808 enum tree_code code
= TREE_CODE (type
);
6810 char charType
= '?';
6812 if (code
== INTEGER_TYPE
)
6814 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6816 /* Unsigned integer types. */
6818 if (TYPE_MODE (type
) == QImode
)
6820 else if (TYPE_MODE (type
) == HImode
)
6822 else if (TYPE_MODE (type
) == SImode
)
6824 if (type
== long_unsigned_type_node
)
6829 else if (TYPE_MODE (type
) == DImode
)
6834 /* Signed integer types. */
6836 if (TYPE_MODE (type
) == QImode
)
6838 else if (TYPE_MODE (type
) == HImode
)
6840 else if (TYPE_MODE (type
) == SImode
)
6842 if (type
== long_integer_type_node
)
6848 else if (TYPE_MODE (type
) == DImode
)
6856 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6857 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6861 encode_field_decl (field_decl
, curtype
, format
)
6868 type
= TREE_TYPE (field_decl
);
6870 /* If this field is obviously a bitfield, or is a bitfield that has been
6871 clobbered to look like a ordinary integer mode, go ahead and generate
6872 the bitfield typing information. */
6873 if (flag_next_runtime
)
6875 if (DECL_BIT_FIELD (field_decl
))
6876 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6878 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6882 if (DECL_BIT_FIELD (field_decl
))
6883 encode_complete_bitfield (int_bit_position (field_decl
),
6884 DECL_BIT_FIELD_TYPE (field_decl
),
6885 tree_low_cst (DECL_SIZE (field_decl
), 1));
6887 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6892 expr_last (complex_expr
)
6898 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6899 complex_expr
= next
;
6901 return complex_expr
;
6904 /* The selector of the current method,
6905 or NULL if we aren't compiling a method. */
6908 maybe_objc_method_name (decl
)
6909 tree decl ATTRIBUTE_UNUSED
;
6912 return METHOD_SEL_NAME (method_context
);
6917 /* Transform a method definition into a function definition as follows:
6918 - synthesize the first two arguments, "self" and "_cmd". */
6921 start_method_def (method
)
6926 /* Required to implement _msgSuper. */
6927 method_context
= method
;
6928 UOBJC_SUPER_decl
= NULL_TREE
;
6930 /* Must be called BEFORE start_function. */
6933 /* Generate prototype declarations for arguments..."new-style". */
6935 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
6936 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6938 /* Really a `struct objc_class *'. However, we allow people to
6939 assign to self, which changes its type midstream. */
6940 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6942 push_parm_decl (build_tree_list
6943 (build_tree_list (decl_specs
,
6944 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6945 build_tree_list (unused_list
, NULL_TREE
)));
6947 #ifdef OBJC_INT_SELECTORS
6948 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
6949 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
6950 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
6951 build_tree_list (unused_list
, NULL_TREE
)));
6952 #else /* not OBJC_INT_SELECTORS */
6953 decl_specs
= build_tree_list (NULL_TREE
,
6954 xref_tag (RECORD_TYPE
,
6955 get_identifier (TAG_SELECTOR
)));
6956 push_parm_decl (build_tree_list
6957 (build_tree_list (decl_specs
,
6958 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6959 build_tree_list (unused_list
, NULL_TREE
)));
6960 #endif /* not OBJC_INT_SELECTORS */
6962 /* Generate argument declarations if a keyword_decl. */
6963 if (METHOD_SEL_ARGS (method
))
6965 tree arglist
= METHOD_SEL_ARGS (method
);
6968 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6969 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6973 tree last_expr
= expr_last (arg_decl
);
6975 /* Unite the abstract decl with its name. */
6976 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6977 push_parm_decl (build_tree_list
6978 (build_tree_list (arg_spec
, arg_decl
),
6979 build_tree_list (NULL_TREE
, NULL_TREE
)));
6981 /* Unhook: restore the abstract declarator. */
6982 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6986 push_parm_decl (build_tree_list
6987 (build_tree_list (arg_spec
,
6988 KEYWORD_ARG_NAME (arglist
)),
6989 build_tree_list (NULL_TREE
, NULL_TREE
)));
6991 arglist
= TREE_CHAIN (arglist
);
6996 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6997 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6999 /* We have a variable length selector - in "prototype" format. */
7000 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7003 /* This must be done prior to calling pushdecl. pushdecl is
7004 going to change our chain on us. */
7005 tree nextkey
= TREE_CHAIN (akey
);
7013 warn_with_method (message
, mtype
, method
)
7014 const char *message
;
7018 if (count_error (1) == 0)
7021 report_error_function (DECL_SOURCE_FILE (method
));
7023 fprintf (stderr
, "%s:%d: warning: ",
7024 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7025 memset (errbuf
, 0, BUFSIZE
);
7026 fprintf (stderr
, "%s `%c%s'\n",
7027 message
, mtype
, gen_method_decl (method
, errbuf
));
7030 /* Return 1 if METHOD is consistent with PROTO. */
7033 comp_method_with_proto (method
, proto
)
7036 static tree function_type
= 0;
7038 /* Create a function_type node once. */
7041 function_type
= make_node (FUNCTION_TYPE
);
7042 ggc_add_tree_root (&function_type
, 1);
7045 /* Install argument types - normally set by build_function_type. */
7046 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7048 /* install return type */
7049 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7051 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7054 /* Return 1 if PROTO1 is consistent with PROTO2. */
7057 comp_proto_with_proto (proto0
, proto1
)
7058 tree proto0
, proto1
;
7060 static tree function_type
[2];
7062 /* Create a couple function_type node's once. */
7063 if (!function_type
[0])
7065 function_type
[0] = make_node (FUNCTION_TYPE
);
7066 function_type
[1] = make_node (FUNCTION_TYPE
);
7067 ggc_add_tree_root (function_type
, 2);
7070 /* Install argument types; normally set by build_function_type. */
7071 TYPE_ARG_TYPES (function_type
[0]) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7072 TYPE_ARG_TYPES (function_type
[1]) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7074 /* Install return type. */
7075 TREE_TYPE (function_type
[0]) = groktypename (TREE_TYPE (proto0
));
7076 TREE_TYPE (function_type
[1]) = groktypename (TREE_TYPE (proto1
));
7078 return comptypes (function_type
[0], function_type
[1]);
7081 /* - Generate an identifier for the function. the format is "_n_cls",
7082 where 1 <= n <= nMethods, and cls is the name the implementation we
7084 - Install the return type from the method declaration.
7085 - If we have a prototype, check for type consistency. */
7088 really_start_method (method
, parmlist
)
7089 tree method
, parmlist
;
7091 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7092 tree method_decl
, method_id
;
7093 const char *sel_name
, *class_name
, *cat_name
;
7096 /* Synth the storage class & assemble the return type. */
7097 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7098 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7099 decl_specs
= chainon (sc_spec
, ret_spec
);
7101 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7102 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7103 cat_name
= ((TREE_CODE (implementation_context
)
7104 == CLASS_IMPLEMENTATION_TYPE
)
7106 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7109 /* Make sure this is big enough for any plausible method label. */
7110 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7111 + (cat_name
? strlen (cat_name
) : 0));
7113 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7114 class_name
, cat_name
, sel_name
, method_slot
);
7116 method_id
= get_identifier (buf
);
7118 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7120 /* Check the declarator portion of the return type for the method. */
7121 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7123 /* Unite the complex decl (specified in the abstract decl) with the
7124 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7125 tree save_expr
= expr_last (ret_decl
);
7127 TREE_OPERAND (save_expr
, 0) = method_decl
;
7128 method_decl
= ret_decl
;
7130 /* Fool the parser into thinking it is starting a function. */
7131 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7133 /* Unhook: this has the effect of restoring the abstract declarator. */
7134 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7139 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7141 /* Fool the parser into thinking it is starting a function. */
7142 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7144 /* Unhook: this has the effect of restoring the abstract declarator. */
7145 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7148 METHOD_DEFINITION (method
) = current_function_decl
;
7150 if (implementation_template
!= implementation_context
)
7154 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7155 proto
= lookup_instance_method_static (implementation_template
,
7156 METHOD_SEL_NAME (method
));
7158 proto
= lookup_class_method_static (implementation_template
,
7159 METHOD_SEL_NAME (method
));
7161 if (proto
&& ! comp_method_with_proto (method
, proto
))
7163 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7165 warn_with_method ("conflicting types for", type
, method
);
7166 warn_with_method ("previous declaration of", type
, proto
);
7171 /* The following routine is always called...this "architecture" is to
7172 accommodate "old-style" variable length selectors.
7174 - a:a b:b // prototype ; id c; id d; // old-style. */
7177 continue_method_def ()
7181 if (METHOD_ADD_ARGS (method_context
) == objc_ellipsis_node
)
7182 /* We have a `, ...' immediately following the selector. */
7183 parmlist
= get_parm_info (0);
7185 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7187 /* Set self_decl from the first argument...this global is used by
7188 build_ivar_reference calling build_indirect_ref. */
7189 self_decl
= TREE_PURPOSE (parmlist
);
7192 really_start_method (method_context
, parmlist
);
7193 store_parm_decls ();
7196 /* Called by the parser, from the `pushlevel' production. */
7201 if (!UOBJC_SUPER_decl
)
7203 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7204 build_tree_list (NULL_TREE
,
7205 objc_super_template
),
7206 0, NULL_TREE
, NULL_TREE
);
7208 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7210 /* This prevents `unused variable' warnings when compiling with -Wall. */
7211 TREE_USED (UOBJC_SUPER_decl
) = 1;
7212 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7216 /* _n_Method (id self, SEL sel, ...)
7218 struct objc_super _S;
7219 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7223 get_super_receiver ()
7227 tree super_expr
, super_expr_list
;
7229 /* Set receiver to self. */
7230 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7231 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7232 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7234 /* Set class to begin searching. */
7235 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7236 get_identifier ("class"));
7238 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7240 /* [_cls, __cls]Super are "pre-built" in
7241 synth_forward_declarations. */
7243 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7244 ((TREE_CODE (method_context
)
7245 == INSTANCE_METHOD_DECL
)
7247 : uucls_super_ref
));
7251 /* We have a category. */
7253 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7258 error ("no super class declared in interface for `%s'",
7259 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7260 return error_mark_node
;
7263 if (flag_next_runtime
)
7265 super_class
= get_class_reference (super_name
);
7266 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7268 = build_component_ref (build_indirect_ref (super_class
, "->"),
7269 get_identifier ("isa"));
7273 add_class_reference (super_name
);
7274 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7275 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7276 assemble_external (super_class
);
7278 = build_function_call
7282 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7283 IDENTIFIER_POINTER (super_name
))));
7286 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7287 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7290 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7292 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7293 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7295 return build_compound_expr (super_expr_list
);
7299 error ("[super ...] must appear in a method context");
7300 return error_mark_node
;
7305 encode_method_def (func_decl
)
7310 HOST_WIDE_INT max_parm_end
= 0;
7315 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7316 obstack_object_size (&util_obstack
),
7317 OBJC_ENCODE_INLINE_DEFS
);
7320 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7321 parms
= TREE_CHAIN (parms
))
7323 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7324 + int_size_in_bytes (TREE_TYPE (parms
)));
7326 if (! offset_is_register
&& parm_end
> max_parm_end
)
7327 max_parm_end
= parm_end
;
7330 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7332 sprintf (buffer
, "%d", stack_size
);
7333 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7335 /* Argument types. */
7336 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7337 parms
= TREE_CHAIN (parms
))
7340 encode_type (TREE_TYPE (parms
),
7341 obstack_object_size (&util_obstack
),
7342 OBJC_ENCODE_INLINE_DEFS
);
7344 /* Compute offset. */
7345 sprintf (buffer
, "%d", forwarding_offset (parms
));
7347 /* Indicate register. */
7348 if (offset_is_register
)
7349 obstack_1grow (&util_obstack
, '+');
7351 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7354 obstack_1grow (&util_obstack
, 0);
7355 result
= get_identifier (obstack_finish (&util_obstack
));
7356 obstack_free (&util_obstack
, util_firstobj
);
7361 objc_expand_function_end ()
7363 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7367 finish_method_def ()
7369 lang_expand_function_end
= objc_expand_function_end
;
7370 finish_function (0);
7371 lang_expand_function_end
= NULL
;
7373 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7374 since the optimizer may find "may be used before set" errors. */
7375 method_context
= NULL_TREE
;
7380 lang_report_error_function (decl
)
7385 fprintf (stderr
, "In method `%s'\n",
7386 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7396 is_complex_decl (type
)
7399 return (TREE_CODE (type
) == ARRAY_TYPE
7400 || TREE_CODE (type
) == FUNCTION_TYPE
7401 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7405 /* Code to convert a decl node into text for a declaration in C. */
7407 static char tmpbuf
[256];
7410 adorn_decl (decl
, str
)
7414 enum tree_code code
= TREE_CODE (decl
);
7416 if (code
== ARRAY_REF
)
7418 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7420 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7421 sprintf (str
+ strlen (str
), "[%ld]",
7422 (long) TREE_INT_CST_LOW (an_int_cst
));
7427 else if (code
== ARRAY_TYPE
)
7429 tree an_int_cst
= TYPE_SIZE (decl
);
7430 tree array_of
= TREE_TYPE (decl
);
7432 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7433 sprintf (str
+ strlen (str
), "[%ld]",
7434 (long) (TREE_INT_CST_LOW (an_int_cst
)
7435 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7440 else if (code
== CALL_EXPR
)
7442 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7447 gen_declaration (chain
, str
);
7448 chain
= TREE_CHAIN (chain
);
7455 else if (code
== FUNCTION_TYPE
)
7457 tree chain
= TYPE_ARG_TYPES (decl
);
7460 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7462 gen_declaration (TREE_VALUE (chain
), str
);
7463 chain
= TREE_CHAIN (chain
);
7464 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7470 else if (code
== INDIRECT_REF
)
7472 strcpy (tmpbuf
, "*");
7473 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7477 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7479 chain
= TREE_CHAIN (chain
))
7481 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7483 strcat (tmpbuf
, " ");
7484 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7488 strcat (tmpbuf
, " ");
7490 strcat (tmpbuf
, str
);
7491 strcpy (str
, tmpbuf
);
7494 else if (code
== POINTER_TYPE
)
7496 strcpy (tmpbuf
, "*");
7497 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7499 if (TREE_READONLY (decl
))
7500 strcat (tmpbuf
, " const");
7501 if (TYPE_VOLATILE (decl
))
7502 strcat (tmpbuf
, " volatile");
7504 strcat (tmpbuf
, " ");
7506 strcat (tmpbuf
, str
);
7507 strcpy (str
, tmpbuf
);
7512 gen_declarator (decl
, buf
, name
)
7519 enum tree_code code
= TREE_CODE (decl
);
7529 op
= TREE_OPERAND (decl
, 0);
7531 /* We have a pointer to a function or array...(*)(), (*)[] */
7532 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7533 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7536 str
= gen_declarator (op
, buf
, name
);
7540 strcpy (tmpbuf
, "(");
7541 strcat (tmpbuf
, str
);
7542 strcat (tmpbuf
, ")");
7543 strcpy (str
, tmpbuf
);
7546 adorn_decl (decl
, str
);
7555 /* This clause is done iteratively rather than recursively. */
7558 op
= (is_complex_decl (TREE_TYPE (decl
))
7559 ? TREE_TYPE (decl
) : NULL_TREE
);
7561 adorn_decl (decl
, str
);
7563 /* We have a pointer to a function or array...(*)(), (*)[] */
7564 if (code
== POINTER_TYPE
7565 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7566 || TREE_CODE (op
) == ARRAY_TYPE
))
7568 strcpy (tmpbuf
, "(");
7569 strcat (tmpbuf
, str
);
7570 strcat (tmpbuf
, ")");
7571 strcpy (str
, tmpbuf
);
7574 decl
= (is_complex_decl (TREE_TYPE (decl
))
7575 ? TREE_TYPE (decl
) : NULL_TREE
);
7578 while (decl
&& (code
= TREE_CODE (decl
)))
7583 case IDENTIFIER_NODE
:
7584 /* Will only happen if we are processing a "raw" expr-decl. */
7585 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7596 /* We have an abstract declarator or a _DECL node. */
7604 gen_declspecs (declspecs
, buf
, raw
)
7613 for (chain
= nreverse (copy_list (declspecs
));
7614 chain
; chain
= TREE_CHAIN (chain
))
7616 tree aspec
= TREE_VALUE (chain
);
7618 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7619 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7620 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7622 if (TYPE_NAME (aspec
))
7624 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7626 if (! TREE_STATIC_TEMPLATE (aspec
))
7627 strcat (buf
, "struct ");
7628 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7633 tree chain
= protocol_list
;
7640 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7641 chain
= TREE_CHAIN (chain
);
7650 strcat (buf
, "untagged struct");
7653 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7655 if (TYPE_NAME (aspec
))
7657 if (! TREE_STATIC_TEMPLATE (aspec
))
7658 strcat (buf
, "union ");
7659 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7662 strcat (buf
, "untagged union");
7665 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7667 if (TYPE_NAME (aspec
))
7669 if (! TREE_STATIC_TEMPLATE (aspec
))
7670 strcat (buf
, "enum ");
7671 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7674 strcat (buf
, "untagged enum");
7677 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7678 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7680 else if (IS_ID (aspec
))
7682 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7687 tree chain
= protocol_list
;
7694 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7695 chain
= TREE_CHAIN (chain
);
7702 if (TREE_CHAIN (chain
))
7708 /* Type qualifiers. */
7709 if (TREE_READONLY (declspecs
))
7710 strcat (buf
, "const ");
7711 if (TYPE_VOLATILE (declspecs
))
7712 strcat (buf
, "volatile ");
7714 switch (TREE_CODE (declspecs
))
7716 /* Type specifiers. */
7719 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7721 /* Signed integer types. */
7723 if (declspecs
== short_integer_type_node
)
7724 strcat (buf
, "short int ");
7725 else if (declspecs
== integer_type_node
)
7726 strcat (buf
, "int ");
7727 else if (declspecs
== long_integer_type_node
)
7728 strcat (buf
, "long int ");
7729 else if (declspecs
== long_long_integer_type_node
)
7730 strcat (buf
, "long long int ");
7731 else if (declspecs
== signed_char_type_node
7732 || declspecs
== char_type_node
)
7733 strcat (buf
, "char ");
7735 /* Unsigned integer types. */
7737 else if (declspecs
== short_unsigned_type_node
)
7738 strcat (buf
, "unsigned short ");
7739 else if (declspecs
== unsigned_type_node
)
7740 strcat (buf
, "unsigned int ");
7741 else if (declspecs
== long_unsigned_type_node
)
7742 strcat (buf
, "unsigned long ");
7743 else if (declspecs
== long_long_unsigned_type_node
)
7744 strcat (buf
, "unsigned long long ");
7745 else if (declspecs
== unsigned_char_type_node
)
7746 strcat (buf
, "unsigned char ");
7750 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7752 if (declspecs
== float_type_node
)
7753 strcat (buf
, "float ");
7754 else if (declspecs
== double_type_node
)
7755 strcat (buf
, "double ");
7756 else if (declspecs
== long_double_type_node
)
7757 strcat (buf
, "long double ");
7761 if (TYPE_NAME (declspecs
)
7762 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7764 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7766 if (! TREE_STATIC_TEMPLATE (declspecs
))
7767 strcat (buf
, "struct ");
7768 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7772 tree chain
= protocol_list
;
7779 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7780 chain
= TREE_CHAIN (chain
);
7789 strcat (buf
, "untagged struct");
7795 if (TYPE_NAME (declspecs
)
7796 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7798 strcat (buf
, "union ");
7799 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7804 strcat (buf
, "untagged union ");
7808 if (TYPE_NAME (declspecs
)
7809 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7811 strcat (buf
, "enum ");
7812 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7817 strcat (buf
, "untagged enum ");
7821 strcat (buf
, "void ");
7826 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7831 tree chain
= protocol_list
;
7838 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7839 chain
= TREE_CHAIN (chain
);
7856 gen_declaration (atype_or_adecl
, buf
)
7857 tree atype_or_adecl
;
7862 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7864 tree declspecs
; /* "identifier_node", "record_type" */
7865 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7867 /* We have a "raw", abstract declarator (typename). */
7868 declarator
= TREE_VALUE (atype_or_adecl
);
7869 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7871 gen_declspecs (declspecs
, buf
, 1);
7875 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7882 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7883 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7885 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7886 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7887 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7888 atype
= TREE_TYPE (atype_or_adecl
);
7890 /* Assume we have a *_type node. */
7891 atype
= atype_or_adecl
;
7893 if (is_complex_decl (atype
))
7897 /* Get the declaration specifier; it is at the end of the list. */
7898 declarator
= chain
= atype
;
7900 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7901 while (is_complex_decl (chain
));
7908 declarator
= NULL_TREE
;
7911 gen_declspecs (declspecs
, buf
, 0);
7913 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7914 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7915 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7917 const char *decl_name
=
7918 (DECL_NAME (atype_or_adecl
)
7919 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7924 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7927 else if (decl_name
[0])
7930 strcat (buf
, decl_name
);
7933 else if (declarator
)
7936 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7943 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7946 gen_method_decl (method
, buf
)
7952 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7955 gen_declaration (TREE_TYPE (method
), buf
);
7959 chain
= METHOD_SEL_ARGS (method
);
7962 /* We have a chain of keyword_decls. */
7965 if (KEYWORD_KEY_NAME (chain
))
7966 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7969 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7972 gen_declaration (TREE_TYPE (chain
), buf
);
7976 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7977 if ((chain
= TREE_CHAIN (chain
)))
7982 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7983 strcat (buf
, ", ...");
7984 else if (METHOD_ADD_ARGS (method
))
7986 /* We have a tree list node as generate by get_parm_info. */
7987 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7989 /* Know we have a chain of parm_decls. */
7993 gen_declaration (chain
, buf
);
7994 chain
= TREE_CHAIN (chain
);
8000 /* We have a unary selector. */
8001 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8009 dump_interface (fp
, chain
)
8013 char *buf
= (char *)xmalloc (256);
8014 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8015 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8016 tree nst_methods
= CLASS_NST_METHODS (chain
);
8017 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8019 fprintf (fp
, "\n@interface %s", my_name
);
8021 if (CLASS_SUPER_NAME (chain
))
8023 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8024 fprintf (fp
, " : %s\n", super_name
);
8031 fprintf (fp
, "{\n");
8034 memset (buf
, 0, 256);
8035 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8036 ivar_decls
= TREE_CHAIN (ivar_decls
);
8039 fprintf (fp
, "}\n");
8044 memset (buf
, 0, 256);
8045 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8046 nst_methods
= TREE_CHAIN (nst_methods
);
8051 memset (buf
, 0, 256);
8052 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8053 cls_methods
= TREE_CHAIN (cls_methods
);
8055 fprintf (fp
, "\n@end");
8058 /* Demangle function for Objective-C */
8060 objc_demangle (mangled
)
8061 const char *mangled
;
8063 char *demangled
, *cp
;
8065 if (mangled
[0] == '_' &&
8066 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8069 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8070 if (mangled
[1] == 'i')
8071 *cp
++ = '-'; /* for instance method */
8073 *cp
++ = '+'; /* for class method */
8074 *cp
++ = '['; /* opening left brace */
8075 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8076 while (*cp
&& *cp
== '_')
8077 cp
++; /* skip any initial underbars in class name */
8078 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8081 free(demangled
); /* not mangled name */
8084 if (cp
[1] == '_') /* easy case: no category name */
8086 *cp
++ = ' '; /* replace two '_' with one ' ' */
8087 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8091 *cp
++ = '('; /* less easy case: category name */
8092 cp
= strchr(cp
, '_');
8095 free(demangled
); /* not mangled name */
8099 *cp
++ = ' '; /* overwriting 1st char of method name... */
8100 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8102 while (*cp
&& *cp
== '_')
8103 cp
++; /* skip any initial underbars in method name */
8106 *cp
= ':'; /* replace remaining '_' with ':' */
8107 *cp
++ = ']'; /* closing right brace */
8108 *cp
++ = 0; /* string terminator */
8112 return mangled
; /* not an objc mangled name */
8116 objc_printable_name (decl
, kind
)
8118 int kind ATTRIBUTE_UNUSED
;
8120 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8126 /* Add the special tree codes of Objective C to the tables. */
8128 #define LAST_CODE LAST_C_TREE_CODE
8130 gcc_obstack_init (&util_obstack
);
8131 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8133 memcpy (tree_code_type
+ (int) LAST_CODE
,
8134 objc_tree_code_type
,
8135 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8136 memcpy (tree_code_length
+ (int) LAST_CODE
,
8137 objc_tree_code_length
,
8138 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8139 memcpy (tree_code_name
+ (int) LAST_CODE
,
8140 objc_tree_code_name
,
8141 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8143 errbuf
= (char *)xmalloc (BUFSIZE
);
8145 synth_module_prologue ();
8147 /* Change the default error function */
8148 decl_printable_name
= objc_printable_name
;
8149 lang_expand_expr
= c_expand_expr
;
8150 lang_expand_decl_stmt
= c_expand_decl_stmt
;
8156 struct imp_entry
*impent
;
8158 /* The internally generated initializers appear to have missing braces.
8159 Don't warn about this. */
8160 int save_warn_missing_braces
= warn_missing_braces
;
8161 warn_missing_braces
= 0;
8163 generate_forward_declaration_to_string_table ();
8165 #ifdef OBJC_PROLOGUE
8169 /* Process the static instances here because initialization of objc_symtab
8171 if (objc_static_instances
)
8172 generate_static_references ();
8174 if (implementation_context
|| class_names_chain
8175 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8176 generate_objc_symtab_decl ();
8178 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8180 implementation_context
= impent
->imp_context
;
8181 implementation_template
= impent
->imp_template
;
8183 UOBJC_CLASS_decl
= impent
->class_decl
;
8184 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8186 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8188 /* all of the following reference the string pool... */
8189 generate_ivar_lists ();
8190 generate_dispatch_tables ();
8191 generate_shared_structures ();
8195 generate_dispatch_tables ();
8196 generate_category (implementation_context
);
8200 /* If we are using an array of selectors, we must always
8201 finish up the array decl even if no selectors were used. */
8202 if (! flag_next_runtime
|| sel_ref_chain
)
8203 build_selector_translation_table ();
8206 generate_protocols ();
8208 if (implementation_context
|| class_names_chain
|| objc_static_instances
8209 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8211 /* Arrange for Objc data structures to be initialized at run time. */
8212 const char *init_name
= build_module_descriptor ();
8214 assemble_constructor (init_name
);
8217 /* Dump the class references. This forces the appropriate classes
8218 to be linked into the executable image, preserving unix archive
8219 semantics. This can be removed when we move to a more dynamically
8220 linked environment. */
8222 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8224 handle_class_ref (chain
);
8225 if (TREE_PURPOSE (chain
))
8226 generate_classref_translation_entry (chain
);
8229 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8230 handle_impent (impent
);
8232 /* Dump the string table last. */
8234 generate_strings ();
8236 if (flag_gen_declaration
)
8238 add_class (implementation_context
);
8239 dump_interface (gen_declaration_file
, implementation_context
);
8247 /* Run through the selector hash tables and print a warning for any
8248 selector which has multiple methods. */
8250 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8251 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8254 tree meth
= hsh
->key
;
8255 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8259 warning ("potential selector conflict for method `%s'",
8260 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8261 warn_with_method ("found", type
, meth
);
8262 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8263 warn_with_method ("found", type
, loop
->value
);
8266 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8267 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8270 tree meth
= hsh
->key
;
8271 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8275 warning ("potential selector conflict for method `%s'",
8276 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8277 warn_with_method ("found", type
, meth
);
8278 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8279 warn_with_method ("found", type
, loop
->value
);
8283 warn_missing_braces
= save_warn_missing_braces
;
8286 /* Subroutines of finish_objc. */
8289 generate_classref_translation_entry (chain
)
8292 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8295 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8297 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8298 expr
= build_c_cast (type
, expr
); /* cast! */
8300 name
= DECL_NAME (TREE_PURPOSE (chain
));
8302 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8304 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8305 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8307 /* The decl that is returned from start_decl is the one that we
8308 forward declared in build_class_reference. */
8309 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8310 finish_decl (decl
, expr
, NULL_TREE
);
8315 handle_class_ref (chain
)
8318 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8319 if (! flag_next_runtime
)
8322 char *string
= (char *) alloca (strlen (name
) + 30);
8325 sprintf (string
, "%sobjc_class_name_%s",
8326 (flag_next_runtime
? "." : "__"), name
);
8328 /* Make a decl for this name, so we can use its address in a tree. */
8329 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8330 DECL_EXTERNAL (decl
) = 1;
8331 TREE_PUBLIC (decl
) = 1;
8334 rest_of_decl_compilation (decl
, 0, 0, 0);
8336 /* Make following constant read-only (why not)? */
8337 readonly_data_section ();
8339 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8341 /* Align the section properly. */
8342 assemble_constant_align (exp
);
8344 /* Inform the assembler about this new external thing. */
8345 assemble_external (decl
);
8347 /* Output a constant to reference this address. */
8348 output_constant (exp
, int_size_in_bytes (string_type_node
));
8352 /* This overreliance on our assembler (i.e. lack of portability)
8353 should be dealt with at some point. The GNU strategy (above)
8354 won't work either, but it is a start. */
8355 char *string
= (char *) alloca (strlen (name
) + 30);
8356 sprintf (string
, ".reference .objc_class_name_%s", name
);
8357 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8362 handle_impent (impent
)
8363 struct imp_entry
*impent
;
8365 implementation_context
= impent
->imp_context
;
8366 implementation_template
= impent
->imp_template
;
8368 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8370 const char *class_name
=
8371 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8372 char *string
= (char *) alloca (strlen (class_name
) + 30);
8374 if (flag_next_runtime
)
8376 /* Grossly unportable.
8377 People should know better than to assume
8378 such things about assembler syntax! */
8379 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8380 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8382 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8383 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8388 sprintf (string
, "%sobjc_class_name_%s",
8389 (flag_next_runtime
? "." : "__"), class_name
);
8390 assemble_global (string
);
8391 assemble_label (string
);
8395 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8397 const char *class_name
=
8398 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8399 const char *class_super_name
=
8400 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8401 char *string
= (char *) alloca (strlen (class_name
)
8402 + strlen (class_super_name
) + 30);
8404 /* Do the same for categories. Even though no references to these
8405 symbols are generated automatically by the compiler, it gives
8406 you a handle to pull them into an archive by hand. */
8407 if (flag_next_runtime
)
8409 /* Grossly unportable. */
8410 sprintf (string
, ".objc_category_name_%s_%s=0",
8411 class_name
, class_super_name
);
8412 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8414 sprintf (string
, ".globl .objc_category_name_%s_%s",
8415 class_name
, class_super_name
);
8416 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8421 sprintf (string
, "%sobjc_category_name_%s_%s",
8422 (flag_next_runtime
? "." : "__"),
8423 class_name
, class_super_name
);
8424 assemble_global (string
);
8425 assemble_label (string
);
8436 char *buf
= (char *)xmalloc (256);
8438 { /* dump function prototypes */
8439 tree loop
= UOBJC_MODULES_decl
;
8441 fprintf (fp
, "\n\nfunction prototypes:\n");
8444 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8446 /* We have a function definition: generate prototype. */
8447 memset (errbuf
, 0, BUFSIZE
);
8448 gen_declaration (loop
, errbuf
);
8449 fprintf (fp
, "%s;\n", errbuf
);
8451 loop
= TREE_CHAIN (loop
);
8455 /* Dump global chains. */
8457 int i
, index
= 0, offset
= 0;
8460 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8462 if (hashlist
= nst_method_hash_list
[i
])
8464 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8467 memset (buf
, 0, 256);
8468 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8469 hashlist
= hashlist
->next
;
8475 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8477 if (hashlist
= cls_method_hash_list
[i
])
8479 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8482 memset (buf
, 0, 256);
8483 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8484 hashlist
= hashlist
->next
;
8490 fprintf (fp
, "\nsel_refdef_chain:\n");
8491 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8493 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8494 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8496 /* add one for the '\0' character */
8497 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8500 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8506 print_lang_statistics ()
8511 ggc_mark_imp_list (arg
)
8514 struct imp_entry
*impent
;
8516 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8518 ggc_mark_tree (impent
->imp_context
);
8519 ggc_mark_tree (impent
->imp_template
);
8520 ggc_mark_tree (impent
->class_decl
);
8521 ggc_mark_tree (impent
->meta_decl
);
8526 ggc_mark_hash_table (arg
)
8529 hash
*hash_table
= *(hash
**)arg
;
8534 if (hash_table
== NULL
)
8536 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8537 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8539 ggc_mark_tree (hst
->key
);
8540 for (list
= hst
->list
; list
; list
= list
->next
)
8541 ggc_mark_tree (list
->value
);
8545 /* Add GC roots for variables local to this file. */
8547 objc_act_parse_init ()
8549 ggc_add_tree_root (&objc_ellipsis_node
, 1);
8550 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8551 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8552 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8553 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8556 /* Look up ID as an instance variable. */
8558 lookup_objc_ivar (id
)
8563 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8564 /* we have a message to super */
8565 return get_super_receiver ();
8566 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8568 if (is_private (decl
))
8569 return error_mark_node
;
8571 return build_ivar_reference (id
);
8577 /* Parser callbacks. */
8579 forget_protocol_qualifiers ()
8581 C_IS_RESERVED_WORD (ridpointers
[(int) RID_IN
]) = 0;
8582 C_IS_RESERVED_WORD (ridpointers
[(int) RID_OUT
]) = 0;
8583 C_IS_RESERVED_WORD (ridpointers
[(int) RID_INOUT
]) = 0;
8584 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYCOPY
]) = 0;
8585 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYREF
]) = 0;
8586 C_IS_RESERVED_WORD (ridpointers
[(int) RID_ONEWAY
]) = 0;
8590 remember_protocol_qualifiers ()
8592 C_IS_RESERVED_WORD (ridpointers
[(int) RID_IN
]) = 1;
8593 C_IS_RESERVED_WORD (ridpointers
[(int) RID_OUT
]) = 1;
8594 C_IS_RESERVED_WORD (ridpointers
[(int) RID_INOUT
]) = 1;
8595 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYCOPY
]) = 1;
8596 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYREF
]) = 1;
8597 C_IS_RESERVED_WORD (ridpointers
[(int) RID_ONEWAY
]) = 1;