1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
40 - OBJC_INT_SELECTORS */
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
87 /* Define the special tree codes that we use. */
89 /* Table indexed by tree code giving a string containing a character
90 classifying the tree code. Possibilities are
91 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
95 static const char objc_tree_code_type
[] = {
97 #include "objc-tree.def"
101 /* Table indexed by tree code giving number of expression
102 operands beyond the fixed part of the node structure.
103 Not used for types or decls. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
107 static const int objc_tree_code_length
[] = {
109 #include "objc-tree.def"
113 /* Names of tree components.
114 Used for printing out the tree and error messages. */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
117 static const char * const objc_tree_code_name
[] = {
119 #include "objc-tree.def"
123 /* Set up for use of obstacks. */
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
130 /* This obstack is used to accumulate the encoding of a data type. */
131 static struct obstack util_obstack
;
132 /* This points to the beginning of obstack contents,
133 so we can free the whole contents. */
136 /* for encode_method_def */
139 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
140 #define PROTOCOL_VERSION 2
142 #define OBJC_ENCODE_INLINE_DEFS 0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
145 /*** Private Interface (procedures) ***/
147 /* Used by compile_file. */
149 static void init_objc
PARAMS ((void));
150 static void finish_objc
PARAMS ((void));
152 /* Code generation. */
154 static void synth_module_prologue
PARAMS ((void));
155 static tree build_constructor
PARAMS ((tree
, tree
));
156 static const char *build_module_descriptor
PARAMS ((void));
157 static tree init_module_descriptor
PARAMS ((tree
));
158 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
160 static void generate_strings
PARAMS ((void));
161 static tree get_proto_encoding
PARAMS ((tree
));
162 static void build_selector_translation_table
PARAMS ((void));
163 static tree build_ivar_chain
PARAMS ((tree
, int));
165 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
167 static tree build_ivar_template
PARAMS ((void));
168 static tree build_method_template
PARAMS ((void));
169 static tree build_private_template
PARAMS ((tree
));
170 static void build_class_template
PARAMS ((void));
171 static void build_selector_template
PARAMS ((void));
172 static void build_category_template
PARAMS ((void));
173 static tree build_super_template
PARAMS ((void));
174 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
176 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
179 static void synth_forward_declarations
PARAMS ((void));
180 static void generate_ivar_lists
PARAMS ((void));
181 static void generate_dispatch_tables
PARAMS ((void));
182 static void generate_shared_structures
PARAMS ((void));
183 static tree generate_protocol_list
PARAMS ((tree
));
184 static void generate_forward_declaration_to_string_table
PARAMS ((void));
185 static void build_protocol_reference
PARAMS ((tree
));
188 static tree init_selector
PARAMS ((int));
190 static tree build_keyword_selector
PARAMS ((tree
));
191 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
193 static void generate_static_references
PARAMS ((void));
194 static int check_methods_accessible
PARAMS ((tree
, tree
,
196 static void encode_aggregate_within
PARAMS ((tree
, int, int,
198 static const char *objc_demangle
PARAMS ((const char *));
199 static const char *objc_printable_name
PARAMS ((tree
, int));
200 static void objc_expand_function_end
PARAMS ((void));
202 /* Misc. bookkeeping */
204 typedef struct hashed_entry
*hash
;
205 typedef struct hashed_attribute
*attr
;
207 struct hashed_attribute
219 static void hash_init
PARAMS ((void));
220 static void hash_enter
PARAMS ((hash
*, tree
));
221 static hash hash_lookup
PARAMS ((hash
*, tree
));
222 static void hash_add_attr
PARAMS ((hash
, tree
));
223 static tree lookup_method
PARAMS ((tree
, tree
));
224 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
225 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
226 static tree add_class
PARAMS ((tree
));
227 static void add_category
PARAMS ((tree
, tree
));
231 class_names
, /* class, category, protocol, module names */
232 meth_var_names
, /* method and variable names */
233 meth_var_types
/* method and variable type descriptors */
236 static tree add_objc_string
PARAMS ((tree
,
237 enum string_section
));
238 static tree get_objc_string_decl
PARAMS ((tree
,
239 enum string_section
));
240 static tree build_objc_string_decl
PARAMS ((enum string_section
));
241 static tree build_selector_reference_decl
PARAMS ((void));
243 /* Protocol additions. */
245 static tree add_protocol
PARAMS ((tree
));
246 static tree lookup_protocol
PARAMS ((tree
));
247 static tree lookup_and_install_protocols
PARAMS ((tree
));
251 static void encode_type_qualifiers
PARAMS ((tree
));
252 static void encode_pointer
PARAMS ((tree
, int, int));
253 static void encode_array
PARAMS ((tree
, int, int));
254 static void encode_aggregate
PARAMS ((tree
, int, int));
255 static void encode_bitfield
PARAMS ((int));
256 static void encode_type
PARAMS ((tree
, int, int));
257 static void encode_field_decl
PARAMS ((tree
, int, int));
259 static void really_start_method
PARAMS ((tree
, tree
));
260 static int comp_method_with_proto
PARAMS ((tree
, tree
));
261 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
262 static tree get_arg_type_list
PARAMS ((tree
, int, int));
263 static tree expr_last
PARAMS ((tree
));
265 /* Utilities for debugging and error diagnostics. */
267 static void warn_with_method
PARAMS ((const char *, int, tree
));
268 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
269 static char *gen_method_decl
PARAMS ((tree
, char *));
270 static char *gen_declaration
PARAMS ((tree
, char *));
271 static char *gen_declarator
PARAMS ((tree
, char *,
273 static int is_complex_decl
PARAMS ((tree
));
274 static void adorn_decl
PARAMS ((tree
, char *));
275 static void dump_interface
PARAMS ((FILE *, tree
));
277 /* Everything else. */
279 static void objc_fatal
PARAMS ((void))
281 static tree define_decl
PARAMS ((tree
, tree
));
282 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
283 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
284 static tree create_builtin_decl
PARAMS ((enum tree_code
,
285 tree
, const char *));
286 static tree my_build_string
PARAMS ((int, const char *));
287 static void build_objc_symtab_template
PARAMS ((void));
288 static tree init_def_list
PARAMS ((tree
));
289 static tree init_objc_symtab
PARAMS ((tree
));
290 static void forward_declare_categories
PARAMS ((void));
291 static void generate_objc_symtab_decl
PARAMS ((void));
292 static tree build_selector
PARAMS ((tree
));
294 static tree build_msg_pool_reference
PARAMS ((int));
296 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
297 static tree build_selector_reference
PARAMS ((tree
));
298 static tree build_class_reference_decl
PARAMS ((void));
299 static void add_class_reference
PARAMS ((tree
));
300 static tree objc_copy_list
PARAMS ((tree
, tree
*));
301 static tree build_protocol_template
PARAMS ((void));
302 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
303 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
304 static tree build_method_prototype_template
PARAMS ((void));
305 static int forwarding_offset
PARAMS ((tree
));
306 static tree encode_method_prototype
PARAMS ((tree
, tree
));
307 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
309 static void generate_method_descriptors
PARAMS ((tree
));
310 static tree build_tmp_function_decl
PARAMS ((void));
311 static void hack_method_prototype
PARAMS ((tree
, tree
));
312 static void generate_protocol_references
PARAMS ((tree
));
313 static void generate_protocols
PARAMS ((void));
314 static void check_ivars
PARAMS ((tree
, tree
));
315 static tree build_ivar_list_template
PARAMS ((tree
, int));
316 static tree build_method_list_template
PARAMS ((tree
, int));
317 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
318 static tree generate_ivars_list
PARAMS ((tree
, const char *,
320 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
321 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
323 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
324 tree
, int, tree
, tree
,
326 static void generate_category
PARAMS ((tree
));
327 static int is_objc_type_qualifier
PARAMS ((tree
));
328 static tree adjust_type_for_id_default
PARAMS ((tree
));
329 static tree check_duplicates
PARAMS ((hash
));
330 static tree receiver_is_class_object
PARAMS ((tree
));
331 static int check_methods
PARAMS ((tree
, tree
, int));
332 static int conforms_to_protocol
PARAMS ((tree
, tree
));
333 static void check_protocols
PARAMS ((tree
, const char *,
335 static tree encode_method_def
PARAMS ((tree
));
336 static void gen_declspecs
PARAMS ((tree
, char *, int));
337 static void generate_classref_translation_entry
PARAMS ((tree
));
338 static void handle_class_ref
PARAMS ((tree
));
339 static void generate_struct_by_value_array
PARAMS ((void))
341 static void objc_act_parse_init
PARAMS ((void));
342 static void ggc_mark_imp_list
PARAMS ((void *));
343 static void ggc_mark_hash_table
PARAMS ((void *));
345 /*** Private Interface (data) ***/
347 /* Reserved tag definitions. */
350 #define TAG_OBJECT "objc_object"
351 #define TAG_CLASS "objc_class"
352 #define TAG_SUPER "objc_super"
353 #define TAG_SELECTOR "objc_selector"
355 #define UTAG_CLASS "_objc_class"
356 #define UTAG_IVAR "_objc_ivar"
357 #define UTAG_IVAR_LIST "_objc_ivar_list"
358 #define UTAG_METHOD "_objc_method"
359 #define UTAG_METHOD_LIST "_objc_method_list"
360 #define UTAG_CATEGORY "_objc_category"
361 #define UTAG_MODULE "_objc_module"
362 #define UTAG_STATICS "_objc_statics"
363 #define UTAG_SYMTAB "_objc_symtab"
364 #define UTAG_SUPER "_objc_super"
365 #define UTAG_SELECTOR "_objc_selector"
367 #define UTAG_PROTOCOL "_objc_protocol"
368 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
369 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
370 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
372 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
373 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
375 static const char *constant_string_class_name
= NULL
;
377 static const char *TAG_GETCLASS
;
378 static const char *TAG_GETMETACLASS
;
379 static const char *TAG_MSGSEND
;
380 static const char *TAG_MSGSENDSUPER
;
381 static const char *TAG_EXECCLASS
;
383 /* Set by `continue_class' and checked by `is_public'. */
385 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
386 #define TYPED_OBJECT(type) \
387 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
389 tree objc_ellipsis_node
;
394 OCTI_STATIC_NST_DECL
,
400 OCTI_UMSG_SUPER_DECL
,
402 OCTI_GET_MCLASS_DECL
,
416 OCTI_CLS_NAMES_CHAIN
,
417 OCTI_METH_VAR_NAMES_CHAIN
,
418 OCTI_METH_VAR_TYPES_CHAIN
,
440 OCTI_UUCLS_SUPER_REF
,
458 static tree objc_global_trees
[OCTI_MAX
];
460 /* List of classes with list of their static instances. */
461 #define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
463 /* The declaration of the array administrating the static instances. */
464 #define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
466 /* Some commonly used instances of "identifier_node". */
468 #define self_id objc_global_trees[OCTI_SELF_ID]
469 #define ucmd_id objc_global_trees[OCTI_UCMD_ID]
470 #define unused_list objc_global_trees[OCTI_UNUSED_LIST]
472 #define self_decl objc_global_trees[OCTI_SELF_DECL]
473 #define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
474 #define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
475 #define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
476 #define objc_get_meta_class_decl \
477 objc_global_trees[OCTI_GET_MCLASS_DECL]
479 #define super_type objc_global_trees[OCTI_SUPER_TYPE]
480 #define selector_type objc_global_trees[OCTI_SEL_TYPE]
481 #define id_type objc_global_trees[OCTI_ID_TYPE]
482 #define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
483 #define instance_type objc_global_trees[OCTI_NST_TYPE]
484 #define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
486 /* Type checking macros. */
488 #define IS_ID(TYPE) \
489 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
490 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
491 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
492 #define IS_SUPER(TYPE) \
493 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
495 #define class_chain objc_global_trees[OCTI_CLS_CHAIN]
496 #define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
497 #define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
498 #define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
500 /* Chains to manage selectors that are referenced and defined in the
503 #define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
504 #define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
506 /* Chains to manage uniquing of strings. */
508 #define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
509 #define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
510 #define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
512 /* Hash tables to manage the global pool of method prototypes. */
514 static hash
*nst_method_hash_list
= 0;
515 static hash
*cls_method_hash_list
= 0;
517 /* Backend data declarations. */
519 #define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
520 #define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
521 #define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
522 #define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
523 #define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
524 #define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
525 #define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
526 #define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
527 #define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
528 #define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
530 /* The following are used when compiling a class implementation.
531 implementation_template will normally be an interface, however if
532 none exists this will be equal to implementation_context...it is
533 set in start_class. */
535 #define implementation_context objc_global_trees[OCTI_IMPL_CTX]
536 #define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
540 struct imp_entry
*next
;
543 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
544 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
547 static void handle_impent
PARAMS ((struct imp_entry
*));
549 static struct imp_entry
*imp_list
= 0;
550 static int imp_count
= 0; /* `@implementation' */
551 static int cat_count
= 0; /* `@category' */
553 #define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
554 #define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
555 #define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
556 #define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
557 #define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
558 #define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
559 #define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
561 #define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
562 #define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
563 #define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
564 #define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
565 #define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
566 #define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
568 #define objc_object_id objc_global_trees[OCTI_OBJ_ID]
569 #define objc_class_id objc_global_trees[OCTI_CLS_ID]
570 #define objc_id_id objc_global_trees[OCTI_ID_ID]
571 #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
572 #define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
573 #define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
575 #define method_context objc_global_trees[OCTI_METH_CTX]
576 static int method_slot
= 0; /* Used by start_method_def, */
580 static char *errbuf
; /* Buffer for error diagnostics */
582 /* Data imported from tree.c. */
584 extern enum debug_info_type write_symbols
;
586 /* Data imported from toplev.c. */
588 extern const char *dump_base_name
;
590 /* Generate code for GNU or NeXT runtime environment. */
592 #ifdef NEXT_OBJC_RUNTIME
593 int flag_next_runtime
= 1;
595 int flag_next_runtime
= 0;
598 int flag_typed_selectors
;
600 /* Open and close the file for outputting class declarations, if requested. */
602 int flag_gen_declaration
= 0;
604 FILE *gen_declaration_file
;
606 /* Warn if multiple methods are seen for the same selector, but with
607 different argument types. */
609 int warn_selector
= 0;
611 /* Warn if methods required by a protocol are not implemented in the
612 class adopting it. When turned off, methods inherited to that
613 class are also considered implemented */
615 int flag_warn_protocol
= 1;
617 /* Tells "encode_pointer/encode_aggregate" whether we are generating
618 type descriptors for instance variables (as opposed to methods).
619 Type descriptors for instance variables contain more information
620 than methods (for static typing and embedded structures). This
621 was added to support features being planned for dbkit2. */
623 static int generating_instance_variables
= 0;
625 /* Tells the compiler that this is a special run. Do not perform
626 any compiling, instead we are to test some platform dependent
627 features and output a C header file with appropriate definitions. */
629 static int print_struct_values
= 0;
631 /* Some platforms pass small structures through registers versus through
632 an invisible pointer. Determine at what size structure is the
633 transition point between the two possibilities. */
636 generate_struct_by_value_array ()
639 tree field_decl
, field_decl_chain
;
641 int aggregate_in_mem
[32];
644 /* Presumbaly no platform passes 32 byte structures in a register. */
645 for (i
= 1; i
< 32; i
++)
649 /* Create an unnamed struct that has `i' character components */
650 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
652 strcpy (buffer
, "c1");
653 field_decl
= create_builtin_decl (FIELD_DECL
,
656 field_decl_chain
= field_decl
;
658 for (j
= 1; j
< i
; j
++)
660 sprintf (buffer
, "c%d", j
+ 1);
661 field_decl
= create_builtin_decl (FIELD_DECL
,
664 chainon (field_decl_chain
, field_decl
);
666 finish_struct (type
, field_decl_chain
, NULL_TREE
);
668 aggregate_in_mem
[i
] = aggregate_value_p (type
);
669 if (!aggregate_in_mem
[i
])
673 /* We found some structures that are returned in registers instead of memory
674 so output the necessary data. */
677 for (i
= 31; i
>= 0; i
--)
678 if (!aggregate_in_mem
[i
])
680 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
682 /* The first member of the structure is always 0 because we don't handle
683 structures with 0 members */
684 printf ("static int struct_forward_array[] = {\n 0");
686 for (j
= 1; j
<= i
; j
++)
687 printf (", %d", aggregate_in_mem
[j
]);
697 parse_in
= cpp_create_reader (CLK_OBJC
);
698 c_language
= clk_objective_c
;
704 /* Force the line number back to 0; check_newline will have
705 raised it to 1, which will make the builtin functions appear
706 not to be built in. */
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 fatal ("Objective-C text in C source file");
757 finish_objc (); /* Objective-C finalization */
759 if (gen_declaration_file
)
760 fclose (gen_declaration_file
);
775 lang_decode_option (argc
, argv
)
779 const char *p
= argv
[0];
781 if (!strcmp (p
, "-gen-decls"))
782 flag_gen_declaration
= 1;
783 else if (!strcmp (p
, "-Wselector"))
785 else if (!strcmp (p
, "-Wno-selector"))
787 else if (!strcmp (p
, "-Wprotocol"))
788 flag_warn_protocol
= 1;
789 else if (!strcmp (p
, "-Wno-protocol"))
790 flag_warn_protocol
= 0;
791 else if (!strcmp (p
, "-fgnu-runtime"))
792 flag_next_runtime
= 0;
793 else if (!strcmp (p
, "-fno-next-runtime"))
794 flag_next_runtime
= 0;
795 else if (!strcmp (p
, "-fno-gnu-runtime"))
796 flag_next_runtime
= 1;
797 else if (!strcmp (p
, "-fnext-runtime"))
798 flag_next_runtime
= 1;
799 else if (!strcmp (p
, "-print-objc-runtime-info"))
800 print_struct_values
= 1;
801 #define CSTSTRCLASS "-fconstant-string-class="
802 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
803 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
804 error ("no class name specified as argument to -fconstant-string-class");
805 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
809 return c_decode_option (argc
, argv
);
814 /* used by print-tree.c */
817 lang_print_xnode (file
, node
, indent
)
818 FILE *file ATTRIBUTE_UNUSED
;
819 tree node ATTRIBUTE_UNUSED
;
820 int indent ATTRIBUTE_UNUSED
;
826 define_decl (declarator
, declspecs
)
830 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
831 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
835 /* Return 1 if LHS and RHS are compatible types for assignment or
836 various other operations. Return 0 if they are incompatible, and
837 return -1 if we choose to not decide. When the operation is
838 REFLEXIVE, check for compatibility in either direction.
840 For statically typed objects, an assignment of the form `a' = `b'
844 `a' and `b' are the same class type, or
845 `a' and `b' are of class types A and B such that B is a descendant of A. */
848 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
852 return objc_comptypes (lhs
, rhs
, reflexive
);
856 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
864 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
866 p
= TREE_VALUE (rproto
);
868 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
870 if ((fnd
= lookup_method (class_meth
871 ? PROTOCOL_CLS_METHODS (p
)
872 : PROTOCOL_NST_METHODS (p
), sel_name
)))
874 else if (PROTOCOL_LIST (p
))
875 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
876 sel_name
, class_meth
);
880 ; /* An identifier...if we could not find a protocol. */
891 lookup_protocol_in_reflist (rproto_list
, lproto
)
897 /* Make sure the protocol is support by the object on the rhs. */
898 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
901 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
903 p
= TREE_VALUE (rproto
);
905 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
910 else if (PROTOCOL_LIST (p
))
911 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
920 ; /* An identifier...if we could not find a protocol. */
926 /* Return 1 if LHS and RHS are compatible types for assignment
927 or various other operations. Return 0 if they are incompatible,
928 and return -1 if we choose to not decide. When the operation
929 is REFLEXIVE, check for compatibility in either direction. */
932 objc_comptypes (lhs
, rhs
, reflexive
)
937 /* New clause for protocols. */
939 if (TREE_CODE (lhs
) == POINTER_TYPE
940 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
941 && TREE_CODE (rhs
) == POINTER_TYPE
942 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
944 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
945 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
949 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
950 tree rproto
, rproto_list
;
955 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
957 /* Make sure the protocol is supported by the object
959 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
961 p
= TREE_VALUE (lproto
);
962 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
965 warning ("object does not conform to the `%s' protocol",
966 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
969 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
971 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
974 /* Make sure the protocol is supported by the object
976 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
978 p
= TREE_VALUE (lproto
);
980 rinter
= lookup_interface (rname
);
982 while (rinter
&& !rproto
)
986 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
987 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
989 /* Check for protocols adopted by categories. */
990 cat
= CLASS_CATEGORY_LIST (rinter
);
991 while (cat
&& !rproto
)
993 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
994 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
996 cat
= CLASS_CATEGORY_LIST (cat
);
999 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
1003 warning ("class `%s' does not implement the `%s' protocol",
1004 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
1005 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1009 /* May change...based on whether there was any mismatch */
1012 else if (rhs_is_proto
)
1013 /* Lhs is not a protocol...warn if it is statically typed */
1014 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
1017 /* Defer to comptypes .*/
1021 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
1022 ; /* Fall thru. This is the case we have been handling all along */
1024 /* Defer to comptypes. */
1027 /* `id' = `<class> *', `<class> *' = `id' */
1029 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
1030 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
1033 /* `id' = `Class', `Class' = `id' */
1035 else if ((TYPE_NAME (lhs
) == objc_object_id
1036 && TYPE_NAME (rhs
) == objc_class_id
)
1037 || (TYPE_NAME (lhs
) == objc_class_id
1038 && TYPE_NAME (rhs
) == objc_object_id
))
1041 /* `<class> *' = `<class> *' */
1043 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1045 tree lname
= TYPE_NAME (lhs
);
1046 tree rname
= TYPE_NAME (rhs
);
1052 /* If the left hand side is a super class of the right hand side,
1054 for (inter
= lookup_interface (rname
); inter
;
1055 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1056 if (lname
== CLASS_SUPER_NAME (inter
))
1059 /* Allow the reverse when reflexive. */
1061 for (inter
= lookup_interface (lname
); inter
;
1062 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1063 if (rname
== CLASS_SUPER_NAME (inter
))
1069 /* Defer to comptypes. */
1073 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1076 objc_check_decl (decl
)
1079 tree type
= TREE_TYPE (decl
);
1081 if (TREE_CODE (type
) == RECORD_TYPE
1082 && TREE_STATIC_TEMPLATE (type
)
1083 && type
!= constant_string_type
)
1085 error_with_decl (decl
, "`%s' cannot be statically allocated");
1086 fatal ("statically allocated objects not supported");
1091 maybe_objc_check_decl (decl
)
1094 objc_check_decl (decl
);
1097 /* Implement static typing. At this point, we know we have an interface. */
1100 get_static_reference (interface
, protocols
)
1104 tree type
= xref_tag (RECORD_TYPE
, interface
);
1108 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1110 t
= copy_node (type
);
1111 TYPE_BINFO (t
) = make_tree_vec (2);
1113 /* Add this type to the chain of variants of TYPE. */
1114 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1115 TYPE_NEXT_VARIANT (m
) = t
;
1117 /* Look up protocols and install in lang specific list. */
1118 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1120 /* This forces a new pointer type to be created later
1121 (in build_pointer_type)...so that the new template
1122 we just created will actually be used...what a hack! */
1123 if (TYPE_POINTER_TO (t
))
1124 TYPE_POINTER_TO (t
) = 0;
1133 get_object_reference (protocols
)
1136 tree type_decl
= lookup_name (objc_id_id
);
1139 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1141 type
= TREE_TYPE (type_decl
);
1142 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1143 warning ("Unexpected type for `id' (%s)",
1144 gen_declaration (type
, errbuf
));
1147 fatal ("Undefined type `id', please import <objc/objc.h>");
1149 /* This clause creates a new pointer type that is qualified with
1150 the protocol specification...this info is used later to do more
1151 elaborate type checking. */
1155 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1157 t
= copy_node (type
);
1158 TYPE_BINFO (t
) = make_tree_vec (2);
1160 /* Add this type to the chain of variants of TYPE. */
1161 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1162 TYPE_NEXT_VARIANT (m
) = t
;
1164 /* Look up protocols...and install in lang specific list */
1165 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1167 /* This forces a new pointer type to be created later
1168 (in build_pointer_type)...so that the new template
1169 we just created will actually be used...what a hack! */
1170 if (TYPE_POINTER_TO (t
))
1171 TYPE_POINTER_TO (t
) = NULL
;
1179 lookup_and_install_protocols (protocols
)
1184 tree return_value
= protocols
;
1186 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1188 tree ident
= TREE_VALUE (proto
);
1189 tree p
= lookup_protocol (ident
);
1193 error ("Cannot find protocol declaration for `%s'",
1194 IDENTIFIER_POINTER (ident
));
1196 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1198 return_value
= TREE_CHAIN (proto
);
1202 /* Replace identifier with actual protocol node. */
1203 TREE_VALUE (proto
) = p
;
1208 return return_value
;
1211 /* Create and push a decl for a built-in external variable or field NAME.
1213 TYPE is its data type. */
1216 create_builtin_decl (code
, type
, name
)
1217 enum tree_code code
;
1221 tree decl
= build_decl (code
, get_identifier (name
), type
);
1223 if (code
== VAR_DECL
)
1225 TREE_STATIC (decl
) = 1;
1226 make_decl_rtl (decl
, 0, 1);
1230 DECL_ARTIFICIAL (decl
) = 1;
1234 /* Purpose: "play" parser, creating/installing representations
1235 of the declarations that are required by Objective-C.
1239 type_spec--------->sc_spec
1240 (tree_list) (tree_list)
1243 identifier_node identifier_node */
1246 synth_module_prologue ()
1251 /* Defined in `objc.h' */
1252 objc_object_id
= get_identifier (TAG_OBJECT
);
1254 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1256 id_type
= build_pointer_type (objc_object_reference
);
1258 objc_id_id
= get_identifier (TYPE_ID
);
1259 objc_class_id
= get_identifier (TAG_CLASS
);
1261 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1262 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1263 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1265 /* Declare type of selector-objects that represent an operation name. */
1267 #ifdef OBJC_INT_SELECTORS
1268 /* `unsigned int' */
1269 selector_type
= unsigned_type_node
;
1271 /* `struct objc_selector *' */
1273 = build_pointer_type (xref_tag (RECORD_TYPE
,
1274 get_identifier (TAG_SELECTOR
)));
1275 #endif /* not OBJC_INT_SELECTORS */
1277 /* Forward declare type, or else the prototype for msgSendSuper will
1280 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1281 get_identifier (TAG_SUPER
)));
1284 /* id objc_msgSend (id, SEL, ...); */
1287 = build_function_type (id_type
,
1288 tree_cons (NULL_TREE
, id_type
,
1289 tree_cons (NULL_TREE
, selector_type
,
1292 if (! flag_next_runtime
)
1294 umsg_decl
= build_decl (FUNCTION_DECL
,
1295 get_identifier (TAG_MSGSEND
), temp_type
);
1296 DECL_EXTERNAL (umsg_decl
) = 1;
1297 TREE_PUBLIC (umsg_decl
) = 1;
1298 DECL_INLINE (umsg_decl
) = 1;
1299 DECL_ARTIFICIAL (umsg_decl
) = 1;
1301 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1302 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1304 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1305 pushdecl (umsg_decl
);
1308 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1310 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1313 = build_function_type (id_type
,
1314 tree_cons (NULL_TREE
, super_p
,
1315 tree_cons (NULL_TREE
, selector_type
,
1318 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1319 temp_type
, 0, NOT_BUILT_IN
, 0);
1321 /* id objc_getClass (const char *); */
1323 temp_type
= build_function_type (id_type
,
1324 tree_cons (NULL_TREE
,
1325 const_string_type_node
,
1326 tree_cons (NULL_TREE
, void_type_node
,
1330 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1332 /* id objc_getMetaClass (const char *); */
1334 objc_get_meta_class_decl
1335 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1337 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1339 if (! flag_next_runtime
)
1341 if (flag_typed_selectors
)
1343 /* Suppress outputting debug symbols, because
1344 dbxout_init hasn'r been called yet. */
1345 enum debug_info_type save_write_symbols
= write_symbols
;
1346 write_symbols
= NO_DEBUG
;
1348 build_selector_template ();
1349 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1351 write_symbols
= save_write_symbols
;
1354 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1356 layout_type (temp_type
);
1357 UOBJC_SELECTOR_TABLE_decl
1358 = create_builtin_decl (VAR_DECL
, temp_type
,
1359 "_OBJC_SELECTOR_TABLE");
1361 /* Avoid warning when not sending messages. */
1362 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1365 generate_forward_declaration_to_string_table ();
1367 /* Forward declare constant_string_id and constant_string_type. */
1368 if (!constant_string_class_name
)
1369 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1371 constant_string_id
= get_identifier (constant_string_class_name
);
1372 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1375 /* Custom build_string which sets TREE_TYPE! */
1378 my_build_string (len
, str
)
1383 tree a_string
= build_string (len
, str
);
1385 /* Some code from combine_strings, which is local to c-parse.y. */
1386 if (TREE_TYPE (a_string
) == int_array_type_node
)
1389 TREE_TYPE (a_string
)
1390 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1391 build_index_type (build_int_2 (len
- 1, 0)));
1393 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1394 TREE_STATIC (a_string
) = 1;
1399 /* Given a chain of STRING_CST's, build a static instance of
1400 NXConstanString which points at the concatenation of those strings.
1401 We place the string object in the __string_objects section of the
1402 __OBJC segment. The Objective-C runtime will initialize the isa
1403 pointers of the string objects to point at the NXConstandString class
1407 build_objc_string_object (strings
)
1410 tree string
, initlist
, constructor
;
1413 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1415 error ("Cannot find interface declaration for `%s'",
1416 IDENTIFIER_POINTER (constant_string_id
));
1417 return error_mark_node
;
1420 add_class_reference (constant_string_id
);
1422 string
= combine_strings (strings
);
1423 TREE_SET_CODE (string
, STRING_CST
);
1424 length
= TREE_STRING_LENGTH (string
) - 1;
1426 /* & ((NXConstantString) {0, string, length}) */
1428 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1430 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1432 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1433 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1435 if (!flag_next_runtime
)
1438 = objc_add_static_instance (constructor
, constant_string_type
);
1441 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1444 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1447 objc_add_static_instance (constructor
, class_decl
)
1448 tree constructor
, class_decl
;
1450 static int num_static_inst
;
1454 /* Find the list of static instances for the CLASS_DECL. Create one if
1456 for (chain
= &objc_static_instances
;
1457 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1458 chain
= &TREE_CHAIN (*chain
));
1461 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1462 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1465 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1466 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1467 DECL_COMMON (decl
) = 1;
1468 TREE_STATIC (decl
) = 1;
1469 DECL_ARTIFICIAL (decl
) = 1;
1470 pushdecl_top_level (decl
);
1471 rest_of_decl_compilation (decl
, 0, 1, 0);
1473 /* Do this here so it gets output later instead of possibly
1474 inside something else we are writing. */
1475 DECL_INITIAL (decl
) = constructor
;
1477 /* Add the DECL to the head of this CLASS' list. */
1478 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1483 /* Build a static constant CONSTRUCTOR
1484 with type TYPE and elements ELTS. */
1487 build_constructor (type
, elts
)
1490 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1492 TREE_CONSTANT (constructor
) = 1;
1493 TREE_STATIC (constructor
) = 1;
1494 TREE_READONLY (constructor
) = 1;
1499 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1501 /* Predefine the following data type:
1509 void *defs[cls_def_cnt + cat_def_cnt];
1513 build_objc_symtab_template ()
1515 tree field_decl
, field_decl_chain
, index
;
1517 objc_symtab_template
1518 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1520 /* long sel_ref_cnt; */
1522 field_decl
= create_builtin_decl (FIELD_DECL
,
1523 long_integer_type_node
,
1525 field_decl_chain
= field_decl
;
1529 field_decl
= create_builtin_decl (FIELD_DECL
,
1530 build_pointer_type (selector_type
),
1532 chainon (field_decl_chain
, field_decl
);
1534 /* short cls_def_cnt; */
1536 field_decl
= create_builtin_decl (FIELD_DECL
,
1537 short_integer_type_node
,
1539 chainon (field_decl_chain
, field_decl
);
1541 /* short cat_def_cnt; */
1543 field_decl
= create_builtin_decl (FIELD_DECL
,
1544 short_integer_type_node
,
1546 chainon (field_decl_chain
, field_decl
);
1548 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1550 if (!flag_next_runtime
)
1551 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1553 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1554 imp_count
== 0 && cat_count
== 0
1556 field_decl
= create_builtin_decl (FIELD_DECL
,
1557 build_array_type (ptr_type_node
, index
),
1559 chainon (field_decl_chain
, field_decl
);
1561 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1564 /* Create the initial value for the `defs' field of _objc_symtab.
1565 This is a CONSTRUCTOR. */
1568 init_def_list (type
)
1571 tree expr
, initlist
= NULL_TREE
;
1572 struct imp_entry
*impent
;
1575 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1577 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1579 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1580 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1585 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1587 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1589 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1590 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1594 if (!flag_next_runtime
)
1596 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1599 if (static_instances_decl
)
1600 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1602 expr
= build_int_2 (0, 0);
1604 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1607 return build_constructor (type
, nreverse (initlist
));
1610 /* Construct the initial value for all of _objc_symtab. */
1613 init_objc_symtab (type
)
1618 /* sel_ref_cnt = { ..., 5, ... } */
1620 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1622 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1624 if (flag_next_runtime
|| ! sel_ref_chain
)
1625 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1627 initlist
= tree_cons (NULL_TREE
,
1628 build_unary_op (ADDR_EXPR
,
1629 UOBJC_SELECTOR_TABLE_decl
, 1),
1632 /* cls_def_cnt = { ..., 5, ... } */
1634 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1636 /* cat_def_cnt = { ..., 5, ... } */
1638 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1640 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1642 if (imp_count
|| cat_count
|| static_instances_decl
)
1645 tree field
= TYPE_FIELDS (type
);
1646 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1648 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1652 return build_constructor (type
, nreverse (initlist
));
1655 /* Push forward-declarations of all the categories
1656 so that init_def_list can use them in a CONSTRUCTOR. */
1659 forward_declare_categories ()
1661 struct imp_entry
*impent
;
1662 tree sav
= implementation_context
;
1664 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1666 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1668 /* Set an invisible arg to synth_id_with_class_suffix. */
1669 implementation_context
= impent
->imp_context
;
1671 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1672 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1675 implementation_context
= sav
;
1678 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1679 and initialized appropriately. */
1682 generate_objc_symtab_decl ()
1686 if (!objc_category_template
)
1687 build_category_template ();
1689 /* forward declare categories */
1691 forward_declare_categories ();
1693 if (!objc_symtab_template
)
1694 build_objc_symtab_template ();
1696 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1698 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1699 tree_cons (NULL_TREE
,
1700 objc_symtab_template
, sc_spec
),
1702 NULL_TREE
, NULL_TREE
);
1704 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1705 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1706 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1707 finish_decl (UOBJC_SYMBOLS_decl
,
1708 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1713 init_module_descriptor (type
)
1716 tree initlist
, expr
;
1718 /* version = { 1, ... } */
1720 expr
= build_int_2 (OBJC_VERSION
, 0);
1721 initlist
= build_tree_list (NULL_TREE
, expr
);
1723 /* size = { ..., sizeof (struct objc_module), ... } */
1725 expr
= size_in_bytes (objc_module_template
);
1726 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1728 /* name = { ..., "foo.m", ... } */
1730 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1731 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1733 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1735 if (UOBJC_SYMBOLS_decl
)
1736 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1738 expr
= build_int_2 (0, 0);
1739 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1741 return build_constructor (type
, nreverse (initlist
));
1744 /* Write out the data structures to describe Objective C classes defined.
1745 If appropriate, compile and output a setup function to initialize them.
1746 Return a string which is the name of a function to call to initialize
1747 the Objective C data structures for this file (and perhaps for other files
1750 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1753 build_module_descriptor ()
1755 tree decl_specs
, field_decl
, field_decl_chain
;
1757 objc_module_template
1758 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1762 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1763 field_decl
= get_identifier ("version");
1765 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1766 field_decl_chain
= field_decl
;
1770 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1771 field_decl
= get_identifier ("size");
1773 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1774 chainon (field_decl_chain
, field_decl
);
1778 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1779 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1781 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1782 chainon (field_decl_chain
, field_decl
);
1784 /* struct objc_symtab *symtab; */
1786 decl_specs
= get_identifier (UTAG_SYMTAB
);
1787 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1788 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1790 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1791 chainon (field_decl_chain
, field_decl
);
1793 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1795 /* Create an instance of "objc_module". */
1797 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1798 build_tree_list (NULL_TREE
,
1799 ridpointers
[(int) RID_STATIC
]));
1801 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1802 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1804 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1805 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1806 finish_decl (UOBJC_MODULES_decl
,
1807 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1810 /* Mark the decl to avoid "defined but not used" warning. */
1811 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1813 /* Generate a constructor call for the module descriptor.
1814 This code was generated by reading the grammar rules
1815 of c-parse.in; Therefore, it may not be the most efficient
1816 way of generating the requisite code. */
1818 if (flag_next_runtime
)
1822 tree parms
, function_decl
, decelerator
, void_list_node_1
;
1824 tree init_function_name
= get_file_function_name ('I');
1826 /* Declare void __objc_execClass (void *); */
1828 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1830 = build_function_type (void_type_node
,
1831 tree_cons (NULL_TREE
, ptr_type_node
,
1833 function_decl
= build_decl (FUNCTION_DECL
,
1834 get_identifier (TAG_EXECCLASS
),
1836 DECL_EXTERNAL (function_decl
) = 1;
1837 DECL_ARTIFICIAL (function_decl
) = 1;
1838 TREE_PUBLIC (function_decl
) = 1;
1840 pushdecl (function_decl
);
1841 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1844 = build_tree_list (NULL_TREE
,
1845 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1846 decelerator
= build_function_call (function_decl
, parms
);
1848 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1850 start_function (void_list_node_1
,
1851 build_parse_node (CALL_EXPR
, init_function_name
,
1852 /* This has the format of the output
1853 of get_parm_info. */
1854 tree_cons (NULL_TREE
, NULL_TREE
,
1857 NULL_TREE
, NULL_TREE
);
1858 #if 0 /* This should be turned back on later
1859 for the systems where collect is not needed. */
1860 /* Make these functions nonglobal
1861 so each file can use the same name. */
1862 TREE_PUBLIC (current_function_decl
) = 0;
1864 TREE_USED (current_function_decl
) = 1;
1865 store_parm_decls ();
1867 assemble_external (function_decl
);
1868 c_expand_expr_stmt (decelerator
);
1870 TREE_PUBLIC (current_function_decl
) = 1;
1872 function_decl
= current_function_decl
;
1873 finish_function (0);
1875 /* Return the name of the constructor function. */
1876 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1880 /* extern const char _OBJC_STRINGS[]; */
1883 generate_forward_declaration_to_string_table ()
1885 tree sc_spec
, decl_specs
, expr_decl
;
1887 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1888 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1891 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1893 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1896 /* Return the DECL of the string IDENT in the SECTION. */
1899 get_objc_string_decl (ident
, section
)
1901 enum string_section section
;
1905 if (section
== class_names
)
1906 chain
= class_names_chain
;
1907 else if (section
== meth_var_names
)
1908 chain
= meth_var_names_chain
;
1909 else if (section
== meth_var_types
)
1910 chain
= meth_var_types_chain
;
1914 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1915 if (TREE_VALUE (chain
) == ident
)
1916 return (TREE_PURPOSE (chain
));
1922 /* Output references to all statically allocated objects. Return the DECL
1923 for the array built. */
1926 generate_static_references ()
1928 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1929 tree class_name
, class, decl
, initlist
;
1930 tree cl_chain
, in_chain
, type
;
1931 int num_inst
, num_class
;
1934 if (flag_next_runtime
)
1937 for (cl_chain
= objc_static_instances
, num_class
= 0;
1938 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1940 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1941 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1943 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1944 ident
= get_identifier (buf
);
1946 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1947 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1948 build_tree_list (NULL_TREE
,
1949 ridpointers
[(int) RID_STATIC
]));
1950 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1951 DECL_CONTEXT (decl
) = 0;
1952 DECL_ARTIFICIAL (decl
) = 1;
1954 /* Output {class_name, ...}. */
1955 class = TREE_VALUE (cl_chain
);
1956 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1957 initlist
= build_tree_list (NULL_TREE
,
1958 build_unary_op (ADDR_EXPR
, class_name
, 1));
1960 /* Output {..., instance, ...}. */
1961 for (in_chain
= TREE_PURPOSE (cl_chain
);
1962 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1964 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1965 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1968 /* Output {..., NULL}. */
1969 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1971 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1972 finish_decl (decl
, expr
, NULL_TREE
);
1973 TREE_USED (decl
) = 1;
1975 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1976 decl
= build_decl (VAR_DECL
, ident
, type
);
1977 make_decl_rtl (decl
, 0, 1);
1978 TREE_USED (decl
) = 1;
1980 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1983 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1984 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1985 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1986 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1987 build_tree_list (NULL_TREE
,
1988 ridpointers
[(int) RID_STATIC
]));
1989 static_instances_decl
1990 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1991 TREE_USED (static_instances_decl
) = 1;
1992 DECL_CONTEXT (static_instances_decl
) = 0;
1993 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1994 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1996 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1999 /* Output all strings. */
2004 tree sc_spec
, decl_specs
, expr_decl
;
2005 tree chain
, string_expr
;
2008 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2010 string
= TREE_VALUE (chain
);
2011 decl
= TREE_PURPOSE (chain
);
2013 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2014 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2015 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2016 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2017 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2018 IDENTIFIER_POINTER (string
));
2019 finish_decl (decl
, string_expr
, NULL_TREE
);
2022 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2024 string
= TREE_VALUE (chain
);
2025 decl
= TREE_PURPOSE (chain
);
2027 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2028 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2029 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2030 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2031 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2032 IDENTIFIER_POINTER (string
));
2033 finish_decl (decl
, string_expr
, NULL_TREE
);
2036 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2038 string
= TREE_VALUE (chain
);
2039 decl
= TREE_PURPOSE (chain
);
2041 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2042 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2043 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2044 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2045 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2046 IDENTIFIER_POINTER (string
));
2047 finish_decl (decl
, string_expr
, NULL_TREE
);
2052 build_selector_reference_decl ()
2058 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2060 ident
= get_identifier (buf
);
2062 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2063 DECL_EXTERNAL (decl
) = 1;
2064 TREE_PUBLIC (decl
) = 1;
2065 TREE_USED (decl
) = 1;
2066 TREE_READONLY (decl
) = 1;
2067 DECL_ARTIFICIAL (decl
) = 1;
2068 DECL_CONTEXT (decl
) = 0;
2070 make_decl_rtl (decl
, 0, 1);
2071 pushdecl_top_level (decl
);
2076 /* Just a handy wrapper for add_objc_string. */
2079 build_selector (ident
)
2082 tree expr
= add_objc_string (ident
, meth_var_names
);
2083 if (flag_typed_selectors
)
2086 return build_c_cast (selector_type
, expr
); /* cast! */
2089 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2090 The cast stops the compiler from issuing the following message:
2091 grok.m: warning: initialization of non-const * pointer from const *
2092 grok.m: warning: initialization between incompatible pointer types. */
2096 build_msg_pool_reference (offset
)
2099 tree expr
= build_int_2 (offset
, 0);
2102 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2103 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2105 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2106 ridpointers
[(int) RID_CHAR
]),
2107 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2108 TREE_TYPE (expr
) = groktypename (cast
);
2113 init_selector (offset
)
2116 tree expr
= build_msg_pool_reference (offset
);
2117 TREE_TYPE (expr
) = selector_type
;
2123 build_selector_translation_table ()
2125 tree sc_spec
, decl_specs
;
2126 tree chain
, initlist
= NULL_TREE
;
2128 tree decl
= NULL_TREE
, var_decl
, name
;
2130 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2134 expr
= build_selector (TREE_VALUE (chain
));
2136 if (flag_next_runtime
)
2138 name
= DECL_NAME (TREE_PURPOSE (chain
));
2140 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2142 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2143 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2147 /* The `decl' that is returned from start_decl is the one that we
2148 forward declared in `build_selector_reference' */
2149 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2152 /* add one for the '\0' character */
2153 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2155 if (flag_next_runtime
)
2156 finish_decl (decl
, expr
, NULL_TREE
);
2159 if (flag_typed_selectors
)
2161 tree eltlist
= NULL_TREE
;
2162 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2163 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2164 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2165 expr
= build_constructor (objc_selector_template
,
2166 nreverse (eltlist
));
2168 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2173 if (! flag_next_runtime
)
2175 /* Cause the variable and its initial value to be actually output. */
2176 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2177 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2178 /* NULL terminate the list and fix the decl for output. */
2179 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2180 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2181 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2182 nreverse (initlist
));
2183 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2184 current_function_decl
= NULL_TREE
;
2189 get_proto_encoding (proto
)
2197 if (! METHOD_ENCODING (proto
))
2199 tmp_decl
= build_tmp_function_decl ();
2200 hack_method_prototype (proto
, tmp_decl
);
2201 encoding
= encode_method_prototype (proto
, tmp_decl
);
2202 METHOD_ENCODING (proto
) = encoding
;
2205 encoding
= METHOD_ENCODING (proto
);
2207 return add_objc_string (encoding
, meth_var_types
);
2210 return build_int_2 (0, 0);
2213 /* sel_ref_chain is a list whose "value" fields will be instances of
2214 identifier_node that represent the selector. */
2217 build_typed_selector_reference (ident
, proto
)
2220 tree
*chain
= &sel_ref_chain
;
2226 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2227 goto return_at_index
;
2230 chain
= &TREE_CHAIN (*chain
);
2233 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2236 expr
= build_unary_op (ADDR_EXPR
,
2237 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2238 build_int_2 (index
, 0)),
2240 return build_c_cast (selector_type
, expr
);
2244 build_selector_reference (ident
)
2247 tree
*chain
= &sel_ref_chain
;
2253 if (TREE_VALUE (*chain
) == ident
)
2254 return (flag_next_runtime
2255 ? TREE_PURPOSE (*chain
)
2256 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2257 build_int_2 (index
, 0)));
2260 chain
= &TREE_CHAIN (*chain
);
2263 expr
= build_selector_reference_decl ();
2265 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2267 return (flag_next_runtime
2269 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2270 build_int_2 (index
, 0)));
2274 build_class_reference_decl ()
2280 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2282 ident
= get_identifier (buf
);
2284 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2285 DECL_EXTERNAL (decl
) = 1;
2286 TREE_PUBLIC (decl
) = 1;
2287 TREE_USED (decl
) = 1;
2288 TREE_READONLY (decl
) = 1;
2289 DECL_CONTEXT (decl
) = 0;
2290 DECL_ARTIFICIAL (decl
) = 1;
2292 make_decl_rtl (decl
, 0, 1);
2293 pushdecl_top_level (decl
);
2298 /* Create a class reference, but don't create a variable to reference
2302 add_class_reference (ident
)
2307 if ((chain
= cls_ref_chain
))
2312 if (ident
== TREE_VALUE (chain
))
2316 chain
= TREE_CHAIN (chain
);
2320 /* Append to the end of the list */
2321 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2324 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2327 /* Get a class reference, creating it if necessary. Also create the
2328 reference variable. */
2331 get_class_reference (ident
)
2334 if (flag_next_runtime
)
2339 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2340 if (TREE_VALUE (*chain
) == ident
)
2342 if (! TREE_PURPOSE (*chain
))
2343 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2345 return TREE_PURPOSE (*chain
);
2348 decl
= build_class_reference_decl ();
2349 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2356 add_class_reference (ident
);
2358 params
= build_tree_list (NULL_TREE
,
2359 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2360 IDENTIFIER_POINTER (ident
)));
2362 assemble_external (objc_get_class_decl
);
2363 return build_function_call (objc_get_class_decl
, params
);
2367 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2368 of identifier_node that represent the selector. It returns the
2369 offset of the selector from the beginning of the _OBJC_STRINGS
2370 pool. This offset is typically used by init_selector during code
2373 For each string section we have a chain which maps identifier nodes
2374 to decls for the strings. */
2377 add_objc_string (ident
, section
)
2379 enum string_section section
;
2383 if (section
== class_names
)
2384 chain
= &class_names_chain
;
2385 else if (section
== meth_var_names
)
2386 chain
= &meth_var_names_chain
;
2387 else if (section
== meth_var_types
)
2388 chain
= &meth_var_types_chain
;
2394 if (TREE_VALUE (*chain
) == ident
)
2395 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2397 chain
= &TREE_CHAIN (*chain
);
2400 decl
= build_objc_string_decl (section
);
2402 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2404 return build_unary_op (ADDR_EXPR
, decl
, 1);
2408 build_objc_string_decl (section
)
2409 enum string_section section
;
2413 static int class_names_idx
= 0;
2414 static int meth_var_names_idx
= 0;
2415 static int meth_var_types_idx
= 0;
2417 if (section
== class_names
)
2418 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2419 else if (section
== meth_var_names
)
2420 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2421 else if (section
== meth_var_types
)
2422 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2424 ident
= get_identifier (buf
);
2426 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2427 DECL_EXTERNAL (decl
) = 1;
2428 TREE_PUBLIC (decl
) = 1;
2429 TREE_USED (decl
) = 1;
2430 TREE_READONLY (decl
) = 1;
2431 TREE_CONSTANT (decl
) = 1;
2432 DECL_CONTEXT (decl
) = 0;
2433 DECL_ARTIFICIAL (decl
) = 1;
2435 make_decl_rtl (decl
, 0, 1);
2436 pushdecl_top_level (decl
);
2443 objc_declare_alias (alias_ident
, class_ident
)
2447 if (is_class_name (class_ident
) != class_ident
)
2448 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2449 else if (is_class_name (alias_ident
))
2450 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2452 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2456 objc_declare_class (ident_list
)
2461 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2463 tree ident
= TREE_VALUE (list
);
2466 if ((decl
= lookup_name (ident
)))
2468 error ("`%s' redeclared as different kind of symbol",
2469 IDENTIFIER_POINTER (ident
));
2470 error_with_decl (decl
, "previous declaration of `%s'");
2473 if (! is_class_name (ident
))
2475 tree record
= xref_tag (RECORD_TYPE
, ident
);
2476 TREE_STATIC_TEMPLATE (record
) = 1;
2477 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2483 is_class_name (ident
)
2488 if (lookup_interface (ident
))
2491 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2493 if (ident
== TREE_VALUE (chain
))
2497 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2499 if (ident
== TREE_VALUE (chain
))
2500 return TREE_PURPOSE (chain
);
2507 lookup_interface (ident
)
2512 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2514 if (ident
== CLASS_NAME (chain
))
2521 objc_copy_list (list
, head
)
2525 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2529 tail
= copy_node (list
);
2531 /* The following statement fixes a bug when inheriting instance
2532 variables that are declared to be bitfields. finish_struct
2533 expects to find the width of the bitfield in DECL_INITIAL. */
2534 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2535 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2537 newlist
= chainon (newlist
, tail
);
2538 list
= TREE_CHAIN (list
);
2545 /* Used by: build_private_template, get_class_ivars, and
2546 continue_class. COPY is 1 when called from @defs. In this case
2547 copy all fields. Otherwise don't copy leaf ivars since we rely on
2548 them being side-effected exactly once by finish_struct. */
2551 build_ivar_chain (interface
, copy
)
2555 tree my_name
, super_name
, ivar_chain
;
2557 my_name
= CLASS_NAME (interface
);
2558 super_name
= CLASS_SUPER_NAME (interface
);
2560 /* Possibly copy leaf ivars. */
2562 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2564 ivar_chain
= CLASS_IVARS (interface
);
2569 tree super_interface
= lookup_interface (super_name
);
2571 if (!super_interface
)
2573 /* fatal did not work with 2 args...should fix */
2574 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2575 IDENTIFIER_POINTER (super_name
),
2576 IDENTIFIER_POINTER (my_name
));
2577 exit (FATAL_EXIT_CODE
);
2580 if (super_interface
== interface
)
2582 fatal ("Circular inheritance in interface declaration for `%s'",
2583 IDENTIFIER_POINTER (super_name
));
2586 interface
= super_interface
;
2587 my_name
= CLASS_NAME (interface
);
2588 super_name
= CLASS_SUPER_NAME (interface
);
2590 op1
= CLASS_IVARS (interface
);
2593 tree head
, tail
= objc_copy_list (op1
, &head
);
2595 /* Prepend super class ivars...make a copy of the list, we
2596 do not want to alter the original. */
2597 TREE_CHAIN (tail
) = ivar_chain
;
2604 /* struct <classname> {
2605 struct objc_class *isa;
2610 build_private_template (class)
2615 if (CLASS_STATIC_TEMPLATE (class))
2617 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2618 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2622 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2624 ivar_context
= build_ivar_chain (class, 0);
2626 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2628 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2630 /* mark this record as class template - for class type checking */
2631 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2635 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2637 build1 (INDIRECT_REF
, NULL_TREE
,
2640 return ivar_context
;
2643 /* Begin code generation for protocols... */
2645 /* struct objc_protocol {
2646 char *protocol_name;
2647 struct objc_protocol **protocol_list;
2648 struct objc_method_desc *instance_methods;
2649 struct objc_method_desc *class_methods;
2653 build_protocol_template ()
2655 tree decl_specs
, field_decl
, field_decl_chain
;
2658 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2660 /* struct objc_class *isa; */
2662 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2663 get_identifier (UTAG_CLASS
)));
2664 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2666 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2667 field_decl_chain
= field_decl
;
2669 /* char *protocol_name; */
2671 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2673 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2675 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2676 chainon (field_decl_chain
, field_decl
);
2678 /* struct objc_protocol **protocol_list; */
2680 decl_specs
= build_tree_list (NULL_TREE
, template);
2682 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2683 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2685 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2686 chainon (field_decl_chain
, field_decl
);
2688 /* struct objc_method_list *instance_methods; */
2691 = build_tree_list (NULL_TREE
,
2692 xref_tag (RECORD_TYPE
,
2693 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2695 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2697 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2698 chainon (field_decl_chain
, field_decl
);
2700 /* struct objc_method_list *class_methods; */
2703 = build_tree_list (NULL_TREE
,
2704 xref_tag (RECORD_TYPE
,
2705 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2707 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2709 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2710 chainon (field_decl_chain
, field_decl
);
2712 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2716 build_descriptor_table_initializer (type
, entries
)
2720 tree initlist
= NULL_TREE
;
2724 tree eltlist
= NULL_TREE
;
2727 = tree_cons (NULL_TREE
,
2728 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2730 = tree_cons (NULL_TREE
,
2731 add_objc_string (METHOD_ENCODING (entries
),
2736 = tree_cons (NULL_TREE
,
2737 build_constructor (type
, nreverse (eltlist
)), initlist
);
2739 entries
= TREE_CHAIN (entries
);
2743 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2746 /* struct objc_method_prototype_list {
2748 struct objc_method_prototype {
2755 build_method_prototype_list_template (list_type
, size
)
2759 tree objc_ivar_list_record
;
2760 tree decl_specs
, field_decl
, field_decl_chain
;
2762 /* Generate an unnamed struct definition. */
2764 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2766 /* int method_count; */
2768 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2769 field_decl
= get_identifier ("method_count");
2772 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2773 field_decl_chain
= field_decl
;
2775 /* struct objc_method method_list[]; */
2777 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2778 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2779 build_int_2 (size
, 0));
2782 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2783 chainon (field_decl_chain
, field_decl
);
2785 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2787 return objc_ivar_list_record
;
2791 build_method_prototype_template ()
2794 tree decl_specs
, field_decl
, field_decl_chain
;
2797 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2799 #ifdef OBJC_INT_SELECTORS
2800 /* unsigned int _cmd; */
2802 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2803 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2804 field_decl
= get_identifier ("_cmd");
2805 #else /* OBJC_INT_SELECTORS */
2806 /* struct objc_selector *_cmd; */
2807 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2808 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2809 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2810 #endif /* OBJC_INT_SELECTORS */
2813 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2814 field_decl_chain
= field_decl
;
2816 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2818 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2820 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2821 chainon (field_decl_chain
, field_decl
);
2823 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2825 return proto_record
;
2828 /* True if last call to forwarding_offset yielded a register offset. */
2829 static int offset_is_register
;
2832 forwarding_offset (parm
)
2835 int offset_in_bytes
;
2837 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2839 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2841 /* ??? Here we assume that the parm address is indexed
2842 off the frame pointer or arg pointer.
2843 If that is not true, we produce meaningless results,
2844 but do not crash. */
2845 if (GET_CODE (addr
) == PLUS
2846 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2847 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2849 offset_in_bytes
= 0;
2851 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2852 offset_is_register
= 0;
2854 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2856 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2857 offset_in_bytes
= apply_args_register_offset (regno
);
2858 offset_is_register
= 1;
2863 /* This is the case where the parm is passed as an int or double
2864 and it is converted to a char, short or float and stored back
2865 in the parmlist. In this case, describe the parm
2866 with the variable's declared type, and adjust the address
2867 if the least significant bytes (which we are using) are not
2869 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2870 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2871 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2873 return offset_in_bytes
;
2877 encode_method_prototype (method_decl
, func_decl
)
2884 HOST_WIDE_INT max_parm_end
= 0;
2888 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2889 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2892 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2893 obstack_object_size (&util_obstack
),
2894 OBJC_ENCODE_INLINE_DEFS
);
2897 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2898 parms
= TREE_CHAIN (parms
))
2900 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2901 + int_size_in_bytes (TREE_TYPE (parms
)));
2903 if (!offset_is_register
&& max_parm_end
< parm_end
)
2904 max_parm_end
= parm_end
;
2907 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2909 sprintf (buf
, "%d", stack_size
);
2910 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2912 user_args
= METHOD_SEL_ARGS (method_decl
);
2914 /* Argument types. */
2915 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2916 parms
= TREE_CHAIN (parms
), i
++)
2918 /* Process argument qualifiers for user supplied arguments. */
2921 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2922 user_args
= TREE_CHAIN (user_args
);
2926 encode_type (TREE_TYPE (parms
),
2927 obstack_object_size (&util_obstack
),
2928 OBJC_ENCODE_INLINE_DEFS
);
2930 /* Compute offset. */
2931 sprintf (buf
, "%d", forwarding_offset (parms
));
2933 /* Indicate register. */
2934 if (offset_is_register
)
2935 obstack_1grow (&util_obstack
, '+');
2937 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2940 obstack_1grow (&util_obstack
, '\0');
2941 result
= get_identifier (obstack_finish (&util_obstack
));
2942 obstack_free (&util_obstack
, util_firstobj
);
2947 generate_descriptor_table (type
, name
, size
, list
, proto
)
2954 tree sc_spec
, decl_specs
, decl
, initlist
;
2956 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2957 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2959 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2960 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2962 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2963 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2965 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2972 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2975 static tree objc_method_prototype_template
;
2976 tree initlist
, chain
, method_list_template
;
2977 tree cast
, variable_length_type
;
2980 if (!objc_method_prototype_template
)
2982 objc_method_prototype_template
= build_method_prototype_template ();
2983 ggc_add_tree_root (&objc_method_prototype_template
, 1);
2986 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2987 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2989 variable_length_type
= groktypename (cast
);
2991 chain
= PROTOCOL_CLS_METHODS (protocol
);
2994 size
= list_length (chain
);
2996 method_list_template
2997 = build_method_prototype_list_template (objc_method_prototype_template
,
3001 = build_descriptor_table_initializer (objc_method_prototype_template
,
3004 UOBJC_CLASS_METHODS_decl
3005 = generate_descriptor_table (method_list_template
,
3006 "_OBJC_PROTOCOL_CLASS_METHODS",
3007 size
, initlist
, protocol
);
3008 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3011 UOBJC_CLASS_METHODS_decl
= 0;
3013 chain
= PROTOCOL_NST_METHODS (protocol
);
3016 size
= list_length (chain
);
3018 method_list_template
3019 = build_method_prototype_list_template (objc_method_prototype_template
,
3022 = build_descriptor_table_initializer (objc_method_prototype_template
,
3025 UOBJC_INSTANCE_METHODS_decl
3026 = generate_descriptor_table (method_list_template
,
3027 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3028 size
, initlist
, protocol
);
3029 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3032 UOBJC_INSTANCE_METHODS_decl
= 0;
3036 build_tmp_function_decl ()
3038 tree decl_specs
, expr_decl
, parms
;
3042 /* struct objc_object *objc_xxx (id, SEL, ...); */
3044 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3045 push_parm_decl (build_tree_list
3046 (build_tree_list (decl_specs
,
3047 build1 (INDIRECT_REF
, NULL_TREE
,
3049 build_tree_list (NULL_TREE
, NULL_TREE
)));
3051 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3052 get_identifier (TAG_SELECTOR
)));
3053 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3055 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3056 build_tree_list (NULL_TREE
, NULL_TREE
)));
3057 parms
= get_parm_info (0);
3060 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3061 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3062 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3063 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3065 return define_decl (expr_decl
, decl_specs
);
3069 hack_method_prototype (nst_methods
, tmp_decl
)
3076 /* Hack to avoid problem with static typing of self arg. */
3077 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3078 start_method_def (nst_methods
);
3079 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3081 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
3082 parms
= get_parm_info (0); /* we have a `, ...' */
3084 parms
= get_parm_info (1); /* place a `void_at_end' */
3086 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3088 /* Usually called from store_parm_decls -> init_function_start. */
3090 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3091 current_function_decl
= tmp_decl
;
3094 /* Code taken from start_function. */
3095 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3096 /* Promote the value to int before returning it. */
3097 if (TREE_CODE (restype
) == INTEGER_TYPE
3098 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3099 restype
= integer_type_node
;
3100 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3103 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3104 DECL_CONTEXT (parm
) = tmp_decl
;
3106 init_function_start (tmp_decl
, "objc-act", 0);
3108 /* Typically called from expand_function_start for function definitions. */
3109 assign_parms (tmp_decl
);
3111 /* install return type */
3112 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3117 generate_protocol_references (plist
)
3122 /* Forward declare protocols referenced. */
3123 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3125 tree proto
= TREE_VALUE (lproto
);
3127 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3128 && PROTOCOL_NAME (proto
))
3130 if (! PROTOCOL_FORWARD_DECL (proto
))
3131 build_protocol_reference (proto
);
3133 if (PROTOCOL_LIST (proto
))
3134 generate_protocol_references (PROTOCOL_LIST (proto
));
3140 generate_protocols ()
3142 tree p
, tmp_decl
, encoding
;
3143 tree sc_spec
, decl_specs
, decl
;
3144 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3147 tmp_decl
= build_tmp_function_decl ();
3149 if (! objc_protocol_template
)
3150 objc_protocol_template
= build_protocol_template ();
3152 /* If a protocol was directly referenced, pull in indirect references. */
3153 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3154 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3155 generate_protocol_references (PROTOCOL_LIST (p
));
3157 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3159 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3160 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3162 /* If protocol wasn't referenced, don't generate any code. */
3163 if (! PROTOCOL_FORWARD_DECL (p
))
3166 /* Make sure we link in the Protocol class. */
3167 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3171 if (! METHOD_ENCODING (nst_methods
))
3173 hack_method_prototype (nst_methods
, tmp_decl
);
3174 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3175 METHOD_ENCODING (nst_methods
) = encoding
;
3177 nst_methods
= TREE_CHAIN (nst_methods
);
3182 if (! METHOD_ENCODING (cls_methods
))
3184 hack_method_prototype (cls_methods
, tmp_decl
);
3185 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3186 METHOD_ENCODING (cls_methods
) = encoding
;
3189 cls_methods
= TREE_CHAIN (cls_methods
);
3191 generate_method_descriptors (p
);
3193 if (PROTOCOL_LIST (p
))
3194 refs_decl
= generate_protocol_list (p
);
3198 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3200 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3202 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3204 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3205 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3207 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3213 (build_tree_list (build_tree_list (NULL_TREE
,
3214 objc_protocol_template
),
3215 build1 (INDIRECT_REF
, NULL_TREE
,
3216 build1 (INDIRECT_REF
, NULL_TREE
,
3219 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3220 TREE_TYPE (refs_expr
) = cast_type2
;
3223 refs_expr
= build_int_2 (0, 0);
3225 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3226 by generate_method_descriptors, which is called above. */
3227 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3228 protocol_name_expr
, refs_expr
,
3229 UOBJC_INSTANCE_METHODS_decl
,
3230 UOBJC_CLASS_METHODS_decl
);
3231 finish_decl (decl
, initlist
, NULL_TREE
);
3233 /* Mark the decl as used to avoid "defined but not used" warning. */
3234 TREE_USED (decl
) = 1;
3239 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3240 instance_methods
, class_methods
)
3244 tree instance_methods
;
3247 tree initlist
= NULL_TREE
, expr
;
3250 cast_type
= groktypename
3252 (build_tree_list (NULL_TREE
,
3253 xref_tag (RECORD_TYPE
,
3254 get_identifier (UTAG_CLASS
))),
3255 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3257 /* Filling the "isa" in with one allows the runtime system to
3258 detect that the version change...should remove before final release. */
3260 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3261 TREE_TYPE (expr
) = cast_type
;
3262 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3263 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3264 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3266 if (!instance_methods
)
3267 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3270 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3271 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3275 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3278 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3279 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3282 return build_constructor (type
, nreverse (initlist
));
3285 /* struct objc_category {
3286 char *category_name;
3288 struct objc_method_list *instance_methods;
3289 struct objc_method_list *class_methods;
3290 struct objc_protocol_list *protocols;
3294 build_category_template ()
3296 tree decl_specs
, field_decl
, field_decl_chain
;
3298 objc_category_template
= start_struct (RECORD_TYPE
,
3299 get_identifier (UTAG_CATEGORY
));
3300 /* char *category_name; */
3302 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3304 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3306 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3307 field_decl_chain
= field_decl
;
3309 /* char *class_name; */
3311 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3312 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3314 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3315 chainon (field_decl_chain
, field_decl
);
3317 /* struct objc_method_list *instance_methods; */
3319 decl_specs
= build_tree_list (NULL_TREE
,
3320 xref_tag (RECORD_TYPE
,
3321 get_identifier (UTAG_METHOD_LIST
)));
3323 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3325 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3326 chainon (field_decl_chain
, field_decl
);
3328 /* struct objc_method_list *class_methods; */
3330 decl_specs
= build_tree_list (NULL_TREE
,
3331 xref_tag (RECORD_TYPE
,
3332 get_identifier (UTAG_METHOD_LIST
)));
3334 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3336 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3337 chainon (field_decl_chain
, field_decl
);
3339 /* struct objc_protocol **protocol_list; */
3341 decl_specs
= build_tree_list (NULL_TREE
,
3342 xref_tag (RECORD_TYPE
,
3343 get_identifier (UTAG_PROTOCOL
)));
3345 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3346 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3348 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3349 chainon (field_decl_chain
, field_decl
);
3351 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3354 /* struct objc_selector {
3360 build_selector_template ()
3363 tree decl_specs
, field_decl
, field_decl_chain
;
3365 objc_selector_template
3366 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3370 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3371 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3373 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3374 field_decl_chain
= field_decl
;
3376 /* char *sel_type; */
3378 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3379 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3381 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3382 chainon (field_decl_chain
, field_decl
);
3384 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3387 /* struct objc_class {
3388 struct objc_class *isa;
3389 struct objc_class *super_class;
3394 struct objc_ivar_list *ivars;
3395 struct objc_method_list *methods;
3396 if (flag_next_runtime)
3397 struct objc_cache *cache;
3399 struct sarray *dtable;
3400 struct objc_class *subclass_list;
3401 struct objc_class *sibling_class;
3403 struct objc_protocol_list *protocols;
3404 void *gc_object_type;
3408 build_class_template ()
3410 tree decl_specs
, field_decl
, field_decl_chain
;
3413 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3415 /* struct objc_class *isa; */
3417 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3418 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3420 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3421 field_decl_chain
= field_decl
;
3423 /* struct objc_class *super_class; */
3425 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3427 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3429 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3430 chainon (field_decl_chain
, field_decl
);
3434 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3435 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3437 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3438 chainon (field_decl_chain
, field_decl
);
3442 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3443 field_decl
= get_identifier ("version");
3445 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3446 chainon (field_decl_chain
, field_decl
);
3450 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3451 field_decl
= get_identifier ("info");
3453 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3454 chainon (field_decl_chain
, field_decl
);
3456 /* long instance_size; */
3458 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3459 field_decl
= get_identifier ("instance_size");
3461 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3462 chainon (field_decl_chain
, field_decl
);
3464 /* struct objc_ivar_list *ivars; */
3466 decl_specs
= build_tree_list (NULL_TREE
,
3467 xref_tag (RECORD_TYPE
,
3468 get_identifier (UTAG_IVAR_LIST
)));
3469 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3471 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3472 chainon (field_decl_chain
, field_decl
);
3474 /* struct objc_method_list *methods; */
3476 decl_specs
= build_tree_list (NULL_TREE
,
3477 xref_tag (RECORD_TYPE
,
3478 get_identifier (UTAG_METHOD_LIST
)));
3479 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3481 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3482 chainon (field_decl_chain
, field_decl
);
3484 if (flag_next_runtime
)
3486 /* struct objc_cache *cache; */
3488 decl_specs
= build_tree_list (NULL_TREE
,
3489 xref_tag (RECORD_TYPE
,
3490 get_identifier ("objc_cache")));
3491 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3492 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3493 decl_specs
, NULL_TREE
);
3494 chainon (field_decl_chain
, field_decl
);
3498 /* struct sarray *dtable; */
3500 decl_specs
= build_tree_list (NULL_TREE
,
3501 xref_tag (RECORD_TYPE
,
3502 get_identifier ("sarray")));
3503 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3504 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3505 decl_specs
, NULL_TREE
);
3506 chainon (field_decl_chain
, field_decl
);
3508 /* struct objc_class *subclass_list; */
3510 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3512 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3513 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3514 decl_specs
, NULL_TREE
);
3515 chainon (field_decl_chain
, field_decl
);
3517 /* struct objc_class *sibling_class; */
3519 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3521 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3522 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3523 decl_specs
, NULL_TREE
);
3524 chainon (field_decl_chain
, field_decl
);
3527 /* struct objc_protocol **protocol_list; */
3529 decl_specs
= build_tree_list (NULL_TREE
,
3530 xref_tag (RECORD_TYPE
,
3531 get_identifier (UTAG_PROTOCOL
)));
3533 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3535 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3536 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3537 decl_specs
, NULL_TREE
);
3538 chainon (field_decl_chain
, field_decl
);
3542 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3543 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3545 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3546 chainon (field_decl_chain
, field_decl
);
3548 /* void *gc_object_type; */
3550 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3551 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3553 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3554 chainon (field_decl_chain
, field_decl
);
3556 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3559 /* Generate appropriate forward declarations for an implementation. */
3562 synth_forward_declarations ()
3564 tree sc_spec
, decl_specs
, an_id
;
3566 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3568 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3570 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3571 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3572 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3573 TREE_USED (UOBJC_CLASS_decl
) = 1;
3574 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3576 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3578 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3579 implementation_context
);
3581 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3582 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3583 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3585 /* Pre-build the following entities - for speed/convenience. */
3587 an_id
= get_identifier ("super_class");
3588 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3589 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3593 error_with_ivar (message
, decl
, rawdecl
)
3594 const char *message
;
3600 report_error_function (DECL_SOURCE_FILE (decl
));
3602 fprintf (stderr
, "%s:%d: ",
3603 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3604 memset (errbuf
, 0, BUFSIZE
);
3605 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3608 #define USERTYPE(t) \
3609 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3610 || TREE_CODE (t) == ENUMERAL_TYPE)
3613 check_ivars (inter
, imp
)
3617 tree intdecls
= CLASS_IVARS (inter
);
3618 tree impdecls
= CLASS_IVARS (imp
);
3619 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3620 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3626 if (intdecls
== 0 && impdecls
== 0)
3628 if (intdecls
== 0 || impdecls
== 0)
3630 error ("inconsistent instance variable specification");
3634 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3636 if (!comptypes (t1
, t2
))
3638 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3640 error_with_ivar ("conflicting instance variable type",
3641 impdecls
, rawimpdecls
);
3642 error_with_ivar ("previous declaration of",
3643 intdecls
, rawintdecls
);
3645 else /* both the type and the name don't match */
3647 error ("inconsistent instance variable specification");
3652 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3654 error_with_ivar ("conflicting instance variable name",
3655 impdecls
, rawimpdecls
);
3656 error_with_ivar ("previous declaration of",
3657 intdecls
, rawintdecls
);
3660 intdecls
= TREE_CHAIN (intdecls
);
3661 impdecls
= TREE_CHAIN (impdecls
);
3662 rawintdecls
= TREE_CHAIN (rawintdecls
);
3663 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3667 /* Set super_type to the data type node for struct objc_super *,
3668 first defining struct objc_super itself.
3669 This needs to be done just once per compilation. */
3672 build_super_template ()
3674 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3676 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3678 /* struct objc_object *self; */
3680 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3681 field_decl
= get_identifier ("self");
3682 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3683 field_decl
= grokfield (input_filename
, lineno
,
3684 field_decl
, decl_specs
, NULL_TREE
);
3685 field_decl_chain
= field_decl
;
3687 /* struct objc_class *class; */
3689 decl_specs
= get_identifier (UTAG_CLASS
);
3690 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3691 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3693 field_decl
= grokfield (input_filename
, lineno
,
3694 field_decl
, decl_specs
, NULL_TREE
);
3695 chainon (field_decl_chain
, field_decl
);
3697 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3699 /* `struct objc_super *' */
3700 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3702 build1 (INDIRECT_REF
,
3703 NULL_TREE
, NULL_TREE
)));
3707 /* struct objc_ivar {
3714 build_ivar_template ()
3716 tree objc_ivar_id
, objc_ivar_record
;
3717 tree decl_specs
, field_decl
, field_decl_chain
;
3719 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3720 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3722 /* char *ivar_name; */
3724 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3725 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3727 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3728 decl_specs
, NULL_TREE
);
3729 field_decl_chain
= field_decl
;
3731 /* char *ivar_type; */
3733 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3734 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3736 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3737 decl_specs
, NULL_TREE
);
3738 chainon (field_decl_chain
, field_decl
);
3740 /* int ivar_offset; */
3742 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3743 field_decl
= get_identifier ("ivar_offset");
3745 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3746 decl_specs
, NULL_TREE
);
3747 chainon (field_decl_chain
, field_decl
);
3749 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3751 return objc_ivar_record
;
3756 struct objc_ivar ivar_list[ivar_count];
3760 build_ivar_list_template (list_type
, size
)
3764 tree objc_ivar_list_record
;
3765 tree decl_specs
, field_decl
, field_decl_chain
;
3767 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3769 /* int ivar_count; */
3771 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3772 field_decl
= get_identifier ("ivar_count");
3774 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3775 decl_specs
, NULL_TREE
);
3776 field_decl_chain
= field_decl
;
3778 /* struct objc_ivar ivar_list[]; */
3780 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3781 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3782 build_int_2 (size
, 0));
3784 field_decl
= grokfield (input_filename
, lineno
,
3785 field_decl
, decl_specs
, NULL_TREE
);
3786 chainon (field_decl_chain
, field_decl
);
3788 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3790 return objc_ivar_list_record
;
3796 struct objc_method method_list[method_count];
3800 build_method_list_template (list_type
, size
)
3804 tree objc_ivar_list_record
;
3805 tree decl_specs
, field_decl
, field_decl_chain
;
3807 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3809 /* int method_next; */
3814 xref_tag (RECORD_TYPE
,
3815 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3817 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3818 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3819 decl_specs
, NULL_TREE
);
3820 field_decl_chain
= field_decl
;
3822 /* int method_count; */
3824 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3825 field_decl
= get_identifier ("method_count");
3827 field_decl
= grokfield (input_filename
, lineno
,
3828 field_decl
, decl_specs
, NULL_TREE
);
3829 chainon (field_decl_chain
, field_decl
);
3831 /* struct objc_method method_list[]; */
3833 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3834 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3835 build_int_2 (size
, 0));
3837 field_decl
= grokfield (input_filename
, lineno
,
3838 field_decl
, decl_specs
, NULL_TREE
);
3839 chainon (field_decl_chain
, field_decl
);
3841 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3843 return objc_ivar_list_record
;
3847 build_ivar_list_initializer (type
, field_decl
)
3851 tree initlist
= NULL_TREE
;
3855 tree ivar
= NULL_TREE
;
3858 if (DECL_NAME (field_decl
))
3859 ivar
= tree_cons (NULL_TREE
,
3860 add_objc_string (DECL_NAME (field_decl
),
3864 /* Unnamed bit-field ivar (yuck). */
3865 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3868 encode_field_decl (field_decl
,
3869 obstack_object_size (&util_obstack
),
3870 OBJC_ENCODE_DONT_INLINE_DEFS
);
3872 /* Null terminate string. */
3873 obstack_1grow (&util_obstack
, 0);
3877 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3880 obstack_free (&util_obstack
, util_firstobj
);
3883 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3884 initlist
= tree_cons (NULL_TREE
,
3885 build_constructor (type
, nreverse (ivar
)),
3888 field_decl
= TREE_CHAIN (field_decl
);
3892 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3896 generate_ivars_list (type
, name
, size
, list
)
3902 tree sc_spec
, decl_specs
, decl
, initlist
;
3904 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3905 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3907 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3908 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3910 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3911 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3914 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3921 generate_ivar_lists ()
3923 tree initlist
, ivar_list_template
, chain
;
3924 tree cast
, variable_length_type
;
3927 generating_instance_variables
= 1;
3929 if (!objc_ivar_template
)
3930 objc_ivar_template
= build_ivar_template ();
3934 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3935 get_identifier (UTAG_IVAR_LIST
))),
3937 variable_length_type
= groktypename (cast
);
3939 /* Only generate class variables for the root of the inheritance
3940 hierarchy since these will be the same for every class. */
3942 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3943 && (chain
= TYPE_FIELDS (objc_class_template
)))
3945 size
= list_length (chain
);
3947 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3948 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3950 UOBJC_CLASS_VARIABLES_decl
3951 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3953 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3956 UOBJC_CLASS_VARIABLES_decl
= 0;
3958 chain
= CLASS_IVARS (implementation_template
);
3961 size
= list_length (chain
);
3962 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3963 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3965 UOBJC_INSTANCE_VARIABLES_decl
3966 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3968 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3971 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3973 generating_instance_variables
= 0;
3977 build_dispatch_table_initializer (type
, entries
)
3981 tree initlist
= NULL_TREE
;
3985 tree elemlist
= NULL_TREE
;
3987 elemlist
= tree_cons (NULL_TREE
,
3988 build_selector (METHOD_SEL_NAME (entries
)),
3991 elemlist
= tree_cons (NULL_TREE
,
3992 add_objc_string (METHOD_ENCODING (entries
),
3996 elemlist
= tree_cons (NULL_TREE
,
3997 build_unary_op (ADDR_EXPR
,
3998 METHOD_DEFINITION (entries
), 1),
4001 initlist
= tree_cons (NULL_TREE
,
4002 build_constructor (type
, nreverse (elemlist
)),
4005 entries
= TREE_CHAIN (entries
);
4009 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4012 /* To accomplish method prototyping without generating all kinds of
4013 inane warnings, the definition of the dispatch table entries were
4016 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4018 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4021 build_method_template ()
4024 tree decl_specs
, field_decl
, field_decl_chain
;
4026 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4028 #ifdef OBJC_INT_SELECTORS
4029 /* unsigned int _cmd; */
4030 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
4032 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
4033 field_decl
= get_identifier ("_cmd");
4034 #else /* not OBJC_INT_SELECTORS */
4035 /* struct objc_selector *_cmd; */
4036 decl_specs
= tree_cons (NULL_TREE
,
4037 xref_tag (RECORD_TYPE
,
4038 get_identifier (TAG_SELECTOR
)),
4040 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4041 #endif /* not OBJC_INT_SELECTORS */
4043 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4044 decl_specs
, NULL_TREE
);
4045 field_decl_chain
= field_decl
;
4047 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4048 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4049 get_identifier ("method_types"));
4050 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4051 decl_specs
, NULL_TREE
);
4052 chainon (field_decl_chain
, field_decl
);
4056 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4057 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4058 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4059 decl_specs
, NULL_TREE
);
4060 chainon (field_decl_chain
, field_decl
);
4062 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4069 generate_dispatch_table (type
, name
, size
, list
)
4075 tree sc_spec
, decl_specs
, decl
, initlist
;
4077 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4078 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4080 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4081 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4083 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4084 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4085 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4088 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4095 generate_dispatch_tables ()
4097 tree initlist
, chain
, method_list_template
;
4098 tree cast
, variable_length_type
;
4101 if (!objc_method_template
)
4102 objc_method_template
= build_method_template ();
4106 (build_tree_list (NULL_TREE
,
4107 xref_tag (RECORD_TYPE
,
4108 get_identifier (UTAG_METHOD_LIST
))),
4111 variable_length_type
= groktypename (cast
);
4113 chain
= CLASS_CLS_METHODS (implementation_context
);
4116 size
= list_length (chain
);
4118 method_list_template
4119 = build_method_list_template (objc_method_template
, size
);
4121 = build_dispatch_table_initializer (objc_method_template
, chain
);
4123 UOBJC_CLASS_METHODS_decl
4124 = generate_dispatch_table (method_list_template
,
4125 ((TREE_CODE (implementation_context
)
4126 == CLASS_IMPLEMENTATION_TYPE
)
4127 ? "_OBJC_CLASS_METHODS"
4128 : "_OBJC_CATEGORY_CLASS_METHODS"),
4130 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4133 UOBJC_CLASS_METHODS_decl
= 0;
4135 chain
= CLASS_NST_METHODS (implementation_context
);
4138 size
= list_length (chain
);
4140 method_list_template
4141 = build_method_list_template (objc_method_template
, size
);
4143 = build_dispatch_table_initializer (objc_method_template
, chain
);
4145 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4146 UOBJC_INSTANCE_METHODS_decl
4147 = generate_dispatch_table (method_list_template
,
4148 "_OBJC_INSTANCE_METHODS",
4151 /* We have a category. */
4152 UOBJC_INSTANCE_METHODS_decl
4153 = generate_dispatch_table (method_list_template
,
4154 "_OBJC_CATEGORY_INSTANCE_METHODS",
4156 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4159 UOBJC_INSTANCE_METHODS_decl
= 0;
4163 generate_protocol_list (i_or_p
)
4166 tree initlist
, decl_specs
, sc_spec
;
4167 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4171 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4172 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4173 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4174 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4175 plist
= PROTOCOL_LIST (i_or_p
);
4179 cast_type
= groktypename
4181 (build_tree_list (NULL_TREE
,
4182 xref_tag (RECORD_TYPE
,
4183 get_identifier (UTAG_PROTOCOL
))),
4184 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4187 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4188 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4189 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4192 /* Build initializer. */
4193 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4195 e
= build_int_2 (size
, 0);
4196 TREE_TYPE (e
) = cast_type
;
4197 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4199 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4201 tree pval
= TREE_VALUE (lproto
);
4203 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4204 && PROTOCOL_FORWARD_DECL (pval
))
4206 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4207 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4211 /* static struct objc_protocol *refs[n]; */
4213 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4214 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4215 get_identifier (UTAG_PROTOCOL
)),
4218 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4219 expr_decl
= build_nt (ARRAY_REF
,
4220 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4222 build_int_2 (size
+ 2, 0));
4223 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4224 expr_decl
= build_nt (ARRAY_REF
,
4225 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4227 build_int_2 (size
+ 2, 0));
4228 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4230 = build_nt (ARRAY_REF
,
4231 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4233 build_int_2 (size
+ 2, 0));
4237 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4239 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4241 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4242 nreverse (initlist
)),
4249 build_category_initializer (type
, cat_name
, class_name
,
4250 instance_methods
, class_methods
, protocol_list
)
4254 tree instance_methods
;
4258 tree initlist
= NULL_TREE
, expr
;
4260 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4261 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4263 if (!instance_methods
)
4264 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4267 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4268 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4271 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4274 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4275 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4278 /* protocol_list = */
4280 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4283 tree cast_type2
= groktypename
4285 (build_tree_list (NULL_TREE
,
4286 xref_tag (RECORD_TYPE
,
4287 get_identifier (UTAG_PROTOCOL
))),
4288 build1 (INDIRECT_REF
, NULL_TREE
,
4289 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4291 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4292 TREE_TYPE (expr
) = cast_type2
;
4293 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4296 return build_constructor (type
, nreverse (initlist
));
4299 /* struct objc_class {
4300 struct objc_class *isa;
4301 struct objc_class *super_class;
4306 struct objc_ivar_list *ivars;
4307 struct objc_method_list *methods;
4308 if (flag_next_runtime)
4309 struct objc_cache *cache;
4311 struct sarray *dtable;
4312 struct objc_class *subclass_list;
4313 struct objc_class *sibling_class;
4315 struct objc_protocol_list *protocols;
4316 void *gc_object_type;
4320 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4321 dispatch_table
, ivar_list
, protocol_list
)
4328 tree dispatch_table
;
4332 tree initlist
= NULL_TREE
, expr
;
4335 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4338 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4341 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4344 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4347 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4349 /* instance_size = */
4350 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4352 /* objc_ivar_list = */
4354 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4357 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4358 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4361 /* objc_method_list = */
4362 if (!dispatch_table
)
4363 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4366 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4367 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4370 if (flag_next_runtime
)
4371 /* method_cache = */
4372 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4376 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4378 /* subclass_list = */
4379 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4381 /* sibling_class = */
4382 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4385 /* protocol_list = */
4386 if (! protocol_list
)
4387 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4393 (build_tree_list (NULL_TREE
,
4394 xref_tag (RECORD_TYPE
,
4395 get_identifier (UTAG_PROTOCOL
))),
4396 build1 (INDIRECT_REF
, NULL_TREE
,
4397 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4399 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4400 TREE_TYPE (expr
) = cast_type2
;
4401 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4404 /* gc_object_type = NULL */
4405 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4407 return build_constructor (type
, nreverse (initlist
));
4410 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4413 generate_category (cat
)
4416 tree sc_spec
, decl_specs
, decl
;
4417 tree initlist
, cat_name_expr
, class_name_expr
;
4418 tree protocol_decl
, category
;
4420 add_class_reference (CLASS_NAME (cat
));
4421 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4423 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4425 category
= CLASS_CATEGORY_LIST (implementation_template
);
4427 /* find the category interface from the class it is associated with */
4430 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4432 category
= CLASS_CATEGORY_LIST (category
);
4435 if (category
&& CLASS_PROTOCOL_LIST (category
))
4437 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4438 protocol_decl
= generate_protocol_list (category
);
4443 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4444 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4446 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4447 implementation_context
),
4448 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4450 initlist
= build_category_initializer (TREE_TYPE (decl
),
4451 cat_name_expr
, class_name_expr
,
4452 UOBJC_INSTANCE_METHODS_decl
,
4453 UOBJC_CLASS_METHODS_decl
,
4456 TREE_USED (decl
) = 1;
4457 finish_decl (decl
, initlist
, NULL_TREE
);
4460 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4461 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4464 generate_shared_structures ()
4466 tree sc_spec
, decl_specs
, decl
;
4467 tree name_expr
, super_expr
, root_expr
;
4468 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4469 tree cast_type
, initlist
, protocol_decl
;
4471 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4474 add_class_reference (my_super_id
);
4476 /* Compute "my_root_id" - this is required for code generation.
4477 the "isa" for all meta class structures points to the root of
4478 the inheritance hierarchy (e.g. "__Object")... */
4479 my_root_id
= my_super_id
;
4482 tree my_root_int
= lookup_interface (my_root_id
);
4484 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4485 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4492 /* No super class. */
4493 my_root_id
= CLASS_NAME (implementation_template
);
4496 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4497 objc_class_template
),
4498 build1 (INDIRECT_REF
,
4499 NULL_TREE
, NULL_TREE
)));
4501 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4504 /* Install class `isa' and `super' pointers at runtime. */
4507 super_expr
= add_objc_string (my_super_id
, class_names
);
4508 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4511 super_expr
= build_int_2 (0, 0);
4513 root_expr
= add_objc_string (my_root_id
, class_names
);
4514 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4516 if (CLASS_PROTOCOL_LIST (implementation_template
))
4518 generate_protocol_references
4519 (CLASS_PROTOCOL_LIST (implementation_template
));
4520 protocol_decl
= generate_protocol_list (implementation_template
);
4525 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4527 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4528 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4530 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4531 NULL_TREE
, NULL_TREE
);
4534 = build_shared_structure_initializer
4536 root_expr
, super_expr
, name_expr
,
4537 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4539 UOBJC_CLASS_METHODS_decl
,
4540 UOBJC_CLASS_VARIABLES_decl
,
4543 finish_decl (decl
, initlist
, NULL_TREE
);
4545 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4547 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4548 NULL_TREE
, NULL_TREE
);
4551 = build_shared_structure_initializer
4553 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4554 super_expr
, name_expr
,
4555 convert (integer_type_node
,
4556 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4557 (implementation_template
))),
4559 UOBJC_INSTANCE_METHODS_decl
,
4560 UOBJC_INSTANCE_VARIABLES_decl
,
4563 finish_decl (decl
, initlist
, NULL_TREE
);
4567 synth_id_with_class_suffix (preamble
, ctxt
)
4568 const char *preamble
;
4572 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4573 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4575 const char *class_name
4576 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4577 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4578 sprintf (string
, "%s_%s", preamble
,
4579 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4581 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4582 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4584 /* We have a category. */
4585 const char *class_name
4586 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4587 const char *class_super_name
4588 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4589 string
= (char *) alloca (strlen (preamble
)
4590 + strlen (class_name
)
4591 + strlen (class_super_name
)
4593 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4595 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4597 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4599 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4600 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4605 return get_identifier (string
);
4609 is_objc_type_qualifier (node
)
4612 return (TREE_CODE (node
) == IDENTIFIER_NODE
4613 && (node
== ridpointers
[(int) RID_CONST
]
4614 || node
== ridpointers
[(int) RID_VOLATILE
]
4615 || node
== ridpointers
[(int) RID_IN
]
4616 || node
== ridpointers
[(int) RID_OUT
]
4617 || node
== ridpointers
[(int) RID_INOUT
]
4618 || node
== ridpointers
[(int) RID_BYCOPY
]
4619 || node
== ridpointers
[(int) RID_BYREF
]
4620 || node
== ridpointers
[(int) RID_ONEWAY
]));
4623 /* If type is empty or only type qualifiers are present, add default
4624 type of id (otherwise grokdeclarator will default to int). */
4627 adjust_type_for_id_default (type
)
4630 tree declspecs
, chain
;
4633 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4634 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4636 declspecs
= TREE_PURPOSE (type
);
4638 /* Determine if a typespec is present. */
4639 for (chain
= declspecs
;
4641 chain
= TREE_CHAIN (chain
))
4643 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4647 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4649 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4654 selector ':' '(' typename ')' identifier
4657 Transform an Objective-C keyword argument into
4658 the C equivalent parameter declarator.
4660 In: key_name, an "identifier_node" (optional).
4661 arg_type, a "tree_list" (optional).
4662 arg_name, an "identifier_node".
4664 Note: It would be really nice to strongly type the preceding
4665 arguments in the function prototype; however, then I
4666 could not use the "accessor" macros defined in "tree.h".
4668 Out: an instance of "keyword_decl". */
4671 build_keyword_decl (key_name
, arg_type
, arg_name
)
4678 /* If no type is specified, default to "id". */
4679 arg_type
= adjust_type_for_id_default (arg_type
);
4681 keyword_decl
= make_node (KEYWORD_DECL
);
4683 TREE_TYPE (keyword_decl
) = arg_type
;
4684 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4685 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4687 return keyword_decl
;
4690 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4693 build_keyword_selector (selector
)
4697 tree key_chain
, key_name
;
4700 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4702 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4703 key_name
= KEYWORD_KEY_NAME (key_chain
);
4704 else if (TREE_CODE (selector
) == TREE_LIST
)
4705 key_name
= TREE_PURPOSE (key_chain
);
4710 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4712 /* Just a ':' arg. */
4716 buf
= (char *)alloca (len
+ 1);
4717 memset (buf
, 0, len
+ 1);
4719 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4721 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4722 key_name
= KEYWORD_KEY_NAME (key_chain
);
4723 else if (TREE_CODE (selector
) == TREE_LIST
)
4724 key_name
= TREE_PURPOSE (key_chain
);
4729 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4733 return get_identifier (buf
);
4736 /* Used for declarations and definitions. */
4739 build_method_decl (code
, ret_type
, selector
, add_args
)
4740 enum tree_code code
;
4747 /* If no type is specified, default to "id". */
4748 ret_type
= adjust_type_for_id_default (ret_type
);
4750 method_decl
= make_node (code
);
4751 TREE_TYPE (method_decl
) = ret_type
;
4753 /* If we have a keyword selector, create an identifier_node that
4754 represents the full selector name (`:' included)... */
4755 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4757 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4758 METHOD_SEL_ARGS (method_decl
) = selector
;
4759 METHOD_ADD_ARGS (method_decl
) = add_args
;
4763 METHOD_SEL_NAME (method_decl
) = selector
;
4764 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4765 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4771 #define METHOD_DEF 0
4772 #define METHOD_REF 1
4774 /* Used by `build_message_expr' and `comp_method_types'. Return an
4775 argument list for method METH. CONTEXT is either METHOD_DEF or
4776 METHOD_REF, saying whether we are trying to define a method or call
4777 one. SUPERFLAG says this is for a send to super; this makes a
4778 difference for the NeXT calling sequence in which the lookup and
4779 the method call are done together. */
4782 get_arg_type_list (meth
, context
, superflag
)
4789 /* Receiver type. */
4790 if (flag_next_runtime
&& superflag
)
4791 arglist
= build_tree_list (NULL_TREE
, super_type
);
4792 else if (context
== METHOD_DEF
)
4793 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4795 arglist
= build_tree_list (NULL_TREE
, id_type
);
4797 /* Selector type - will eventually change to `int'. */
4798 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4800 /* Build a list of argument types. */
4801 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4803 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4804 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4807 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4808 /* We have a `, ...' immediately following the selector,
4809 finalize the arglist...simulate get_parm_info (0). */
4811 else if (METHOD_ADD_ARGS (meth
))
4813 /* we have a variable length selector */
4814 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4815 chainon (arglist
, add_arg_list
);
4818 /* finalize the arglist...simulate get_parm_info (1) */
4819 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4825 check_duplicates (hsh
)
4828 tree meth
= NULL_TREE
;
4836 /* We have two methods with the same name and different types. */
4838 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4840 warning ("multiple declarations for method `%s'",
4841 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4843 warn_with_method ("using", type
, meth
);
4844 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4845 warn_with_method ("also found", type
, loop
->value
);
4851 /* If RECEIVER is a class reference, return the identifier node for the
4852 referenced class. RECEIVER is created by get_class_reference, so we
4853 check the exact form created depending on which runtimes are used. */
4856 receiver_is_class_object (receiver
)
4859 tree chain
, exp
, arg
;
4860 if (flag_next_runtime
)
4862 /* The receiver is a variable created by build_class_reference_decl. */
4863 if (TREE_CODE (receiver
) == VAR_DECL
4864 && TREE_TYPE (receiver
) == objc_class_type
)
4865 /* Look up the identifier. */
4866 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4867 if (TREE_PURPOSE (chain
) == receiver
)
4868 return TREE_VALUE (chain
);
4872 /* The receiver is a function call that returns an id. Check if
4873 it is a call to objc_getClass, if so, pick up the class name. */
4874 if ((exp
= TREE_OPERAND (receiver
, 0))
4875 && TREE_CODE (exp
) == ADDR_EXPR
4876 && (exp
= TREE_OPERAND (exp
, 0))
4877 && TREE_CODE (exp
) == FUNCTION_DECL
4878 && exp
== objc_get_class_decl
4879 /* we have a call to objc_getClass! */
4880 && (arg
= TREE_OPERAND (receiver
, 1))
4881 && TREE_CODE (arg
) == TREE_LIST
4882 && (arg
= TREE_VALUE (arg
)))
4885 if (TREE_CODE (arg
) == ADDR_EXPR
4886 && (arg
= TREE_OPERAND (arg
, 0))
4887 && TREE_CODE (arg
) == STRING_CST
)
4888 /* Finally, we have the class name. */
4889 return get_identifier (TREE_STRING_POINTER (arg
));
4895 /* If we are currently building a message expr, this holds
4896 the identifier of the selector of the message. This is
4897 used when printing warnings about argument mismatches. */
4899 static tree building_objc_message_expr
= 0;
4902 maybe_building_objc_message_expr ()
4904 return building_objc_message_expr
;
4907 /* Construct an expression for sending a message.
4908 MESS has the object to send to in TREE_PURPOSE
4909 and the argument list (including selector) in TREE_VALUE.
4911 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4912 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4915 build_message_expr (mess
)
4918 tree receiver
= TREE_PURPOSE (mess
);
4919 tree selector
, self_object
;
4920 tree rtype
, sel_name
;
4921 tree args
= TREE_VALUE (mess
);
4922 tree method_params
= NULL_TREE
;
4923 tree method_prototype
= NULL_TREE
;
4925 int statically_typed
= 0, statically_allocated
= 0;
4926 tree class_ident
= 0;
4928 /* 1 if this is sending to the superclass. */
4931 if (TREE_CODE (receiver
) == ERROR_MARK
)
4932 return error_mark_node
;
4934 /* Determine receiver type. */
4935 rtype
= TREE_TYPE (receiver
);
4936 super
= IS_SUPER (rtype
);
4940 if (TREE_STATIC_TEMPLATE (rtype
))
4941 statically_allocated
= 1;
4942 else if (TREE_CODE (rtype
) == POINTER_TYPE
4943 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4944 statically_typed
= 1;
4945 else if ((flag_next_runtime
4946 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4947 && (class_ident
= receiver_is_class_object (receiver
)))
4949 else if (! IS_ID (rtype
)
4950 /* Allow any type that matches objc_class_type. */
4951 && ! comptypes (rtype
, objc_class_type
))
4953 memset (errbuf
, 0, BUFSIZE
);
4954 warning ("invalid receiver type `%s'",
4955 gen_declaration (rtype
, errbuf
));
4958 if (statically_allocated
)
4959 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4961 /* Don't evaluate the receiver twice. */
4962 receiver
= save_expr (receiver
);
4963 self_object
= receiver
;
4966 /* If sending to `super', use current self as the object. */
4967 self_object
= self_decl
;
4969 /* Obtain the full selector name. */
4971 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4972 /* A unary selector. */
4974 else if (TREE_CODE (args
) == TREE_LIST
)
4975 sel_name
= build_keyword_selector (args
);
4979 /* Build the parameter list to give to the method. */
4981 method_params
= NULL_TREE
;
4982 if (TREE_CODE (args
) == TREE_LIST
)
4984 tree chain
= args
, prev
= NULL_TREE
;
4986 /* We have a keyword selector--check for comma expressions. */
4989 tree element
= TREE_VALUE (chain
);
4991 /* We have a comma expression, must collapse... */
4992 if (TREE_CODE (element
) == TREE_LIST
)
4995 TREE_CHAIN (prev
) = element
;
5000 chain
= TREE_CHAIN (chain
);
5002 method_params
= args
;
5005 /* Determine operation return type. */
5007 if (IS_SUPER (rtype
))
5011 if (CLASS_SUPER_NAME (implementation_template
))
5014 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5016 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5017 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5019 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5021 if (iface
&& !method_prototype
)
5022 warning ("`%s' does not respond to `%s'",
5023 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5024 IDENTIFIER_POINTER (sel_name
));
5028 error ("no super class declared in interface for `%s'",
5029 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5030 return error_mark_node
;
5034 else if (statically_allocated
)
5036 tree ctype
= TREE_TYPE (rtype
);
5037 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5040 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5042 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5044 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5047 if (!method_prototype
)
5048 warning ("`%s' does not respond to `%s'",
5049 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5050 IDENTIFIER_POINTER (sel_name
));
5052 else if (statically_typed
)
5054 tree ctype
= TREE_TYPE (rtype
);
5056 /* `self' is now statically_typed. All methods should be visible
5057 within the context of the implementation. */
5058 if (implementation_context
5059 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5062 = lookup_instance_method_static (implementation_template
,
5065 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5067 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5070 if (! method_prototype
5071 && implementation_template
!= implementation_context
)
5072 /* The method is not published in the interface. Check
5075 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5082 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5083 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5085 if (! method_prototype
)
5087 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5090 = lookup_method_in_protocol_list (protocol_list
,
5095 if (!method_prototype
)
5096 warning ("`%s' does not respond to `%s'",
5097 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5098 IDENTIFIER_POINTER (sel_name
));
5100 else if (class_ident
)
5102 if (implementation_context
5103 && CLASS_NAME (implementation_context
) == class_ident
)
5106 = lookup_class_method_static (implementation_template
, sel_name
);
5108 if (!method_prototype
5109 && implementation_template
!= implementation_context
)
5110 /* The method is not published in the interface. Check
5113 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5120 if ((iface
= lookup_interface (class_ident
)))
5121 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5124 if (!method_prototype
)
5126 warning ("cannot find class (factory) method.");
5127 warning ("return type for `%s' defaults to id",
5128 IDENTIFIER_POINTER (sel_name
));
5131 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5133 /* An anonymous object that has been qualified with a protocol. */
5135 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5137 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5140 if (!method_prototype
)
5144 warning ("method `%s' not implemented by protocol.",
5145 IDENTIFIER_POINTER (sel_name
));
5147 /* Try and find the method signature in the global pools. */
5149 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5150 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5152 if (!(method_prototype
= check_duplicates (hsh
)))
5153 warning ("return type defaults to id");
5160 /* We think we have an instance...loophole: extern id Object; */
5161 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5163 /* For various loopholes, like sending messages to self in a
5165 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5167 method_prototype
= check_duplicates (hsh
);
5168 if (!method_prototype
)
5170 warning ("cannot find method.");
5171 warning ("return type for `%s' defaults to id",
5172 IDENTIFIER_POINTER (sel_name
));
5176 /* Save the selector name for printing error messages. */
5177 building_objc_message_expr
= sel_name
;
5179 /* Build the parameters list for looking up the method.
5180 These are the object itself and the selector. */
5182 if (flag_typed_selectors
)
5183 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5185 selector
= build_selector_reference (sel_name
);
5187 retval
= build_objc_method_call (super
, method_prototype
,
5188 receiver
, self_object
,
5189 selector
, method_params
);
5191 building_objc_message_expr
= 0;
5196 /* Build a tree expression to send OBJECT the operation SELECTOR,
5197 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5198 assuming the method has prototype METHOD_PROTOTYPE.
5199 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5200 Use METHOD_PARAMS as list of args to pass to the method.
5201 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5204 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5205 selector
, method_params
)
5207 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5209 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5210 tree rcv_p
= (super_flag
5211 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5212 get_identifier (TAG_SUPER
)))
5215 if (flag_next_runtime
)
5217 if (! method_prototype
)
5219 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5220 tree_cons (NULL_TREE
, selector
,
5222 assemble_external (sender
);
5223 return build_function_call (sender
, method_params
);
5227 /* This is a real kludge, but it is used only for the Next.
5228 Clobber the data type of SENDER temporarily to accept
5229 all the arguments for this operation, and to return
5230 whatever this operation returns. */
5231 tree arglist
= NULL_TREE
;
5234 /* Save the proper contents of SENDER's data type. */
5235 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5236 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5238 /* Install this method's argument types. */
5239 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5241 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5243 /* Install this method's return type. */
5244 TREE_TYPE (TREE_TYPE (sender
))
5245 = groktypename (TREE_TYPE (method_prototype
));
5247 /* Call SENDER with all the parameters. This will do type
5248 checking using the arg types for this method. */
5249 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5250 tree_cons (NULL_TREE
, selector
,
5252 assemble_external (sender
);
5253 retval
= build_function_call (sender
, method_params
);
5255 /* Restore SENDER's return/argument types. */
5256 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5257 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5263 /* This is the portable way.
5264 First call the lookup function to get a pointer to the method,
5265 then cast the pointer, then call it with the method arguments. */
5268 /* Avoid trouble since we may evaluate each of these twice. */
5269 object
= save_expr (object
);
5270 selector
= save_expr (selector
);
5272 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5274 assemble_external (sender
);
5276 = build_function_call (sender
,
5277 tree_cons (NULL_TREE
, lookup_object
,
5278 tree_cons (NULL_TREE
, selector
,
5281 /* If we have a method prototype, construct the data type this
5282 method needs, and cast what we got from SENDER into a pointer
5284 if (method_prototype
)
5286 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5288 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5289 tree fake_function_type
= build_function_type (valtype
, arglist
);
5290 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5294 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5296 /* Pass the object to the method. */
5297 assemble_external (method
);
5298 return build_function_call (method
,
5299 tree_cons (NULL_TREE
, object
,
5300 tree_cons (NULL_TREE
, selector
,
5306 build_protocol_reference (p
)
5309 tree decl
, ident
, ptype
;
5311 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5313 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5315 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5316 objc_protocol_template
),
5319 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5320 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5323 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5324 DECL_EXTERNAL (decl
) = 1;
5325 TREE_PUBLIC (decl
) = 1;
5326 TREE_USED (decl
) = 1;
5327 DECL_ARTIFICIAL (decl
) = 1;
5329 make_decl_rtl (decl
, 0, 1);
5330 pushdecl_top_level (decl
);
5333 PROTOCOL_FORWARD_DECL (p
) = decl
;
5337 build_protocol_expr (protoname
)
5341 tree p
= lookup_protocol (protoname
);
5345 error ("Cannot find protocol declaration for `%s'",
5346 IDENTIFIER_POINTER (protoname
));
5347 return error_mark_node
;
5350 if (!PROTOCOL_FORWARD_DECL (p
))
5351 build_protocol_reference (p
);
5353 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5355 TREE_TYPE (expr
) = protocol_type
;
5361 build_selector_expr (selnamelist
)
5366 /* Obtain the full selector name. */
5367 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5368 /* A unary selector. */
5369 selname
= selnamelist
;
5370 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5371 selname
= build_keyword_selector (selnamelist
);
5375 if (flag_typed_selectors
)
5376 return build_typed_selector_reference (selname
, 0);
5378 return build_selector_reference (selname
);
5382 build_encode_expr (type
)
5388 encode_type (type
, obstack_object_size (&util_obstack
),
5389 OBJC_ENCODE_INLINE_DEFS
);
5390 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5391 string
= obstack_finish (&util_obstack
);
5393 /* Synthesize a string that represents the encoded struct/union. */
5394 result
= my_build_string (strlen (string
) + 1, string
);
5395 obstack_free (&util_obstack
, util_firstobj
);
5400 build_ivar_reference (id
)
5403 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5405 /* Historically, a class method that produced objects (factory
5406 method) would assign `self' to the instance that it
5407 allocated. This would effectively turn the class method into
5408 an instance method. Following this assignment, the instance
5409 variables could be accessed. That practice, while safe,
5410 violates the simple rule that a class method should not refer
5411 to an instance variable. It's better to catch the cases
5412 where this is done unknowingly than to support the above
5414 warning ("instance variable `%s' accessed in class method",
5415 IDENTIFIER_POINTER (id
));
5416 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5419 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5422 #define HASH_ALLOC_LIST_SIZE 170
5423 #define ATTR_ALLOC_LIST_SIZE 170
5424 #define SIZEHASHTABLE 257
5427 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5432 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5433 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5435 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5436 perror ("unable to allocate space in objc-tree.c");
5441 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5443 nst_method_hash_list
[i
] = 0;
5444 cls_method_hash_list
[i
] = 0;
5450 hash_enter (hashlist
, method
)
5454 static hash hash_alloc_list
= 0;
5455 static int hash_alloc_index
= 0;
5457 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5459 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5461 hash_alloc_index
= 0;
5462 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5463 * HASH_ALLOC_LIST_SIZE
);
5464 if (! hash_alloc_list
)
5465 perror ("unable to allocate in objc-tree.c");
5467 obj
= &hash_alloc_list
[hash_alloc_index
++];
5469 obj
->next
= hashlist
[slot
];
5472 hashlist
[slot
] = obj
; /* append to front */
5476 hash_lookup (hashlist
, sel_name
)
5482 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5486 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5489 target
= target
->next
;
5495 hash_add_attr (entry
, value
)
5499 static attr attr_alloc_list
= 0;
5500 static int attr_alloc_index
= 0;
5503 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5505 attr_alloc_index
= 0;
5506 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5507 * ATTR_ALLOC_LIST_SIZE
);
5508 if (! attr_alloc_list
)
5509 perror ("unable to allocate in objc-tree.c");
5511 obj
= &attr_alloc_list
[attr_alloc_index
++];
5512 obj
->next
= entry
->list
;
5515 entry
->list
= obj
; /* append to front */
5519 lookup_method (mchain
, method
)
5525 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5528 key
= METHOD_SEL_NAME (method
);
5532 if (METHOD_SEL_NAME (mchain
) == key
)
5534 mchain
= TREE_CHAIN (mchain
);
5540 lookup_instance_method_static (interface
, ident
)
5544 tree inter
= interface
;
5545 tree chain
= CLASS_NST_METHODS (inter
);
5546 tree meth
= NULL_TREE
;
5550 if ((meth
= lookup_method (chain
, ident
)))
5553 if (CLASS_CATEGORY_LIST (inter
))
5555 tree category
= CLASS_CATEGORY_LIST (inter
);
5556 chain
= CLASS_NST_METHODS (category
);
5560 if ((meth
= lookup_method (chain
, ident
)))
5563 /* Check for instance methods in protocols in categories. */
5564 if (CLASS_PROTOCOL_LIST (category
))
5566 if ((meth
= (lookup_method_in_protocol_list
5567 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5571 if ((category
= CLASS_CATEGORY_LIST (category
)))
5572 chain
= CLASS_NST_METHODS (category
);
5577 if (CLASS_PROTOCOL_LIST (inter
))
5579 if ((meth
= (lookup_method_in_protocol_list
5580 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5584 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5585 chain
= CLASS_NST_METHODS (inter
);
5593 lookup_class_method_static (interface
, ident
)
5597 tree inter
= interface
;
5598 tree chain
= CLASS_CLS_METHODS (inter
);
5599 tree meth
= NULL_TREE
;
5600 tree root_inter
= NULL_TREE
;
5604 if ((meth
= lookup_method (chain
, ident
)))
5607 if (CLASS_CATEGORY_LIST (inter
))
5609 tree category
= CLASS_CATEGORY_LIST (inter
);
5610 chain
= CLASS_CLS_METHODS (category
);
5614 if ((meth
= lookup_method (chain
, ident
)))
5617 /* Check for class methods in protocols in categories. */
5618 if (CLASS_PROTOCOL_LIST (category
))
5620 if ((meth
= (lookup_method_in_protocol_list
5621 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5625 if ((category
= CLASS_CATEGORY_LIST (category
)))
5626 chain
= CLASS_CLS_METHODS (category
);
5631 /* Check for class methods in protocols. */
5632 if (CLASS_PROTOCOL_LIST (inter
))
5634 if ((meth
= (lookup_method_in_protocol_list
5635 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5640 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5641 chain
= CLASS_CLS_METHODS (inter
);
5645 /* Simulate wrap around. */
5646 return lookup_instance_method_static (root_inter
, ident
);
5650 add_class_method (class, method
)
5657 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5659 /* put method on list in reverse order */
5660 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5661 CLASS_CLS_METHODS (class) = method
;
5665 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5666 error ("duplicate definition of class method `%s'.",
5667 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5670 /* Check types; if different, complain. */
5671 if (!comp_proto_with_proto (method
, mth
))
5672 error ("duplicate declaration of class method `%s'.",
5673 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5677 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5679 /* Install on a global chain. */
5680 hash_enter (cls_method_hash_list
, method
);
5684 /* Check types; if different, add to a list. */
5685 if (!comp_proto_with_proto (method
, hsh
->key
))
5686 hash_add_attr (hsh
, method
);
5692 add_instance_method (class, method
)
5699 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5701 /* Put method on list in reverse order. */
5702 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5703 CLASS_NST_METHODS (class) = method
;
5707 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5708 error ("duplicate definition of instance method `%s'.",
5709 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5712 /* Check types; if different, complain. */
5713 if (!comp_proto_with_proto (method
, mth
))
5714 error ("duplicate declaration of instance method `%s'.",
5715 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5719 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5721 /* Install on a global chain. */
5722 hash_enter (nst_method_hash_list
, method
);
5726 /* Check types; if different, add to a list. */
5727 if (!comp_proto_with_proto (method
, hsh
->key
))
5728 hash_add_attr (hsh
, method
);
5737 /* Put interfaces on list in reverse order. */
5738 TREE_CHAIN (class) = interface_chain
;
5739 interface_chain
= class;
5740 return interface_chain
;
5744 add_category (class, category
)
5748 /* Put categories on list in reverse order. */
5749 tree cat
= CLASS_CATEGORY_LIST (class);
5753 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5754 warning ("duplicate interface declaration for category `%s(%s)'",
5755 IDENTIFIER_POINTER (CLASS_NAME (class)),
5756 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5757 cat
= CLASS_CATEGORY_LIST (cat
);
5760 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5761 CLASS_CATEGORY_LIST (class) = category
;
5764 /* Called after parsing each instance variable declaration. Necessary to
5765 preserve typedefs and implement public/private...
5767 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5770 add_instance_variable (class, public, declarator
, declspecs
, width
)
5777 tree field_decl
, raw_decl
;
5779 raw_decl
= build_tree_list (declspecs
, declarator
);
5781 if (CLASS_RAW_IVARS (class))
5782 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5784 CLASS_RAW_IVARS (class) = raw_decl
;
5786 field_decl
= grokfield (input_filename
, lineno
,
5787 declarator
, declspecs
, width
);
5789 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5793 TREE_PUBLIC (field_decl
) = 0;
5794 TREE_PRIVATE (field_decl
) = 0;
5795 TREE_PROTECTED (field_decl
) = 1;
5799 TREE_PUBLIC (field_decl
) = 1;
5800 TREE_PRIVATE (field_decl
) = 0;
5801 TREE_PROTECTED (field_decl
) = 0;
5805 TREE_PUBLIC (field_decl
) = 0;
5806 TREE_PRIVATE (field_decl
) = 1;
5807 TREE_PROTECTED (field_decl
) = 0;
5812 if (CLASS_IVARS (class))
5813 chainon (CLASS_IVARS (class), field_decl
);
5815 CLASS_IVARS (class) = field_decl
;
5821 is_ivar (decl_chain
, ident
)
5825 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5826 if (DECL_NAME (decl_chain
) == ident
)
5831 /* True if the ivar is private and we are not in its implementation. */
5837 if (TREE_PRIVATE (decl
)
5838 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5840 error ("instance variable `%s' is declared private",
5841 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5848 /* We have an instance variable reference;, check to see if it is public. */
5851 is_public (expr
, identifier
)
5855 tree basetype
= TREE_TYPE (expr
);
5856 enum tree_code code
= TREE_CODE (basetype
);
5859 if (code
== RECORD_TYPE
)
5861 if (TREE_STATIC_TEMPLATE (basetype
))
5863 if (!lookup_interface (TYPE_NAME (basetype
)))
5865 error ("Cannot find interface declaration for `%s'",
5866 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5870 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5872 if (TREE_PUBLIC (decl
))
5875 /* Important difference between the Stepstone translator:
5876 all instance variables should be public within the context
5877 of the implementation. */
5878 if (implementation_context
5879 && (((TREE_CODE (implementation_context
)
5880 == CLASS_IMPLEMENTATION_TYPE
)
5881 || (TREE_CODE (implementation_context
)
5882 == CATEGORY_IMPLEMENTATION_TYPE
))
5883 && (CLASS_NAME (implementation_context
)
5884 == TYPE_NAME (basetype
))))
5885 return ! is_private (decl
);
5887 error ("instance variable `%s' is declared %s",
5888 IDENTIFIER_POINTER (identifier
),
5889 TREE_PRIVATE (decl
) ? "private" : "protected");
5894 else if (implementation_context
&& (basetype
== objc_object_reference
))
5896 TREE_TYPE (expr
) = uprivate_record
;
5897 warning ("static access to object of type `id'");
5904 /* Implement @defs (<classname>) within struct bodies. */
5907 get_class_ivars (interface
)
5910 return build_ivar_chain (interface
, 1);
5913 /* Make sure all entries in CHAIN are also in LIST. */
5916 check_methods (chain
, list
, mtype
)
5925 if (!lookup_method (list
, chain
))
5929 if (TREE_CODE (implementation_context
)
5930 == CLASS_IMPLEMENTATION_TYPE
)
5931 warning ("incomplete implementation of class `%s'",
5932 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5933 else if (TREE_CODE (implementation_context
)
5934 == CATEGORY_IMPLEMENTATION_TYPE
)
5935 warning ("incomplete implementation of category `%s'",
5936 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5940 warning ("method definition for `%c%s' not found",
5941 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5944 chain
= TREE_CHAIN (chain
);
5951 conforms_to_protocol (class, protocol
)
5957 tree p
= CLASS_PROTOCOL_LIST (class);
5959 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5964 tree super
= (CLASS_SUPER_NAME (class)
5965 ? lookup_interface (CLASS_SUPER_NAME (class))
5967 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5972 protocol
= TREE_CHAIN (protocol
);
5978 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5979 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5982 check_methods_accessible (chain
, context
, mtype
)
5989 tree base_context
= context
;
5993 context
= base_context
;
5997 list
= CLASS_CLS_METHODS (context
);
5999 list
= CLASS_NST_METHODS (context
);
6001 if (lookup_method (list
, chain
))
6004 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6005 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6006 context
= (CLASS_SUPER_NAME (context
)
6007 ? lookup_interface (CLASS_SUPER_NAME (context
))
6010 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6011 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6012 context
= (CLASS_NAME (context
)
6013 ? lookup_interface (CLASS_NAME (context
))
6019 if (context
== NULL_TREE
)
6023 if (TREE_CODE (implementation_context
)
6024 == CLASS_IMPLEMENTATION_TYPE
)
6025 warning ("incomplete implementation of class `%s'",
6027 (CLASS_NAME (implementation_context
)));
6028 else if (TREE_CODE (implementation_context
)
6029 == CATEGORY_IMPLEMENTATION_TYPE
)
6030 warning ("incomplete implementation of category `%s'",
6032 (CLASS_SUPER_NAME (implementation_context
)));
6035 warning ("method definition for `%c%s' not found",
6036 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6039 chain
= TREE_CHAIN (chain
); /* next method... */
6045 check_protocols (proto_list
, type
, name
)
6050 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6052 tree p
= TREE_VALUE (proto_list
);
6054 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6058 /* Ensure that all protocols have bodies. */
6059 if (flag_warn_protocol
) {
6060 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6061 CLASS_CLS_METHODS (implementation_context
),
6063 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6064 CLASS_NST_METHODS (implementation_context
),
6067 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6068 implementation_context
,
6070 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6071 implementation_context
,
6076 warning ("%s `%s' does not fully implement the `%s' protocol",
6077 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6082 ; /* An identifier if we could not find a protocol. */
6085 /* Check protocols recursively. */
6086 if (PROTOCOL_LIST (p
))
6089 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6090 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6091 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6096 /* Make sure that the class CLASS_NAME is defined
6097 CODE says which kind of thing CLASS_NAME ought to be.
6098 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6099 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6102 start_class (code
, class_name
, super_name
, protocol_list
)
6103 enum tree_code code
;
6110 class = make_node (code
);
6111 TYPE_BINFO (class) = make_tree_vec (5);
6113 CLASS_NAME (class) = class_name
;
6114 CLASS_SUPER_NAME (class) = super_name
;
6115 CLASS_CLS_METHODS (class) = NULL_TREE
;
6117 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6119 error ("`%s' redeclared as different kind of symbol",
6120 IDENTIFIER_POINTER (class_name
));
6121 error_with_decl (decl
, "previous declaration of `%s'");
6124 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6127 static tree implemented_classes
= 0;
6128 tree chain
= implemented_classes
;
6129 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6130 if (TREE_VALUE (chain
) == class_name
)
6132 error ("reimplementation of class `%s'",
6133 IDENTIFIER_POINTER (class_name
));
6134 return error_mark_node
;
6136 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6137 implemented_classes
);
6140 /* Pre-build the following entities - for speed/convenience. */
6142 self_id
= get_identifier ("self");
6144 ucmd_id
= get_identifier ("_cmd");
6147 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6148 if (!objc_super_template
)
6149 objc_super_template
= build_super_template ();
6151 /* Reset for multiple classes per file. */
6154 implementation_context
= class;
6156 /* Lookup the interface for this implementation. */
6158 if (!(implementation_template
= lookup_interface (class_name
)))
6160 warning ("Cannot find interface declaration for `%s'",
6161 IDENTIFIER_POINTER (class_name
));
6162 add_class (implementation_template
= implementation_context
);
6165 /* If a super class has been specified in the implementation,
6166 insure it conforms to the one specified in the interface. */
6169 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6171 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6173 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6174 error ("conflicting super class name `%s'",
6175 IDENTIFIER_POINTER (super_name
));
6176 error ("previous declaration of `%s'", name
);
6179 else if (! super_name
)
6181 CLASS_SUPER_NAME (implementation_context
)
6182 = CLASS_SUPER_NAME (implementation_template
);
6186 else if (code
== CLASS_INTERFACE_TYPE
)
6188 if (lookup_interface (class_name
))
6189 warning ("duplicate interface declaration for class `%s'",
6190 IDENTIFIER_POINTER (class_name
));
6195 CLASS_PROTOCOL_LIST (class)
6196 = lookup_and_install_protocols (protocol_list
);
6199 else if (code
== CATEGORY_INTERFACE_TYPE
)
6201 tree class_category_is_assoc_with
;
6203 /* For a category, class_name is really the name of the class that
6204 the following set of methods will be associated with. We must
6205 find the interface so that can derive the objects template. */
6207 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6209 error ("Cannot find interface declaration for `%s'",
6210 IDENTIFIER_POINTER (class_name
));
6211 exit (FATAL_EXIT_CODE
);
6214 add_category (class_category_is_assoc_with
, class);
6217 CLASS_PROTOCOL_LIST (class)
6218 = lookup_and_install_protocols (protocol_list
);
6221 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6223 /* Pre-build the following entities for speed/convenience. */
6225 self_id
= get_identifier ("self");
6227 ucmd_id
= get_identifier ("_cmd");
6230 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6231 if (!objc_super_template
)
6232 objc_super_template
= build_super_template ();
6234 /* Reset for multiple classes per file. */
6237 implementation_context
= class;
6239 /* For a category, class_name is really the name of the class that
6240 the following set of methods will be associated with. We must
6241 find the interface so that can derive the objects template. */
6243 if (!(implementation_template
= lookup_interface (class_name
)))
6245 error ("Cannot find interface declaration for `%s'",
6246 IDENTIFIER_POINTER (class_name
));
6247 exit (FATAL_EXIT_CODE
);
6254 continue_class (class)
6257 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6258 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6260 struct imp_entry
*imp_entry
;
6263 /* Check consistency of the instance variables. */
6265 if (CLASS_IVARS (class))
6266 check_ivars (implementation_template
, class);
6268 /* code generation */
6270 ivar_context
= build_private_template (implementation_template
);
6272 if (!objc_class_template
)
6273 build_class_template ();
6276 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6277 perror ("unable to allocate in objc-tree.c");
6279 imp_entry
->next
= imp_list
;
6280 imp_entry
->imp_context
= class;
6281 imp_entry
->imp_template
= implementation_template
;
6283 synth_forward_declarations ();
6284 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6285 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6287 /* Append to front and increment count. */
6288 imp_list
= imp_entry
;
6289 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6294 return ivar_context
;
6297 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6299 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6301 if (!TYPE_FIELDS (record
))
6303 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6304 CLASS_STATIC_TEMPLATE (class) = record
;
6306 /* Mark this record as a class template for static typing. */
6307 TREE_STATIC_TEMPLATE (record
) = 1;
6314 return error_mark_node
;
6317 /* This is called once we see the "@end" in an interface/implementation. */
6320 finish_class (class)
6323 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6325 /* All code generation is done in finish_objc. */
6327 if (implementation_template
!= implementation_context
)
6329 /* Ensure that all method listed in the interface contain bodies. */
6330 check_methods (CLASS_CLS_METHODS (implementation_template
),
6331 CLASS_CLS_METHODS (implementation_context
), '+');
6332 check_methods (CLASS_NST_METHODS (implementation_template
),
6333 CLASS_NST_METHODS (implementation_context
), '-');
6335 if (CLASS_PROTOCOL_LIST (implementation_template
))
6336 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6338 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6342 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6344 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6346 /* Find the category interface from the class it is associated with. */
6349 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6351 category
= CLASS_CATEGORY_LIST (category
);
6356 /* Ensure all method listed in the interface contain bodies. */
6357 check_methods (CLASS_CLS_METHODS (category
),
6358 CLASS_CLS_METHODS (implementation_context
), '+');
6359 check_methods (CLASS_NST_METHODS (category
),
6360 CLASS_NST_METHODS (implementation_context
), '-');
6362 if (CLASS_PROTOCOL_LIST (category
))
6363 check_protocols (CLASS_PROTOCOL_LIST (category
),
6365 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6369 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6372 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6373 char *string
= (char *) alloca (strlen (class_name
) + 3);
6375 /* extern struct objc_object *_<my_name>; */
6377 sprintf (string
, "_%s", class_name
);
6379 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6380 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6381 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6387 add_protocol (protocol
)
6390 /* Put protocol on list in reverse order. */
6391 TREE_CHAIN (protocol
) = protocol_chain
;
6392 protocol_chain
= protocol
;
6393 return protocol_chain
;
6397 lookup_protocol (ident
)
6402 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6404 if (ident
== PROTOCOL_NAME (chain
))
6412 start_protocol (code
, name
, list
)
6413 enum tree_code code
;
6419 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6420 if (!objc_protocol_template
)
6421 objc_protocol_template
= build_protocol_template ();
6423 protocol
= make_node (code
);
6424 TYPE_BINFO (protocol
) = make_tree_vec (2);
6426 PROTOCOL_NAME (protocol
) = name
;
6427 PROTOCOL_LIST (protocol
) = list
;
6429 lookup_and_install_protocols (list
);
6431 if (lookup_protocol (name
))
6432 warning ("duplicate declaration for protocol `%s'",
6433 IDENTIFIER_POINTER (name
));
6435 add_protocol (protocol
);
6437 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6443 finish_protocol (protocol
)
6444 tree protocol ATTRIBUTE_UNUSED
;
6449 /* "Encode" a data type into a string, which grows in util_obstack.
6450 ??? What is the FORMAT? Someone please document this! */
6453 encode_type_qualifiers (declspecs
)
6458 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6460 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6461 obstack_1grow (&util_obstack
, 'r');
6462 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6463 obstack_1grow (&util_obstack
, 'n');
6464 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6465 obstack_1grow (&util_obstack
, 'N');
6466 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6467 obstack_1grow (&util_obstack
, 'o');
6468 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6469 obstack_1grow (&util_obstack
, 'O');
6470 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6471 obstack_1grow (&util_obstack
, 'R');
6472 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6473 obstack_1grow (&util_obstack
, 'V');
6477 /* Encode a pointer type. */
6480 encode_pointer (type
, curtype
, format
)
6485 tree pointer_to
= TREE_TYPE (type
);
6487 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6489 if (TYPE_NAME (pointer_to
)
6490 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6492 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6494 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6496 obstack_1grow (&util_obstack
, '@');
6499 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6501 if (generating_instance_variables
)
6503 obstack_1grow (&util_obstack
, '@');
6504 obstack_1grow (&util_obstack
, '"');
6505 obstack_grow (&util_obstack
, name
, strlen (name
));
6506 obstack_1grow (&util_obstack
, '"');
6511 obstack_1grow (&util_obstack
, '@');
6515 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6517 obstack_1grow (&util_obstack
, '#');
6520 #ifndef OBJC_INT_SELECTORS
6521 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6523 obstack_1grow (&util_obstack
, ':');
6526 #endif /* OBJC_INT_SELECTORS */
6529 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6530 && TYPE_MODE (pointer_to
) == QImode
)
6532 obstack_1grow (&util_obstack
, '*');
6536 /* We have a type that does not get special treatment. */
6538 /* NeXT extension */
6539 obstack_1grow (&util_obstack
, '^');
6540 encode_type (pointer_to
, curtype
, format
);
6544 encode_array (type
, curtype
, format
)
6549 tree an_int_cst
= TYPE_SIZE (type
);
6550 tree array_of
= TREE_TYPE (type
);
6553 /* An incomplete array is treated like a pointer. */
6554 if (an_int_cst
== NULL
)
6556 encode_pointer (type
, curtype
, format
);
6560 sprintf (buffer
, "[%ld",
6561 (long) (TREE_INT_CST_LOW (an_int_cst
)
6562 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6564 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6565 encode_type (array_of
, curtype
, format
);
6566 obstack_1grow (&util_obstack
, ']');
6571 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6578 if (obstack_object_size (&util_obstack
) > 0
6579 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6581 tree name
= TYPE_NAME (type
);
6583 /* we have a reference; this is a NeXT extension. */
6585 if (obstack_object_size (&util_obstack
) - curtype
== 1
6586 && format
== OBJC_ENCODE_INLINE_DEFS
)
6588 /* Output format of struct for first level only. */
6589 tree fields
= TYPE_FIELDS (type
);
6591 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6593 obstack_1grow (&util_obstack
, left
);
6594 obstack_grow (&util_obstack
,
6595 IDENTIFIER_POINTER (name
),
6596 strlen (IDENTIFIER_POINTER (name
)));
6597 obstack_1grow (&util_obstack
, '=');
6601 obstack_1grow (&util_obstack
, left
);
6602 obstack_grow (&util_obstack
, "?=", 2);
6605 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6606 encode_field_decl (fields
, curtype
, format
);
6608 obstack_1grow (&util_obstack
, right
);
6611 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6613 obstack_1grow (&util_obstack
, left
);
6614 obstack_grow (&util_obstack
,
6615 IDENTIFIER_POINTER (name
),
6616 strlen (IDENTIFIER_POINTER (name
)));
6617 obstack_1grow (&util_obstack
, right
);
6622 /* We have an untagged structure or a typedef. */
6623 obstack_1grow (&util_obstack
, left
);
6624 obstack_1grow (&util_obstack
, '?');
6625 obstack_1grow (&util_obstack
, right
);
6631 tree name
= TYPE_NAME (type
);
6632 tree fields
= TYPE_FIELDS (type
);
6634 if (format
== OBJC_ENCODE_INLINE_DEFS
6635 || generating_instance_variables
)
6637 obstack_1grow (&util_obstack
, left
);
6638 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6639 obstack_grow (&util_obstack
,
6640 IDENTIFIER_POINTER (name
),
6641 strlen (IDENTIFIER_POINTER (name
)));
6643 obstack_1grow (&util_obstack
, '?');
6645 obstack_1grow (&util_obstack
, '=');
6647 for (; fields
; fields
= TREE_CHAIN (fields
))
6649 if (generating_instance_variables
)
6651 tree fname
= DECL_NAME (fields
);
6653 obstack_1grow (&util_obstack
, '"');
6654 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6656 obstack_grow (&util_obstack
,
6657 IDENTIFIER_POINTER (fname
),
6658 strlen (IDENTIFIER_POINTER (fname
)));
6661 obstack_1grow (&util_obstack
, '"');
6664 encode_field_decl (fields
, curtype
, format
);
6667 obstack_1grow (&util_obstack
, right
);
6672 obstack_1grow (&util_obstack
, left
);
6673 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6674 obstack_grow (&util_obstack
,
6675 IDENTIFIER_POINTER (name
),
6676 strlen (IDENTIFIER_POINTER (name
)));
6678 /* We have an untagged structure or a typedef. */
6679 obstack_1grow (&util_obstack
, '?');
6681 obstack_1grow (&util_obstack
, right
);
6687 encode_aggregate (type
, curtype
, format
)
6692 enum tree_code code
= TREE_CODE (type
);
6698 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6703 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6708 obstack_1grow (&util_obstack
, 'i');
6716 /* Support bitfields. The current version of Objective-C does not support
6717 them. The string will consist of one or more "b:n"'s where n is an
6718 integer describing the width of the bitfield. Currently, classes in
6719 the kit implement a method "-(char *)describeBitfieldStruct:" that
6720 simulates this. If they do not implement this method, the archiver
6721 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6722 according to the GNU compiler. After looking at the "kit", it appears
6723 that all classes currently rely on this default behavior, rather than
6724 hand generating this string (which is tedious). */
6727 encode_bitfield (width
)
6731 sprintf (buffer
, "b%d", width
);
6732 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6735 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6738 encode_type (type
, curtype
, format
)
6743 enum tree_code code
= TREE_CODE (type
);
6745 if (code
== INTEGER_TYPE
)
6747 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6749 /* Unsigned integer types. */
6751 if (TYPE_MODE (type
) == QImode
)
6752 obstack_1grow (&util_obstack
, 'C');
6753 else if (TYPE_MODE (type
) == HImode
)
6754 obstack_1grow (&util_obstack
, 'S');
6755 else if (TYPE_MODE (type
) == SImode
)
6757 if (type
== long_unsigned_type_node
)
6758 obstack_1grow (&util_obstack
, 'L');
6760 obstack_1grow (&util_obstack
, 'I');
6762 else if (TYPE_MODE (type
) == DImode
)
6763 obstack_1grow (&util_obstack
, 'Q');
6767 /* Signed integer types. */
6769 if (TYPE_MODE (type
) == QImode
)
6770 obstack_1grow (&util_obstack
, 'c');
6771 else if (TYPE_MODE (type
) == HImode
)
6772 obstack_1grow (&util_obstack
, 's');
6773 else if (TYPE_MODE (type
) == SImode
)
6775 if (type
== long_integer_type_node
)
6776 obstack_1grow (&util_obstack
, 'l');
6778 obstack_1grow (&util_obstack
, 'i');
6781 else if (TYPE_MODE (type
) == DImode
)
6782 obstack_1grow (&util_obstack
, 'q');
6786 else if (code
== REAL_TYPE
)
6788 /* Floating point types. */
6790 if (TYPE_MODE (type
) == SFmode
)
6791 obstack_1grow (&util_obstack
, 'f');
6792 else if (TYPE_MODE (type
) == DFmode
6793 || TYPE_MODE (type
) == TFmode
)
6794 obstack_1grow (&util_obstack
, 'd');
6797 else if (code
== VOID_TYPE
)
6798 obstack_1grow (&util_obstack
, 'v');
6800 else if (code
== ARRAY_TYPE
)
6801 encode_array (type
, curtype
, format
);
6803 else if (code
== POINTER_TYPE
)
6804 encode_pointer (type
, curtype
, format
);
6806 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6807 encode_aggregate (type
, curtype
, format
);
6809 else if (code
== FUNCTION_TYPE
) /* '?' */
6810 obstack_1grow (&util_obstack
, '?');
6814 encode_complete_bitfield (int position
, tree type
, int size
)
6816 enum tree_code code
= TREE_CODE (type
);
6818 char charType
= '?';
6820 if (code
== INTEGER_TYPE
)
6822 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6824 /* Unsigned integer types. */
6826 if (TYPE_MODE (type
) == QImode
)
6828 else if (TYPE_MODE (type
) == HImode
)
6830 else if (TYPE_MODE (type
) == SImode
)
6832 if (type
== long_unsigned_type_node
)
6837 else if (TYPE_MODE (type
) == DImode
)
6842 /* Signed integer types. */
6844 if (TYPE_MODE (type
) == QImode
)
6846 else if (TYPE_MODE (type
) == HImode
)
6848 else if (TYPE_MODE (type
) == SImode
)
6850 if (type
== long_integer_type_node
)
6856 else if (TYPE_MODE (type
) == DImode
)
6864 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6865 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6869 encode_field_decl (field_decl
, curtype
, format
)
6876 type
= TREE_TYPE (field_decl
);
6878 /* If this field is obviously a bitfield, or is a bitfield that has been
6879 clobbered to look like a ordinary integer mode, go ahead and generate
6880 the bitfield typing information. */
6881 if (flag_next_runtime
)
6883 if (DECL_BIT_FIELD (field_decl
))
6884 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6886 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6890 if (DECL_BIT_FIELD (field_decl
))
6891 encode_complete_bitfield (int_bit_position (field_decl
),
6892 DECL_BIT_FIELD_TYPE (field_decl
),
6893 tree_low_cst (DECL_SIZE (field_decl
), 1));
6895 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6900 expr_last (complex_expr
)
6906 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6907 complex_expr
= next
;
6909 return complex_expr
;
6912 /* The selector of the current method,
6913 or NULL if we aren't compiling a method. */
6916 maybe_objc_method_name (decl
)
6917 tree decl ATTRIBUTE_UNUSED
;
6920 return METHOD_SEL_NAME (method_context
);
6925 /* Transform a method definition into a function definition as follows:
6926 - synthesize the first two arguments, "self" and "_cmd". */
6929 start_method_def (method
)
6934 /* Required to implement _msgSuper. */
6935 method_context
= method
;
6936 UOBJC_SUPER_decl
= NULL_TREE
;
6938 /* Must be called BEFORE start_function. */
6941 /* Generate prototype declarations for arguments..."new-style". */
6943 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
6944 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6946 /* Really a `struct objc_class *'. However, we allow people to
6947 assign to self, which changes its type midstream. */
6948 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6950 push_parm_decl (build_tree_list
6951 (build_tree_list (decl_specs
,
6952 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6953 build_tree_list (unused_list
, NULL_TREE
)));
6955 #ifdef OBJC_INT_SELECTORS
6956 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
6957 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
6958 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
6959 build_tree_list (unused_list
, NULL_TREE
)));
6960 #else /* not OBJC_INT_SELECTORS */
6961 decl_specs
= build_tree_list (NULL_TREE
,
6962 xref_tag (RECORD_TYPE
,
6963 get_identifier (TAG_SELECTOR
)));
6964 push_parm_decl (build_tree_list
6965 (build_tree_list (decl_specs
,
6966 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6967 build_tree_list (unused_list
, NULL_TREE
)));
6968 #endif /* not OBJC_INT_SELECTORS */
6970 /* Generate argument declarations if a keyword_decl. */
6971 if (METHOD_SEL_ARGS (method
))
6973 tree arglist
= METHOD_SEL_ARGS (method
);
6976 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6977 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6981 tree last_expr
= expr_last (arg_decl
);
6983 /* Unite the abstract decl with its name. */
6984 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6985 push_parm_decl (build_tree_list
6986 (build_tree_list (arg_spec
, arg_decl
),
6987 build_tree_list (NULL_TREE
, NULL_TREE
)));
6989 /* Unhook: restore the abstract declarator. */
6990 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6994 push_parm_decl (build_tree_list
6995 (build_tree_list (arg_spec
,
6996 KEYWORD_ARG_NAME (arglist
)),
6997 build_tree_list (NULL_TREE
, NULL_TREE
)));
6999 arglist
= TREE_CHAIN (arglist
);
7004 if (METHOD_ADD_ARGS (method
) != NULL_TREE
7005 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7007 /* We have a variable length selector - in "prototype" format. */
7008 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7011 /* This must be done prior to calling pushdecl. pushdecl is
7012 going to change our chain on us. */
7013 tree nextkey
= TREE_CHAIN (akey
);
7021 warn_with_method (message
, mtype
, method
)
7022 const char *message
;
7026 if (count_error (1) == 0)
7029 report_error_function (DECL_SOURCE_FILE (method
));
7031 fprintf (stderr
, "%s:%d: warning: ",
7032 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7033 memset (errbuf
, 0, BUFSIZE
);
7034 fprintf (stderr
, "%s `%c%s'\n",
7035 message
, mtype
, gen_method_decl (method
, errbuf
));
7038 /* Return 1 if METHOD is consistent with PROTO. */
7041 comp_method_with_proto (method
, proto
)
7044 static tree function_type
= 0;
7046 /* Create a function_type node once. */
7049 function_type
= make_node (FUNCTION_TYPE
);
7050 ggc_add_tree_root (&function_type
, 1);
7053 /* Install argument types - normally set by build_function_type. */
7054 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7056 /* install return type */
7057 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7059 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7062 /* Return 1 if PROTO1 is consistent with PROTO2. */
7065 comp_proto_with_proto (proto0
, proto1
)
7066 tree proto0
, proto1
;
7068 static tree function_type
[2];
7070 /* Create a couple function_type node's once. */
7071 if (!function_type
[0])
7073 function_type
[0] = make_node (FUNCTION_TYPE
);
7074 function_type
[1] = make_node (FUNCTION_TYPE
);
7075 ggc_add_tree_root (function_type
, 2);
7078 /* Install argument types; normally set by build_function_type. */
7079 TYPE_ARG_TYPES (function_type
[0]) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7080 TYPE_ARG_TYPES (function_type
[1]) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7082 /* Install return type. */
7083 TREE_TYPE (function_type
[0]) = groktypename (TREE_TYPE (proto0
));
7084 TREE_TYPE (function_type
[1]) = groktypename (TREE_TYPE (proto1
));
7086 return comptypes (function_type
[0], function_type
[1]);
7089 /* - Generate an identifier for the function. the format is "_n_cls",
7090 where 1 <= n <= nMethods, and cls is the name the implementation we
7092 - Install the return type from the method declaration.
7093 - If we have a prototype, check for type consistency. */
7096 really_start_method (method
, parmlist
)
7097 tree method
, parmlist
;
7099 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7100 tree method_decl
, method_id
;
7101 const char *sel_name
, *class_name
, *cat_name
;
7104 /* Synth the storage class & assemble the return type. */
7105 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7106 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7107 decl_specs
= chainon (sc_spec
, ret_spec
);
7109 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7110 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7111 cat_name
= ((TREE_CODE (implementation_context
)
7112 == CLASS_IMPLEMENTATION_TYPE
)
7114 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7117 /* Make sure this is big enough for any plausible method label. */
7118 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7119 + (cat_name
? strlen (cat_name
) : 0));
7121 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7122 class_name
, cat_name
, sel_name
, method_slot
);
7124 method_id
= get_identifier (buf
);
7126 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7128 /* Check the declarator portion of the return type for the method. */
7129 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7131 /* Unite the complex decl (specified in the abstract decl) with the
7132 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7133 tree save_expr
= expr_last (ret_decl
);
7135 TREE_OPERAND (save_expr
, 0) = method_decl
;
7136 method_decl
= ret_decl
;
7138 /* Fool the parser into thinking it is starting a function. */
7139 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7141 /* Unhook: this has the effect of restoring the abstract declarator. */
7142 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7147 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7149 /* Fool the parser into thinking it is starting a function. */
7150 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7152 /* Unhook: this has the effect of restoring the abstract declarator. */
7153 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7156 METHOD_DEFINITION (method
) = current_function_decl
;
7158 if (implementation_template
!= implementation_context
)
7162 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7163 proto
= lookup_instance_method_static (implementation_template
,
7164 METHOD_SEL_NAME (method
));
7166 proto
= lookup_class_method_static (implementation_template
,
7167 METHOD_SEL_NAME (method
));
7169 if (proto
&& ! comp_method_with_proto (method
, proto
))
7171 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7173 warn_with_method ("conflicting types for", type
, method
);
7174 warn_with_method ("previous declaration of", type
, proto
);
7179 /* The following routine is always called...this "architecture" is to
7180 accommodate "old-style" variable length selectors.
7182 - a:a b:b // prototype ; id c; id d; // old-style. */
7185 continue_method_def ()
7189 if (METHOD_ADD_ARGS (method_context
) == objc_ellipsis_node
)
7190 /* We have a `, ...' immediately following the selector. */
7191 parmlist
= get_parm_info (0);
7193 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7195 /* Set self_decl from the first argument...this global is used by
7196 build_ivar_reference calling build_indirect_ref. */
7197 self_decl
= TREE_PURPOSE (parmlist
);
7200 really_start_method (method_context
, parmlist
);
7201 store_parm_decls ();
7204 /* Called by the parser, from the `pushlevel' production. */
7209 if (!UOBJC_SUPER_decl
)
7211 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7212 build_tree_list (NULL_TREE
,
7213 objc_super_template
),
7214 0, NULL_TREE
, NULL_TREE
);
7216 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7218 /* This prevents `unused variable' warnings when compiling with -Wall. */
7219 TREE_USED (UOBJC_SUPER_decl
) = 1;
7220 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7224 /* _n_Method (id self, SEL sel, ...)
7226 struct objc_super _S;
7227 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7231 get_super_receiver ()
7235 tree super_expr
, super_expr_list
;
7237 /* Set receiver to self. */
7238 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7239 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7240 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7242 /* Set class to begin searching. */
7243 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7244 get_identifier ("class"));
7246 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7248 /* [_cls, __cls]Super are "pre-built" in
7249 synth_forward_declarations. */
7251 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7252 ((TREE_CODE (method_context
)
7253 == INSTANCE_METHOD_DECL
)
7255 : uucls_super_ref
));
7259 /* We have a category. */
7261 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7266 error ("no super class declared in interface for `%s'",
7267 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7268 return error_mark_node
;
7271 if (flag_next_runtime
)
7273 super_class
= get_class_reference (super_name
);
7274 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7276 = build_component_ref (build_indirect_ref (super_class
, "->"),
7277 get_identifier ("isa"));
7281 add_class_reference (super_name
);
7282 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7283 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7284 assemble_external (super_class
);
7286 = build_function_call
7290 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7291 IDENTIFIER_POINTER (super_name
))));
7294 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7295 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7298 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7300 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7301 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7303 return build_compound_expr (super_expr_list
);
7307 error ("[super ...] must appear in a method context");
7308 return error_mark_node
;
7313 encode_method_def (func_decl
)
7318 HOST_WIDE_INT max_parm_end
= 0;
7323 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7324 obstack_object_size (&util_obstack
),
7325 OBJC_ENCODE_INLINE_DEFS
);
7328 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7329 parms
= TREE_CHAIN (parms
))
7331 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7332 + int_size_in_bytes (TREE_TYPE (parms
)));
7334 if (! offset_is_register
&& parm_end
> max_parm_end
)
7335 max_parm_end
= parm_end
;
7338 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7340 sprintf (buffer
, "%d", stack_size
);
7341 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7343 /* Argument types. */
7344 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7345 parms
= TREE_CHAIN (parms
))
7348 encode_type (TREE_TYPE (parms
),
7349 obstack_object_size (&util_obstack
),
7350 OBJC_ENCODE_INLINE_DEFS
);
7352 /* Compute offset. */
7353 sprintf (buffer
, "%d", forwarding_offset (parms
));
7355 /* Indicate register. */
7356 if (offset_is_register
)
7357 obstack_1grow (&util_obstack
, '+');
7359 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7362 obstack_1grow (&util_obstack
, 0);
7363 result
= get_identifier (obstack_finish (&util_obstack
));
7364 obstack_free (&util_obstack
, util_firstobj
);
7369 objc_expand_function_end ()
7371 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7375 finish_method_def ()
7377 lang_expand_function_end
= objc_expand_function_end
;
7378 finish_function (0);
7379 lang_expand_function_end
= NULL
;
7381 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7382 since the optimizer may find "may be used before set" errors. */
7383 method_context
= NULL_TREE
;
7388 lang_report_error_function (decl
)
7393 fprintf (stderr
, "In method `%s'\n",
7394 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7404 is_complex_decl (type
)
7407 return (TREE_CODE (type
) == ARRAY_TYPE
7408 || TREE_CODE (type
) == FUNCTION_TYPE
7409 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7413 /* Code to convert a decl node into text for a declaration in C. */
7415 static char tmpbuf
[256];
7418 adorn_decl (decl
, str
)
7422 enum tree_code code
= TREE_CODE (decl
);
7424 if (code
== ARRAY_REF
)
7426 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7428 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7429 sprintf (str
+ strlen (str
), "[%ld]",
7430 (long) TREE_INT_CST_LOW (an_int_cst
));
7435 else if (code
== ARRAY_TYPE
)
7437 tree an_int_cst
= TYPE_SIZE (decl
);
7438 tree array_of
= TREE_TYPE (decl
);
7440 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7441 sprintf (str
+ strlen (str
), "[%ld]",
7442 (long) (TREE_INT_CST_LOW (an_int_cst
)
7443 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7448 else if (code
== CALL_EXPR
)
7450 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7455 gen_declaration (chain
, str
);
7456 chain
= TREE_CHAIN (chain
);
7463 else if (code
== FUNCTION_TYPE
)
7465 tree chain
= TYPE_ARG_TYPES (decl
);
7468 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7470 gen_declaration (TREE_VALUE (chain
), str
);
7471 chain
= TREE_CHAIN (chain
);
7472 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7478 else if (code
== INDIRECT_REF
)
7480 strcpy (tmpbuf
, "*");
7481 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7485 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7487 chain
= TREE_CHAIN (chain
))
7489 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7491 strcat (tmpbuf
, " ");
7492 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7496 strcat (tmpbuf
, " ");
7498 strcat (tmpbuf
, str
);
7499 strcpy (str
, tmpbuf
);
7502 else if (code
== POINTER_TYPE
)
7504 strcpy (tmpbuf
, "*");
7505 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7507 if (TREE_READONLY (decl
))
7508 strcat (tmpbuf
, " const");
7509 if (TYPE_VOLATILE (decl
))
7510 strcat (tmpbuf
, " volatile");
7512 strcat (tmpbuf
, " ");
7514 strcat (tmpbuf
, str
);
7515 strcpy (str
, tmpbuf
);
7520 gen_declarator (decl
, buf
, name
)
7527 enum tree_code code
= TREE_CODE (decl
);
7537 op
= TREE_OPERAND (decl
, 0);
7539 /* We have a pointer to a function or array...(*)(), (*)[] */
7540 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7541 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7544 str
= gen_declarator (op
, buf
, name
);
7548 strcpy (tmpbuf
, "(");
7549 strcat (tmpbuf
, str
);
7550 strcat (tmpbuf
, ")");
7551 strcpy (str
, tmpbuf
);
7554 adorn_decl (decl
, str
);
7563 /* This clause is done iteratively rather than recursively. */
7566 op
= (is_complex_decl (TREE_TYPE (decl
))
7567 ? TREE_TYPE (decl
) : NULL_TREE
);
7569 adorn_decl (decl
, str
);
7571 /* We have a pointer to a function or array...(*)(), (*)[] */
7572 if (code
== POINTER_TYPE
7573 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7574 || TREE_CODE (op
) == ARRAY_TYPE
))
7576 strcpy (tmpbuf
, "(");
7577 strcat (tmpbuf
, str
);
7578 strcat (tmpbuf
, ")");
7579 strcpy (str
, tmpbuf
);
7582 decl
= (is_complex_decl (TREE_TYPE (decl
))
7583 ? TREE_TYPE (decl
) : NULL_TREE
);
7586 while (decl
&& (code
= TREE_CODE (decl
)))
7591 case IDENTIFIER_NODE
:
7592 /* Will only happen if we are processing a "raw" expr-decl. */
7593 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7604 /* We have an abstract declarator or a _DECL node. */
7612 gen_declspecs (declspecs
, buf
, raw
)
7621 for (chain
= nreverse (copy_list (declspecs
));
7622 chain
; chain
= TREE_CHAIN (chain
))
7624 tree aspec
= TREE_VALUE (chain
);
7626 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7627 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7628 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7630 if (TYPE_NAME (aspec
))
7632 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7634 if (! TREE_STATIC_TEMPLATE (aspec
))
7635 strcat (buf
, "struct ");
7636 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7641 tree chain
= protocol_list
;
7648 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7649 chain
= TREE_CHAIN (chain
);
7658 strcat (buf
, "untagged struct");
7661 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7663 if (TYPE_NAME (aspec
))
7665 if (! TREE_STATIC_TEMPLATE (aspec
))
7666 strcat (buf
, "union ");
7667 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7670 strcat (buf
, "untagged union");
7673 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7675 if (TYPE_NAME (aspec
))
7677 if (! TREE_STATIC_TEMPLATE (aspec
))
7678 strcat (buf
, "enum ");
7679 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7682 strcat (buf
, "untagged enum");
7685 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7686 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7688 else if (IS_ID (aspec
))
7690 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7695 tree chain
= protocol_list
;
7702 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7703 chain
= TREE_CHAIN (chain
);
7710 if (TREE_CHAIN (chain
))
7716 /* Type qualifiers. */
7717 if (TREE_READONLY (declspecs
))
7718 strcat (buf
, "const ");
7719 if (TYPE_VOLATILE (declspecs
))
7720 strcat (buf
, "volatile ");
7722 switch (TREE_CODE (declspecs
))
7724 /* Type specifiers. */
7727 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7729 /* Signed integer types. */
7731 if (declspecs
== short_integer_type_node
)
7732 strcat (buf
, "short int ");
7733 else if (declspecs
== integer_type_node
)
7734 strcat (buf
, "int ");
7735 else if (declspecs
== long_integer_type_node
)
7736 strcat (buf
, "long int ");
7737 else if (declspecs
== long_long_integer_type_node
)
7738 strcat (buf
, "long long int ");
7739 else if (declspecs
== signed_char_type_node
7740 || declspecs
== char_type_node
)
7741 strcat (buf
, "char ");
7743 /* Unsigned integer types. */
7745 else if (declspecs
== short_unsigned_type_node
)
7746 strcat (buf
, "unsigned short ");
7747 else if (declspecs
== unsigned_type_node
)
7748 strcat (buf
, "unsigned int ");
7749 else if (declspecs
== long_unsigned_type_node
)
7750 strcat (buf
, "unsigned long ");
7751 else if (declspecs
== long_long_unsigned_type_node
)
7752 strcat (buf
, "unsigned long long ");
7753 else if (declspecs
== unsigned_char_type_node
)
7754 strcat (buf
, "unsigned char ");
7758 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7760 if (declspecs
== float_type_node
)
7761 strcat (buf
, "float ");
7762 else if (declspecs
== double_type_node
)
7763 strcat (buf
, "double ");
7764 else if (declspecs
== long_double_type_node
)
7765 strcat (buf
, "long double ");
7769 if (TYPE_NAME (declspecs
)
7770 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7772 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7774 if (! TREE_STATIC_TEMPLATE (declspecs
))
7775 strcat (buf
, "struct ");
7776 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7780 tree chain
= protocol_list
;
7787 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7788 chain
= TREE_CHAIN (chain
);
7797 strcat (buf
, "untagged struct");
7803 if (TYPE_NAME (declspecs
)
7804 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7806 strcat (buf
, "union ");
7807 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7812 strcat (buf
, "untagged union ");
7816 if (TYPE_NAME (declspecs
)
7817 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7819 strcat (buf
, "enum ");
7820 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7825 strcat (buf
, "untagged enum ");
7829 strcat (buf
, "void ");
7834 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7839 tree chain
= protocol_list
;
7846 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7847 chain
= TREE_CHAIN (chain
);
7864 gen_declaration (atype_or_adecl
, buf
)
7865 tree atype_or_adecl
;
7870 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7872 tree declspecs
; /* "identifier_node", "record_type" */
7873 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7875 /* We have a "raw", abstract declarator (typename). */
7876 declarator
= TREE_VALUE (atype_or_adecl
);
7877 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7879 gen_declspecs (declspecs
, buf
, 1);
7883 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7890 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7891 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7893 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7894 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7895 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7896 atype
= TREE_TYPE (atype_or_adecl
);
7898 /* Assume we have a *_type node. */
7899 atype
= atype_or_adecl
;
7901 if (is_complex_decl (atype
))
7905 /* Get the declaration specifier; it is at the end of the list. */
7906 declarator
= chain
= atype
;
7908 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7909 while (is_complex_decl (chain
));
7916 declarator
= NULL_TREE
;
7919 gen_declspecs (declspecs
, buf
, 0);
7921 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7922 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7923 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7925 const char *decl_name
=
7926 (DECL_NAME (atype_or_adecl
)
7927 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7932 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7935 else if (decl_name
[0])
7938 strcat (buf
, decl_name
);
7941 else if (declarator
)
7944 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7951 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7954 gen_method_decl (method
, buf
)
7960 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7963 gen_declaration (TREE_TYPE (method
), buf
);
7967 chain
= METHOD_SEL_ARGS (method
);
7970 /* We have a chain of keyword_decls. */
7973 if (KEYWORD_KEY_NAME (chain
))
7974 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7977 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7980 gen_declaration (TREE_TYPE (chain
), buf
);
7984 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7985 if ((chain
= TREE_CHAIN (chain
)))
7990 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7991 strcat (buf
, ", ...");
7992 else if (METHOD_ADD_ARGS (method
))
7994 /* We have a tree list node as generate by get_parm_info. */
7995 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7997 /* Know we have a chain of parm_decls. */
8001 gen_declaration (chain
, buf
);
8002 chain
= TREE_CHAIN (chain
);
8008 /* We have a unary selector. */
8009 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8017 dump_interface (fp
, chain
)
8021 char *buf
= (char *)xmalloc (256);
8022 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8023 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8024 tree nst_methods
= CLASS_NST_METHODS (chain
);
8025 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8027 fprintf (fp
, "\n@interface %s", my_name
);
8029 if (CLASS_SUPER_NAME (chain
))
8031 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8032 fprintf (fp
, " : %s\n", super_name
);
8039 fprintf (fp
, "{\n");
8042 memset (buf
, 0, 256);
8043 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8044 ivar_decls
= TREE_CHAIN (ivar_decls
);
8047 fprintf (fp
, "}\n");
8052 memset (buf
, 0, 256);
8053 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8054 nst_methods
= TREE_CHAIN (nst_methods
);
8059 memset (buf
, 0, 256);
8060 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8061 cls_methods
= TREE_CHAIN (cls_methods
);
8063 fprintf (fp
, "\n@end");
8066 /* Demangle function for Objective-C */
8068 objc_demangle (mangled
)
8069 const char *mangled
;
8071 char *demangled
, *cp
;
8073 if (mangled
[0] == '_' &&
8074 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8077 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8078 if (mangled
[1] == 'i')
8079 *cp
++ = '-'; /* for instance method */
8081 *cp
++ = '+'; /* for class method */
8082 *cp
++ = '['; /* opening left brace */
8083 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8084 while (*cp
&& *cp
== '_')
8085 cp
++; /* skip any initial underbars in class name */
8086 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8089 free(demangled
); /* not mangled name */
8092 if (cp
[1] == '_') /* easy case: no category name */
8094 *cp
++ = ' '; /* replace two '_' with one ' ' */
8095 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8099 *cp
++ = '('; /* less easy case: category name */
8100 cp
= strchr(cp
, '_');
8103 free(demangled
); /* not mangled name */
8107 *cp
++ = ' '; /* overwriting 1st char of method name... */
8108 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8110 while (*cp
&& *cp
== '_')
8111 cp
++; /* skip any initial underbars in method name */
8114 *cp
= ':'; /* replace remaining '_' with ':' */
8115 *cp
++ = ']'; /* closing right brace */
8116 *cp
++ = 0; /* string terminator */
8120 return mangled
; /* not an objc mangled name */
8124 objc_printable_name (decl
, kind
)
8126 int kind ATTRIBUTE_UNUSED
;
8128 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8134 /* Add the special tree codes of Objective C to the tables. */
8136 #define LAST_CODE LAST_C_TREE_CODE
8138 gcc_obstack_init (&util_obstack
);
8139 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8141 memcpy (tree_code_type
+ (int) LAST_CODE
,
8142 objc_tree_code_type
,
8143 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8144 memcpy (tree_code_length
+ (int) LAST_CODE
,
8145 objc_tree_code_length
,
8146 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8147 memcpy (tree_code_name
+ (int) LAST_CODE
,
8148 objc_tree_code_name
,
8149 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8151 errbuf
= (char *)xmalloc (BUFSIZE
);
8153 synth_module_prologue ();
8155 /* Change the default error function */
8156 decl_printable_name
= objc_printable_name
;
8157 lang_expand_expr
= c_expand_expr
;
8158 lang_expand_decl_stmt
= c_expand_decl_stmt
;
8164 struct imp_entry
*impent
;
8166 /* The internally generated initializers appear to have missing braces.
8167 Don't warn about this. */
8168 int save_warn_missing_braces
= warn_missing_braces
;
8169 warn_missing_braces
= 0;
8171 generate_forward_declaration_to_string_table ();
8173 #ifdef OBJC_PROLOGUE
8177 /* Process the static instances here because initialization of objc_symtab
8179 if (objc_static_instances
)
8180 generate_static_references ();
8182 if (implementation_context
|| class_names_chain
8183 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8184 generate_objc_symtab_decl ();
8186 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8188 implementation_context
= impent
->imp_context
;
8189 implementation_template
= impent
->imp_template
;
8191 UOBJC_CLASS_decl
= impent
->class_decl
;
8192 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8194 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8196 /* all of the following reference the string pool... */
8197 generate_ivar_lists ();
8198 generate_dispatch_tables ();
8199 generate_shared_structures ();
8203 generate_dispatch_tables ();
8204 generate_category (implementation_context
);
8208 /* If we are using an array of selectors, we must always
8209 finish up the array decl even if no selectors were used. */
8210 if (! flag_next_runtime
|| sel_ref_chain
)
8211 build_selector_translation_table ();
8214 generate_protocols ();
8216 if (implementation_context
|| class_names_chain
|| objc_static_instances
8217 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8219 /* Arrange for Objc data structures to be initialized at run time. */
8220 const char *init_name
= build_module_descriptor ();
8222 assemble_constructor (init_name
);
8225 /* Dump the class references. This forces the appropriate classes
8226 to be linked into the executable image, preserving unix archive
8227 semantics. This can be removed when we move to a more dynamically
8228 linked environment. */
8230 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8232 handle_class_ref (chain
);
8233 if (TREE_PURPOSE (chain
))
8234 generate_classref_translation_entry (chain
);
8237 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8238 handle_impent (impent
);
8240 /* Dump the string table last. */
8242 generate_strings ();
8244 if (flag_gen_declaration
)
8246 add_class (implementation_context
);
8247 dump_interface (gen_declaration_file
, implementation_context
);
8255 /* Run through the selector hash tables and print a warning for any
8256 selector which has multiple methods. */
8258 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8259 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8262 tree meth
= hsh
->key
;
8263 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8267 warning ("potential selector conflict for method `%s'",
8268 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8269 warn_with_method ("found", type
, meth
);
8270 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8271 warn_with_method ("found", type
, loop
->value
);
8274 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8275 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8278 tree meth
= hsh
->key
;
8279 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8283 warning ("potential selector conflict for method `%s'",
8284 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8285 warn_with_method ("found", type
, meth
);
8286 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8287 warn_with_method ("found", type
, loop
->value
);
8291 warn_missing_braces
= save_warn_missing_braces
;
8294 /* Subroutines of finish_objc. */
8297 generate_classref_translation_entry (chain
)
8300 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8303 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8305 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8306 expr
= build_c_cast (type
, expr
); /* cast! */
8308 name
= DECL_NAME (TREE_PURPOSE (chain
));
8310 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8312 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8313 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8315 /* The decl that is returned from start_decl is the one that we
8316 forward declared in build_class_reference. */
8317 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8318 finish_decl (decl
, expr
, NULL_TREE
);
8323 handle_class_ref (chain
)
8326 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8327 if (! flag_next_runtime
)
8330 char *string
= (char *) alloca (strlen (name
) + 30);
8333 sprintf (string
, "%sobjc_class_name_%s",
8334 (flag_next_runtime
? "." : "__"), name
);
8336 /* Make a decl for this name, so we can use its address in a tree. */
8337 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8338 DECL_EXTERNAL (decl
) = 1;
8339 TREE_PUBLIC (decl
) = 1;
8342 rest_of_decl_compilation (decl
, 0, 0, 0);
8344 /* Make following constant read-only (why not)? */
8345 readonly_data_section ();
8347 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8349 /* Align the section properly. */
8350 assemble_constant_align (exp
);
8352 /* Inform the assembler about this new external thing. */
8353 assemble_external (decl
);
8355 /* Output a constant to reference this address. */
8356 output_constant (exp
, int_size_in_bytes (string_type_node
));
8360 /* This overreliance on our assembler (i.e. lack of portability)
8361 should be dealt with at some point. The GNU strategy (above)
8362 won't work either, but it is a start. */
8363 char *string
= (char *) alloca (strlen (name
) + 30);
8364 sprintf (string
, ".reference .objc_class_name_%s", name
);
8365 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8370 handle_impent (impent
)
8371 struct imp_entry
*impent
;
8373 implementation_context
= impent
->imp_context
;
8374 implementation_template
= impent
->imp_template
;
8376 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8378 const char *class_name
=
8379 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8380 char *string
= (char *) alloca (strlen (class_name
) + 30);
8382 if (flag_next_runtime
)
8384 /* Grossly unportable.
8385 People should know better than to assume
8386 such things about assembler syntax! */
8387 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8388 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8390 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8391 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8396 sprintf (string
, "%sobjc_class_name_%s",
8397 (flag_next_runtime
? "." : "__"), class_name
);
8398 assemble_global (string
);
8399 assemble_label (string
);
8403 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8405 const char *class_name
=
8406 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8407 const char *class_super_name
=
8408 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8409 char *string
= (char *) alloca (strlen (class_name
)
8410 + strlen (class_super_name
) + 30);
8412 /* Do the same for categories. Even though no references to these
8413 symbols are generated automatically by the compiler, it gives
8414 you a handle to pull them into an archive by hand. */
8415 if (flag_next_runtime
)
8417 /* Grossly unportable. */
8418 sprintf (string
, ".objc_category_name_%s_%s=0",
8419 class_name
, class_super_name
);
8420 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8422 sprintf (string
, ".globl .objc_category_name_%s_%s",
8423 class_name
, class_super_name
);
8424 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8429 sprintf (string
, "%sobjc_category_name_%s_%s",
8430 (flag_next_runtime
? "." : "__"),
8431 class_name
, class_super_name
);
8432 assemble_global (string
);
8433 assemble_label (string
);
8444 char *buf
= (char *)xmalloc (256);
8446 { /* dump function prototypes */
8447 tree loop
= UOBJC_MODULES_decl
;
8449 fprintf (fp
, "\n\nfunction prototypes:\n");
8452 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8454 /* We have a function definition: generate prototype. */
8455 memset (errbuf
, 0, BUFSIZE
);
8456 gen_declaration (loop
, errbuf
);
8457 fprintf (fp
, "%s;\n", errbuf
);
8459 loop
= TREE_CHAIN (loop
);
8463 /* Dump global chains. */
8465 int i
, index
= 0, offset
= 0;
8468 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8470 if (hashlist
= nst_method_hash_list
[i
])
8472 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8475 memset (buf
, 0, 256);
8476 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8477 hashlist
= hashlist
->next
;
8483 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8485 if (hashlist
= cls_method_hash_list
[i
])
8487 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8490 memset (buf
, 0, 256);
8491 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8492 hashlist
= hashlist
->next
;
8498 fprintf (fp
, "\nsel_refdef_chain:\n");
8499 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8501 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8502 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8504 /* add one for the '\0' character */
8505 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8508 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8514 print_lang_statistics ()
8519 ggc_mark_imp_list (arg
)
8522 struct imp_entry
*impent
;
8524 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8526 ggc_mark_tree (impent
->imp_context
);
8527 ggc_mark_tree (impent
->imp_template
);
8528 ggc_mark_tree (impent
->class_decl
);
8529 ggc_mark_tree (impent
->meta_decl
);
8534 ggc_mark_hash_table (arg
)
8537 hash
*hash_table
= *(hash
**)arg
;
8542 if (hash_table
== NULL
)
8544 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8545 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8547 ggc_mark_tree (hst
->key
);
8548 for (list
= hst
->list
; list
; list
= list
->next
)
8549 ggc_mark_tree (list
->value
);
8553 /* Add GC roots for variables local to this file. */
8555 objc_act_parse_init ()
8557 ggc_add_tree_root (&objc_ellipsis_node
, 1);
8558 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8559 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8560 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8561 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8564 /* Look up ID as an instance variable. */
8566 lookup_objc_ivar (id
)
8571 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8572 /* we have a message to super */
8573 return get_super_receiver ();
8574 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8576 if (is_private (decl
))
8577 return error_mark_node
;
8579 return build_ivar_reference (id
);
8585 /* Parser callbacks. */
8587 forget_protocol_qualifiers ()
8589 C_IS_RESERVED_WORD (ridpointers
[(int) RID_IN
]) = 0;
8590 C_IS_RESERVED_WORD (ridpointers
[(int) RID_OUT
]) = 0;
8591 C_IS_RESERVED_WORD (ridpointers
[(int) RID_INOUT
]) = 0;
8592 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYCOPY
]) = 0;
8593 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYREF
]) = 0;
8594 C_IS_RESERVED_WORD (ridpointers
[(int) RID_ONEWAY
]) = 0;
8598 remember_protocol_qualifiers ()
8600 C_IS_RESERVED_WORD (ridpointers
[(int) RID_IN
]) = 1;
8601 C_IS_RESERVED_WORD (ridpointers
[(int) RID_OUT
]) = 1;
8602 C_IS_RESERVED_WORD (ridpointers
[(int) RID_INOUT
]) = 1;
8603 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYCOPY
]) = 1;
8604 C_IS_RESERVED_WORD (ridpointers
[(int) RID_BYREF
]) = 1;
8605 C_IS_RESERVED_WORD (ridpointers
[(int) RID_ONEWAY
]) = 1;