1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000, 2001 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
40 - OBJC_INT_SELECTORS */
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
87 /* Define the special tree codes that we use. */
89 /* Table indexed by tree code giving a string containing a character
90 classifying the tree code. Possibilities are
91 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
95 static const char objc_tree_code_type
[] = {
97 #include "objc-tree.def"
101 /* Table indexed by tree code giving number of expression
102 operands beyond the fixed part of the node structure.
103 Not used for types or decls. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
107 static const int objc_tree_code_length
[] = {
109 #include "objc-tree.def"
113 /* Names of tree components.
114 Used for printing out the tree and error messages. */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
117 static const char * const objc_tree_code_name
[] = {
119 #include "objc-tree.def"
123 /* Set up for use of obstacks. */
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
130 /* This obstack is used to accumulate the encoding of a data type. */
131 static struct obstack util_obstack
;
132 /* This points to the beginning of obstack contents,
133 so we can free the whole contents. */
136 /* for encode_method_def */
139 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
140 #define PROTOCOL_VERSION 2
142 #define OBJC_ENCODE_INLINE_DEFS 0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
145 /*** Private Interface (procedures) ***/
147 /* Used by compile_file. */
149 static void init_objc
PARAMS ((void));
150 static void finish_objc
PARAMS ((void));
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 c_common_lang_init ();
709 /* If gen_declaration desired, open the output file. */
710 if (flag_gen_declaration
)
712 register char * const dumpname
= concat (dumpname
, ".decl", NULL
);
713 gen_declaration_file
= fopen (dumpname
, "w");
714 if (gen_declaration_file
== 0)
715 pfatal_with_name (dumpname
);
719 if (flag_next_runtime
)
721 TAG_GETCLASS
= "objc_getClass";
722 TAG_GETMETACLASS
= "objc_getMetaClass";
723 TAG_MSGSEND
= "objc_msgSend";
724 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
725 TAG_EXECCLASS
= "__objc_execClass";
729 TAG_GETCLASS
= "objc_get_class";
730 TAG_GETMETACLASS
= "objc_get_meta_class";
731 TAG_MSGSEND
= "objc_msg_lookup";
732 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
733 TAG_EXECCLASS
= "__objc_exec_class";
734 flag_typed_selectors
= 1;
737 objc_ellipsis_node
= make_node (ERROR_MARK
);
741 if (print_struct_values
)
742 generate_struct_by_value_array ();
744 objc_act_parse_init ();
751 finish_objc (); /* Objective-C finalization */
753 if (gen_declaration_file
)
754 fclose (gen_declaration_file
);
769 lang_decode_option (argc
, argv
)
773 const char *p
= argv
[0];
775 if (!strcmp (p
, "-gen-decls"))
776 flag_gen_declaration
= 1;
777 else if (!strcmp (p
, "-Wselector"))
779 else if (!strcmp (p
, "-Wno-selector"))
781 else if (!strcmp (p
, "-Wprotocol"))
782 flag_warn_protocol
= 1;
783 else if (!strcmp (p
, "-Wno-protocol"))
784 flag_warn_protocol
= 0;
785 else if (!strcmp (p
, "-fgnu-runtime"))
786 flag_next_runtime
= 0;
787 else if (!strcmp (p
, "-fno-next-runtime"))
788 flag_next_runtime
= 0;
789 else if (!strcmp (p
, "-fno-gnu-runtime"))
790 flag_next_runtime
= 1;
791 else if (!strcmp (p
, "-fnext-runtime"))
792 flag_next_runtime
= 1;
793 else if (!strcmp (p
, "-print-objc-runtime-info"))
794 print_struct_values
= 1;
795 #define CSTSTRCLASS "-fconstant-string-class="
796 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
797 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
798 error ("no class name specified as argument to -fconstant-string-class");
799 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
803 return c_decode_option (argc
, argv
);
808 /* used by print-tree.c */
811 lang_print_xnode (file
, node
, indent
)
812 FILE *file ATTRIBUTE_UNUSED
;
813 tree node ATTRIBUTE_UNUSED
;
814 int indent ATTRIBUTE_UNUSED
;
820 define_decl (declarator
, declspecs
)
824 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
825 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
829 /* Return 1 if LHS and RHS are compatible types for assignment or
830 various other operations. Return 0 if they are incompatible, and
831 return -1 if we choose to not decide. When the operation is
832 REFLEXIVE, check for compatibility in either direction.
834 For statically typed objects, an assignment of the form `a' = `b'
838 `a' and `b' are the same class type, or
839 `a' and `b' are of class types A and B such that B is a descendant of A. */
842 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
846 return objc_comptypes (lhs
, rhs
, reflexive
);
850 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
858 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
860 p
= TREE_VALUE (rproto
);
862 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
864 if ((fnd
= lookup_method (class_meth
865 ? PROTOCOL_CLS_METHODS (p
)
866 : PROTOCOL_NST_METHODS (p
), sel_name
)))
868 else if (PROTOCOL_LIST (p
))
869 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
870 sel_name
, class_meth
);
874 ; /* An identifier...if we could not find a protocol. */
885 lookup_protocol_in_reflist (rproto_list
, lproto
)
891 /* Make sure the protocol is support by the object on the rhs. */
892 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
895 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
897 p
= TREE_VALUE (rproto
);
899 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
904 else if (PROTOCOL_LIST (p
))
905 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
914 ; /* An identifier...if we could not find a protocol. */
920 /* Return 1 if LHS and RHS are compatible types for assignment
921 or various other operations. Return 0 if they are incompatible,
922 and return -1 if we choose to not decide. When the operation
923 is REFLEXIVE, check for compatibility in either direction. */
926 objc_comptypes (lhs
, rhs
, reflexive
)
931 /* New clause for protocols. */
933 if (TREE_CODE (lhs
) == POINTER_TYPE
934 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
935 && TREE_CODE (rhs
) == POINTER_TYPE
936 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
938 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
939 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
943 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
944 tree rproto
, rproto_list
;
949 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
951 /* Make sure the protocol is supported by the object
953 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
955 p
= TREE_VALUE (lproto
);
956 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
959 warning ("object does not conform to the `%s' protocol",
960 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
963 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
965 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
968 /* Make sure the protocol is supported by the object
970 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
972 p
= TREE_VALUE (lproto
);
974 rinter
= lookup_interface (rname
);
976 while (rinter
&& !rproto
)
980 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
981 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
983 /* Check for protocols adopted by categories. */
984 cat
= CLASS_CATEGORY_LIST (rinter
);
985 while (cat
&& !rproto
)
987 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
988 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
990 cat
= CLASS_CATEGORY_LIST (cat
);
993 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
997 warning ("class `%s' does not implement the `%s' protocol",
998 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
999 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1003 /* May change...based on whether there was any mismatch */
1006 else if (rhs_is_proto
)
1007 /* Lhs is not a protocol...warn if it is statically typed */
1008 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
1011 /* Defer to comptypes .*/
1015 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
1016 ; /* Fall thru. This is the case we have been handling all along */
1018 /* Defer to comptypes. */
1021 /* `id' = `<class> *', `<class> *' = `id' */
1023 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
1024 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
1027 /* `id' = `Class', `Class' = `id' */
1029 else if ((TYPE_NAME (lhs
) == objc_object_id
1030 && TYPE_NAME (rhs
) == objc_class_id
)
1031 || (TYPE_NAME (lhs
) == objc_class_id
1032 && TYPE_NAME (rhs
) == objc_object_id
))
1035 /* `<class> *' = `<class> *' */
1037 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1039 tree lname
= TYPE_NAME (lhs
);
1040 tree rname
= TYPE_NAME (rhs
);
1046 /* If the left hand side is a super class of the right hand side,
1048 for (inter
= lookup_interface (rname
); inter
;
1049 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1050 if (lname
== CLASS_SUPER_NAME (inter
))
1053 /* Allow the reverse when reflexive. */
1055 for (inter
= lookup_interface (lname
); inter
;
1056 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1057 if (rname
== CLASS_SUPER_NAME (inter
))
1063 /* Defer to comptypes. */
1067 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1070 objc_check_decl (decl
)
1073 tree type
= TREE_TYPE (decl
);
1075 if (TREE_CODE (type
) == RECORD_TYPE
1076 && TREE_STATIC_TEMPLATE (type
)
1077 && type
!= constant_string_type
)
1079 error_with_decl (decl
, "`%s' cannot be statically allocated");
1080 fatal ("statically allocated objects not supported");
1085 maybe_objc_check_decl (decl
)
1088 objc_check_decl (decl
);
1091 /* Implement static typing. At this point, we know we have an interface. */
1094 get_static_reference (interface
, protocols
)
1098 tree type
= xref_tag (RECORD_TYPE
, interface
);
1102 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1104 t
= copy_node (type
);
1105 TYPE_BINFO (t
) = make_tree_vec (2);
1107 /* Add this type to the chain of variants of TYPE. */
1108 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1109 TYPE_NEXT_VARIANT (m
) = t
;
1111 /* Look up protocols and install in lang specific list. */
1112 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1114 /* This forces a new pointer type to be created later
1115 (in build_pointer_type)...so that the new template
1116 we just created will actually be used...what a hack! */
1117 if (TYPE_POINTER_TO (t
))
1118 TYPE_POINTER_TO (t
) = 0;
1127 get_object_reference (protocols
)
1130 tree type_decl
= lookup_name (objc_id_id
);
1133 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1135 type
= TREE_TYPE (type_decl
);
1136 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1137 warning ("Unexpected type for `id' (%s)",
1138 gen_declaration (type
, errbuf
));
1141 fatal ("Undefined type `id', please import <objc/objc.h>");
1143 /* This clause creates a new pointer type that is qualified with
1144 the protocol specification...this info is used later to do more
1145 elaborate type checking. */
1149 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1151 t
= copy_node (type
);
1152 TYPE_BINFO (t
) = make_tree_vec (2);
1154 /* Add this type to the chain of variants of TYPE. */
1155 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1156 TYPE_NEXT_VARIANT (m
) = t
;
1158 /* Look up protocols...and install in lang specific list */
1159 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1161 /* This forces a new pointer type to be created later
1162 (in build_pointer_type)...so that the new template
1163 we just created will actually be used...what a hack! */
1164 if (TYPE_POINTER_TO (t
))
1165 TYPE_POINTER_TO (t
) = NULL
;
1173 lookup_and_install_protocols (protocols
)
1178 tree return_value
= protocols
;
1180 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1182 tree ident
= TREE_VALUE (proto
);
1183 tree p
= lookup_protocol (ident
);
1187 error ("Cannot find protocol declaration for `%s'",
1188 IDENTIFIER_POINTER (ident
));
1190 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1192 return_value
= TREE_CHAIN (proto
);
1196 /* Replace identifier with actual protocol node. */
1197 TREE_VALUE (proto
) = p
;
1202 return return_value
;
1205 /* Create and push a decl for a built-in external variable or field NAME.
1207 TYPE is its data type. */
1210 create_builtin_decl (code
, type
, name
)
1211 enum tree_code code
;
1215 tree decl
= build_decl (code
, get_identifier (name
), type
);
1217 if (code
== VAR_DECL
)
1219 TREE_STATIC (decl
) = 1;
1220 make_decl_rtl (decl
, 0, 1);
1224 DECL_ARTIFICIAL (decl
) = 1;
1228 /* Purpose: "play" parser, creating/installing representations
1229 of the declarations that are required by Objective-C.
1233 type_spec--------->sc_spec
1234 (tree_list) (tree_list)
1237 identifier_node identifier_node */
1240 synth_module_prologue ()
1245 /* Defined in `objc.h' */
1246 objc_object_id
= get_identifier (TAG_OBJECT
);
1248 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1250 id_type
= build_pointer_type (objc_object_reference
);
1252 objc_id_id
= get_identifier (TYPE_ID
);
1253 objc_class_id
= get_identifier (TAG_CLASS
);
1255 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1256 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1257 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1259 /* Declare type of selector-objects that represent an operation name. */
1261 #ifdef OBJC_INT_SELECTORS
1262 /* `unsigned int' */
1263 selector_type
= unsigned_type_node
;
1265 /* `struct objc_selector *' */
1267 = build_pointer_type (xref_tag (RECORD_TYPE
,
1268 get_identifier (TAG_SELECTOR
)));
1269 #endif /* not OBJC_INT_SELECTORS */
1271 /* Forward declare type, or else the prototype for msgSendSuper will
1274 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1275 get_identifier (TAG_SUPER
)));
1278 /* id objc_msgSend (id, SEL, ...); */
1281 = build_function_type (id_type
,
1282 tree_cons (NULL_TREE
, id_type
,
1283 tree_cons (NULL_TREE
, selector_type
,
1286 if (! flag_next_runtime
)
1288 umsg_decl
= build_decl (FUNCTION_DECL
,
1289 get_identifier (TAG_MSGSEND
), temp_type
);
1290 DECL_EXTERNAL (umsg_decl
) = 1;
1291 TREE_PUBLIC (umsg_decl
) = 1;
1292 DECL_INLINE (umsg_decl
) = 1;
1293 DECL_ARTIFICIAL (umsg_decl
) = 1;
1295 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1296 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1298 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1299 pushdecl (umsg_decl
);
1302 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1304 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1307 = build_function_type (id_type
,
1308 tree_cons (NULL_TREE
, super_p
,
1309 tree_cons (NULL_TREE
, selector_type
,
1312 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1313 temp_type
, 0, NOT_BUILT_IN
, 0);
1315 /* id objc_getClass (const char *); */
1317 temp_type
= build_function_type (id_type
,
1318 tree_cons (NULL_TREE
,
1319 const_string_type_node
,
1320 tree_cons (NULL_TREE
, void_type_node
,
1324 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1326 /* id objc_getMetaClass (const char *); */
1328 objc_get_meta_class_decl
1329 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1331 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1333 if (! flag_next_runtime
)
1335 if (flag_typed_selectors
)
1337 /* Suppress outputting debug symbols, because
1338 dbxout_init hasn'r been called yet. */
1339 enum debug_info_type save_write_symbols
= write_symbols
;
1340 write_symbols
= NO_DEBUG
;
1342 build_selector_template ();
1343 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1345 write_symbols
= save_write_symbols
;
1348 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1350 layout_type (temp_type
);
1351 UOBJC_SELECTOR_TABLE_decl
1352 = create_builtin_decl (VAR_DECL
, temp_type
,
1353 "_OBJC_SELECTOR_TABLE");
1355 /* Avoid warning when not sending messages. */
1356 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1359 generate_forward_declaration_to_string_table ();
1361 /* Forward declare constant_string_id and constant_string_type. */
1362 if (!constant_string_class_name
)
1363 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1365 constant_string_id
= get_identifier (constant_string_class_name
);
1366 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1369 /* Custom build_string which sets TREE_TYPE! */
1372 my_build_string (len
, str
)
1377 tree a_string
= build_string (len
, str
);
1379 /* Some code from combine_strings, which is local to c-parse.y. */
1380 if (TREE_TYPE (a_string
) == int_array_type_node
)
1383 TREE_TYPE (a_string
)
1384 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1385 build_index_type (build_int_2 (len
- 1, 0)));
1387 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1388 TREE_STATIC (a_string
) = 1;
1393 /* Given a chain of STRING_CST's, build a static instance of
1394 NXConstanString which points at the concatenation of those strings.
1395 We place the string object in the __string_objects section of the
1396 __OBJC segment. The Objective-C runtime will initialize the isa
1397 pointers of the string objects to point at the NXConstandString class
1401 build_objc_string_object (strings
)
1404 tree string
, initlist
, constructor
;
1407 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1409 error ("Cannot find interface declaration for `%s'",
1410 IDENTIFIER_POINTER (constant_string_id
));
1411 return error_mark_node
;
1414 add_class_reference (constant_string_id
);
1416 string
= combine_strings (strings
);
1417 TREE_SET_CODE (string
, STRING_CST
);
1418 length
= TREE_STRING_LENGTH (string
) - 1;
1420 /* & ((NXConstantString) {0, string, length}) */
1422 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1424 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1426 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1427 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1429 if (!flag_next_runtime
)
1432 = objc_add_static_instance (constructor
, constant_string_type
);
1435 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1438 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1441 objc_add_static_instance (constructor
, class_decl
)
1442 tree constructor
, class_decl
;
1444 static int num_static_inst
;
1448 /* Find the list of static instances for the CLASS_DECL. Create one if
1450 for (chain
= &objc_static_instances
;
1451 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1452 chain
= &TREE_CHAIN (*chain
));
1455 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1456 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1459 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1460 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1461 DECL_COMMON (decl
) = 1;
1462 TREE_STATIC (decl
) = 1;
1463 DECL_ARTIFICIAL (decl
) = 1;
1464 pushdecl_top_level (decl
);
1465 rest_of_decl_compilation (decl
, 0, 1, 0);
1467 /* Do this here so it gets output later instead of possibly
1468 inside something else we are writing. */
1469 DECL_INITIAL (decl
) = constructor
;
1471 /* Add the DECL to the head of this CLASS' list. */
1472 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1477 /* Build a static constant CONSTRUCTOR
1478 with type TYPE and elements ELTS. */
1481 build_constructor (type
, elts
)
1484 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1486 TREE_CONSTANT (constructor
) = 1;
1487 TREE_STATIC (constructor
) = 1;
1488 TREE_READONLY (constructor
) = 1;
1493 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1495 /* Predefine the following data type:
1503 void *defs[cls_def_cnt + cat_def_cnt];
1507 build_objc_symtab_template ()
1509 tree field_decl
, field_decl_chain
, index
;
1511 objc_symtab_template
1512 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1514 /* long sel_ref_cnt; */
1516 field_decl
= create_builtin_decl (FIELD_DECL
,
1517 long_integer_type_node
,
1519 field_decl_chain
= field_decl
;
1523 field_decl
= create_builtin_decl (FIELD_DECL
,
1524 build_pointer_type (selector_type
),
1526 chainon (field_decl_chain
, field_decl
);
1528 /* short cls_def_cnt; */
1530 field_decl
= create_builtin_decl (FIELD_DECL
,
1531 short_integer_type_node
,
1533 chainon (field_decl_chain
, field_decl
);
1535 /* short cat_def_cnt; */
1537 field_decl
= create_builtin_decl (FIELD_DECL
,
1538 short_integer_type_node
,
1540 chainon (field_decl_chain
, field_decl
);
1542 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1544 if (!flag_next_runtime
)
1545 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1547 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1548 imp_count
== 0 && cat_count
== 0
1550 field_decl
= create_builtin_decl (FIELD_DECL
,
1551 build_array_type (ptr_type_node
, index
),
1553 chainon (field_decl_chain
, field_decl
);
1555 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1558 /* Create the initial value for the `defs' field of _objc_symtab.
1559 This is a CONSTRUCTOR. */
1562 init_def_list (type
)
1565 tree expr
, initlist
= NULL_TREE
;
1566 struct imp_entry
*impent
;
1569 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1571 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1573 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1574 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1579 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1581 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1583 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1584 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1588 if (!flag_next_runtime
)
1590 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1593 if (static_instances_decl
)
1594 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1596 expr
= build_int_2 (0, 0);
1598 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1601 return build_constructor (type
, nreverse (initlist
));
1604 /* Construct the initial value for all of _objc_symtab. */
1607 init_objc_symtab (type
)
1612 /* sel_ref_cnt = { ..., 5, ... } */
1614 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1616 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1618 if (flag_next_runtime
|| ! sel_ref_chain
)
1619 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1621 initlist
= tree_cons (NULL_TREE
,
1622 build_unary_op (ADDR_EXPR
,
1623 UOBJC_SELECTOR_TABLE_decl
, 1),
1626 /* cls_def_cnt = { ..., 5, ... } */
1628 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1630 /* cat_def_cnt = { ..., 5, ... } */
1632 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1634 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1636 if (imp_count
|| cat_count
|| static_instances_decl
)
1639 tree field
= TYPE_FIELDS (type
);
1640 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1642 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1646 return build_constructor (type
, nreverse (initlist
));
1649 /* Push forward-declarations of all the categories
1650 so that init_def_list can use them in a CONSTRUCTOR. */
1653 forward_declare_categories ()
1655 struct imp_entry
*impent
;
1656 tree sav
= implementation_context
;
1658 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1660 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1662 /* Set an invisible arg to synth_id_with_class_suffix. */
1663 implementation_context
= impent
->imp_context
;
1665 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1666 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1669 implementation_context
= sav
;
1672 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1673 and initialized appropriately. */
1676 generate_objc_symtab_decl ()
1680 if (!objc_category_template
)
1681 build_category_template ();
1683 /* forward declare categories */
1685 forward_declare_categories ();
1687 if (!objc_symtab_template
)
1688 build_objc_symtab_template ();
1690 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1692 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1693 tree_cons (NULL_TREE
,
1694 objc_symtab_template
, sc_spec
),
1696 NULL_TREE
, NULL_TREE
);
1698 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1699 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1700 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1701 finish_decl (UOBJC_SYMBOLS_decl
,
1702 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1707 init_module_descriptor (type
)
1710 tree initlist
, expr
;
1712 /* version = { 1, ... } */
1714 expr
= build_int_2 (OBJC_VERSION
, 0);
1715 initlist
= build_tree_list (NULL_TREE
, expr
);
1717 /* size = { ..., sizeof (struct objc_module), ... } */
1719 expr
= size_in_bytes (objc_module_template
);
1720 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1722 /* name = { ..., "foo.m", ... } */
1724 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1725 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1727 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1729 if (UOBJC_SYMBOLS_decl
)
1730 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1732 expr
= build_int_2 (0, 0);
1733 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1735 return build_constructor (type
, nreverse (initlist
));
1738 /* Write out the data structures to describe Objective C classes defined.
1739 If appropriate, compile and output a setup function to initialize them.
1740 Return a string which is the name of a function to call to initialize
1741 the Objective C data structures for this file (and perhaps for other files
1744 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1747 build_module_descriptor ()
1749 tree decl_specs
, field_decl
, field_decl_chain
;
1751 objc_module_template
1752 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1756 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1757 field_decl
= get_identifier ("version");
1759 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1760 field_decl_chain
= field_decl
;
1764 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1765 field_decl
= get_identifier ("size");
1767 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1768 chainon (field_decl_chain
, field_decl
);
1772 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1773 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1775 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1776 chainon (field_decl_chain
, field_decl
);
1778 /* struct objc_symtab *symtab; */
1780 decl_specs
= get_identifier (UTAG_SYMTAB
);
1781 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1782 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1784 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1785 chainon (field_decl_chain
, field_decl
);
1787 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1789 /* Create an instance of "objc_module". */
1791 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1792 build_tree_list (NULL_TREE
,
1793 ridpointers
[(int) RID_STATIC
]));
1795 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1796 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1798 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1799 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1800 finish_decl (UOBJC_MODULES_decl
,
1801 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1804 /* Mark the decl to avoid "defined but not used" warning. */
1805 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1807 /* Generate a constructor call for the module descriptor.
1808 This code was generated by reading the grammar rules
1809 of c-parse.in; Therefore, it may not be the most efficient
1810 way of generating the requisite code. */
1812 if (flag_next_runtime
)
1816 tree parms
, function_decl
, decelerator
, void_list_node_1
;
1818 tree init_function_name
= get_file_function_name ('I');
1820 /* Declare void __objc_execClass (void *); */
1822 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1824 = build_function_type (void_type_node
,
1825 tree_cons (NULL_TREE
, ptr_type_node
,
1827 function_decl
= build_decl (FUNCTION_DECL
,
1828 get_identifier (TAG_EXECCLASS
),
1830 DECL_EXTERNAL (function_decl
) = 1;
1831 DECL_ARTIFICIAL (function_decl
) = 1;
1832 TREE_PUBLIC (function_decl
) = 1;
1834 pushdecl (function_decl
);
1835 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1838 = build_tree_list (NULL_TREE
,
1839 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1840 decelerator
= build_function_call (function_decl
, parms
);
1842 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1844 start_function (void_list_node_1
,
1845 build_parse_node (CALL_EXPR
, init_function_name
,
1846 /* This has the format of the output
1847 of get_parm_info. */
1848 tree_cons (NULL_TREE
, NULL_TREE
,
1851 NULL_TREE
, NULL_TREE
);
1852 #if 0 /* This should be turned back on later
1853 for the systems where collect is not needed. */
1854 /* Make these functions nonglobal
1855 so each file can use the same name. */
1856 TREE_PUBLIC (current_function_decl
) = 0;
1858 TREE_USED (current_function_decl
) = 1;
1859 store_parm_decls ();
1861 assemble_external (function_decl
);
1862 c_expand_expr_stmt (decelerator
);
1864 TREE_PUBLIC (current_function_decl
) = 1;
1866 function_decl
= current_function_decl
;
1867 finish_function (0);
1869 /* Return the name of the constructor function. */
1870 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1874 /* extern const char _OBJC_STRINGS[]; */
1877 generate_forward_declaration_to_string_table ()
1879 tree sc_spec
, decl_specs
, expr_decl
;
1881 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1882 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1885 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1887 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1890 /* Return the DECL of the string IDENT in the SECTION. */
1893 get_objc_string_decl (ident
, section
)
1895 enum string_section section
;
1899 if (section
== class_names
)
1900 chain
= class_names_chain
;
1901 else if (section
== meth_var_names
)
1902 chain
= meth_var_names_chain
;
1903 else if (section
== meth_var_types
)
1904 chain
= meth_var_types_chain
;
1908 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1909 if (TREE_VALUE (chain
) == ident
)
1910 return (TREE_PURPOSE (chain
));
1916 /* Output references to all statically allocated objects. Return the DECL
1917 for the array built. */
1920 generate_static_references ()
1922 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1923 tree class_name
, class, decl
, initlist
;
1924 tree cl_chain
, in_chain
, type
;
1925 int num_inst
, num_class
;
1928 if (flag_next_runtime
)
1931 for (cl_chain
= objc_static_instances
, num_class
= 0;
1932 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1934 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1935 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1937 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1938 ident
= get_identifier (buf
);
1940 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1941 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1942 build_tree_list (NULL_TREE
,
1943 ridpointers
[(int) RID_STATIC
]));
1944 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1945 DECL_CONTEXT (decl
) = 0;
1946 DECL_ARTIFICIAL (decl
) = 1;
1948 /* Output {class_name, ...}. */
1949 class = TREE_VALUE (cl_chain
);
1950 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1951 initlist
= build_tree_list (NULL_TREE
,
1952 build_unary_op (ADDR_EXPR
, class_name
, 1));
1954 /* Output {..., instance, ...}. */
1955 for (in_chain
= TREE_PURPOSE (cl_chain
);
1956 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1958 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1959 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1962 /* Output {..., NULL}. */
1963 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1965 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1966 finish_decl (decl
, expr
, NULL_TREE
);
1967 TREE_USED (decl
) = 1;
1969 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1970 decl
= build_decl (VAR_DECL
, ident
, type
);
1971 make_decl_rtl (decl
, 0, 1);
1972 TREE_USED (decl
) = 1;
1974 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1977 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1978 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1979 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1980 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1981 build_tree_list (NULL_TREE
,
1982 ridpointers
[(int) RID_STATIC
]));
1983 static_instances_decl
1984 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1985 TREE_USED (static_instances_decl
) = 1;
1986 DECL_CONTEXT (static_instances_decl
) = 0;
1987 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1988 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1990 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1993 /* Output all strings. */
1998 tree sc_spec
, decl_specs
, expr_decl
;
1999 tree chain
, string_expr
;
2002 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2004 string
= TREE_VALUE (chain
);
2005 decl
= TREE_PURPOSE (chain
);
2007 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2008 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2009 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2010 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2011 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2012 IDENTIFIER_POINTER (string
));
2013 finish_decl (decl
, string_expr
, NULL_TREE
);
2016 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2018 string
= TREE_VALUE (chain
);
2019 decl
= TREE_PURPOSE (chain
);
2021 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2022 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2023 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2024 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2025 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2026 IDENTIFIER_POINTER (string
));
2027 finish_decl (decl
, string_expr
, NULL_TREE
);
2030 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2032 string
= TREE_VALUE (chain
);
2033 decl
= TREE_PURPOSE (chain
);
2035 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2036 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2037 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2038 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2039 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2040 IDENTIFIER_POINTER (string
));
2041 finish_decl (decl
, string_expr
, NULL_TREE
);
2046 build_selector_reference_decl ()
2052 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2054 ident
= get_identifier (buf
);
2056 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2057 DECL_EXTERNAL (decl
) = 1;
2058 TREE_PUBLIC (decl
) = 1;
2059 TREE_USED (decl
) = 1;
2060 TREE_READONLY (decl
) = 1;
2061 DECL_ARTIFICIAL (decl
) = 1;
2062 DECL_CONTEXT (decl
) = 0;
2064 make_decl_rtl (decl
, 0, 1);
2065 pushdecl_top_level (decl
);
2070 /* Just a handy wrapper for add_objc_string. */
2073 build_selector (ident
)
2076 tree expr
= add_objc_string (ident
, meth_var_names
);
2077 if (flag_typed_selectors
)
2080 return build_c_cast (selector_type
, expr
); /* cast! */
2083 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2084 The cast stops the compiler from issuing the following message:
2085 grok.m: warning: initialization of non-const * pointer from const *
2086 grok.m: warning: initialization between incompatible pointer types. */
2090 build_msg_pool_reference (offset
)
2093 tree expr
= build_int_2 (offset
, 0);
2096 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2097 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2099 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2100 ridpointers
[(int) RID_CHAR
]),
2101 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2102 TREE_TYPE (expr
) = groktypename (cast
);
2107 init_selector (offset
)
2110 tree expr
= build_msg_pool_reference (offset
);
2111 TREE_TYPE (expr
) = selector_type
;
2117 build_selector_translation_table ()
2119 tree sc_spec
, decl_specs
;
2120 tree chain
, initlist
= NULL_TREE
;
2122 tree decl
= NULL_TREE
, var_decl
, name
;
2124 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2128 expr
= build_selector (TREE_VALUE (chain
));
2130 if (flag_next_runtime
)
2132 name
= DECL_NAME (TREE_PURPOSE (chain
));
2134 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2136 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2137 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2141 /* The `decl' that is returned from start_decl is the one that we
2142 forward declared in `build_selector_reference' */
2143 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2146 /* add one for the '\0' character */
2147 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2149 if (flag_next_runtime
)
2150 finish_decl (decl
, expr
, NULL_TREE
);
2153 if (flag_typed_selectors
)
2155 tree eltlist
= NULL_TREE
;
2156 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2157 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2158 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2159 expr
= build_constructor (objc_selector_template
,
2160 nreverse (eltlist
));
2162 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2167 if (! flag_next_runtime
)
2169 /* Cause the variable and its initial value to be actually output. */
2170 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2171 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2172 /* NULL terminate the list and fix the decl for output. */
2173 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2174 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2175 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2176 nreverse (initlist
));
2177 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2178 current_function_decl
= NULL_TREE
;
2183 get_proto_encoding (proto
)
2191 if (! METHOD_ENCODING (proto
))
2193 tmp_decl
= build_tmp_function_decl ();
2194 hack_method_prototype (proto
, tmp_decl
);
2195 encoding
= encode_method_prototype (proto
, tmp_decl
);
2196 METHOD_ENCODING (proto
) = encoding
;
2199 encoding
= METHOD_ENCODING (proto
);
2201 return add_objc_string (encoding
, meth_var_types
);
2204 return build_int_2 (0, 0);
2207 /* sel_ref_chain is a list whose "value" fields will be instances of
2208 identifier_node that represent the selector. */
2211 build_typed_selector_reference (ident
, proto
)
2214 tree
*chain
= &sel_ref_chain
;
2220 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2221 goto return_at_index
;
2224 chain
= &TREE_CHAIN (*chain
);
2227 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2230 expr
= build_unary_op (ADDR_EXPR
,
2231 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2232 build_int_2 (index
, 0)),
2234 return build_c_cast (selector_type
, expr
);
2238 build_selector_reference (ident
)
2241 tree
*chain
= &sel_ref_chain
;
2247 if (TREE_VALUE (*chain
) == ident
)
2248 return (flag_next_runtime
2249 ? TREE_PURPOSE (*chain
)
2250 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2251 build_int_2 (index
, 0)));
2254 chain
= &TREE_CHAIN (*chain
);
2257 expr
= build_selector_reference_decl ();
2259 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2261 return (flag_next_runtime
2263 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2264 build_int_2 (index
, 0)));
2268 build_class_reference_decl ()
2274 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2276 ident
= get_identifier (buf
);
2278 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2279 DECL_EXTERNAL (decl
) = 1;
2280 TREE_PUBLIC (decl
) = 1;
2281 TREE_USED (decl
) = 1;
2282 TREE_READONLY (decl
) = 1;
2283 DECL_CONTEXT (decl
) = 0;
2284 DECL_ARTIFICIAL (decl
) = 1;
2286 make_decl_rtl (decl
, 0, 1);
2287 pushdecl_top_level (decl
);
2292 /* Create a class reference, but don't create a variable to reference
2296 add_class_reference (ident
)
2301 if ((chain
= cls_ref_chain
))
2306 if (ident
== TREE_VALUE (chain
))
2310 chain
= TREE_CHAIN (chain
);
2314 /* Append to the end of the list */
2315 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2318 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2321 /* Get a class reference, creating it if necessary. Also create the
2322 reference variable. */
2325 get_class_reference (ident
)
2328 if (flag_next_runtime
)
2333 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2334 if (TREE_VALUE (*chain
) == ident
)
2336 if (! TREE_PURPOSE (*chain
))
2337 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2339 return TREE_PURPOSE (*chain
);
2342 decl
= build_class_reference_decl ();
2343 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2350 add_class_reference (ident
);
2352 params
= build_tree_list (NULL_TREE
,
2353 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2354 IDENTIFIER_POINTER (ident
)));
2356 assemble_external (objc_get_class_decl
);
2357 return build_function_call (objc_get_class_decl
, params
);
2361 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2362 of identifier_node that represent the selector. It returns the
2363 offset of the selector from the beginning of the _OBJC_STRINGS
2364 pool. This offset is typically used by init_selector during code
2367 For each string section we have a chain which maps identifier nodes
2368 to decls for the strings. */
2371 add_objc_string (ident
, section
)
2373 enum string_section section
;
2377 if (section
== class_names
)
2378 chain
= &class_names_chain
;
2379 else if (section
== meth_var_names
)
2380 chain
= &meth_var_names_chain
;
2381 else if (section
== meth_var_types
)
2382 chain
= &meth_var_types_chain
;
2388 if (TREE_VALUE (*chain
) == ident
)
2389 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2391 chain
= &TREE_CHAIN (*chain
);
2394 decl
= build_objc_string_decl (section
);
2396 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2398 return build_unary_op (ADDR_EXPR
, decl
, 1);
2402 build_objc_string_decl (section
)
2403 enum string_section section
;
2407 static int class_names_idx
= 0;
2408 static int meth_var_names_idx
= 0;
2409 static int meth_var_types_idx
= 0;
2411 if (section
== class_names
)
2412 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2413 else if (section
== meth_var_names
)
2414 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2415 else if (section
== meth_var_types
)
2416 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2418 ident
= get_identifier (buf
);
2420 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2421 DECL_EXTERNAL (decl
) = 1;
2422 TREE_PUBLIC (decl
) = 1;
2423 TREE_USED (decl
) = 1;
2424 TREE_READONLY (decl
) = 1;
2425 TREE_CONSTANT (decl
) = 1;
2426 DECL_CONTEXT (decl
) = 0;
2427 DECL_ARTIFICIAL (decl
) = 1;
2429 make_decl_rtl (decl
, 0, 1);
2430 pushdecl_top_level (decl
);
2437 objc_declare_alias (alias_ident
, class_ident
)
2441 if (is_class_name (class_ident
) != class_ident
)
2442 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2443 else if (is_class_name (alias_ident
))
2444 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2446 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2450 objc_declare_class (ident_list
)
2455 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2457 tree ident
= TREE_VALUE (list
);
2460 if ((decl
= lookup_name (ident
)))
2462 error ("`%s' redeclared as different kind of symbol",
2463 IDENTIFIER_POINTER (ident
));
2464 error_with_decl (decl
, "previous declaration of `%s'");
2467 if (! is_class_name (ident
))
2469 tree record
= xref_tag (RECORD_TYPE
, ident
);
2470 TREE_STATIC_TEMPLATE (record
) = 1;
2471 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2477 is_class_name (ident
)
2482 if (lookup_interface (ident
))
2485 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2487 if (ident
== TREE_VALUE (chain
))
2491 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2493 if (ident
== TREE_VALUE (chain
))
2494 return TREE_PURPOSE (chain
);
2501 lookup_interface (ident
)
2506 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2508 if (ident
== CLASS_NAME (chain
))
2515 objc_copy_list (list
, head
)
2519 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2523 tail
= copy_node (list
);
2525 /* The following statement fixes a bug when inheriting instance
2526 variables that are declared to be bitfields. finish_struct
2527 expects to find the width of the bitfield in DECL_INITIAL. */
2528 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2529 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2531 newlist
= chainon (newlist
, tail
);
2532 list
= TREE_CHAIN (list
);
2539 /* Used by: build_private_template, get_class_ivars, and
2540 continue_class. COPY is 1 when called from @defs. In this case
2541 copy all fields. Otherwise don't copy leaf ivars since we rely on
2542 them being side-effected exactly once by finish_struct. */
2545 build_ivar_chain (interface
, copy
)
2549 tree my_name
, super_name
, ivar_chain
;
2551 my_name
= CLASS_NAME (interface
);
2552 super_name
= CLASS_SUPER_NAME (interface
);
2554 /* Possibly copy leaf ivars. */
2556 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2558 ivar_chain
= CLASS_IVARS (interface
);
2563 tree super_interface
= lookup_interface (super_name
);
2565 if (!super_interface
)
2567 /* fatal did not work with 2 args...should fix */
2568 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2569 IDENTIFIER_POINTER (super_name
),
2570 IDENTIFIER_POINTER (my_name
));
2571 exit (FATAL_EXIT_CODE
);
2574 if (super_interface
== interface
)
2576 fatal ("Circular inheritance in interface declaration for `%s'",
2577 IDENTIFIER_POINTER (super_name
));
2580 interface
= super_interface
;
2581 my_name
= CLASS_NAME (interface
);
2582 super_name
= CLASS_SUPER_NAME (interface
);
2584 op1
= CLASS_IVARS (interface
);
2587 tree head
, tail
= objc_copy_list (op1
, &head
);
2589 /* Prepend super class ivars...make a copy of the list, we
2590 do not want to alter the original. */
2591 TREE_CHAIN (tail
) = ivar_chain
;
2598 /* struct <classname> {
2599 struct objc_class *isa;
2604 build_private_template (class)
2609 if (CLASS_STATIC_TEMPLATE (class))
2611 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2612 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2616 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2618 ivar_context
= build_ivar_chain (class, 0);
2620 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2622 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2624 /* mark this record as class template - for class type checking */
2625 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2629 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2631 build1 (INDIRECT_REF
, NULL_TREE
,
2634 return ivar_context
;
2637 /* Begin code generation for protocols... */
2639 /* struct objc_protocol {
2640 char *protocol_name;
2641 struct objc_protocol **protocol_list;
2642 struct objc_method_desc *instance_methods;
2643 struct objc_method_desc *class_methods;
2647 build_protocol_template ()
2649 tree decl_specs
, field_decl
, field_decl_chain
;
2652 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2654 /* struct objc_class *isa; */
2656 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2657 get_identifier (UTAG_CLASS
)));
2658 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2660 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2661 field_decl_chain
= field_decl
;
2663 /* char *protocol_name; */
2665 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2667 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2669 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2670 chainon (field_decl_chain
, field_decl
);
2672 /* struct objc_protocol **protocol_list; */
2674 decl_specs
= build_tree_list (NULL_TREE
, template);
2676 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2677 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2679 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2680 chainon (field_decl_chain
, field_decl
);
2682 /* struct objc_method_list *instance_methods; */
2685 = build_tree_list (NULL_TREE
,
2686 xref_tag (RECORD_TYPE
,
2687 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2689 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2691 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2692 chainon (field_decl_chain
, field_decl
);
2694 /* struct objc_method_list *class_methods; */
2697 = build_tree_list (NULL_TREE
,
2698 xref_tag (RECORD_TYPE
,
2699 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2701 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2703 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2704 chainon (field_decl_chain
, field_decl
);
2706 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2710 build_descriptor_table_initializer (type
, entries
)
2714 tree initlist
= NULL_TREE
;
2718 tree eltlist
= NULL_TREE
;
2721 = tree_cons (NULL_TREE
,
2722 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2724 = tree_cons (NULL_TREE
,
2725 add_objc_string (METHOD_ENCODING (entries
),
2730 = tree_cons (NULL_TREE
,
2731 build_constructor (type
, nreverse (eltlist
)), initlist
);
2733 entries
= TREE_CHAIN (entries
);
2737 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2740 /* struct objc_method_prototype_list {
2742 struct objc_method_prototype {
2749 build_method_prototype_list_template (list_type
, size
)
2753 tree objc_ivar_list_record
;
2754 tree decl_specs
, field_decl
, field_decl_chain
;
2756 /* Generate an unnamed struct definition. */
2758 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2760 /* int method_count; */
2762 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2763 field_decl
= get_identifier ("method_count");
2766 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2767 field_decl_chain
= field_decl
;
2769 /* struct objc_method method_list[]; */
2771 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2772 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2773 build_int_2 (size
, 0));
2776 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2777 chainon (field_decl_chain
, field_decl
);
2779 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2781 return objc_ivar_list_record
;
2785 build_method_prototype_template ()
2788 tree decl_specs
, field_decl
, field_decl_chain
;
2791 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2793 #ifdef OBJC_INT_SELECTORS
2794 /* unsigned int _cmd; */
2796 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2797 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2798 field_decl
= get_identifier ("_cmd");
2799 #else /* OBJC_INT_SELECTORS */
2800 /* struct objc_selector *_cmd; */
2801 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2802 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2803 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2804 #endif /* OBJC_INT_SELECTORS */
2807 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2808 field_decl_chain
= field_decl
;
2810 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2812 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2814 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2815 chainon (field_decl_chain
, field_decl
);
2817 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2819 return proto_record
;
2822 /* True if last call to forwarding_offset yielded a register offset. */
2823 static int offset_is_register
;
2826 forwarding_offset (parm
)
2829 int offset_in_bytes
;
2831 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2833 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2835 /* ??? Here we assume that the parm address is indexed
2836 off the frame pointer or arg pointer.
2837 If that is not true, we produce meaningless results,
2838 but do not crash. */
2839 if (GET_CODE (addr
) == PLUS
2840 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2841 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2843 offset_in_bytes
= 0;
2845 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2846 offset_is_register
= 0;
2848 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2850 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2851 offset_in_bytes
= apply_args_register_offset (regno
);
2852 offset_is_register
= 1;
2857 /* This is the case where the parm is passed as an int or double
2858 and it is converted to a char, short or float and stored back
2859 in the parmlist. In this case, describe the parm
2860 with the variable's declared type, and adjust the address
2861 if the least significant bytes (which we are using) are not
2863 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2864 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2865 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2867 return offset_in_bytes
;
2871 encode_method_prototype (method_decl
, func_decl
)
2878 HOST_WIDE_INT max_parm_end
= 0;
2882 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2883 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2886 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2887 obstack_object_size (&util_obstack
),
2888 OBJC_ENCODE_INLINE_DEFS
);
2891 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2892 parms
= TREE_CHAIN (parms
))
2894 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2895 + int_size_in_bytes (TREE_TYPE (parms
)));
2897 if (!offset_is_register
&& max_parm_end
< parm_end
)
2898 max_parm_end
= parm_end
;
2901 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2903 sprintf (buf
, "%d", stack_size
);
2904 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2906 user_args
= METHOD_SEL_ARGS (method_decl
);
2908 /* Argument types. */
2909 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2910 parms
= TREE_CHAIN (parms
), i
++)
2912 /* Process argument qualifiers for user supplied arguments. */
2915 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2916 user_args
= TREE_CHAIN (user_args
);
2920 encode_type (TREE_TYPE (parms
),
2921 obstack_object_size (&util_obstack
),
2922 OBJC_ENCODE_INLINE_DEFS
);
2924 /* Compute offset. */
2925 sprintf (buf
, "%d", forwarding_offset (parms
));
2927 /* Indicate register. */
2928 if (offset_is_register
)
2929 obstack_1grow (&util_obstack
, '+');
2931 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2934 obstack_1grow (&util_obstack
, '\0');
2935 result
= get_identifier (obstack_finish (&util_obstack
));
2936 obstack_free (&util_obstack
, util_firstobj
);
2941 generate_descriptor_table (type
, name
, size
, list
, proto
)
2948 tree sc_spec
, decl_specs
, decl
, initlist
;
2950 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2951 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2953 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2954 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2956 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2957 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2959 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2966 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2969 static tree objc_method_prototype_template
;
2970 tree initlist
, chain
, method_list_template
;
2971 tree cast
, variable_length_type
;
2974 if (!objc_method_prototype_template
)
2976 objc_method_prototype_template
= build_method_prototype_template ();
2977 ggc_add_tree_root (&objc_method_prototype_template
, 1);
2980 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2981 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2983 variable_length_type
= groktypename (cast
);
2985 chain
= PROTOCOL_CLS_METHODS (protocol
);
2988 size
= list_length (chain
);
2990 method_list_template
2991 = build_method_prototype_list_template (objc_method_prototype_template
,
2995 = build_descriptor_table_initializer (objc_method_prototype_template
,
2998 UOBJC_CLASS_METHODS_decl
2999 = generate_descriptor_table (method_list_template
,
3000 "_OBJC_PROTOCOL_CLASS_METHODS",
3001 size
, initlist
, protocol
);
3002 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3005 UOBJC_CLASS_METHODS_decl
= 0;
3007 chain
= PROTOCOL_NST_METHODS (protocol
);
3010 size
= list_length (chain
);
3012 method_list_template
3013 = build_method_prototype_list_template (objc_method_prototype_template
,
3016 = build_descriptor_table_initializer (objc_method_prototype_template
,
3019 UOBJC_INSTANCE_METHODS_decl
3020 = generate_descriptor_table (method_list_template
,
3021 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3022 size
, initlist
, protocol
);
3023 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3026 UOBJC_INSTANCE_METHODS_decl
= 0;
3030 build_tmp_function_decl ()
3032 tree decl_specs
, expr_decl
, parms
;
3036 /* struct objc_object *objc_xxx (id, SEL, ...); */
3038 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3039 push_parm_decl (build_tree_list
3040 (build_tree_list (decl_specs
,
3041 build1 (INDIRECT_REF
, NULL_TREE
,
3043 build_tree_list (NULL_TREE
, NULL_TREE
)));
3045 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3046 get_identifier (TAG_SELECTOR
)));
3047 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3049 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3050 build_tree_list (NULL_TREE
, NULL_TREE
)));
3051 parms
= get_parm_info (0);
3054 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3055 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3056 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3057 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3059 return define_decl (expr_decl
, decl_specs
);
3063 hack_method_prototype (nst_methods
, tmp_decl
)
3070 /* Hack to avoid problem with static typing of self arg. */
3071 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3072 start_method_def (nst_methods
);
3073 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3075 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
3076 parms
= get_parm_info (0); /* we have a `, ...' */
3078 parms
= get_parm_info (1); /* place a `void_at_end' */
3080 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3082 /* Usually called from store_parm_decls -> init_function_start. */
3084 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3085 current_function_decl
= tmp_decl
;
3088 /* Code taken from start_function. */
3089 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3090 /* Promote the value to int before returning it. */
3091 if (TREE_CODE (restype
) == INTEGER_TYPE
3092 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3093 restype
= integer_type_node
;
3094 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3097 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3098 DECL_CONTEXT (parm
) = tmp_decl
;
3100 init_function_start (tmp_decl
, "objc-act", 0);
3102 /* Typically called from expand_function_start for function definitions. */
3103 assign_parms (tmp_decl
);
3105 /* install return type */
3106 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3111 generate_protocol_references (plist
)
3116 /* Forward declare protocols referenced. */
3117 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3119 tree proto
= TREE_VALUE (lproto
);
3121 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3122 && PROTOCOL_NAME (proto
))
3124 if (! PROTOCOL_FORWARD_DECL (proto
))
3125 build_protocol_reference (proto
);
3127 if (PROTOCOL_LIST (proto
))
3128 generate_protocol_references (PROTOCOL_LIST (proto
));
3134 generate_protocols ()
3136 tree p
, tmp_decl
, encoding
;
3137 tree sc_spec
, decl_specs
, decl
;
3138 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3141 tmp_decl
= build_tmp_function_decl ();
3143 if (! objc_protocol_template
)
3144 objc_protocol_template
= build_protocol_template ();
3146 /* If a protocol was directly referenced, pull in indirect references. */
3147 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3148 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3149 generate_protocol_references (PROTOCOL_LIST (p
));
3151 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3153 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3154 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3156 /* If protocol wasn't referenced, don't generate any code. */
3157 if (! PROTOCOL_FORWARD_DECL (p
))
3160 /* Make sure we link in the Protocol class. */
3161 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3165 if (! METHOD_ENCODING (nst_methods
))
3167 hack_method_prototype (nst_methods
, tmp_decl
);
3168 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3169 METHOD_ENCODING (nst_methods
) = encoding
;
3171 nst_methods
= TREE_CHAIN (nst_methods
);
3176 if (! METHOD_ENCODING (cls_methods
))
3178 hack_method_prototype (cls_methods
, tmp_decl
);
3179 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3180 METHOD_ENCODING (cls_methods
) = encoding
;
3183 cls_methods
= TREE_CHAIN (cls_methods
);
3185 generate_method_descriptors (p
);
3187 if (PROTOCOL_LIST (p
))
3188 refs_decl
= generate_protocol_list (p
);
3192 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3194 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3196 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3198 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3199 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3201 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3207 (build_tree_list (build_tree_list (NULL_TREE
,
3208 objc_protocol_template
),
3209 build1 (INDIRECT_REF
, NULL_TREE
,
3210 build1 (INDIRECT_REF
, NULL_TREE
,
3213 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3214 TREE_TYPE (refs_expr
) = cast_type2
;
3217 refs_expr
= build_int_2 (0, 0);
3219 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3220 by generate_method_descriptors, which is called above. */
3221 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3222 protocol_name_expr
, refs_expr
,
3223 UOBJC_INSTANCE_METHODS_decl
,
3224 UOBJC_CLASS_METHODS_decl
);
3225 finish_decl (decl
, initlist
, NULL_TREE
);
3227 /* Mark the decl as used to avoid "defined but not used" warning. */
3228 TREE_USED (decl
) = 1;
3233 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3234 instance_methods
, class_methods
)
3238 tree instance_methods
;
3241 tree initlist
= NULL_TREE
, expr
;
3244 cast_type
= groktypename
3246 (build_tree_list (NULL_TREE
,
3247 xref_tag (RECORD_TYPE
,
3248 get_identifier (UTAG_CLASS
))),
3249 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3251 /* Filling the "isa" in with one allows the runtime system to
3252 detect that the version change...should remove before final release. */
3254 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3255 TREE_TYPE (expr
) = cast_type
;
3256 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3257 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3258 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3260 if (!instance_methods
)
3261 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3264 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3265 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3269 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3272 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3273 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3276 return build_constructor (type
, nreverse (initlist
));
3279 /* struct objc_category {
3280 char *category_name;
3282 struct objc_method_list *instance_methods;
3283 struct objc_method_list *class_methods;
3284 struct objc_protocol_list *protocols;
3288 build_category_template ()
3290 tree decl_specs
, field_decl
, field_decl_chain
;
3292 objc_category_template
= start_struct (RECORD_TYPE
,
3293 get_identifier (UTAG_CATEGORY
));
3294 /* char *category_name; */
3296 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3298 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3300 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3301 field_decl_chain
= field_decl
;
3303 /* char *class_name; */
3305 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3306 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3308 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3309 chainon (field_decl_chain
, field_decl
);
3311 /* struct objc_method_list *instance_methods; */
3313 decl_specs
= build_tree_list (NULL_TREE
,
3314 xref_tag (RECORD_TYPE
,
3315 get_identifier (UTAG_METHOD_LIST
)));
3317 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3319 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3320 chainon (field_decl_chain
, field_decl
);
3322 /* struct objc_method_list *class_methods; */
3324 decl_specs
= build_tree_list (NULL_TREE
,
3325 xref_tag (RECORD_TYPE
,
3326 get_identifier (UTAG_METHOD_LIST
)));
3328 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3330 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3331 chainon (field_decl_chain
, field_decl
);
3333 /* struct objc_protocol **protocol_list; */
3335 decl_specs
= build_tree_list (NULL_TREE
,
3336 xref_tag (RECORD_TYPE
,
3337 get_identifier (UTAG_PROTOCOL
)));
3339 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3340 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3342 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3343 chainon (field_decl_chain
, field_decl
);
3345 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3348 /* struct objc_selector {
3354 build_selector_template ()
3357 tree decl_specs
, field_decl
, field_decl_chain
;
3359 objc_selector_template
3360 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3364 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3365 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3367 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3368 field_decl_chain
= field_decl
;
3370 /* char *sel_type; */
3372 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3373 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3375 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3376 chainon (field_decl_chain
, field_decl
);
3378 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3381 /* struct objc_class {
3382 struct objc_class *isa;
3383 struct objc_class *super_class;
3388 struct objc_ivar_list *ivars;
3389 struct objc_method_list *methods;
3390 if (flag_next_runtime)
3391 struct objc_cache *cache;
3393 struct sarray *dtable;
3394 struct objc_class *subclass_list;
3395 struct objc_class *sibling_class;
3397 struct objc_protocol_list *protocols;
3398 void *gc_object_type;
3402 build_class_template ()
3404 tree decl_specs
, field_decl
, field_decl_chain
;
3407 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3409 /* struct objc_class *isa; */
3411 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3412 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3414 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3415 field_decl_chain
= field_decl
;
3417 /* struct objc_class *super_class; */
3419 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3421 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3423 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3424 chainon (field_decl_chain
, field_decl
);
3428 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3429 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3431 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3432 chainon (field_decl_chain
, field_decl
);
3436 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3437 field_decl
= get_identifier ("version");
3439 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3440 chainon (field_decl_chain
, field_decl
);
3444 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3445 field_decl
= get_identifier ("info");
3447 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3448 chainon (field_decl_chain
, field_decl
);
3450 /* long instance_size; */
3452 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3453 field_decl
= get_identifier ("instance_size");
3455 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3456 chainon (field_decl_chain
, field_decl
);
3458 /* struct objc_ivar_list *ivars; */
3460 decl_specs
= build_tree_list (NULL_TREE
,
3461 xref_tag (RECORD_TYPE
,
3462 get_identifier (UTAG_IVAR_LIST
)));
3463 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3465 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3466 chainon (field_decl_chain
, field_decl
);
3468 /* struct objc_method_list *methods; */
3470 decl_specs
= build_tree_list (NULL_TREE
,
3471 xref_tag (RECORD_TYPE
,
3472 get_identifier (UTAG_METHOD_LIST
)));
3473 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3475 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3476 chainon (field_decl_chain
, field_decl
);
3478 if (flag_next_runtime
)
3480 /* struct objc_cache *cache; */
3482 decl_specs
= build_tree_list (NULL_TREE
,
3483 xref_tag (RECORD_TYPE
,
3484 get_identifier ("objc_cache")));
3485 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3486 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3487 decl_specs
, NULL_TREE
);
3488 chainon (field_decl_chain
, field_decl
);
3492 /* struct sarray *dtable; */
3494 decl_specs
= build_tree_list (NULL_TREE
,
3495 xref_tag (RECORD_TYPE
,
3496 get_identifier ("sarray")));
3497 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3498 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3499 decl_specs
, NULL_TREE
);
3500 chainon (field_decl_chain
, field_decl
);
3502 /* struct objc_class *subclass_list; */
3504 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3506 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3507 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3508 decl_specs
, NULL_TREE
);
3509 chainon (field_decl_chain
, field_decl
);
3511 /* struct objc_class *sibling_class; */
3513 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3515 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3516 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3517 decl_specs
, NULL_TREE
);
3518 chainon (field_decl_chain
, field_decl
);
3521 /* struct objc_protocol **protocol_list; */
3523 decl_specs
= build_tree_list (NULL_TREE
,
3524 xref_tag (RECORD_TYPE
,
3525 get_identifier (UTAG_PROTOCOL
)));
3527 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3529 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3530 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3531 decl_specs
, NULL_TREE
);
3532 chainon (field_decl_chain
, field_decl
);
3536 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3537 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3539 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3540 chainon (field_decl_chain
, field_decl
);
3542 /* void *gc_object_type; */
3544 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3545 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3547 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3548 chainon (field_decl_chain
, field_decl
);
3550 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3553 /* Generate appropriate forward declarations for an implementation. */
3556 synth_forward_declarations ()
3558 tree sc_spec
, decl_specs
, an_id
;
3560 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3562 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3564 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3565 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3566 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3567 TREE_USED (UOBJC_CLASS_decl
) = 1;
3568 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3570 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3572 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3573 implementation_context
);
3575 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3576 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3577 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3579 /* Pre-build the following entities - for speed/convenience. */
3581 an_id
= get_identifier ("super_class");
3582 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3583 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3587 error_with_ivar (message
, decl
, rawdecl
)
3588 const char *message
;
3594 report_error_function (DECL_SOURCE_FILE (decl
));
3596 fprintf (stderr
, "%s:%d: ",
3597 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3598 memset (errbuf
, 0, BUFSIZE
);
3599 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3602 #define USERTYPE(t) \
3603 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3604 || TREE_CODE (t) == ENUMERAL_TYPE)
3607 check_ivars (inter
, imp
)
3611 tree intdecls
= CLASS_IVARS (inter
);
3612 tree impdecls
= CLASS_IVARS (imp
);
3613 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3614 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3620 if (intdecls
== 0 && impdecls
== 0)
3622 if (intdecls
== 0 || impdecls
== 0)
3624 error ("inconsistent instance variable specification");
3628 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3630 if (!comptypes (t1
, t2
))
3632 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3634 error_with_ivar ("conflicting instance variable type",
3635 impdecls
, rawimpdecls
);
3636 error_with_ivar ("previous declaration of",
3637 intdecls
, rawintdecls
);
3639 else /* both the type and the name don't match */
3641 error ("inconsistent instance variable specification");
3646 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3648 error_with_ivar ("conflicting instance variable name",
3649 impdecls
, rawimpdecls
);
3650 error_with_ivar ("previous declaration of",
3651 intdecls
, rawintdecls
);
3654 intdecls
= TREE_CHAIN (intdecls
);
3655 impdecls
= TREE_CHAIN (impdecls
);
3656 rawintdecls
= TREE_CHAIN (rawintdecls
);
3657 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3661 /* Set super_type to the data type node for struct objc_super *,
3662 first defining struct objc_super itself.
3663 This needs to be done just once per compilation. */
3666 build_super_template ()
3668 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3670 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3672 /* struct objc_object *self; */
3674 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3675 field_decl
= get_identifier ("self");
3676 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3677 field_decl
= grokfield (input_filename
, lineno
,
3678 field_decl
, decl_specs
, NULL_TREE
);
3679 field_decl_chain
= field_decl
;
3681 /* struct objc_class *class; */
3683 decl_specs
= get_identifier (UTAG_CLASS
);
3684 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3685 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3687 field_decl
= grokfield (input_filename
, lineno
,
3688 field_decl
, decl_specs
, NULL_TREE
);
3689 chainon (field_decl_chain
, field_decl
);
3691 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3693 /* `struct objc_super *' */
3694 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3696 build1 (INDIRECT_REF
,
3697 NULL_TREE
, NULL_TREE
)));
3701 /* struct objc_ivar {
3708 build_ivar_template ()
3710 tree objc_ivar_id
, objc_ivar_record
;
3711 tree decl_specs
, field_decl
, field_decl_chain
;
3713 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3714 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3716 /* char *ivar_name; */
3718 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3719 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3721 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3722 decl_specs
, NULL_TREE
);
3723 field_decl_chain
= field_decl
;
3725 /* char *ivar_type; */
3727 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3728 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3730 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3731 decl_specs
, NULL_TREE
);
3732 chainon (field_decl_chain
, field_decl
);
3734 /* int ivar_offset; */
3736 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3737 field_decl
= get_identifier ("ivar_offset");
3739 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3740 decl_specs
, NULL_TREE
);
3741 chainon (field_decl_chain
, field_decl
);
3743 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3745 return objc_ivar_record
;
3750 struct objc_ivar ivar_list[ivar_count];
3754 build_ivar_list_template (list_type
, size
)
3758 tree objc_ivar_list_record
;
3759 tree decl_specs
, field_decl
, field_decl_chain
;
3761 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3763 /* int ivar_count; */
3765 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3766 field_decl
= get_identifier ("ivar_count");
3768 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3769 decl_specs
, NULL_TREE
);
3770 field_decl_chain
= field_decl
;
3772 /* struct objc_ivar ivar_list[]; */
3774 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3775 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3776 build_int_2 (size
, 0));
3778 field_decl
= grokfield (input_filename
, lineno
,
3779 field_decl
, decl_specs
, NULL_TREE
);
3780 chainon (field_decl_chain
, field_decl
);
3782 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3784 return objc_ivar_list_record
;
3790 struct objc_method method_list[method_count];
3794 build_method_list_template (list_type
, size
)
3798 tree objc_ivar_list_record
;
3799 tree decl_specs
, field_decl
, field_decl_chain
;
3801 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3803 /* int method_next; */
3808 xref_tag (RECORD_TYPE
,
3809 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3811 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3812 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3813 decl_specs
, NULL_TREE
);
3814 field_decl_chain
= field_decl
;
3816 /* int method_count; */
3818 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3819 field_decl
= get_identifier ("method_count");
3821 field_decl
= grokfield (input_filename
, lineno
,
3822 field_decl
, decl_specs
, NULL_TREE
);
3823 chainon (field_decl_chain
, field_decl
);
3825 /* struct objc_method method_list[]; */
3827 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3828 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3829 build_int_2 (size
, 0));
3831 field_decl
= grokfield (input_filename
, lineno
,
3832 field_decl
, decl_specs
, NULL_TREE
);
3833 chainon (field_decl_chain
, field_decl
);
3835 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3837 return objc_ivar_list_record
;
3841 build_ivar_list_initializer (type
, field_decl
)
3845 tree initlist
= NULL_TREE
;
3849 tree ivar
= NULL_TREE
;
3852 if (DECL_NAME (field_decl
))
3853 ivar
= tree_cons (NULL_TREE
,
3854 add_objc_string (DECL_NAME (field_decl
),
3858 /* Unnamed bit-field ivar (yuck). */
3859 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3862 encode_field_decl (field_decl
,
3863 obstack_object_size (&util_obstack
),
3864 OBJC_ENCODE_DONT_INLINE_DEFS
);
3866 /* Null terminate string. */
3867 obstack_1grow (&util_obstack
, 0);
3871 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3874 obstack_free (&util_obstack
, util_firstobj
);
3877 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3878 initlist
= tree_cons (NULL_TREE
,
3879 build_constructor (type
, nreverse (ivar
)),
3882 field_decl
= TREE_CHAIN (field_decl
);
3886 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3890 generate_ivars_list (type
, name
, size
, list
)
3896 tree sc_spec
, decl_specs
, decl
, initlist
;
3898 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3899 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3901 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3902 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3904 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3905 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3908 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3915 generate_ivar_lists ()
3917 tree initlist
, ivar_list_template
, chain
;
3918 tree cast
, variable_length_type
;
3921 generating_instance_variables
= 1;
3923 if (!objc_ivar_template
)
3924 objc_ivar_template
= build_ivar_template ();
3928 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3929 get_identifier (UTAG_IVAR_LIST
))),
3931 variable_length_type
= groktypename (cast
);
3933 /* Only generate class variables for the root of the inheritance
3934 hierarchy since these will be the same for every class. */
3936 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3937 && (chain
= TYPE_FIELDS (objc_class_template
)))
3939 size
= list_length (chain
);
3941 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3942 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3944 UOBJC_CLASS_VARIABLES_decl
3945 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3947 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3950 UOBJC_CLASS_VARIABLES_decl
= 0;
3952 chain
= CLASS_IVARS (implementation_template
);
3955 size
= list_length (chain
);
3956 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3957 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3959 UOBJC_INSTANCE_VARIABLES_decl
3960 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3962 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3965 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3967 generating_instance_variables
= 0;
3971 build_dispatch_table_initializer (type
, entries
)
3975 tree initlist
= NULL_TREE
;
3979 tree elemlist
= NULL_TREE
;
3981 elemlist
= tree_cons (NULL_TREE
,
3982 build_selector (METHOD_SEL_NAME (entries
)),
3985 elemlist
= tree_cons (NULL_TREE
,
3986 add_objc_string (METHOD_ENCODING (entries
),
3990 elemlist
= tree_cons (NULL_TREE
,
3991 build_unary_op (ADDR_EXPR
,
3992 METHOD_DEFINITION (entries
), 1),
3995 initlist
= tree_cons (NULL_TREE
,
3996 build_constructor (type
, nreverse (elemlist
)),
3999 entries
= TREE_CHAIN (entries
);
4003 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4006 /* To accomplish method prototyping without generating all kinds of
4007 inane warnings, the definition of the dispatch table entries were
4010 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4012 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4015 build_method_template ()
4018 tree decl_specs
, field_decl
, field_decl_chain
;
4020 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4022 #ifdef OBJC_INT_SELECTORS
4023 /* unsigned int _cmd; */
4024 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
4026 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
4027 field_decl
= get_identifier ("_cmd");
4028 #else /* not OBJC_INT_SELECTORS */
4029 /* struct objc_selector *_cmd; */
4030 decl_specs
= tree_cons (NULL_TREE
,
4031 xref_tag (RECORD_TYPE
,
4032 get_identifier (TAG_SELECTOR
)),
4034 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4035 #endif /* not OBJC_INT_SELECTORS */
4037 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4038 decl_specs
, NULL_TREE
);
4039 field_decl_chain
= field_decl
;
4041 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4042 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4043 get_identifier ("method_types"));
4044 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4045 decl_specs
, NULL_TREE
);
4046 chainon (field_decl_chain
, field_decl
);
4050 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4051 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4052 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4053 decl_specs
, NULL_TREE
);
4054 chainon (field_decl_chain
, field_decl
);
4056 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4063 generate_dispatch_table (type
, name
, size
, list
)
4069 tree sc_spec
, decl_specs
, decl
, initlist
;
4071 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4072 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4074 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4075 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4077 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4078 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4079 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4082 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4089 generate_dispatch_tables ()
4091 tree initlist
, chain
, method_list_template
;
4092 tree cast
, variable_length_type
;
4095 if (!objc_method_template
)
4096 objc_method_template
= build_method_template ();
4100 (build_tree_list (NULL_TREE
,
4101 xref_tag (RECORD_TYPE
,
4102 get_identifier (UTAG_METHOD_LIST
))),
4105 variable_length_type
= groktypename (cast
);
4107 chain
= CLASS_CLS_METHODS (implementation_context
);
4110 size
= list_length (chain
);
4112 method_list_template
4113 = build_method_list_template (objc_method_template
, size
);
4115 = build_dispatch_table_initializer (objc_method_template
, chain
);
4117 UOBJC_CLASS_METHODS_decl
4118 = generate_dispatch_table (method_list_template
,
4119 ((TREE_CODE (implementation_context
)
4120 == CLASS_IMPLEMENTATION_TYPE
)
4121 ? "_OBJC_CLASS_METHODS"
4122 : "_OBJC_CATEGORY_CLASS_METHODS"),
4124 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4127 UOBJC_CLASS_METHODS_decl
= 0;
4129 chain
= CLASS_NST_METHODS (implementation_context
);
4132 size
= list_length (chain
);
4134 method_list_template
4135 = build_method_list_template (objc_method_template
, size
);
4137 = build_dispatch_table_initializer (objc_method_template
, chain
);
4139 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4140 UOBJC_INSTANCE_METHODS_decl
4141 = generate_dispatch_table (method_list_template
,
4142 "_OBJC_INSTANCE_METHODS",
4145 /* We have a category. */
4146 UOBJC_INSTANCE_METHODS_decl
4147 = generate_dispatch_table (method_list_template
,
4148 "_OBJC_CATEGORY_INSTANCE_METHODS",
4150 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4153 UOBJC_INSTANCE_METHODS_decl
= 0;
4157 generate_protocol_list (i_or_p
)
4160 tree initlist
, decl_specs
, sc_spec
;
4161 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4165 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4166 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4167 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4168 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4169 plist
= PROTOCOL_LIST (i_or_p
);
4173 cast_type
= groktypename
4175 (build_tree_list (NULL_TREE
,
4176 xref_tag (RECORD_TYPE
,
4177 get_identifier (UTAG_PROTOCOL
))),
4178 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4181 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4182 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4183 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4186 /* Build initializer. */
4187 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4189 e
= build_int_2 (size
, 0);
4190 TREE_TYPE (e
) = cast_type
;
4191 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4193 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4195 tree pval
= TREE_VALUE (lproto
);
4197 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4198 && PROTOCOL_FORWARD_DECL (pval
))
4200 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4201 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4205 /* static struct objc_protocol *refs[n]; */
4207 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4208 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4209 get_identifier (UTAG_PROTOCOL
)),
4212 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4213 expr_decl
= build_nt (ARRAY_REF
,
4214 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4216 build_int_2 (size
+ 2, 0));
4217 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4218 expr_decl
= build_nt (ARRAY_REF
,
4219 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4221 build_int_2 (size
+ 2, 0));
4222 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4224 = build_nt (ARRAY_REF
,
4225 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4227 build_int_2 (size
+ 2, 0));
4231 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4233 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4235 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4236 nreverse (initlist
)),
4243 build_category_initializer (type
, cat_name
, class_name
,
4244 instance_methods
, class_methods
, protocol_list
)
4248 tree instance_methods
;
4252 tree initlist
= NULL_TREE
, expr
;
4254 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4255 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4257 if (!instance_methods
)
4258 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4261 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4262 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4265 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4268 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4269 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4272 /* protocol_list = */
4274 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4277 tree cast_type2
= groktypename
4279 (build_tree_list (NULL_TREE
,
4280 xref_tag (RECORD_TYPE
,
4281 get_identifier (UTAG_PROTOCOL
))),
4282 build1 (INDIRECT_REF
, NULL_TREE
,
4283 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4285 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4286 TREE_TYPE (expr
) = cast_type2
;
4287 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4290 return build_constructor (type
, nreverse (initlist
));
4293 /* struct objc_class {
4294 struct objc_class *isa;
4295 struct objc_class *super_class;
4300 struct objc_ivar_list *ivars;
4301 struct objc_method_list *methods;
4302 if (flag_next_runtime)
4303 struct objc_cache *cache;
4305 struct sarray *dtable;
4306 struct objc_class *subclass_list;
4307 struct objc_class *sibling_class;
4309 struct objc_protocol_list *protocols;
4310 void *gc_object_type;
4314 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4315 dispatch_table
, ivar_list
, protocol_list
)
4322 tree dispatch_table
;
4326 tree initlist
= NULL_TREE
, expr
;
4329 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4332 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4335 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4338 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4341 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4343 /* instance_size = */
4344 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4346 /* objc_ivar_list = */
4348 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4351 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4352 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4355 /* objc_method_list = */
4356 if (!dispatch_table
)
4357 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4360 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4361 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4364 if (flag_next_runtime
)
4365 /* method_cache = */
4366 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4370 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4372 /* subclass_list = */
4373 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4375 /* sibling_class = */
4376 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4379 /* protocol_list = */
4380 if (! protocol_list
)
4381 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4387 (build_tree_list (NULL_TREE
,
4388 xref_tag (RECORD_TYPE
,
4389 get_identifier (UTAG_PROTOCOL
))),
4390 build1 (INDIRECT_REF
, NULL_TREE
,
4391 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4393 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4394 TREE_TYPE (expr
) = cast_type2
;
4395 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4398 /* gc_object_type = NULL */
4399 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4401 return build_constructor (type
, nreverse (initlist
));
4404 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4407 generate_category (cat
)
4410 tree sc_spec
, decl_specs
, decl
;
4411 tree initlist
, cat_name_expr
, class_name_expr
;
4412 tree protocol_decl
, category
;
4414 add_class_reference (CLASS_NAME (cat
));
4415 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4417 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4419 category
= CLASS_CATEGORY_LIST (implementation_template
);
4421 /* find the category interface from the class it is associated with */
4424 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4426 category
= CLASS_CATEGORY_LIST (category
);
4429 if (category
&& CLASS_PROTOCOL_LIST (category
))
4431 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4432 protocol_decl
= generate_protocol_list (category
);
4437 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4438 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4440 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4441 implementation_context
),
4442 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4444 initlist
= build_category_initializer (TREE_TYPE (decl
),
4445 cat_name_expr
, class_name_expr
,
4446 UOBJC_INSTANCE_METHODS_decl
,
4447 UOBJC_CLASS_METHODS_decl
,
4450 TREE_USED (decl
) = 1;
4451 finish_decl (decl
, initlist
, NULL_TREE
);
4454 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4455 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4458 generate_shared_structures ()
4460 tree sc_spec
, decl_specs
, decl
;
4461 tree name_expr
, super_expr
, root_expr
;
4462 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4463 tree cast_type
, initlist
, protocol_decl
;
4465 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4468 add_class_reference (my_super_id
);
4470 /* Compute "my_root_id" - this is required for code generation.
4471 the "isa" for all meta class structures points to the root of
4472 the inheritance hierarchy (e.g. "__Object")... */
4473 my_root_id
= my_super_id
;
4476 tree my_root_int
= lookup_interface (my_root_id
);
4478 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4479 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4486 /* No super class. */
4487 my_root_id
= CLASS_NAME (implementation_template
);
4490 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4491 objc_class_template
),
4492 build1 (INDIRECT_REF
,
4493 NULL_TREE
, NULL_TREE
)));
4495 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4498 /* Install class `isa' and `super' pointers at runtime. */
4501 super_expr
= add_objc_string (my_super_id
, class_names
);
4502 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4505 super_expr
= build_int_2 (0, 0);
4507 root_expr
= add_objc_string (my_root_id
, class_names
);
4508 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4510 if (CLASS_PROTOCOL_LIST (implementation_template
))
4512 generate_protocol_references
4513 (CLASS_PROTOCOL_LIST (implementation_template
));
4514 protocol_decl
= generate_protocol_list (implementation_template
);
4519 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4521 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4522 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4524 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4525 NULL_TREE
, NULL_TREE
);
4528 = build_shared_structure_initializer
4530 root_expr
, super_expr
, name_expr
,
4531 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4533 UOBJC_CLASS_METHODS_decl
,
4534 UOBJC_CLASS_VARIABLES_decl
,
4537 finish_decl (decl
, initlist
, NULL_TREE
);
4539 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4541 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4542 NULL_TREE
, NULL_TREE
);
4545 = build_shared_structure_initializer
4547 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4548 super_expr
, name_expr
,
4549 convert (integer_type_node
,
4550 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4551 (implementation_template
))),
4553 UOBJC_INSTANCE_METHODS_decl
,
4554 UOBJC_INSTANCE_VARIABLES_decl
,
4557 finish_decl (decl
, initlist
, NULL_TREE
);
4561 synth_id_with_class_suffix (preamble
, ctxt
)
4562 const char *preamble
;
4566 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4567 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4569 const char *class_name
4570 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4571 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4572 sprintf (string
, "%s_%s", preamble
,
4573 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4575 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4576 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4578 /* We have a category. */
4579 const char *class_name
4580 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4581 const char *class_super_name
4582 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4583 string
= (char *) alloca (strlen (preamble
)
4584 + strlen (class_name
)
4585 + strlen (class_super_name
)
4587 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4589 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4591 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4593 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4594 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4599 return get_identifier (string
);
4603 is_objc_type_qualifier (node
)
4606 return (TREE_CODE (node
) == IDENTIFIER_NODE
4607 && (node
== ridpointers
[(int) RID_CONST
]
4608 || node
== ridpointers
[(int) RID_VOLATILE
]
4609 || node
== ridpointers
[(int) RID_IN
]
4610 || node
== ridpointers
[(int) RID_OUT
]
4611 || node
== ridpointers
[(int) RID_INOUT
]
4612 || node
== ridpointers
[(int) RID_BYCOPY
]
4613 || node
== ridpointers
[(int) RID_BYREF
]
4614 || node
== ridpointers
[(int) RID_ONEWAY
]));
4617 /* If type is empty or only type qualifiers are present, add default
4618 type of id (otherwise grokdeclarator will default to int). */
4621 adjust_type_for_id_default (type
)
4624 tree declspecs
, chain
;
4627 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4628 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4630 declspecs
= TREE_PURPOSE (type
);
4632 /* Determine if a typespec is present. */
4633 for (chain
= declspecs
;
4635 chain
= TREE_CHAIN (chain
))
4637 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4641 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4643 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4648 selector ':' '(' typename ')' identifier
4651 Transform an Objective-C keyword argument into
4652 the C equivalent parameter declarator.
4654 In: key_name, an "identifier_node" (optional).
4655 arg_type, a "tree_list" (optional).
4656 arg_name, an "identifier_node".
4658 Note: It would be really nice to strongly type the preceding
4659 arguments in the function prototype; however, then I
4660 could not use the "accessor" macros defined in "tree.h".
4662 Out: an instance of "keyword_decl". */
4665 build_keyword_decl (key_name
, arg_type
, arg_name
)
4672 /* If no type is specified, default to "id". */
4673 arg_type
= adjust_type_for_id_default (arg_type
);
4675 keyword_decl
= make_node (KEYWORD_DECL
);
4677 TREE_TYPE (keyword_decl
) = arg_type
;
4678 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4679 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4681 return keyword_decl
;
4684 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4687 build_keyword_selector (selector
)
4691 tree key_chain
, key_name
;
4694 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4696 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4697 key_name
= KEYWORD_KEY_NAME (key_chain
);
4698 else if (TREE_CODE (selector
) == TREE_LIST
)
4699 key_name
= TREE_PURPOSE (key_chain
);
4704 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4706 /* Just a ':' arg. */
4710 buf
= (char *)alloca (len
+ 1);
4711 memset (buf
, 0, len
+ 1);
4713 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4715 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4716 key_name
= KEYWORD_KEY_NAME (key_chain
);
4717 else if (TREE_CODE (selector
) == TREE_LIST
)
4718 key_name
= TREE_PURPOSE (key_chain
);
4723 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4727 return get_identifier (buf
);
4730 /* Used for declarations and definitions. */
4733 build_method_decl (code
, ret_type
, selector
, add_args
)
4734 enum tree_code code
;
4741 /* If no type is specified, default to "id". */
4742 ret_type
= adjust_type_for_id_default (ret_type
);
4744 method_decl
= make_node (code
);
4745 TREE_TYPE (method_decl
) = ret_type
;
4747 /* If we have a keyword selector, create an identifier_node that
4748 represents the full selector name (`:' included)... */
4749 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4751 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4752 METHOD_SEL_ARGS (method_decl
) = selector
;
4753 METHOD_ADD_ARGS (method_decl
) = add_args
;
4757 METHOD_SEL_NAME (method_decl
) = selector
;
4758 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4759 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4765 #define METHOD_DEF 0
4766 #define METHOD_REF 1
4768 /* Used by `build_message_expr' and `comp_method_types'. Return an
4769 argument list for method METH. CONTEXT is either METHOD_DEF or
4770 METHOD_REF, saying whether we are trying to define a method or call
4771 one. SUPERFLAG says this is for a send to super; this makes a
4772 difference for the NeXT calling sequence in which the lookup and
4773 the method call are done together. */
4776 get_arg_type_list (meth
, context
, superflag
)
4783 /* Receiver type. */
4784 if (flag_next_runtime
&& superflag
)
4785 arglist
= build_tree_list (NULL_TREE
, super_type
);
4786 else if (context
== METHOD_DEF
)
4787 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4789 arglist
= build_tree_list (NULL_TREE
, id_type
);
4791 /* Selector type - will eventually change to `int'. */
4792 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4794 /* Build a list of argument types. */
4795 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4797 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4798 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4801 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4802 /* We have a `, ...' immediately following the selector,
4803 finalize the arglist...simulate get_parm_info (0). */
4805 else if (METHOD_ADD_ARGS (meth
))
4807 /* we have a variable length selector */
4808 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4809 chainon (arglist
, add_arg_list
);
4812 /* finalize the arglist...simulate get_parm_info (1) */
4813 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4819 check_duplicates (hsh
)
4822 tree meth
= NULL_TREE
;
4830 /* We have two methods with the same name and different types. */
4832 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4834 warning ("multiple declarations for method `%s'",
4835 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4837 warn_with_method ("using", type
, meth
);
4838 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4839 warn_with_method ("also found", type
, loop
->value
);
4845 /* If RECEIVER is a class reference, return the identifier node for the
4846 referenced class. RECEIVER is created by get_class_reference, so we
4847 check the exact form created depending on which runtimes are used. */
4850 receiver_is_class_object (receiver
)
4853 tree chain
, exp
, arg
;
4854 if (flag_next_runtime
)
4856 /* The receiver is a variable created by build_class_reference_decl. */
4857 if (TREE_CODE (receiver
) == VAR_DECL
4858 && TREE_TYPE (receiver
) == objc_class_type
)
4859 /* Look up the identifier. */
4860 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4861 if (TREE_PURPOSE (chain
) == receiver
)
4862 return TREE_VALUE (chain
);
4866 /* The receiver is a function call that returns an id. Check if
4867 it is a call to objc_getClass, if so, pick up the class name. */
4868 if ((exp
= TREE_OPERAND (receiver
, 0))
4869 && TREE_CODE (exp
) == ADDR_EXPR
4870 && (exp
= TREE_OPERAND (exp
, 0))
4871 && TREE_CODE (exp
) == FUNCTION_DECL
4872 && exp
== objc_get_class_decl
4873 /* we have a call to objc_getClass! */
4874 && (arg
= TREE_OPERAND (receiver
, 1))
4875 && TREE_CODE (arg
) == TREE_LIST
4876 && (arg
= TREE_VALUE (arg
)))
4879 if (TREE_CODE (arg
) == ADDR_EXPR
4880 && (arg
= TREE_OPERAND (arg
, 0))
4881 && TREE_CODE (arg
) == STRING_CST
)
4882 /* Finally, we have the class name. */
4883 return get_identifier (TREE_STRING_POINTER (arg
));
4889 /* If we are currently building a message expr, this holds
4890 the identifier of the selector of the message. This is
4891 used when printing warnings about argument mismatches. */
4893 static tree building_objc_message_expr
= 0;
4896 maybe_building_objc_message_expr ()
4898 return building_objc_message_expr
;
4901 /* Construct an expression for sending a message.
4902 MESS has the object to send to in TREE_PURPOSE
4903 and the argument list (including selector) in TREE_VALUE.
4905 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4906 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4909 build_message_expr (mess
)
4912 tree receiver
= TREE_PURPOSE (mess
);
4913 tree selector
, self_object
;
4914 tree rtype
, sel_name
;
4915 tree args
= TREE_VALUE (mess
);
4916 tree method_params
= NULL_TREE
;
4917 tree method_prototype
= NULL_TREE
;
4919 int statically_typed
= 0, statically_allocated
= 0;
4920 tree class_ident
= 0;
4922 /* 1 if this is sending to the superclass. */
4925 if (TREE_CODE (receiver
) == ERROR_MARK
)
4926 return error_mark_node
;
4928 /* Determine receiver type. */
4929 rtype
= TREE_TYPE (receiver
);
4930 super
= IS_SUPER (rtype
);
4934 if (TREE_STATIC_TEMPLATE (rtype
))
4935 statically_allocated
= 1;
4936 else if (TREE_CODE (rtype
) == POINTER_TYPE
4937 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4938 statically_typed
= 1;
4939 else if ((flag_next_runtime
4940 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4941 && (class_ident
= receiver_is_class_object (receiver
)))
4943 else if (! IS_ID (rtype
)
4944 /* Allow any type that matches objc_class_type. */
4945 && ! comptypes (rtype
, objc_class_type
))
4947 memset (errbuf
, 0, BUFSIZE
);
4948 warning ("invalid receiver type `%s'",
4949 gen_declaration (rtype
, errbuf
));
4952 if (statically_allocated
)
4953 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4955 /* Don't evaluate the receiver twice. */
4956 receiver
= save_expr (receiver
);
4957 self_object
= receiver
;
4960 /* If sending to `super', use current self as the object. */
4961 self_object
= self_decl
;
4963 /* Obtain the full selector name. */
4965 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4966 /* A unary selector. */
4968 else if (TREE_CODE (args
) == TREE_LIST
)
4969 sel_name
= build_keyword_selector (args
);
4973 /* Build the parameter list to give to the method. */
4975 method_params
= NULL_TREE
;
4976 if (TREE_CODE (args
) == TREE_LIST
)
4978 tree chain
= args
, prev
= NULL_TREE
;
4980 /* We have a keyword selector--check for comma expressions. */
4983 tree element
= TREE_VALUE (chain
);
4985 /* We have a comma expression, must collapse... */
4986 if (TREE_CODE (element
) == TREE_LIST
)
4989 TREE_CHAIN (prev
) = element
;
4994 chain
= TREE_CHAIN (chain
);
4996 method_params
= args
;
4999 /* Determine operation return type. */
5001 if (IS_SUPER (rtype
))
5005 if (CLASS_SUPER_NAME (implementation_template
))
5008 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5010 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5011 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5013 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5015 if (iface
&& !method_prototype
)
5016 warning ("`%s' does not respond to `%s'",
5017 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5018 IDENTIFIER_POINTER (sel_name
));
5022 error ("no super class declared in interface for `%s'",
5023 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5024 return error_mark_node
;
5028 else if (statically_allocated
)
5030 tree ctype
= TREE_TYPE (rtype
);
5031 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5034 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5036 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5038 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5041 if (!method_prototype
)
5042 warning ("`%s' does not respond to `%s'",
5043 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5044 IDENTIFIER_POINTER (sel_name
));
5046 else if (statically_typed
)
5048 tree ctype
= TREE_TYPE (rtype
);
5050 /* `self' is now statically_typed. All methods should be visible
5051 within the context of the implementation. */
5052 if (implementation_context
5053 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5056 = lookup_instance_method_static (implementation_template
,
5059 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5061 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5064 if (! method_prototype
5065 && implementation_template
!= implementation_context
)
5066 /* The method is not published in the interface. Check
5069 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5076 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5077 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5079 if (! method_prototype
)
5081 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5084 = lookup_method_in_protocol_list (protocol_list
,
5089 if (!method_prototype
)
5090 warning ("`%s' does not respond to `%s'",
5091 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5092 IDENTIFIER_POINTER (sel_name
));
5094 else if (class_ident
)
5096 if (implementation_context
5097 && CLASS_NAME (implementation_context
) == class_ident
)
5100 = lookup_class_method_static (implementation_template
, sel_name
);
5102 if (!method_prototype
5103 && implementation_template
!= implementation_context
)
5104 /* The method is not published in the interface. Check
5107 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5114 if ((iface
= lookup_interface (class_ident
)))
5115 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5118 if (!method_prototype
)
5120 warning ("cannot find class (factory) method.");
5121 warning ("return type for `%s' defaults to id",
5122 IDENTIFIER_POINTER (sel_name
));
5125 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5127 /* An anonymous object that has been qualified with a protocol. */
5129 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5131 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5134 if (!method_prototype
)
5138 warning ("method `%s' not implemented by protocol.",
5139 IDENTIFIER_POINTER (sel_name
));
5141 /* Try and find the method signature in the global pools. */
5143 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5144 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5146 if (!(method_prototype
= check_duplicates (hsh
)))
5147 warning ("return type defaults to id");
5154 /* We think we have an instance...loophole: extern id Object; */
5155 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5157 /* For various loopholes, like sending messages to self in a
5159 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5161 method_prototype
= check_duplicates (hsh
);
5162 if (!method_prototype
)
5164 warning ("cannot find method.");
5165 warning ("return type for `%s' defaults to id",
5166 IDENTIFIER_POINTER (sel_name
));
5170 /* Save the selector name for printing error messages. */
5171 building_objc_message_expr
= sel_name
;
5173 /* Build the parameters list for looking up the method.
5174 These are the object itself and the selector. */
5176 if (flag_typed_selectors
)
5177 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5179 selector
= build_selector_reference (sel_name
);
5181 retval
= build_objc_method_call (super
, method_prototype
,
5182 receiver
, self_object
,
5183 selector
, method_params
);
5185 building_objc_message_expr
= 0;
5190 /* Build a tree expression to send OBJECT the operation SELECTOR,
5191 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5192 assuming the method has prototype METHOD_PROTOTYPE.
5193 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5194 Use METHOD_PARAMS as list of args to pass to the method.
5195 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5198 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5199 selector
, method_params
)
5201 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5203 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5204 tree rcv_p
= (super_flag
5205 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5206 get_identifier (TAG_SUPER
)))
5209 if (flag_next_runtime
)
5211 if (! method_prototype
)
5213 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5214 tree_cons (NULL_TREE
, selector
,
5216 assemble_external (sender
);
5217 return build_function_call (sender
, method_params
);
5221 /* This is a real kludge, but it is used only for the Next.
5222 Clobber the data type of SENDER temporarily to accept
5223 all the arguments for this operation, and to return
5224 whatever this operation returns. */
5225 tree arglist
= NULL_TREE
;
5228 /* Save the proper contents of SENDER's data type. */
5229 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5230 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5232 /* Install this method's argument types. */
5233 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5235 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5237 /* Install this method's return type. */
5238 TREE_TYPE (TREE_TYPE (sender
))
5239 = groktypename (TREE_TYPE (method_prototype
));
5241 /* Call SENDER with all the parameters. This will do type
5242 checking using the arg types for this method. */
5243 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5244 tree_cons (NULL_TREE
, selector
,
5246 assemble_external (sender
);
5247 retval
= build_function_call (sender
, method_params
);
5249 /* Restore SENDER's return/argument types. */
5250 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5251 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5257 /* This is the portable way.
5258 First call the lookup function to get a pointer to the method,
5259 then cast the pointer, then call it with the method arguments. */
5262 /* Avoid trouble since we may evaluate each of these twice. */
5263 object
= save_expr (object
);
5264 selector
= save_expr (selector
);
5266 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5268 assemble_external (sender
);
5270 = build_function_call (sender
,
5271 tree_cons (NULL_TREE
, lookup_object
,
5272 tree_cons (NULL_TREE
, selector
,
5275 /* If we have a method prototype, construct the data type this
5276 method needs, and cast what we got from SENDER into a pointer
5278 if (method_prototype
)
5280 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5282 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5283 tree fake_function_type
= build_function_type (valtype
, arglist
);
5284 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5288 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5290 /* Pass the object to the method. */
5291 assemble_external (method
);
5292 return build_function_call (method
,
5293 tree_cons (NULL_TREE
, object
,
5294 tree_cons (NULL_TREE
, selector
,
5300 build_protocol_reference (p
)
5303 tree decl
, ident
, ptype
;
5305 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5307 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5309 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5310 objc_protocol_template
),
5313 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5314 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5317 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5318 DECL_EXTERNAL (decl
) = 1;
5319 TREE_PUBLIC (decl
) = 1;
5320 TREE_USED (decl
) = 1;
5321 DECL_ARTIFICIAL (decl
) = 1;
5323 make_decl_rtl (decl
, 0, 1);
5324 pushdecl_top_level (decl
);
5327 PROTOCOL_FORWARD_DECL (p
) = decl
;
5331 build_protocol_expr (protoname
)
5335 tree p
= lookup_protocol (protoname
);
5339 error ("Cannot find protocol declaration for `%s'",
5340 IDENTIFIER_POINTER (protoname
));
5341 return error_mark_node
;
5344 if (!PROTOCOL_FORWARD_DECL (p
))
5345 build_protocol_reference (p
);
5347 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5349 TREE_TYPE (expr
) = protocol_type
;
5355 build_selector_expr (selnamelist
)
5360 /* Obtain the full selector name. */
5361 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5362 /* A unary selector. */
5363 selname
= selnamelist
;
5364 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5365 selname
= build_keyword_selector (selnamelist
);
5369 if (flag_typed_selectors
)
5370 return build_typed_selector_reference (selname
, 0);
5372 return build_selector_reference (selname
);
5376 build_encode_expr (type
)
5382 encode_type (type
, obstack_object_size (&util_obstack
),
5383 OBJC_ENCODE_INLINE_DEFS
);
5384 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5385 string
= obstack_finish (&util_obstack
);
5387 /* Synthesize a string that represents the encoded struct/union. */
5388 result
= my_build_string (strlen (string
) + 1, string
);
5389 obstack_free (&util_obstack
, util_firstobj
);
5394 build_ivar_reference (id
)
5397 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5399 /* Historically, a class method that produced objects (factory
5400 method) would assign `self' to the instance that it
5401 allocated. This would effectively turn the class method into
5402 an instance method. Following this assignment, the instance
5403 variables could be accessed. That practice, while safe,
5404 violates the simple rule that a class method should not refer
5405 to an instance variable. It's better to catch the cases
5406 where this is done unknowingly than to support the above
5408 warning ("instance variable `%s' accessed in class method",
5409 IDENTIFIER_POINTER (id
));
5410 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5413 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5416 #define HASH_ALLOC_LIST_SIZE 170
5417 #define ATTR_ALLOC_LIST_SIZE 170
5418 #define SIZEHASHTABLE 257
5421 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5426 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5427 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5429 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5430 perror ("unable to allocate space in objc-tree.c");
5435 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5437 nst_method_hash_list
[i
] = 0;
5438 cls_method_hash_list
[i
] = 0;
5444 hash_enter (hashlist
, method
)
5448 static hash hash_alloc_list
= 0;
5449 static int hash_alloc_index
= 0;
5451 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5453 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5455 hash_alloc_index
= 0;
5456 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5457 * HASH_ALLOC_LIST_SIZE
);
5458 if (! hash_alloc_list
)
5459 perror ("unable to allocate in objc-tree.c");
5461 obj
= &hash_alloc_list
[hash_alloc_index
++];
5463 obj
->next
= hashlist
[slot
];
5466 hashlist
[slot
] = obj
; /* append to front */
5470 hash_lookup (hashlist
, sel_name
)
5476 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5480 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5483 target
= target
->next
;
5489 hash_add_attr (entry
, value
)
5493 static attr attr_alloc_list
= 0;
5494 static int attr_alloc_index
= 0;
5497 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5499 attr_alloc_index
= 0;
5500 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5501 * ATTR_ALLOC_LIST_SIZE
);
5502 if (! attr_alloc_list
)
5503 perror ("unable to allocate in objc-tree.c");
5505 obj
= &attr_alloc_list
[attr_alloc_index
++];
5506 obj
->next
= entry
->list
;
5509 entry
->list
= obj
; /* append to front */
5513 lookup_method (mchain
, method
)
5519 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5522 key
= METHOD_SEL_NAME (method
);
5526 if (METHOD_SEL_NAME (mchain
) == key
)
5528 mchain
= TREE_CHAIN (mchain
);
5534 lookup_instance_method_static (interface
, ident
)
5538 tree inter
= interface
;
5539 tree chain
= CLASS_NST_METHODS (inter
);
5540 tree meth
= NULL_TREE
;
5544 if ((meth
= lookup_method (chain
, ident
)))
5547 if (CLASS_CATEGORY_LIST (inter
))
5549 tree category
= CLASS_CATEGORY_LIST (inter
);
5550 chain
= CLASS_NST_METHODS (category
);
5554 if ((meth
= lookup_method (chain
, ident
)))
5557 /* Check for instance methods in protocols in categories. */
5558 if (CLASS_PROTOCOL_LIST (category
))
5560 if ((meth
= (lookup_method_in_protocol_list
5561 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5565 if ((category
= CLASS_CATEGORY_LIST (category
)))
5566 chain
= CLASS_NST_METHODS (category
);
5571 if (CLASS_PROTOCOL_LIST (inter
))
5573 if ((meth
= (lookup_method_in_protocol_list
5574 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5578 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5579 chain
= CLASS_NST_METHODS (inter
);
5587 lookup_class_method_static (interface
, ident
)
5591 tree inter
= interface
;
5592 tree chain
= CLASS_CLS_METHODS (inter
);
5593 tree meth
= NULL_TREE
;
5594 tree root_inter
= NULL_TREE
;
5598 if ((meth
= lookup_method (chain
, ident
)))
5601 if (CLASS_CATEGORY_LIST (inter
))
5603 tree category
= CLASS_CATEGORY_LIST (inter
);
5604 chain
= CLASS_CLS_METHODS (category
);
5608 if ((meth
= lookup_method (chain
, ident
)))
5611 /* Check for class methods in protocols in categories. */
5612 if (CLASS_PROTOCOL_LIST (category
))
5614 if ((meth
= (lookup_method_in_protocol_list
5615 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5619 if ((category
= CLASS_CATEGORY_LIST (category
)))
5620 chain
= CLASS_CLS_METHODS (category
);
5625 /* Check for class methods in protocols. */
5626 if (CLASS_PROTOCOL_LIST (inter
))
5628 if ((meth
= (lookup_method_in_protocol_list
5629 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5634 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5635 chain
= CLASS_CLS_METHODS (inter
);
5639 /* Simulate wrap around. */
5640 return lookup_instance_method_static (root_inter
, ident
);
5644 add_class_method (class, method
)
5651 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5653 /* put method on list in reverse order */
5654 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5655 CLASS_CLS_METHODS (class) = method
;
5659 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5660 error ("duplicate definition of class method `%s'.",
5661 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5664 /* Check types; if different, complain. */
5665 if (!comp_proto_with_proto (method
, mth
))
5666 error ("duplicate declaration of class method `%s'.",
5667 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5671 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5673 /* Install on a global chain. */
5674 hash_enter (cls_method_hash_list
, method
);
5678 /* Check types; if different, add to a list. */
5679 if (!comp_proto_with_proto (method
, hsh
->key
))
5680 hash_add_attr (hsh
, method
);
5686 add_instance_method (class, method
)
5693 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5695 /* Put method on list in reverse order. */
5696 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5697 CLASS_NST_METHODS (class) = method
;
5701 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5702 error ("duplicate definition of instance method `%s'.",
5703 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5706 /* Check types; if different, complain. */
5707 if (!comp_proto_with_proto (method
, mth
))
5708 error ("duplicate declaration of instance method `%s'.",
5709 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5713 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5715 /* Install on a global chain. */
5716 hash_enter (nst_method_hash_list
, method
);
5720 /* Check types; if different, add to a list. */
5721 if (!comp_proto_with_proto (method
, hsh
->key
))
5722 hash_add_attr (hsh
, method
);
5731 /* Put interfaces on list in reverse order. */
5732 TREE_CHAIN (class) = interface_chain
;
5733 interface_chain
= class;
5734 return interface_chain
;
5738 add_category (class, category
)
5742 /* Put categories on list in reverse order. */
5743 tree cat
= CLASS_CATEGORY_LIST (class);
5747 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5748 warning ("duplicate interface declaration for category `%s(%s)'",
5749 IDENTIFIER_POINTER (CLASS_NAME (class)),
5750 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5751 cat
= CLASS_CATEGORY_LIST (cat
);
5754 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5755 CLASS_CATEGORY_LIST (class) = category
;
5758 /* Called after parsing each instance variable declaration. Necessary to
5759 preserve typedefs and implement public/private...
5761 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5764 add_instance_variable (class, public, declarator
, declspecs
, width
)
5771 tree field_decl
, raw_decl
;
5773 raw_decl
= build_tree_list (declspecs
, declarator
);
5775 if (CLASS_RAW_IVARS (class))
5776 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5778 CLASS_RAW_IVARS (class) = raw_decl
;
5780 field_decl
= grokfield (input_filename
, lineno
,
5781 declarator
, declspecs
, width
);
5783 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5787 TREE_PUBLIC (field_decl
) = 0;
5788 TREE_PRIVATE (field_decl
) = 0;
5789 TREE_PROTECTED (field_decl
) = 1;
5793 TREE_PUBLIC (field_decl
) = 1;
5794 TREE_PRIVATE (field_decl
) = 0;
5795 TREE_PROTECTED (field_decl
) = 0;
5799 TREE_PUBLIC (field_decl
) = 0;
5800 TREE_PRIVATE (field_decl
) = 1;
5801 TREE_PROTECTED (field_decl
) = 0;
5806 if (CLASS_IVARS (class))
5807 chainon (CLASS_IVARS (class), field_decl
);
5809 CLASS_IVARS (class) = field_decl
;
5815 is_ivar (decl_chain
, ident
)
5819 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5820 if (DECL_NAME (decl_chain
) == ident
)
5825 /* True if the ivar is private and we are not in its implementation. */
5831 if (TREE_PRIVATE (decl
)
5832 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5834 error ("instance variable `%s' is declared private",
5835 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5842 /* We have an instance variable reference;, check to see if it is public. */
5845 is_public (expr
, identifier
)
5849 tree basetype
= TREE_TYPE (expr
);
5850 enum tree_code code
= TREE_CODE (basetype
);
5853 if (code
== RECORD_TYPE
)
5855 if (TREE_STATIC_TEMPLATE (basetype
))
5857 if (!lookup_interface (TYPE_NAME (basetype
)))
5859 error ("Cannot find interface declaration for `%s'",
5860 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5864 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5866 if (TREE_PUBLIC (decl
))
5869 /* Important difference between the Stepstone translator:
5870 all instance variables should be public within the context
5871 of the implementation. */
5872 if (implementation_context
5873 && (((TREE_CODE (implementation_context
)
5874 == CLASS_IMPLEMENTATION_TYPE
)
5875 || (TREE_CODE (implementation_context
)
5876 == CATEGORY_IMPLEMENTATION_TYPE
))
5877 && (CLASS_NAME (implementation_context
)
5878 == TYPE_NAME (basetype
))))
5879 return ! is_private (decl
);
5881 error ("instance variable `%s' is declared %s",
5882 IDENTIFIER_POINTER (identifier
),
5883 TREE_PRIVATE (decl
) ? "private" : "protected");
5888 else if (implementation_context
&& (basetype
== objc_object_reference
))
5890 TREE_TYPE (expr
) = uprivate_record
;
5891 warning ("static access to object of type `id'");
5898 /* Implement @defs (<classname>) within struct bodies. */
5901 get_class_ivars (interface
)
5904 return build_ivar_chain (interface
, 1);
5907 /* Make sure all entries in CHAIN are also in LIST. */
5910 check_methods (chain
, list
, mtype
)
5919 if (!lookup_method (list
, chain
))
5923 if (TREE_CODE (implementation_context
)
5924 == CLASS_IMPLEMENTATION_TYPE
)
5925 warning ("incomplete implementation of class `%s'",
5926 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5927 else if (TREE_CODE (implementation_context
)
5928 == CATEGORY_IMPLEMENTATION_TYPE
)
5929 warning ("incomplete implementation of category `%s'",
5930 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5934 warning ("method definition for `%c%s' not found",
5935 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5938 chain
= TREE_CHAIN (chain
);
5945 conforms_to_protocol (class, protocol
)
5951 tree p
= CLASS_PROTOCOL_LIST (class);
5953 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5958 tree super
= (CLASS_SUPER_NAME (class)
5959 ? lookup_interface (CLASS_SUPER_NAME (class))
5961 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5966 protocol
= TREE_CHAIN (protocol
);
5972 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5973 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5976 check_methods_accessible (chain
, context
, mtype
)
5983 tree base_context
= context
;
5987 context
= base_context
;
5991 list
= CLASS_CLS_METHODS (context
);
5993 list
= CLASS_NST_METHODS (context
);
5995 if (lookup_method (list
, chain
))
5998 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5999 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6000 context
= (CLASS_SUPER_NAME (context
)
6001 ? lookup_interface (CLASS_SUPER_NAME (context
))
6004 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6005 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6006 context
= (CLASS_NAME (context
)
6007 ? lookup_interface (CLASS_NAME (context
))
6013 if (context
== NULL_TREE
)
6017 if (TREE_CODE (implementation_context
)
6018 == CLASS_IMPLEMENTATION_TYPE
)
6019 warning ("incomplete implementation of class `%s'",
6021 (CLASS_NAME (implementation_context
)));
6022 else if (TREE_CODE (implementation_context
)
6023 == CATEGORY_IMPLEMENTATION_TYPE
)
6024 warning ("incomplete implementation of category `%s'",
6026 (CLASS_SUPER_NAME (implementation_context
)));
6029 warning ("method definition for `%c%s' not found",
6030 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6033 chain
= TREE_CHAIN (chain
); /* next method... */
6039 check_protocols (proto_list
, type
, name
)
6044 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6046 tree p
= TREE_VALUE (proto_list
);
6048 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6052 /* Ensure that all protocols have bodies. */
6053 if (flag_warn_protocol
) {
6054 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6055 CLASS_CLS_METHODS (implementation_context
),
6057 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6058 CLASS_NST_METHODS (implementation_context
),
6061 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6062 implementation_context
,
6064 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6065 implementation_context
,
6070 warning ("%s `%s' does not fully implement the `%s' protocol",
6071 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6076 ; /* An identifier if we could not find a protocol. */
6079 /* Check protocols recursively. */
6080 if (PROTOCOL_LIST (p
))
6083 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6084 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6085 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6090 /* Make sure that the class CLASS_NAME is defined
6091 CODE says which kind of thing CLASS_NAME ought to be.
6092 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6093 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6096 start_class (code
, class_name
, super_name
, protocol_list
)
6097 enum tree_code code
;
6104 class = make_node (code
);
6105 TYPE_BINFO (class) = make_tree_vec (5);
6107 CLASS_NAME (class) = class_name
;
6108 CLASS_SUPER_NAME (class) = super_name
;
6109 CLASS_CLS_METHODS (class) = NULL_TREE
;
6111 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6113 error ("`%s' redeclared as different kind of symbol",
6114 IDENTIFIER_POINTER (class_name
));
6115 error_with_decl (decl
, "previous declaration of `%s'");
6118 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6121 static tree implemented_classes
= 0;
6122 tree chain
= implemented_classes
;
6123 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6124 if (TREE_VALUE (chain
) == class_name
)
6126 error ("reimplementation of class `%s'",
6127 IDENTIFIER_POINTER (class_name
));
6128 return error_mark_node
;
6130 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6131 implemented_classes
);
6134 /* Pre-build the following entities - for speed/convenience. */
6136 self_id
= get_identifier ("self");
6138 ucmd_id
= get_identifier ("_cmd");
6141 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6142 if (!objc_super_template
)
6143 objc_super_template
= build_super_template ();
6145 /* Reset for multiple classes per file. */
6148 implementation_context
= class;
6150 /* Lookup the interface for this implementation. */
6152 if (!(implementation_template
= lookup_interface (class_name
)))
6154 warning ("Cannot find interface declaration for `%s'",
6155 IDENTIFIER_POINTER (class_name
));
6156 add_class (implementation_template
= implementation_context
);
6159 /* If a super class has been specified in the implementation,
6160 insure it conforms to the one specified in the interface. */
6163 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6165 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6167 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6168 error ("conflicting super class name `%s'",
6169 IDENTIFIER_POINTER (super_name
));
6170 error ("previous declaration of `%s'", name
);
6173 else if (! super_name
)
6175 CLASS_SUPER_NAME (implementation_context
)
6176 = CLASS_SUPER_NAME (implementation_template
);
6180 else if (code
== CLASS_INTERFACE_TYPE
)
6182 if (lookup_interface (class_name
))
6183 warning ("duplicate interface declaration for class `%s'",
6184 IDENTIFIER_POINTER (class_name
));
6189 CLASS_PROTOCOL_LIST (class)
6190 = lookup_and_install_protocols (protocol_list
);
6193 else if (code
== CATEGORY_INTERFACE_TYPE
)
6195 tree class_category_is_assoc_with
;
6197 /* For a category, class_name is really the name of the class that
6198 the following set of methods will be associated with. We must
6199 find the interface so that can derive the objects template. */
6201 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6203 error ("Cannot find interface declaration for `%s'",
6204 IDENTIFIER_POINTER (class_name
));
6205 exit (FATAL_EXIT_CODE
);
6208 add_category (class_category_is_assoc_with
, class);
6211 CLASS_PROTOCOL_LIST (class)
6212 = lookup_and_install_protocols (protocol_list
);
6215 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6217 /* Pre-build the following entities for speed/convenience. */
6219 self_id
= get_identifier ("self");
6221 ucmd_id
= get_identifier ("_cmd");
6224 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6225 if (!objc_super_template
)
6226 objc_super_template
= build_super_template ();
6228 /* Reset for multiple classes per file. */
6231 implementation_context
= class;
6233 /* For a category, class_name is really the name of the class that
6234 the following set of methods will be associated with. We must
6235 find the interface so that can derive the objects template. */
6237 if (!(implementation_template
= lookup_interface (class_name
)))
6239 error ("Cannot find interface declaration for `%s'",
6240 IDENTIFIER_POINTER (class_name
));
6241 exit (FATAL_EXIT_CODE
);
6248 continue_class (class)
6251 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6252 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6254 struct imp_entry
*imp_entry
;
6257 /* Check consistency of the instance variables. */
6259 if (CLASS_IVARS (class))
6260 check_ivars (implementation_template
, class);
6262 /* code generation */
6264 ivar_context
= build_private_template (implementation_template
);
6266 if (!objc_class_template
)
6267 build_class_template ();
6270 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6271 perror ("unable to allocate in objc-tree.c");
6273 imp_entry
->next
= imp_list
;
6274 imp_entry
->imp_context
= class;
6275 imp_entry
->imp_template
= implementation_template
;
6277 synth_forward_declarations ();
6278 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6279 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6281 /* Append to front and increment count. */
6282 imp_list
= imp_entry
;
6283 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6288 return ivar_context
;
6291 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6293 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6295 if (!TYPE_FIELDS (record
))
6297 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6298 CLASS_STATIC_TEMPLATE (class) = record
;
6300 /* Mark this record as a class template for static typing. */
6301 TREE_STATIC_TEMPLATE (record
) = 1;
6308 return error_mark_node
;
6311 /* This is called once we see the "@end" in an interface/implementation. */
6314 finish_class (class)
6317 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6319 /* All code generation is done in finish_objc. */
6321 if (implementation_template
!= implementation_context
)
6323 /* Ensure that all method listed in the interface contain bodies. */
6324 check_methods (CLASS_CLS_METHODS (implementation_template
),
6325 CLASS_CLS_METHODS (implementation_context
), '+');
6326 check_methods (CLASS_NST_METHODS (implementation_template
),
6327 CLASS_NST_METHODS (implementation_context
), '-');
6329 if (CLASS_PROTOCOL_LIST (implementation_template
))
6330 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6332 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6336 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6338 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6340 /* Find the category interface from the class it is associated with. */
6343 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6345 category
= CLASS_CATEGORY_LIST (category
);
6350 /* Ensure all method listed in the interface contain bodies. */
6351 check_methods (CLASS_CLS_METHODS (category
),
6352 CLASS_CLS_METHODS (implementation_context
), '+');
6353 check_methods (CLASS_NST_METHODS (category
),
6354 CLASS_NST_METHODS (implementation_context
), '-');
6356 if (CLASS_PROTOCOL_LIST (category
))
6357 check_protocols (CLASS_PROTOCOL_LIST (category
),
6359 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6363 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6366 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6367 char *string
= (char *) alloca (strlen (class_name
) + 3);
6369 /* extern struct objc_object *_<my_name>; */
6371 sprintf (string
, "_%s", class_name
);
6373 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6374 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6375 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6381 add_protocol (protocol
)
6384 /* Put protocol on list in reverse order. */
6385 TREE_CHAIN (protocol
) = protocol_chain
;
6386 protocol_chain
= protocol
;
6387 return protocol_chain
;
6391 lookup_protocol (ident
)
6396 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6398 if (ident
== PROTOCOL_NAME (chain
))
6406 start_protocol (code
, name
, list
)
6407 enum tree_code code
;
6413 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6414 if (!objc_protocol_template
)
6415 objc_protocol_template
= build_protocol_template ();
6417 protocol
= make_node (code
);
6418 TYPE_BINFO (protocol
) = make_tree_vec (2);
6420 PROTOCOL_NAME (protocol
) = name
;
6421 PROTOCOL_LIST (protocol
) = list
;
6423 lookup_and_install_protocols (list
);
6425 if (lookup_protocol (name
))
6426 warning ("duplicate declaration for protocol `%s'",
6427 IDENTIFIER_POINTER (name
));
6429 add_protocol (protocol
);
6431 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6437 finish_protocol (protocol
)
6438 tree protocol ATTRIBUTE_UNUSED
;
6443 /* "Encode" a data type into a string, which grows in util_obstack.
6444 ??? What is the FORMAT? Someone please document this! */
6447 encode_type_qualifiers (declspecs
)
6452 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6454 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6455 obstack_1grow (&util_obstack
, 'r');
6456 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6457 obstack_1grow (&util_obstack
, 'n');
6458 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6459 obstack_1grow (&util_obstack
, 'N');
6460 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6461 obstack_1grow (&util_obstack
, 'o');
6462 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6463 obstack_1grow (&util_obstack
, 'O');
6464 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6465 obstack_1grow (&util_obstack
, 'R');
6466 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6467 obstack_1grow (&util_obstack
, 'V');
6471 /* Encode a pointer type. */
6474 encode_pointer (type
, curtype
, format
)
6479 tree pointer_to
= TREE_TYPE (type
);
6481 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6483 if (TYPE_NAME (pointer_to
)
6484 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6486 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6488 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6490 obstack_1grow (&util_obstack
, '@');
6493 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6495 if (generating_instance_variables
)
6497 obstack_1grow (&util_obstack
, '@');
6498 obstack_1grow (&util_obstack
, '"');
6499 obstack_grow (&util_obstack
, name
, strlen (name
));
6500 obstack_1grow (&util_obstack
, '"');
6505 obstack_1grow (&util_obstack
, '@');
6509 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6511 obstack_1grow (&util_obstack
, '#');
6514 #ifndef OBJC_INT_SELECTORS
6515 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6517 obstack_1grow (&util_obstack
, ':');
6520 #endif /* OBJC_INT_SELECTORS */
6523 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6524 && TYPE_MODE (pointer_to
) == QImode
)
6526 obstack_1grow (&util_obstack
, '*');
6530 /* We have a type that does not get special treatment. */
6532 /* NeXT extension */
6533 obstack_1grow (&util_obstack
, '^');
6534 encode_type (pointer_to
, curtype
, format
);
6538 encode_array (type
, curtype
, format
)
6543 tree an_int_cst
= TYPE_SIZE (type
);
6544 tree array_of
= TREE_TYPE (type
);
6547 /* An incomplete array is treated like a pointer. */
6548 if (an_int_cst
== NULL
)
6550 encode_pointer (type
, curtype
, format
);
6554 sprintf (buffer
, "[%ld",
6555 (long) (TREE_INT_CST_LOW (an_int_cst
)
6556 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6558 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6559 encode_type (array_of
, curtype
, format
);
6560 obstack_1grow (&util_obstack
, ']');
6565 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6572 if (obstack_object_size (&util_obstack
) > 0
6573 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6575 tree name
= TYPE_NAME (type
);
6577 /* we have a reference; this is a NeXT extension. */
6579 if (obstack_object_size (&util_obstack
) - curtype
== 1
6580 && format
== OBJC_ENCODE_INLINE_DEFS
)
6582 /* Output format of struct for first level only. */
6583 tree fields
= TYPE_FIELDS (type
);
6585 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6587 obstack_1grow (&util_obstack
, left
);
6588 obstack_grow (&util_obstack
,
6589 IDENTIFIER_POINTER (name
),
6590 strlen (IDENTIFIER_POINTER (name
)));
6591 obstack_1grow (&util_obstack
, '=');
6595 obstack_1grow (&util_obstack
, left
);
6596 obstack_grow (&util_obstack
, "?=", 2);
6599 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6600 encode_field_decl (fields
, curtype
, format
);
6602 obstack_1grow (&util_obstack
, right
);
6605 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6607 obstack_1grow (&util_obstack
, left
);
6608 obstack_grow (&util_obstack
,
6609 IDENTIFIER_POINTER (name
),
6610 strlen (IDENTIFIER_POINTER (name
)));
6611 obstack_1grow (&util_obstack
, right
);
6616 /* We have an untagged structure or a typedef. */
6617 obstack_1grow (&util_obstack
, left
);
6618 obstack_1grow (&util_obstack
, '?');
6619 obstack_1grow (&util_obstack
, right
);
6625 tree name
= TYPE_NAME (type
);
6626 tree fields
= TYPE_FIELDS (type
);
6628 if (format
== OBJC_ENCODE_INLINE_DEFS
6629 || generating_instance_variables
)
6631 obstack_1grow (&util_obstack
, left
);
6632 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6633 obstack_grow (&util_obstack
,
6634 IDENTIFIER_POINTER (name
),
6635 strlen (IDENTIFIER_POINTER (name
)));
6637 obstack_1grow (&util_obstack
, '?');
6639 obstack_1grow (&util_obstack
, '=');
6641 for (; fields
; fields
= TREE_CHAIN (fields
))
6643 if (generating_instance_variables
)
6645 tree fname
= DECL_NAME (fields
);
6647 obstack_1grow (&util_obstack
, '"');
6648 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6650 obstack_grow (&util_obstack
,
6651 IDENTIFIER_POINTER (fname
),
6652 strlen (IDENTIFIER_POINTER (fname
)));
6655 obstack_1grow (&util_obstack
, '"');
6658 encode_field_decl (fields
, curtype
, format
);
6661 obstack_1grow (&util_obstack
, right
);
6666 obstack_1grow (&util_obstack
, left
);
6667 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6668 obstack_grow (&util_obstack
,
6669 IDENTIFIER_POINTER (name
),
6670 strlen (IDENTIFIER_POINTER (name
)));
6672 /* We have an untagged structure or a typedef. */
6673 obstack_1grow (&util_obstack
, '?');
6675 obstack_1grow (&util_obstack
, right
);
6681 encode_aggregate (type
, curtype
, format
)
6686 enum tree_code code
= TREE_CODE (type
);
6692 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6697 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6702 obstack_1grow (&util_obstack
, 'i');
6710 /* Support bitfields. The current version of Objective-C does not support
6711 them. The string will consist of one or more "b:n"'s where n is an
6712 integer describing the width of the bitfield. Currently, classes in
6713 the kit implement a method "-(char *)describeBitfieldStruct:" that
6714 simulates this. If they do not implement this method, the archiver
6715 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6716 according to the GNU compiler. After looking at the "kit", it appears
6717 that all classes currently rely on this default behavior, rather than
6718 hand generating this string (which is tedious). */
6721 encode_bitfield (width
)
6725 sprintf (buffer
, "b%d", width
);
6726 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6729 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6732 encode_type (type
, curtype
, format
)
6737 enum tree_code code
= TREE_CODE (type
);
6739 if (code
== INTEGER_TYPE
)
6741 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6743 /* Unsigned integer types. */
6745 if (TYPE_MODE (type
) == QImode
)
6746 obstack_1grow (&util_obstack
, 'C');
6747 else if (TYPE_MODE (type
) == HImode
)
6748 obstack_1grow (&util_obstack
, 'S');
6749 else if (TYPE_MODE (type
) == SImode
)
6751 if (type
== long_unsigned_type_node
)
6752 obstack_1grow (&util_obstack
, 'L');
6754 obstack_1grow (&util_obstack
, 'I');
6756 else if (TYPE_MODE (type
) == DImode
)
6757 obstack_1grow (&util_obstack
, 'Q');
6761 /* Signed integer types. */
6763 if (TYPE_MODE (type
) == QImode
)
6764 obstack_1grow (&util_obstack
, 'c');
6765 else if (TYPE_MODE (type
) == HImode
)
6766 obstack_1grow (&util_obstack
, 's');
6767 else if (TYPE_MODE (type
) == SImode
)
6769 if (type
== long_integer_type_node
)
6770 obstack_1grow (&util_obstack
, 'l');
6772 obstack_1grow (&util_obstack
, 'i');
6775 else if (TYPE_MODE (type
) == DImode
)
6776 obstack_1grow (&util_obstack
, 'q');
6780 else if (code
== REAL_TYPE
)
6782 /* Floating point types. */
6784 if (TYPE_MODE (type
) == SFmode
)
6785 obstack_1grow (&util_obstack
, 'f');
6786 else if (TYPE_MODE (type
) == DFmode
6787 || TYPE_MODE (type
) == TFmode
)
6788 obstack_1grow (&util_obstack
, 'd');
6791 else if (code
== VOID_TYPE
)
6792 obstack_1grow (&util_obstack
, 'v');
6794 else if (code
== ARRAY_TYPE
)
6795 encode_array (type
, curtype
, format
);
6797 else if (code
== POINTER_TYPE
)
6798 encode_pointer (type
, curtype
, format
);
6800 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6801 encode_aggregate (type
, curtype
, format
);
6803 else if (code
== FUNCTION_TYPE
) /* '?' */
6804 obstack_1grow (&util_obstack
, '?');
6808 encode_complete_bitfield (int position
, tree type
, int size
)
6810 enum tree_code code
= TREE_CODE (type
);
6812 char charType
= '?';
6814 if (code
== INTEGER_TYPE
)
6816 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6818 /* Unsigned integer types. */
6820 if (TYPE_MODE (type
) == QImode
)
6822 else if (TYPE_MODE (type
) == HImode
)
6824 else if (TYPE_MODE (type
) == SImode
)
6826 if (type
== long_unsigned_type_node
)
6831 else if (TYPE_MODE (type
) == DImode
)
6836 /* Signed integer types. */
6838 if (TYPE_MODE (type
) == QImode
)
6840 else if (TYPE_MODE (type
) == HImode
)
6842 else if (TYPE_MODE (type
) == SImode
)
6844 if (type
== long_integer_type_node
)
6850 else if (TYPE_MODE (type
) == DImode
)
6858 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6859 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6863 encode_field_decl (field_decl
, curtype
, format
)
6870 type
= TREE_TYPE (field_decl
);
6872 /* If this field is obviously a bitfield, or is a bitfield that has been
6873 clobbered to look like a ordinary integer mode, go ahead and generate
6874 the bitfield typing information. */
6875 if (flag_next_runtime
)
6877 if (DECL_BIT_FIELD (field_decl
))
6878 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6880 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6884 if (DECL_BIT_FIELD (field_decl
))
6885 encode_complete_bitfield (int_bit_position (field_decl
),
6886 DECL_BIT_FIELD_TYPE (field_decl
),
6887 tree_low_cst (DECL_SIZE (field_decl
), 1));
6889 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6894 expr_last (complex_expr
)
6900 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6901 complex_expr
= next
;
6903 return complex_expr
;
6906 /* The selector of the current method,
6907 or NULL if we aren't compiling a method. */
6910 maybe_objc_method_name (decl
)
6911 tree decl ATTRIBUTE_UNUSED
;
6914 return METHOD_SEL_NAME (method_context
);
6919 /* Transform a method definition into a function definition as follows:
6920 - synthesize the first two arguments, "self" and "_cmd". */
6923 start_method_def (method
)
6928 /* Required to implement _msgSuper. */
6929 method_context
= method
;
6930 UOBJC_SUPER_decl
= NULL_TREE
;
6932 /* Must be called BEFORE start_function. */
6935 /* Generate prototype declarations for arguments..."new-style". */
6937 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
6938 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6940 /* Really a `struct objc_class *'. However, we allow people to
6941 assign to self, which changes its type midstream. */
6942 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6944 push_parm_decl (build_tree_list
6945 (build_tree_list (decl_specs
,
6946 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6947 build_tree_list (unused_list
, NULL_TREE
)));
6949 #ifdef OBJC_INT_SELECTORS
6950 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
6951 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
6952 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
6953 build_tree_list (unused_list
, NULL_TREE
)));
6954 #else /* not OBJC_INT_SELECTORS */
6955 decl_specs
= build_tree_list (NULL_TREE
,
6956 xref_tag (RECORD_TYPE
,
6957 get_identifier (TAG_SELECTOR
)));
6958 push_parm_decl (build_tree_list
6959 (build_tree_list (decl_specs
,
6960 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6961 build_tree_list (unused_list
, NULL_TREE
)));
6962 #endif /* not OBJC_INT_SELECTORS */
6964 /* Generate argument declarations if a keyword_decl. */
6965 if (METHOD_SEL_ARGS (method
))
6967 tree arglist
= METHOD_SEL_ARGS (method
);
6970 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6971 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6975 tree last_expr
= expr_last (arg_decl
);
6977 /* Unite the abstract decl with its name. */
6978 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6979 push_parm_decl (build_tree_list
6980 (build_tree_list (arg_spec
, arg_decl
),
6981 build_tree_list (NULL_TREE
, NULL_TREE
)));
6983 /* Unhook: restore the abstract declarator. */
6984 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6988 push_parm_decl (build_tree_list
6989 (build_tree_list (arg_spec
,
6990 KEYWORD_ARG_NAME (arglist
)),
6991 build_tree_list (NULL_TREE
, NULL_TREE
)));
6993 arglist
= TREE_CHAIN (arglist
);
6998 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6999 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7001 /* We have a variable length selector - in "prototype" format. */
7002 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7005 /* This must be done prior to calling pushdecl. pushdecl is
7006 going to change our chain on us. */
7007 tree nextkey
= TREE_CHAIN (akey
);
7015 warn_with_method (message
, mtype
, method
)
7016 const char *message
;
7020 if (count_error (1) == 0)
7023 report_error_function (DECL_SOURCE_FILE (method
));
7025 fprintf (stderr
, "%s:%d: warning: ",
7026 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7027 memset (errbuf
, 0, BUFSIZE
);
7028 fprintf (stderr
, "%s `%c%s'\n",
7029 message
, mtype
, gen_method_decl (method
, errbuf
));
7032 /* Return 1 if METHOD is consistent with PROTO. */
7035 comp_method_with_proto (method
, proto
)
7038 static tree function_type
= 0;
7040 /* Create a function_type node once. */
7043 function_type
= make_node (FUNCTION_TYPE
);
7044 ggc_add_tree_root (&function_type
, 1);
7047 /* Install argument types - normally set by build_function_type. */
7048 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7050 /* install return type */
7051 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7053 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7056 /* Return 1 if PROTO1 is consistent with PROTO2. */
7059 comp_proto_with_proto (proto0
, proto1
)
7060 tree proto0
, proto1
;
7062 static tree function_type
[2];
7064 /* Create a couple function_type node's once. */
7065 if (!function_type
[0])
7067 function_type
[0] = make_node (FUNCTION_TYPE
);
7068 function_type
[1] = make_node (FUNCTION_TYPE
);
7069 ggc_add_tree_root (function_type
, 2);
7072 /* Install argument types; normally set by build_function_type. */
7073 TYPE_ARG_TYPES (function_type
[0]) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7074 TYPE_ARG_TYPES (function_type
[1]) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7076 /* Install return type. */
7077 TREE_TYPE (function_type
[0]) = groktypename (TREE_TYPE (proto0
));
7078 TREE_TYPE (function_type
[1]) = groktypename (TREE_TYPE (proto1
));
7080 return comptypes (function_type
[0], function_type
[1]);
7083 /* - Generate an identifier for the function. the format is "_n_cls",
7084 where 1 <= n <= nMethods, and cls is the name the implementation we
7086 - Install the return type from the method declaration.
7087 - If we have a prototype, check for type consistency. */
7090 really_start_method (method
, parmlist
)
7091 tree method
, parmlist
;
7093 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7094 tree method_decl
, method_id
;
7095 const char *sel_name
, *class_name
, *cat_name
;
7098 /* Synth the storage class & assemble the return type. */
7099 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7100 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7101 decl_specs
= chainon (sc_spec
, ret_spec
);
7103 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7104 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7105 cat_name
= ((TREE_CODE (implementation_context
)
7106 == CLASS_IMPLEMENTATION_TYPE
)
7108 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7111 /* Make sure this is big enough for any plausible method label. */
7112 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7113 + (cat_name
? strlen (cat_name
) : 0));
7115 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7116 class_name
, cat_name
, sel_name
, method_slot
);
7118 method_id
= get_identifier (buf
);
7120 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7122 /* Check the declarator portion of the return type for the method. */
7123 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7125 /* Unite the complex decl (specified in the abstract decl) with the
7126 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7127 tree save_expr
= expr_last (ret_decl
);
7129 TREE_OPERAND (save_expr
, 0) = method_decl
;
7130 method_decl
= ret_decl
;
7132 /* Fool the parser into thinking it is starting a function. */
7133 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7135 /* Unhook: this has the effect of restoring the abstract declarator. */
7136 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7141 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7143 /* Fool the parser into thinking it is starting a function. */
7144 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7146 /* Unhook: this has the effect of restoring the abstract declarator. */
7147 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7150 METHOD_DEFINITION (method
) = current_function_decl
;
7152 if (implementation_template
!= implementation_context
)
7156 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7157 proto
= lookup_instance_method_static (implementation_template
,
7158 METHOD_SEL_NAME (method
));
7160 proto
= lookup_class_method_static (implementation_template
,
7161 METHOD_SEL_NAME (method
));
7163 if (proto
&& ! comp_method_with_proto (method
, proto
))
7165 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7167 warn_with_method ("conflicting types for", type
, method
);
7168 warn_with_method ("previous declaration of", type
, proto
);
7173 /* The following routine is always called...this "architecture" is to
7174 accommodate "old-style" variable length selectors.
7176 - a:a b:b // prototype ; id c; id d; // old-style. */
7179 continue_method_def ()
7183 if (METHOD_ADD_ARGS (method_context
) == objc_ellipsis_node
)
7184 /* We have a `, ...' immediately following the selector. */
7185 parmlist
= get_parm_info (0);
7187 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7189 /* Set self_decl from the first argument...this global is used by
7190 build_ivar_reference calling build_indirect_ref. */
7191 self_decl
= TREE_PURPOSE (parmlist
);
7194 really_start_method (method_context
, parmlist
);
7195 store_parm_decls ();
7198 /* Called by the parser, from the `pushlevel' production. */
7203 if (!UOBJC_SUPER_decl
)
7205 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7206 build_tree_list (NULL_TREE
,
7207 objc_super_template
),
7208 0, NULL_TREE
, NULL_TREE
);
7210 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7212 /* This prevents `unused variable' warnings when compiling with -Wall. */
7213 TREE_USED (UOBJC_SUPER_decl
) = 1;
7214 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7218 /* _n_Method (id self, SEL sel, ...)
7220 struct objc_super _S;
7221 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7225 get_super_receiver ()
7229 tree super_expr
, super_expr_list
;
7231 /* Set receiver to self. */
7232 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7233 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7234 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7236 /* Set class to begin searching. */
7237 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7238 get_identifier ("class"));
7240 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7242 /* [_cls, __cls]Super are "pre-built" in
7243 synth_forward_declarations. */
7245 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7246 ((TREE_CODE (method_context
)
7247 == INSTANCE_METHOD_DECL
)
7249 : uucls_super_ref
));
7253 /* We have a category. */
7255 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7260 error ("no super class declared in interface for `%s'",
7261 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7262 return error_mark_node
;
7265 if (flag_next_runtime
)
7267 super_class
= get_class_reference (super_name
);
7268 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7270 = build_component_ref (build_indirect_ref (super_class
, "->"),
7271 get_identifier ("isa"));
7275 add_class_reference (super_name
);
7276 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7277 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7278 assemble_external (super_class
);
7280 = build_function_call
7284 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7285 IDENTIFIER_POINTER (super_name
))));
7288 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7289 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7292 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7294 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7295 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7297 return build_compound_expr (super_expr_list
);
7301 error ("[super ...] must appear in a method context");
7302 return error_mark_node
;
7307 encode_method_def (func_decl
)
7312 HOST_WIDE_INT max_parm_end
= 0;
7317 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7318 obstack_object_size (&util_obstack
),
7319 OBJC_ENCODE_INLINE_DEFS
);
7322 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7323 parms
= TREE_CHAIN (parms
))
7325 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7326 + int_size_in_bytes (TREE_TYPE (parms
)));
7328 if (! offset_is_register
&& parm_end
> max_parm_end
)
7329 max_parm_end
= parm_end
;
7332 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7334 sprintf (buffer
, "%d", stack_size
);
7335 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7337 /* Argument types. */
7338 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7339 parms
= TREE_CHAIN (parms
))
7342 encode_type (TREE_TYPE (parms
),
7343 obstack_object_size (&util_obstack
),
7344 OBJC_ENCODE_INLINE_DEFS
);
7346 /* Compute offset. */
7347 sprintf (buffer
, "%d", forwarding_offset (parms
));
7349 /* Indicate register. */
7350 if (offset_is_register
)
7351 obstack_1grow (&util_obstack
, '+');
7353 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7356 obstack_1grow (&util_obstack
, 0);
7357 result
= get_identifier (obstack_finish (&util_obstack
));
7358 obstack_free (&util_obstack
, util_firstobj
);
7363 objc_expand_function_end ()
7365 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7369 finish_method_def ()
7371 lang_expand_function_end
= objc_expand_function_end
;
7372 finish_function (0);
7373 lang_expand_function_end
= NULL
;
7375 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7376 since the optimizer may find "may be used before set" errors. */
7377 method_context
= NULL_TREE
;
7382 lang_report_error_function (decl
)
7387 fprintf (stderr
, "In method `%s'\n",
7388 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7398 is_complex_decl (type
)
7401 return (TREE_CODE (type
) == ARRAY_TYPE
7402 || TREE_CODE (type
) == FUNCTION_TYPE
7403 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7407 /* Code to convert a decl node into text for a declaration in C. */
7409 static char tmpbuf
[256];
7412 adorn_decl (decl
, str
)
7416 enum tree_code code
= TREE_CODE (decl
);
7418 if (code
== ARRAY_REF
)
7420 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7422 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7423 sprintf (str
+ strlen (str
), "[%ld]",
7424 (long) TREE_INT_CST_LOW (an_int_cst
));
7429 else if (code
== ARRAY_TYPE
)
7431 tree an_int_cst
= TYPE_SIZE (decl
);
7432 tree array_of
= TREE_TYPE (decl
);
7434 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7435 sprintf (str
+ strlen (str
), "[%ld]",
7436 (long) (TREE_INT_CST_LOW (an_int_cst
)
7437 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7442 else if (code
== CALL_EXPR
)
7444 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7449 gen_declaration (chain
, str
);
7450 chain
= TREE_CHAIN (chain
);
7457 else if (code
== FUNCTION_TYPE
)
7459 tree chain
= TYPE_ARG_TYPES (decl
);
7462 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7464 gen_declaration (TREE_VALUE (chain
), str
);
7465 chain
= TREE_CHAIN (chain
);
7466 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7472 else if (code
== INDIRECT_REF
)
7474 strcpy (tmpbuf
, "*");
7475 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7479 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7481 chain
= TREE_CHAIN (chain
))
7483 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7485 strcat (tmpbuf
, " ");
7486 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7490 strcat (tmpbuf
, " ");
7492 strcat (tmpbuf
, str
);
7493 strcpy (str
, tmpbuf
);
7496 else if (code
== POINTER_TYPE
)
7498 strcpy (tmpbuf
, "*");
7499 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7501 if (TREE_READONLY (decl
))
7502 strcat (tmpbuf
, " const");
7503 if (TYPE_VOLATILE (decl
))
7504 strcat (tmpbuf
, " volatile");
7506 strcat (tmpbuf
, " ");
7508 strcat (tmpbuf
, str
);
7509 strcpy (str
, tmpbuf
);
7514 gen_declarator (decl
, buf
, name
)
7521 enum tree_code code
= TREE_CODE (decl
);
7531 op
= TREE_OPERAND (decl
, 0);
7533 /* We have a pointer to a function or array...(*)(), (*)[] */
7534 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7535 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7538 str
= gen_declarator (op
, buf
, name
);
7542 strcpy (tmpbuf
, "(");
7543 strcat (tmpbuf
, str
);
7544 strcat (tmpbuf
, ")");
7545 strcpy (str
, tmpbuf
);
7548 adorn_decl (decl
, str
);
7557 /* This clause is done iteratively rather than recursively. */
7560 op
= (is_complex_decl (TREE_TYPE (decl
))
7561 ? TREE_TYPE (decl
) : NULL_TREE
);
7563 adorn_decl (decl
, str
);
7565 /* We have a pointer to a function or array...(*)(), (*)[] */
7566 if (code
== POINTER_TYPE
7567 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7568 || TREE_CODE (op
) == ARRAY_TYPE
))
7570 strcpy (tmpbuf
, "(");
7571 strcat (tmpbuf
, str
);
7572 strcat (tmpbuf
, ")");
7573 strcpy (str
, tmpbuf
);
7576 decl
= (is_complex_decl (TREE_TYPE (decl
))
7577 ? TREE_TYPE (decl
) : NULL_TREE
);
7580 while (decl
&& (code
= TREE_CODE (decl
)))
7585 case IDENTIFIER_NODE
:
7586 /* Will only happen if we are processing a "raw" expr-decl. */
7587 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7598 /* We have an abstract declarator or a _DECL node. */
7606 gen_declspecs (declspecs
, buf
, raw
)
7615 for (chain
= nreverse (copy_list (declspecs
));
7616 chain
; chain
= TREE_CHAIN (chain
))
7618 tree aspec
= TREE_VALUE (chain
);
7620 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7621 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7622 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7624 if (TYPE_NAME (aspec
))
7626 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7628 if (! TREE_STATIC_TEMPLATE (aspec
))
7629 strcat (buf
, "struct ");
7630 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7635 tree chain
= protocol_list
;
7642 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7643 chain
= TREE_CHAIN (chain
);
7652 strcat (buf
, "untagged struct");
7655 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7657 if (TYPE_NAME (aspec
))
7659 if (! TREE_STATIC_TEMPLATE (aspec
))
7660 strcat (buf
, "union ");
7661 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7664 strcat (buf
, "untagged union");
7667 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7669 if (TYPE_NAME (aspec
))
7671 if (! TREE_STATIC_TEMPLATE (aspec
))
7672 strcat (buf
, "enum ");
7673 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7676 strcat (buf
, "untagged enum");
7679 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7680 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7682 else if (IS_ID (aspec
))
7684 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7689 tree chain
= protocol_list
;
7696 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7697 chain
= TREE_CHAIN (chain
);
7704 if (TREE_CHAIN (chain
))
7710 /* Type qualifiers. */
7711 if (TREE_READONLY (declspecs
))
7712 strcat (buf
, "const ");
7713 if (TYPE_VOLATILE (declspecs
))
7714 strcat (buf
, "volatile ");
7716 switch (TREE_CODE (declspecs
))
7718 /* Type specifiers. */
7721 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7723 /* Signed integer types. */
7725 if (declspecs
== short_integer_type_node
)
7726 strcat (buf
, "short int ");
7727 else if (declspecs
== integer_type_node
)
7728 strcat (buf
, "int ");
7729 else if (declspecs
== long_integer_type_node
)
7730 strcat (buf
, "long int ");
7731 else if (declspecs
== long_long_integer_type_node
)
7732 strcat (buf
, "long long int ");
7733 else if (declspecs
== signed_char_type_node
7734 || declspecs
== char_type_node
)
7735 strcat (buf
, "char ");
7737 /* Unsigned integer types. */
7739 else if (declspecs
== short_unsigned_type_node
)
7740 strcat (buf
, "unsigned short ");
7741 else if (declspecs
== unsigned_type_node
)
7742 strcat (buf
, "unsigned int ");
7743 else if (declspecs
== long_unsigned_type_node
)
7744 strcat (buf
, "unsigned long ");
7745 else if (declspecs
== long_long_unsigned_type_node
)
7746 strcat (buf
, "unsigned long long ");
7747 else if (declspecs
== unsigned_char_type_node
)
7748 strcat (buf
, "unsigned char ");
7752 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7754 if (declspecs
== float_type_node
)
7755 strcat (buf
, "float ");
7756 else if (declspecs
== double_type_node
)
7757 strcat (buf
, "double ");
7758 else if (declspecs
== long_double_type_node
)
7759 strcat (buf
, "long double ");
7763 if (TYPE_NAME (declspecs
)
7764 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7766 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7768 if (! TREE_STATIC_TEMPLATE (declspecs
))
7769 strcat (buf
, "struct ");
7770 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7774 tree chain
= protocol_list
;
7781 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7782 chain
= TREE_CHAIN (chain
);
7791 strcat (buf
, "untagged struct");
7797 if (TYPE_NAME (declspecs
)
7798 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7800 strcat (buf
, "union ");
7801 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7806 strcat (buf
, "untagged union ");
7810 if (TYPE_NAME (declspecs
)
7811 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7813 strcat (buf
, "enum ");
7814 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7819 strcat (buf
, "untagged enum ");
7823 strcat (buf
, "void ");
7828 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7833 tree chain
= protocol_list
;
7840 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7841 chain
= TREE_CHAIN (chain
);
7858 gen_declaration (atype_or_adecl
, buf
)
7859 tree atype_or_adecl
;
7864 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7866 tree declspecs
; /* "identifier_node", "record_type" */
7867 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7869 /* We have a "raw", abstract declarator (typename). */
7870 declarator
= TREE_VALUE (atype_or_adecl
);
7871 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7873 gen_declspecs (declspecs
, buf
, 1);
7877 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7884 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7885 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7887 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7888 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7889 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7890 atype
= TREE_TYPE (atype_or_adecl
);
7892 /* Assume we have a *_type node. */
7893 atype
= atype_or_adecl
;
7895 if (is_complex_decl (atype
))
7899 /* Get the declaration specifier; it is at the end of the list. */
7900 declarator
= chain
= atype
;
7902 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7903 while (is_complex_decl (chain
));
7910 declarator
= NULL_TREE
;
7913 gen_declspecs (declspecs
, buf
, 0);
7915 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7916 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7917 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7919 const char *decl_name
=
7920 (DECL_NAME (atype_or_adecl
)
7921 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7926 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7929 else if (decl_name
[0])
7932 strcat (buf
, decl_name
);
7935 else if (declarator
)
7938 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7945 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7948 gen_method_decl (method
, buf
)
7954 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7957 gen_declaration (TREE_TYPE (method
), buf
);
7961 chain
= METHOD_SEL_ARGS (method
);
7964 /* We have a chain of keyword_decls. */
7967 if (KEYWORD_KEY_NAME (chain
))
7968 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7971 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7974 gen_declaration (TREE_TYPE (chain
), buf
);
7978 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7979 if ((chain
= TREE_CHAIN (chain
)))
7984 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7985 strcat (buf
, ", ...");
7986 else if (METHOD_ADD_ARGS (method
))
7988 /* We have a tree list node as generate by get_parm_info. */
7989 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7991 /* Know we have a chain of parm_decls. */
7995 gen_declaration (chain
, buf
);
7996 chain
= TREE_CHAIN (chain
);
8002 /* We have a unary selector. */
8003 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8011 dump_interface (fp
, chain
)
8015 char *buf
= (char *)xmalloc (256);
8016 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8017 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8018 tree nst_methods
= CLASS_NST_METHODS (chain
);
8019 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8021 fprintf (fp
, "\n@interface %s", my_name
);
8023 if (CLASS_SUPER_NAME (chain
))
8025 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8026 fprintf (fp
, " : %s\n", super_name
);
8033 fprintf (fp
, "{\n");
8036 memset (buf
, 0, 256);
8037 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8038 ivar_decls
= TREE_CHAIN (ivar_decls
);
8041 fprintf (fp
, "}\n");
8046 memset (buf
, 0, 256);
8047 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8048 nst_methods
= TREE_CHAIN (nst_methods
);
8053 memset (buf
, 0, 256);
8054 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8055 cls_methods
= TREE_CHAIN (cls_methods
);
8057 fprintf (fp
, "\n@end");
8060 /* Demangle function for Objective-C */
8062 objc_demangle (mangled
)
8063 const char *mangled
;
8065 char *demangled
, *cp
;
8067 if (mangled
[0] == '_' &&
8068 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8071 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8072 if (mangled
[1] == 'i')
8073 *cp
++ = '-'; /* for instance method */
8075 *cp
++ = '+'; /* for class method */
8076 *cp
++ = '['; /* opening left brace */
8077 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8078 while (*cp
&& *cp
== '_')
8079 cp
++; /* skip any initial underbars in class name */
8080 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8083 free(demangled
); /* not mangled name */
8086 if (cp
[1] == '_') /* easy case: no category name */
8088 *cp
++ = ' '; /* replace two '_' with one ' ' */
8089 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8093 *cp
++ = '('; /* less easy case: category name */
8094 cp
= strchr(cp
, '_');
8097 free(demangled
); /* not mangled name */
8101 *cp
++ = ' '; /* overwriting 1st char of method name... */
8102 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8104 while (*cp
&& *cp
== '_')
8105 cp
++; /* skip any initial underbars in method name */
8108 *cp
= ':'; /* replace remaining '_' with ':' */
8109 *cp
++ = ']'; /* closing right brace */
8110 *cp
++ = 0; /* string terminator */
8114 return mangled
; /* not an objc mangled name */
8118 objc_printable_name (decl
, kind
)
8120 int kind ATTRIBUTE_UNUSED
;
8122 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8128 /* Add the special tree codes of Objective C to the tables. */
8130 #define LAST_CODE LAST_C_TREE_CODE
8132 gcc_obstack_init (&util_obstack
);
8133 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8135 memcpy (tree_code_type
+ (int) LAST_CODE
,
8136 objc_tree_code_type
,
8137 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8138 memcpy (tree_code_length
+ (int) LAST_CODE
,
8139 objc_tree_code_length
,
8140 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8141 memcpy (tree_code_name
+ (int) LAST_CODE
,
8142 objc_tree_code_name
,
8143 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8145 errbuf
= (char *)xmalloc (BUFSIZE
);
8147 synth_module_prologue ();
8149 /* Change the default error function */
8150 decl_printable_name
= objc_printable_name
;
8151 lang_expand_expr
= c_expand_expr
;
8152 lang_expand_decl_stmt
= c_expand_decl_stmt
;
8158 struct imp_entry
*impent
;
8160 /* The internally generated initializers appear to have missing braces.
8161 Don't warn about this. */
8162 int save_warn_missing_braces
= warn_missing_braces
;
8163 warn_missing_braces
= 0;
8165 generate_forward_declaration_to_string_table ();
8167 #ifdef OBJC_PROLOGUE
8171 /* Process the static instances here because initialization of objc_symtab
8173 if (objc_static_instances
)
8174 generate_static_references ();
8176 if (implementation_context
|| class_names_chain
8177 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8178 generate_objc_symtab_decl ();
8180 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8182 implementation_context
= impent
->imp_context
;
8183 implementation_template
= impent
->imp_template
;
8185 UOBJC_CLASS_decl
= impent
->class_decl
;
8186 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8188 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8190 /* all of the following reference the string pool... */
8191 generate_ivar_lists ();
8192 generate_dispatch_tables ();
8193 generate_shared_structures ();
8197 generate_dispatch_tables ();
8198 generate_category (implementation_context
);
8202 /* If we are using an array of selectors, we must always
8203 finish up the array decl even if no selectors were used. */
8204 if (! flag_next_runtime
|| sel_ref_chain
)
8205 build_selector_translation_table ();
8208 generate_protocols ();
8210 if (implementation_context
|| class_names_chain
|| objc_static_instances
8211 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8213 /* Arrange for Objc data structures to be initialized at run time. */
8214 const char *init_name
= build_module_descriptor ();
8216 assemble_constructor (init_name
);
8219 /* Dump the class references. This forces the appropriate classes
8220 to be linked into the executable image, preserving unix archive
8221 semantics. This can be removed when we move to a more dynamically
8222 linked environment. */
8224 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8226 handle_class_ref (chain
);
8227 if (TREE_PURPOSE (chain
))
8228 generate_classref_translation_entry (chain
);
8231 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8232 handle_impent (impent
);
8234 /* Dump the string table last. */
8236 generate_strings ();
8238 if (flag_gen_declaration
)
8240 add_class (implementation_context
);
8241 dump_interface (gen_declaration_file
, implementation_context
);
8249 /* Run through the selector hash tables and print a warning for any
8250 selector which has multiple methods. */
8252 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8253 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8256 tree meth
= hsh
->key
;
8257 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8261 warning ("potential selector conflict for method `%s'",
8262 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8263 warn_with_method ("found", type
, meth
);
8264 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8265 warn_with_method ("found", type
, loop
->value
);
8268 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8269 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8272 tree meth
= hsh
->key
;
8273 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8277 warning ("potential selector conflict for method `%s'",
8278 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8279 warn_with_method ("found", type
, meth
);
8280 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8281 warn_with_method ("found", type
, loop
->value
);
8285 warn_missing_braces
= save_warn_missing_braces
;
8288 /* Subroutines of finish_objc. */
8291 generate_classref_translation_entry (chain
)
8294 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8297 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8299 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8300 expr
= build_c_cast (type
, expr
); /* cast! */
8302 name
= DECL_NAME (TREE_PURPOSE (chain
));
8304 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8306 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8307 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8309 /* The decl that is returned from start_decl is the one that we
8310 forward declared in build_class_reference. */
8311 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8312 finish_decl (decl
, expr
, NULL_TREE
);
8317 handle_class_ref (chain
)
8320 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8321 if (! flag_next_runtime
)
8324 char *string
= (char *) alloca (strlen (name
) + 30);
8327 sprintf (string
, "%sobjc_class_name_%s",
8328 (flag_next_runtime
? "." : "__"), name
);
8330 /* Make a decl for this name, so we can use its address in a tree. */
8331 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8332 DECL_EXTERNAL (decl
) = 1;
8333 TREE_PUBLIC (decl
) = 1;
8336 rest_of_decl_compilation (decl
, 0, 0, 0);
8338 /* Make following constant read-only (why not)? */
8339 readonly_data_section ();
8341 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8343 /* Align the section properly. */
8344 assemble_constant_align (exp
);
8346 /* Inform the assembler about this new external thing. */
8347 assemble_external (decl
);
8349 /* Output a constant to reference this address. */
8350 output_constant (exp
, int_size_in_bytes (string_type_node
));
8354 /* This overreliance on our assembler (i.e. lack of portability)
8355 should be dealt with at some point. The GNU strategy (above)
8356 won't work either, but it is a start. */
8357 char *string
= (char *) alloca (strlen (name
) + 30);
8358 sprintf (string
, ".reference .objc_class_name_%s", name
);
8359 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8364 handle_impent (impent
)
8365 struct imp_entry
*impent
;
8367 implementation_context
= impent
->imp_context
;
8368 implementation_template
= impent
->imp_template
;
8370 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8372 const char *class_name
=
8373 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8374 char *string
= (char *) alloca (strlen (class_name
) + 30);
8376 if (flag_next_runtime
)
8378 /* Grossly unportable.
8379 People should know better than to assume
8380 such things about assembler syntax! */
8381 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8382 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8384 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8385 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8390 sprintf (string
, "%sobjc_class_name_%s",
8391 (flag_next_runtime
? "." : "__"), class_name
);
8392 assemble_global (string
);
8393 assemble_label (string
);
8397 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8399 const char *class_name
=
8400 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8401 const char *class_super_name
=
8402 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8403 char *string
= (char *) alloca (strlen (class_name
)
8404 + strlen (class_super_name
) + 30);
8406 /* Do the same for categories. Even though no references to these
8407 symbols are generated automatically by the compiler, it gives
8408 you a handle to pull them into an archive by hand. */
8409 if (flag_next_runtime
)
8411 /* Grossly unportable. */
8412 sprintf (string
, ".objc_category_name_%s_%s=0",
8413 class_name
, class_super_name
);
8414 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8416 sprintf (string
, ".globl .objc_category_name_%s_%s",
8417 class_name
, class_super_name
);
8418 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8423 sprintf (string
, "%sobjc_category_name_%s_%s",
8424 (flag_next_runtime
? "." : "__"),
8425 class_name
, class_super_name
);
8426 assemble_global (string
);
8427 assemble_label (string
);
8438 char *buf
= (char *)xmalloc (256);
8440 { /* dump function prototypes */
8441 tree loop
= UOBJC_MODULES_decl
;
8443 fprintf (fp
, "\n\nfunction prototypes:\n");
8446 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8448 /* We have a function definition: generate prototype. */
8449 memset (errbuf
, 0, BUFSIZE
);
8450 gen_declaration (loop
, errbuf
);
8451 fprintf (fp
, "%s;\n", errbuf
);
8453 loop
= TREE_CHAIN (loop
);
8457 /* Dump global chains. */
8459 int i
, index
= 0, offset
= 0;
8462 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8464 if (hashlist
= nst_method_hash_list
[i
])
8466 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8469 memset (buf
, 0, 256);
8470 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8471 hashlist
= hashlist
->next
;
8477 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8479 if (hashlist
= cls_method_hash_list
[i
])
8481 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8484 memset (buf
, 0, 256);
8485 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8486 hashlist
= hashlist
->next
;
8492 fprintf (fp
, "\nsel_refdef_chain:\n");
8493 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8495 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8496 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8498 /* add one for the '\0' character */
8499 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8502 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8508 print_lang_statistics ()
8513 ggc_mark_imp_list (arg
)
8516 struct imp_entry
*impent
;
8518 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8520 ggc_mark_tree (impent
->imp_context
);
8521 ggc_mark_tree (impent
->imp_template
);
8522 ggc_mark_tree (impent
->class_decl
);
8523 ggc_mark_tree (impent
->meta_decl
);
8528 ggc_mark_hash_table (arg
)
8531 hash
*hash_table
= *(hash
**)arg
;
8536 if (hash_table
== NULL
)
8538 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8539 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8541 ggc_mark_tree (hst
->key
);
8542 for (list
= hst
->list
; list
; list
= list
->next
)
8543 ggc_mark_tree (list
->value
);
8547 /* Add GC roots for variables local to this file. */
8549 objc_act_parse_init ()
8551 ggc_add_tree_root (&objc_ellipsis_node
, 1);
8552 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8553 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8554 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8555 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8558 /* Look up ID as an instance variable. */
8560 lookup_objc_ivar (id
)
8565 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8566 /* we have a message to super */
8567 return get_super_receiver ();
8568 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8570 if (is_private (decl
))
8571 return error_mark_node
;
8573 return build_ivar_reference (id
);
8579 /* Parser callbacks. */
8581 forget_protocol_qualifiers ()
8583 C_IS_RESERVED_WORD (ridpointers
[(int) RID_IN
]) = 0;
8584 C_IS_RESERVED_WORD (ridpointers
[(int) RID_OUT
]) = 0;
8585 C_IS_RESERVED_WORD (ridpointers
[(int) RID_INOUT
]) = 0;
8586 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYCOPY
]) = 0;
8587 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYREF
]) = 0;
8588 C_IS_RESERVED_WORD (ridpointers
[(int) RID_ONEWAY
]) = 0;
8592 remember_protocol_qualifiers ()
8594 C_IS_RESERVED_WORD (ridpointers
[(int) RID_IN
]) = 1;
8595 C_IS_RESERVED_WORD (ridpointers
[(int) RID_OUT
]) = 1;
8596 C_IS_RESERVED_WORD (ridpointers
[(int) RID_INOUT
]) = 1;
8597 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYCOPY
]) = 1;
8598 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYREF
]) = 1;
8599 C_IS_RESERVED_WORD (ridpointers
[(int) RID_ONEWAY
]) = 1;