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 */
58 extern cpp_reader parse_in
;
59 extern cpp_options parse_options
;
62 /* This is the default way of generating a method name. */
63 /* I am not sure it is really correct.
64 Perhaps there's a danger that it will make name conflicts
65 if method names contain underscores. -- rms. */
66 #ifndef OBJC_GEN_METHOD_LABEL
67 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
70 sprintf ((BUF), "_%s_%s_%s_%s", \
71 ((IS_INST) ? "i" : "c"), \
73 ((CAT_NAME)? (CAT_NAME) : ""), \
75 for (temp = (BUF); *temp; temp++) \
76 if (*temp == ':') *temp = '_'; \
80 /* These need specifying. */
81 #ifndef OBJC_FORWARDING_STACK_OFFSET
82 #define OBJC_FORWARDING_STACK_OFFSET 0
85 #ifndef OBJC_FORWARDING_MIN_OFFSET
86 #define OBJC_FORWARDING_MIN_OFFSET 0
89 /* Define the special tree codes that we use. */
91 /* Table indexed by tree code giving a string containing a character
92 classifying the tree code. Possibilities are
93 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
95 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
97 static const char objc_tree_code_type
[] = {
99 #include "objc-tree.def"
103 /* Table indexed by tree code giving number of expression
104 operands beyond the fixed part of the node structure.
105 Not used for types or decls. */
107 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
109 static const int objc_tree_code_length
[] = {
111 #include "objc-tree.def"
115 /* Names of tree components.
116 Used for printing out the tree and error messages. */
117 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
119 static const char * const objc_tree_code_name
[] = {
121 #include "objc-tree.def"
125 /* Set up for use of obstacks. */
129 #define obstack_chunk_alloc xmalloc
130 #define obstack_chunk_free free
132 /* This obstack is used to accumulate the encoding of a data type. */
133 static struct obstack util_obstack
;
134 /* This points to the beginning of obstack contents,
135 so we can free the whole contents. */
138 /* for encode_method_def */
142 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
143 #define PROTOCOL_VERSION 2
145 #define OBJC_ENCODE_INLINE_DEFS 0
146 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
148 /*** Private Interface (procedures) ***/
150 /* Used by compile_file. */
152 static void init_objc
PARAMS ((void));
153 static void finish_objc
PARAMS ((void));
155 /* Code generation. */
157 static void synth_module_prologue
PARAMS ((void));
158 static tree build_constructor
PARAMS ((tree
, tree
));
159 static const char *build_module_descriptor
PARAMS ((void));
160 static tree init_module_descriptor
PARAMS ((tree
));
161 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
163 static void generate_strings
PARAMS ((void));
164 static tree get_proto_encoding
PARAMS ((tree
));
165 static void build_selector_translation_table
PARAMS ((void));
166 static tree build_ivar_chain
PARAMS ((tree
, int));
168 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
170 static tree build_ivar_template
PARAMS ((void));
171 static tree build_method_template
PARAMS ((void));
172 static tree build_private_template
PARAMS ((tree
));
173 static void build_class_template
PARAMS ((void));
174 static void build_selector_template
PARAMS ((void));
175 static void build_category_template
PARAMS ((void));
176 static tree build_super_template
PARAMS ((void));
177 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
179 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
182 static void synth_forward_declarations
PARAMS ((void));
183 static void generate_ivar_lists
PARAMS ((void));
184 static void generate_dispatch_tables
PARAMS ((void));
185 static void generate_shared_structures
PARAMS ((void));
186 static tree generate_protocol_list
PARAMS ((tree
));
187 static void generate_forward_declaration_to_string_table
PARAMS ((void));
188 static void build_protocol_reference
PARAMS ((tree
));
191 static tree init_selector
PARAMS ((int));
193 static tree build_keyword_selector
PARAMS ((tree
));
194 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
196 static void generate_static_references
PARAMS ((void));
197 static int check_methods_accessible
PARAMS ((tree
, tree
,
199 static void encode_aggregate_within
PARAMS ((tree
, int, int,
201 static const char *objc_demangle
PARAMS ((const char *));
202 static const char *objc_printable_name
PARAMS ((tree
, int));
204 /* Misc. bookkeeping */
206 typedef struct hashed_entry
*hash
;
207 typedef struct hashed_attribute
*attr
;
209 struct hashed_attribute
221 static void hash_init
PARAMS ((void));
222 static void hash_enter
PARAMS ((hash
*, tree
));
223 static hash hash_lookup
PARAMS ((hash
*, tree
));
224 static void hash_add_attr
PARAMS ((hash
, tree
));
225 static tree lookup_method
PARAMS ((tree
, tree
));
226 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
227 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
228 static tree add_class
PARAMS ((tree
));
229 static void add_category
PARAMS ((tree
, tree
));
233 class_names
, /* class, category, protocol, module names */
234 meth_var_names
, /* method and variable names */
235 meth_var_types
/* method and variable type descriptors */
238 static tree add_objc_string
PARAMS ((tree
,
239 enum string_section
));
240 static tree get_objc_string_decl
PARAMS ((tree
,
241 enum string_section
));
242 static tree build_objc_string_decl
PARAMS ((enum string_section
));
243 static tree build_selector_reference_decl
PARAMS ((void));
245 /* Protocol additions. */
247 static tree add_protocol
PARAMS ((tree
));
248 static tree lookup_protocol
PARAMS ((tree
));
249 static tree lookup_and_install_protocols
PARAMS ((tree
));
253 static void encode_type_qualifiers
PARAMS ((tree
));
254 static void encode_pointer
PARAMS ((tree
, int, int));
255 static void encode_array
PARAMS ((tree
, int, int));
256 static void encode_aggregate
PARAMS ((tree
, int, int));
257 static void encode_bitfield
PARAMS ((int));
258 static void encode_type
PARAMS ((tree
, int, int));
259 static void encode_field_decl
PARAMS ((tree
, int, int));
261 static void really_start_method
PARAMS ((tree
, tree
));
262 static int comp_method_with_proto
PARAMS ((tree
, tree
));
263 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
264 static tree get_arg_type_list
PARAMS ((tree
, int, int));
265 static tree expr_last
PARAMS ((tree
));
267 /* Utilities for debugging and error diagnostics. */
269 static void warn_with_method
PARAMS ((const char *, int, tree
));
270 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
271 static char *gen_method_decl
PARAMS ((tree
, char *));
272 static char *gen_declaration
PARAMS ((tree
, char *));
273 static char *gen_declarator
PARAMS ((tree
, char *,
275 static int is_complex_decl
PARAMS ((tree
));
276 static void adorn_decl
PARAMS ((tree
, char *));
277 static void dump_interface
PARAMS ((FILE *, tree
));
279 /* Everything else. */
281 static void objc_fatal
PARAMS ((void))
283 static tree define_decl
PARAMS ((tree
, tree
));
284 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
285 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
286 static tree create_builtin_decl
PARAMS ((enum tree_code
,
287 tree
, const char *));
288 static tree my_build_string
PARAMS ((int, const char *));
289 static void build_objc_symtab_template
PARAMS ((void));
290 static tree init_def_list
PARAMS ((tree
));
291 static tree init_objc_symtab
PARAMS ((tree
));
292 static void forward_declare_categories
PARAMS ((void));
293 static void generate_objc_symtab_decl
PARAMS ((void));
294 static tree build_selector
PARAMS ((tree
));
296 static tree build_msg_pool_reference
PARAMS ((int));
298 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
299 static tree build_selector_reference
PARAMS ((tree
));
300 static tree build_class_reference_decl
PARAMS ((void));
301 static void add_class_reference
PARAMS ((tree
));
302 static tree objc_copy_list
PARAMS ((tree
, tree
*));
303 static tree build_protocol_template
PARAMS ((void));
304 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
305 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
306 static tree build_method_prototype_template
PARAMS ((void));
307 static int forwarding_offset
PARAMS ((tree
));
308 static tree encode_method_prototype
PARAMS ((tree
, tree
));
309 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
311 static void generate_method_descriptors
PARAMS ((tree
));
312 static tree build_tmp_function_decl
PARAMS ((void));
313 static void hack_method_prototype
PARAMS ((tree
, tree
));
314 static void generate_protocol_references
PARAMS ((tree
));
315 static void generate_protocols
PARAMS ((void));
316 static void check_ivars
PARAMS ((tree
, tree
));
317 static tree build_ivar_list_template
PARAMS ((tree
, int));
318 static tree build_method_list_template
PARAMS ((tree
, int));
319 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
320 static tree generate_ivars_list
PARAMS ((tree
, const char *,
322 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
323 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
325 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
326 tree
, int, tree
, tree
,
328 static void generate_category
PARAMS ((tree
));
329 static int is_objc_type_qualifier
PARAMS ((tree
));
330 static tree adjust_type_for_id_default
PARAMS ((tree
));
331 static tree check_duplicates
PARAMS ((hash
));
332 static tree receiver_is_class_object
PARAMS ((tree
));
333 static int check_methods
PARAMS ((tree
, tree
, int));
334 static int conforms_to_protocol
PARAMS ((tree
, tree
));
335 static void check_protocols
PARAMS ((tree
, const char *,
337 static tree encode_method_def
PARAMS ((tree
));
338 static void gen_declspecs
PARAMS ((tree
, char *, int));
339 static void generate_classref_translation_entry
PARAMS ((tree
));
340 static void handle_class_ref
PARAMS ((tree
));
341 static void generate_struct_by_value_array
PARAMS ((void))
343 static void objc_act_parse_init
PARAMS ((void));
344 static void ggc_mark_imp_list
PARAMS ((void *));
345 static void ggc_mark_hash_table
PARAMS ((void *));
347 /*** Private Interface (data) ***/
349 /* Reserved tag definitions. */
352 #define TAG_OBJECT "objc_object"
353 #define TAG_CLASS "objc_class"
354 #define TAG_SUPER "objc_super"
355 #define TAG_SELECTOR "objc_selector"
357 #define UTAG_CLASS "_objc_class"
358 #define UTAG_IVAR "_objc_ivar"
359 #define UTAG_IVAR_LIST "_objc_ivar_list"
360 #define UTAG_METHOD "_objc_method"
361 #define UTAG_METHOD_LIST "_objc_method_list"
362 #define UTAG_CATEGORY "_objc_category"
363 #define UTAG_MODULE "_objc_module"
364 #define UTAG_STATICS "_objc_statics"
365 #define UTAG_SYMTAB "_objc_symtab"
366 #define UTAG_SUPER "_objc_super"
367 #define UTAG_SELECTOR "_objc_selector"
369 #define UTAG_PROTOCOL "_objc_protocol"
370 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
371 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
372 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
374 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
375 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
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
]);
702 cpp_reader_init (&parse_in
);
703 parse_in
.opts
= &parse_options
;
704 cpp_options_init (&parse_options
);
712 /* The beginning of the file is a new line; check for #.
713 With luck, we discover the real source file's name from that
714 and put it in input_filename. */
715 ungetc (check_newline (), finput
);
721 /* The line number can be -1 if we had -g3 and the input file
722 had a directive specifying line 0. But we want predefined
723 functions to have a line number of 0, not -1. */
727 /* If gen_declaration desired, open the output file. */
728 if (flag_gen_declaration
)
730 register char * const dumpname
= concat (dumpname
, ".decl", NULL
);
731 gen_declaration_file
= fopen (dumpname
, "w");
732 if (gen_declaration_file
== 0)
733 pfatal_with_name (dumpname
);
737 if (flag_next_runtime
)
739 TAG_GETCLASS
= "objc_getClass";
740 TAG_GETMETACLASS
= "objc_getMetaClass";
741 TAG_MSGSEND
= "objc_msgSend";
742 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
743 TAG_EXECCLASS
= "__objc_execClass";
747 TAG_GETCLASS
= "objc_get_class";
748 TAG_GETMETACLASS
= "objc_get_meta_class";
749 TAG_MSGSEND
= "objc_msg_lookup";
750 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
751 TAG_EXECCLASS
= "__objc_exec_class";
752 flag_typed_selectors
= 1;
755 objc_ellipsis_node
= make_node (ERROR_MARK
);
757 if (doing_objc_thang
)
760 if (print_struct_values
)
761 generate_struct_by_value_array ();
763 objc_act_parse_init ();
770 fatal ("Objective-C text in C source file");
776 if (doing_objc_thang
)
777 finish_objc (); /* Objective-C finalization */
779 if (gen_declaration_file
)
780 fclose (gen_declaration_file
);
795 lang_decode_option (argc
, argv
)
799 const char *p
= argv
[0];
800 if (!strcmp (p
, "-lang-objc"))
801 c_language
= clk_objective_c
;
802 else if (!strcmp (p
, "-gen-decls"))
803 flag_gen_declaration
= 1;
804 else if (!strcmp (p
, "-Wselector"))
806 else if (!strcmp (p
, "-Wno-selector"))
808 else if (!strcmp (p
, "-Wprotocol"))
809 flag_warn_protocol
= 1;
810 else if (!strcmp (p
, "-Wno-protocol"))
811 flag_warn_protocol
= 0;
812 else if (!strcmp (p
, "-fgnu-runtime"))
813 flag_next_runtime
= 0;
814 else if (!strcmp (p
, "-fno-next-runtime"))
815 flag_next_runtime
= 0;
816 else if (!strcmp (p
, "-fno-gnu-runtime"))
817 flag_next_runtime
= 1;
818 else if (!strcmp (p
, "-fnext-runtime"))
819 flag_next_runtime
= 1;
820 else if (!strcmp (p
, "-print-objc-runtime-info"))
821 print_struct_values
= 1;
823 return c_decode_option (argc
, argv
);
828 /* used by print-tree.c */
831 lang_print_xnode (file
, node
, indent
)
832 FILE *file ATTRIBUTE_UNUSED
;
833 tree node ATTRIBUTE_UNUSED
;
834 int indent ATTRIBUTE_UNUSED
;
840 define_decl (declarator
, declspecs
)
844 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
845 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
849 /* Return 1 if LHS and RHS are compatible types for assignment or
850 various other operations. Return 0 if they are incompatible, and
851 return -1 if we choose to not decide. When the operation is
852 REFLEXIVE, check for compatibility in either direction.
854 For statically typed objects, an assignment of the form `a' = `b'
858 `a' and `b' are the same class type, or
859 `a' and `b' are of class types A and B such that B is a descendant of A. */
862 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
866 if (doing_objc_thang
)
867 return objc_comptypes (lhs
, rhs
, reflexive
);
872 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
880 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
882 p
= TREE_VALUE (rproto
);
884 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
886 if ((fnd
= lookup_method (class_meth
887 ? PROTOCOL_CLS_METHODS (p
)
888 : PROTOCOL_NST_METHODS (p
), sel_name
)))
890 else if (PROTOCOL_LIST (p
))
891 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
892 sel_name
, class_meth
);
896 ; /* An identifier...if we could not find a protocol. */
907 lookup_protocol_in_reflist (rproto_list
, lproto
)
913 /* Make sure the protocol is support by the object on the rhs. */
914 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
917 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
919 p
= TREE_VALUE (rproto
);
921 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
926 else if (PROTOCOL_LIST (p
))
927 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
936 ; /* An identifier...if we could not find a protocol. */
942 /* Return 1 if LHS and RHS are compatible types for assignment
943 or various other operations. Return 0 if they are incompatible,
944 and return -1 if we choose to not decide. When the operation
945 is REFLEXIVE, check for compatibility in either direction. */
948 objc_comptypes (lhs
, rhs
, reflexive
)
953 /* New clause for protocols. */
955 if (TREE_CODE (lhs
) == POINTER_TYPE
956 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
957 && TREE_CODE (rhs
) == POINTER_TYPE
958 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
960 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
961 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
965 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
966 tree rproto
, rproto_list
;
971 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
973 /* Make sure the protocol is supported by the object
975 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
977 p
= TREE_VALUE (lproto
);
978 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
981 warning ("object does not conform to the `%s' protocol",
982 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
985 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
987 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
990 /* Make sure the protocol is supported by the object
992 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
994 p
= TREE_VALUE (lproto
);
996 rinter
= lookup_interface (rname
);
998 while (rinter
&& !rproto
)
1002 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
1003 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
1005 /* Check for protocols adopted by categories. */
1006 cat
= CLASS_CATEGORY_LIST (rinter
);
1007 while (cat
&& !rproto
)
1009 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
1010 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
1012 cat
= CLASS_CATEGORY_LIST (cat
);
1015 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
1019 warning ("class `%s' does not implement the `%s' protocol",
1020 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
1021 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1025 /* May change...based on whether there was any mismatch */
1028 else if (rhs_is_proto
)
1029 /* Lhs is not a protocol...warn if it is statically typed */
1030 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
1033 /* Defer to comptypes .*/
1037 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
1038 ; /* Fall thru. This is the case we have been handling all along */
1040 /* Defer to comptypes. */
1043 /* `id' = `<class> *', `<class> *' = `id' */
1045 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
1046 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
1049 /* `id' = `Class', `Class' = `id' */
1051 else if ((TYPE_NAME (lhs
) == objc_object_id
1052 && TYPE_NAME (rhs
) == objc_class_id
)
1053 || (TYPE_NAME (lhs
) == objc_class_id
1054 && TYPE_NAME (rhs
) == objc_object_id
))
1057 /* `<class> *' = `<class> *' */
1059 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1061 tree lname
= TYPE_NAME (lhs
);
1062 tree rname
= TYPE_NAME (rhs
);
1068 /* If the left hand side is a super class of the right hand side,
1070 for (inter
= lookup_interface (rname
); inter
;
1071 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1072 if (lname
== CLASS_SUPER_NAME (inter
))
1075 /* Allow the reverse when reflexive. */
1077 for (inter
= lookup_interface (lname
); inter
;
1078 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1079 if (rname
== CLASS_SUPER_NAME (inter
))
1085 /* Defer to comptypes. */
1089 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1092 objc_check_decl (decl
)
1095 tree type
= TREE_TYPE (decl
);
1097 if (TREE_CODE (type
) == RECORD_TYPE
1098 && TREE_STATIC_TEMPLATE (type
)
1099 && type
!= constant_string_type
)
1101 error_with_decl (decl
, "`%s' cannot be statically allocated");
1102 fatal ("statically allocated objects not supported");
1107 maybe_objc_check_decl (decl
)
1110 if (doing_objc_thang
)
1111 objc_check_decl (decl
);
1114 /* Implement static typing. At this point, we know we have an interface. */
1117 get_static_reference (interface
, protocols
)
1121 tree type
= xref_tag (RECORD_TYPE
, interface
);
1125 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1127 t
= copy_node (type
);
1128 TYPE_BINFO (t
) = make_tree_vec (2);
1130 /* Add this type to the chain of variants of TYPE. */
1131 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1132 TYPE_NEXT_VARIANT (m
) = t
;
1134 /* Look up protocols and install in lang specific list. */
1135 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1137 /* This forces a new pointer type to be created later
1138 (in build_pointer_type)...so that the new template
1139 we just created will actually be used...what a hack! */
1140 if (TYPE_POINTER_TO (t
))
1141 TYPE_POINTER_TO (t
) = 0;
1150 get_object_reference (protocols
)
1153 tree type_decl
= lookup_name (objc_id_id
);
1156 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1158 type
= TREE_TYPE (type_decl
);
1159 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1160 warning ("Unexpected type for `id' (%s)",
1161 gen_declaration (type
, errbuf
));
1164 fatal ("Undefined type `id', please import <objc/objc.h>");
1166 /* This clause creates a new pointer type that is qualified with
1167 the protocol specification...this info is used later to do more
1168 elaborate type checking. */
1172 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1174 t
= copy_node (type
);
1175 TYPE_BINFO (t
) = make_tree_vec (2);
1177 /* Add this type to the chain of variants of TYPE. */
1178 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1179 TYPE_NEXT_VARIANT (m
) = t
;
1181 /* Look up protocols...and install in lang specific list */
1182 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1184 /* This forces a new pointer type to be created later
1185 (in build_pointer_type)...so that the new template
1186 we just created will actually be used...what a hack! */
1187 if (TYPE_POINTER_TO (t
))
1188 TYPE_POINTER_TO (t
) = NULL
;
1196 lookup_and_install_protocols (protocols
)
1201 tree return_value
= protocols
;
1203 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1205 tree ident
= TREE_VALUE (proto
);
1206 tree p
= lookup_protocol (ident
);
1210 error ("Cannot find protocol declaration for `%s'",
1211 IDENTIFIER_POINTER (ident
));
1213 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1215 return_value
= TREE_CHAIN (proto
);
1219 /* Replace identifier with actual protocol node. */
1220 TREE_VALUE (proto
) = p
;
1225 return return_value
;
1228 /* Create and push a decl for a built-in external variable or field NAME.
1230 TYPE is its data type. */
1233 create_builtin_decl (code
, type
, name
)
1234 enum tree_code code
;
1238 tree decl
= build_decl (code
, get_identifier (name
), type
);
1240 if (code
== VAR_DECL
)
1242 TREE_STATIC (decl
) = 1;
1243 make_decl_rtl (decl
, 0, 1);
1247 DECL_ARTIFICIAL (decl
) = 1;
1251 /* Purpose: "play" parser, creating/installing representations
1252 of the declarations that are required by Objective-C.
1256 type_spec--------->sc_spec
1257 (tree_list) (tree_list)
1260 identifier_node identifier_node */
1263 synth_module_prologue ()
1268 /* Defined in `objc.h' */
1269 objc_object_id
= get_identifier (TAG_OBJECT
);
1271 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1273 id_type
= build_pointer_type (objc_object_reference
);
1275 objc_id_id
= get_identifier (TYPE_ID
);
1276 objc_class_id
= get_identifier (TAG_CLASS
);
1278 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1279 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1280 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1282 /* Declare type of selector-objects that represent an operation name. */
1284 #ifdef OBJC_INT_SELECTORS
1285 /* `unsigned int' */
1286 selector_type
= unsigned_type_node
;
1288 /* `struct objc_selector *' */
1290 = build_pointer_type (xref_tag (RECORD_TYPE
,
1291 get_identifier (TAG_SELECTOR
)));
1292 #endif /* not OBJC_INT_SELECTORS */
1294 /* Forward declare type, or else the prototype for msgSendSuper will
1297 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1298 get_identifier (TAG_SUPER
)));
1301 /* id objc_msgSend (id, SEL, ...); */
1304 = build_function_type (id_type
,
1305 tree_cons (NULL_TREE
, id_type
,
1306 tree_cons (NULL_TREE
, selector_type
,
1309 if (! flag_next_runtime
)
1311 umsg_decl
= build_decl (FUNCTION_DECL
,
1312 get_identifier (TAG_MSGSEND
), temp_type
);
1313 DECL_EXTERNAL (umsg_decl
) = 1;
1314 TREE_PUBLIC (umsg_decl
) = 1;
1315 DECL_INLINE (umsg_decl
) = 1;
1316 DECL_ARTIFICIAL (umsg_decl
) = 1;
1318 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1319 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1321 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1322 pushdecl (umsg_decl
);
1325 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1327 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1330 = build_function_type (id_type
,
1331 tree_cons (NULL_TREE
, super_p
,
1332 tree_cons (NULL_TREE
, selector_type
,
1335 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1336 temp_type
, 0, NOT_BUILT_IN
, 0);
1338 /* id objc_getClass (const char *); */
1340 temp_type
= build_function_type (id_type
,
1341 tree_cons (NULL_TREE
,
1342 const_string_type_node
,
1343 tree_cons (NULL_TREE
, void_type_node
,
1347 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1349 /* id objc_getMetaClass (const char *); */
1351 objc_get_meta_class_decl
1352 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1354 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1356 if (! flag_next_runtime
)
1358 if (flag_typed_selectors
)
1360 /* Suppress outputting debug symbols, because
1361 dbxout_init hasn'r been called yet. */
1362 enum debug_info_type save_write_symbols
= write_symbols
;
1363 write_symbols
= NO_DEBUG
;
1365 build_selector_template ();
1366 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1368 write_symbols
= save_write_symbols
;
1371 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1373 layout_type (temp_type
);
1374 UOBJC_SELECTOR_TABLE_decl
1375 = create_builtin_decl (VAR_DECL
, temp_type
,
1376 "_OBJC_SELECTOR_TABLE");
1378 /* Avoid warning when not sending messages. */
1379 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1382 generate_forward_declaration_to_string_table ();
1384 /* Forward declare constant_string_id and constant_string_type. */
1385 constant_string_id
= get_identifier (STRING_OBJECT_CLASS_NAME
);
1386 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1389 /* Custom build_string which sets TREE_TYPE! */
1392 my_build_string (len
, str
)
1397 tree a_string
= build_string (len
, str
);
1399 /* Some code from combine_strings, which is local to c-parse.y. */
1400 if (TREE_TYPE (a_string
) == int_array_type_node
)
1403 TREE_TYPE (a_string
)
1404 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1405 build_index_type (build_int_2 (len
- 1, 0)));
1407 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1408 TREE_STATIC (a_string
) = 1;
1413 /* Return a newly constructed OBJC_STRING_CST node whose value is
1414 the LEN characters at STR.
1415 The TREE_TYPE is not initialized. */
1418 build_objc_string (len
, str
)
1422 tree s
= build_string (len
, str
);
1424 TREE_SET_CODE (s
, OBJC_STRING_CST
);
1428 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1429 NXConstanString which points at the concatenation of those strings.
1430 We place the string object in the __string_objects section of the
1431 __OBJC segment. The Objective-C runtime will initialize the isa
1432 pointers of the string objects to point at the NXConstandString class
1436 build_objc_string_object (strings
)
1439 tree string
, initlist
, constructor
;
1442 if (!doing_objc_thang
)
1445 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1447 error ("Cannot find interface declaration for `%s'",
1448 IDENTIFIER_POINTER (constant_string_id
));
1449 return error_mark_node
;
1452 add_class_reference (constant_string_id
);
1454 /* Combine_strings will work for OBJC_STRING_CST's too. */
1455 string
= combine_strings (strings
);
1456 TREE_SET_CODE (string
, STRING_CST
);
1457 length
= TREE_STRING_LENGTH (string
) - 1;
1459 /* & ((NXConstantString) {0, string, length}) */
1461 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1463 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1465 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1466 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1468 if (!flag_next_runtime
)
1471 = objc_add_static_instance (constructor
, constant_string_type
);
1474 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1477 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1480 objc_add_static_instance (constructor
, class_decl
)
1481 tree constructor
, class_decl
;
1483 static int num_static_inst
;
1487 /* Find the list of static instances for the CLASS_DECL. Create one if
1489 for (chain
= &objc_static_instances
;
1490 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1491 chain
= &TREE_CHAIN (*chain
));
1494 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1495 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1498 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1499 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1500 DECL_COMMON (decl
) = 1;
1501 TREE_STATIC (decl
) = 1;
1502 DECL_ARTIFICIAL (decl
) = 1;
1503 pushdecl_top_level (decl
);
1504 rest_of_decl_compilation (decl
, 0, 1, 0);
1506 /* Do this here so it gets output later instead of possibly
1507 inside something else we are writing. */
1508 DECL_INITIAL (decl
) = constructor
;
1510 /* Add the DECL to the head of this CLASS' list. */
1511 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1516 /* Build a static constant CONSTRUCTOR
1517 with type TYPE and elements ELTS. */
1520 build_constructor (type
, elts
)
1523 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1525 TREE_CONSTANT (constructor
) = 1;
1526 TREE_STATIC (constructor
) = 1;
1527 TREE_READONLY (constructor
) = 1;
1532 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1534 /* Predefine the following data type:
1542 void *defs[cls_def_cnt + cat_def_cnt];
1546 build_objc_symtab_template ()
1548 tree field_decl
, field_decl_chain
, index
;
1550 objc_symtab_template
1551 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1553 /* long sel_ref_cnt; */
1555 field_decl
= create_builtin_decl (FIELD_DECL
,
1556 long_integer_type_node
,
1558 field_decl_chain
= field_decl
;
1562 field_decl
= create_builtin_decl (FIELD_DECL
,
1563 build_pointer_type (selector_type
),
1565 chainon (field_decl_chain
, field_decl
);
1567 /* short cls_def_cnt; */
1569 field_decl
= create_builtin_decl (FIELD_DECL
,
1570 short_integer_type_node
,
1572 chainon (field_decl_chain
, field_decl
);
1574 /* short cat_def_cnt; */
1576 field_decl
= create_builtin_decl (FIELD_DECL
,
1577 short_integer_type_node
,
1579 chainon (field_decl_chain
, field_decl
);
1581 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1583 if (!flag_next_runtime
)
1584 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1586 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1587 imp_count
== 0 && cat_count
== 0
1589 field_decl
= create_builtin_decl (FIELD_DECL
,
1590 build_array_type (ptr_type_node
, index
),
1592 chainon (field_decl_chain
, field_decl
);
1594 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1597 /* Create the initial value for the `defs' field of _objc_symtab.
1598 This is a CONSTRUCTOR. */
1601 init_def_list (type
)
1604 tree expr
, initlist
= NULL_TREE
;
1605 struct imp_entry
*impent
;
1608 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1610 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1612 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1613 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1618 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1620 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1622 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1623 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1627 if (!flag_next_runtime
)
1629 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1632 if (static_instances_decl
)
1633 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1635 expr
= build_int_2 (0, 0);
1637 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1640 return build_constructor (type
, nreverse (initlist
));
1643 /* Construct the initial value for all of _objc_symtab. */
1646 init_objc_symtab (type
)
1651 /* sel_ref_cnt = { ..., 5, ... } */
1653 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1655 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1657 if (flag_next_runtime
|| ! sel_ref_chain
)
1658 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1660 initlist
= tree_cons (NULL_TREE
,
1661 build_unary_op (ADDR_EXPR
,
1662 UOBJC_SELECTOR_TABLE_decl
, 1),
1665 /* cls_def_cnt = { ..., 5, ... } */
1667 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1669 /* cat_def_cnt = { ..., 5, ... } */
1671 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1673 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1675 if (imp_count
|| cat_count
|| static_instances_decl
)
1678 tree field
= TYPE_FIELDS (type
);
1679 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1681 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1685 return build_constructor (type
, nreverse (initlist
));
1688 /* Push forward-declarations of all the categories
1689 so that init_def_list can use them in a CONSTRUCTOR. */
1692 forward_declare_categories ()
1694 struct imp_entry
*impent
;
1695 tree sav
= implementation_context
;
1697 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1699 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1701 /* Set an invisible arg to synth_id_with_class_suffix. */
1702 implementation_context
= impent
->imp_context
;
1704 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1705 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1708 implementation_context
= sav
;
1711 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1712 and initialized appropriately. */
1715 generate_objc_symtab_decl ()
1719 if (!objc_category_template
)
1720 build_category_template ();
1722 /* forward declare categories */
1724 forward_declare_categories ();
1726 if (!objc_symtab_template
)
1727 build_objc_symtab_template ();
1729 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1731 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1732 tree_cons (NULL_TREE
,
1733 objc_symtab_template
, sc_spec
),
1735 NULL_TREE
, NULL_TREE
);
1737 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1738 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1739 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1740 finish_decl (UOBJC_SYMBOLS_decl
,
1741 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1746 init_module_descriptor (type
)
1749 tree initlist
, expr
;
1751 /* version = { 1, ... } */
1753 expr
= build_int_2 (OBJC_VERSION
, 0);
1754 initlist
= build_tree_list (NULL_TREE
, expr
);
1756 /* size = { ..., sizeof (struct objc_module), ... } */
1758 expr
= size_in_bytes (objc_module_template
);
1759 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1761 /* name = { ..., "foo.m", ... } */
1763 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1764 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1766 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1768 if (UOBJC_SYMBOLS_decl
)
1769 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1771 expr
= build_int_2 (0, 0);
1772 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1774 return build_constructor (type
, nreverse (initlist
));
1777 /* Write out the data structures to describe Objective C classes defined.
1778 If appropriate, compile and output a setup function to initialize them.
1779 Return a string which is the name of a function to call to initialize
1780 the Objective C data structures for this file (and perhaps for other files
1783 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1786 build_module_descriptor ()
1788 tree decl_specs
, field_decl
, field_decl_chain
;
1790 objc_module_template
1791 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1795 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1796 field_decl
= get_identifier ("version");
1798 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1799 field_decl_chain
= field_decl
;
1803 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1804 field_decl
= get_identifier ("size");
1806 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1807 chainon (field_decl_chain
, field_decl
);
1811 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1812 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1814 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1815 chainon (field_decl_chain
, field_decl
);
1817 /* struct objc_symtab *symtab; */
1819 decl_specs
= get_identifier (UTAG_SYMTAB
);
1820 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1821 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1823 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1824 chainon (field_decl_chain
, field_decl
);
1826 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1828 /* Create an instance of "objc_module". */
1830 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1831 build_tree_list (NULL_TREE
,
1832 ridpointers
[(int) RID_STATIC
]));
1834 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1835 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1837 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1838 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1839 finish_decl (UOBJC_MODULES_decl
,
1840 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1843 /* Mark the decl to avoid "defined but not used" warning. */
1844 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1846 /* Generate a constructor call for the module descriptor.
1847 This code was generated by reading the grammar rules
1848 of c-parse.in; Therefore, it may not be the most efficient
1849 way of generating the requisite code. */
1851 if (flag_next_runtime
)
1855 tree parms
, function_decl
, decelerator
, void_list_node_1
;
1857 tree init_function_name
= get_file_function_name ('I');
1859 /* Declare void __objc_execClass (void *); */
1861 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1863 = build_function_type (void_type_node
,
1864 tree_cons (NULL_TREE
, ptr_type_node
,
1866 function_decl
= build_decl (FUNCTION_DECL
,
1867 get_identifier (TAG_EXECCLASS
),
1869 DECL_EXTERNAL (function_decl
) = 1;
1870 DECL_ARTIFICIAL (function_decl
) = 1;
1871 TREE_PUBLIC (function_decl
) = 1;
1873 pushdecl (function_decl
);
1874 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1877 = build_tree_list (NULL_TREE
,
1878 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1879 decelerator
= build_function_call (function_decl
, parms
);
1881 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1883 start_function (void_list_node_1
,
1884 build_parse_node (CALL_EXPR
, init_function_name
,
1885 /* This has the format of the output
1886 of get_parm_info. */
1887 tree_cons (NULL_TREE
, NULL_TREE
,
1890 NULL_TREE
, NULL_TREE
);
1891 #if 0 /* This should be turned back on later
1892 for the systems where collect is not needed. */
1893 /* Make these functions nonglobal
1894 so each file can use the same name. */
1895 TREE_PUBLIC (current_function_decl
) = 0;
1897 TREE_USED (current_function_decl
) = 1;
1898 store_parm_decls ();
1900 assemble_external (function_decl
);
1901 c_expand_expr_stmt (decelerator
);
1903 TREE_PUBLIC (current_function_decl
) = 1;
1905 function_decl
= current_function_decl
;
1906 finish_function (0);
1908 /* Return the name of the constructor function. */
1909 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1913 /* extern const char _OBJC_STRINGS[]; */
1916 generate_forward_declaration_to_string_table ()
1918 tree sc_spec
, decl_specs
, expr_decl
;
1920 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1921 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1924 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1926 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1929 /* Return the DECL of the string IDENT in the SECTION. */
1932 get_objc_string_decl (ident
, section
)
1934 enum string_section section
;
1938 if (section
== class_names
)
1939 chain
= class_names_chain
;
1940 else if (section
== meth_var_names
)
1941 chain
= meth_var_names_chain
;
1942 else if (section
== meth_var_types
)
1943 chain
= meth_var_types_chain
;
1947 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1948 if (TREE_VALUE (chain
) == ident
)
1949 return (TREE_PURPOSE (chain
));
1955 /* Output references to all statically allocated objects. Return the DECL
1956 for the array built. */
1959 generate_static_references ()
1961 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1962 tree class_name
, class, decl
, initlist
;
1963 tree cl_chain
, in_chain
, type
;
1964 int num_inst
, num_class
;
1967 if (flag_next_runtime
)
1970 for (cl_chain
= objc_static_instances
, num_class
= 0;
1971 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1973 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1974 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1976 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1977 ident
= get_identifier (buf
);
1979 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1980 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1981 build_tree_list (NULL_TREE
,
1982 ridpointers
[(int) RID_STATIC
]));
1983 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1984 DECL_CONTEXT (decl
) = 0;
1985 DECL_ARTIFICIAL (decl
) = 1;
1987 /* Output {class_name, ...}. */
1988 class = TREE_VALUE (cl_chain
);
1989 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1990 initlist
= build_tree_list (NULL_TREE
,
1991 build_unary_op (ADDR_EXPR
, class_name
, 1));
1993 /* Output {..., instance, ...}. */
1994 for (in_chain
= TREE_PURPOSE (cl_chain
);
1995 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1997 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1998 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2001 /* Output {..., NULL}. */
2002 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2004 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
2005 finish_decl (decl
, expr
, NULL_TREE
);
2006 TREE_USED (decl
) = 1;
2008 type
= build_array_type (build_pointer_type (void_type_node
), 0);
2009 decl
= build_decl (VAR_DECL
, ident
, type
);
2010 make_decl_rtl (decl
, 0, 1);
2011 TREE_USED (decl
) = 1;
2013 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
2016 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
2017 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
2018 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
2019 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
2020 build_tree_list (NULL_TREE
,
2021 ridpointers
[(int) RID_STATIC
]));
2022 static_instances_decl
2023 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
2024 TREE_USED (static_instances_decl
) = 1;
2025 DECL_CONTEXT (static_instances_decl
) = 0;
2026 DECL_ARTIFICIAL (static_instances_decl
) = 1;
2027 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
2029 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
2032 /* Output all strings. */
2037 tree sc_spec
, decl_specs
, expr_decl
;
2038 tree chain
, string_expr
;
2041 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2043 string
= TREE_VALUE (chain
);
2044 decl
= TREE_PURPOSE (chain
);
2046 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2047 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2048 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2049 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2050 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2051 IDENTIFIER_POINTER (string
));
2052 finish_decl (decl
, string_expr
, NULL_TREE
);
2055 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2057 string
= TREE_VALUE (chain
);
2058 decl
= TREE_PURPOSE (chain
);
2060 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2061 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2062 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2063 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2064 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2065 IDENTIFIER_POINTER (string
));
2066 finish_decl (decl
, string_expr
, NULL_TREE
);
2069 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2071 string
= TREE_VALUE (chain
);
2072 decl
= TREE_PURPOSE (chain
);
2074 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2075 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2076 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2077 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2078 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2079 IDENTIFIER_POINTER (string
));
2080 finish_decl (decl
, string_expr
, NULL_TREE
);
2085 build_selector_reference_decl ()
2091 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2093 ident
= get_identifier (buf
);
2095 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2096 DECL_EXTERNAL (decl
) = 1;
2097 TREE_PUBLIC (decl
) = 1;
2098 TREE_USED (decl
) = 1;
2099 TREE_READONLY (decl
) = 1;
2100 DECL_ARTIFICIAL (decl
) = 1;
2101 DECL_CONTEXT (decl
) = 0;
2103 make_decl_rtl (decl
, 0, 1);
2104 pushdecl_top_level (decl
);
2109 /* Just a handy wrapper for add_objc_string. */
2112 build_selector (ident
)
2115 tree expr
= add_objc_string (ident
, meth_var_names
);
2116 if (flag_typed_selectors
)
2119 return build_c_cast (selector_type
, expr
); /* cast! */
2122 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2123 The cast stops the compiler from issuing the following message:
2124 grok.m: warning: initialization of non-const * pointer from const *
2125 grok.m: warning: initialization between incompatible pointer types. */
2129 build_msg_pool_reference (offset
)
2132 tree expr
= build_int_2 (offset
, 0);
2135 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2136 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2138 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2139 ridpointers
[(int) RID_CHAR
]),
2140 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2141 TREE_TYPE (expr
) = groktypename (cast
);
2146 init_selector (offset
)
2149 tree expr
= build_msg_pool_reference (offset
);
2150 TREE_TYPE (expr
) = selector_type
;
2156 build_selector_translation_table ()
2158 tree sc_spec
, decl_specs
;
2159 tree chain
, initlist
= NULL_TREE
;
2161 tree decl
= NULL_TREE
, var_decl
, name
;
2163 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2167 expr
= build_selector (TREE_VALUE (chain
));
2169 if (flag_next_runtime
)
2171 name
= DECL_NAME (TREE_PURPOSE (chain
));
2173 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2175 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2176 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2180 /* The `decl' that is returned from start_decl is the one that we
2181 forward declared in `build_selector_reference' */
2182 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2185 /* add one for the '\0' character */
2186 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2188 if (flag_next_runtime
)
2189 finish_decl (decl
, expr
, NULL_TREE
);
2192 if (flag_typed_selectors
)
2194 tree eltlist
= NULL_TREE
;
2195 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2196 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2197 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2198 expr
= build_constructor (objc_selector_template
,
2199 nreverse (eltlist
));
2201 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2206 if (! flag_next_runtime
)
2208 /* Cause the variable and its initial value to be actually output. */
2209 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2210 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2211 /* NULL terminate the list and fix the decl for output. */
2212 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2213 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2214 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2215 nreverse (initlist
));
2216 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2217 current_function_decl
= NULL_TREE
;
2222 get_proto_encoding (proto
)
2230 if (! METHOD_ENCODING (proto
))
2232 tmp_decl
= build_tmp_function_decl ();
2233 hack_method_prototype (proto
, tmp_decl
);
2234 encoding
= encode_method_prototype (proto
, tmp_decl
);
2235 METHOD_ENCODING (proto
) = encoding
;
2238 encoding
= METHOD_ENCODING (proto
);
2240 return add_objc_string (encoding
, meth_var_types
);
2243 return build_int_2 (0, 0);
2246 /* sel_ref_chain is a list whose "value" fields will be instances of
2247 identifier_node that represent the selector. */
2250 build_typed_selector_reference (ident
, proto
)
2253 tree
*chain
= &sel_ref_chain
;
2259 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2260 goto return_at_index
;
2263 chain
= &TREE_CHAIN (*chain
);
2266 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2269 expr
= build_unary_op (ADDR_EXPR
,
2270 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2271 build_int_2 (index
, 0)),
2273 return build_c_cast (selector_type
, expr
);
2277 build_selector_reference (ident
)
2280 tree
*chain
= &sel_ref_chain
;
2286 if (TREE_VALUE (*chain
) == ident
)
2287 return (flag_next_runtime
2288 ? TREE_PURPOSE (*chain
)
2289 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2290 build_int_2 (index
, 0)));
2293 chain
= &TREE_CHAIN (*chain
);
2296 expr
= build_selector_reference_decl ();
2298 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2300 return (flag_next_runtime
2302 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2303 build_int_2 (index
, 0)));
2307 build_class_reference_decl ()
2313 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2315 ident
= get_identifier (buf
);
2317 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2318 DECL_EXTERNAL (decl
) = 1;
2319 TREE_PUBLIC (decl
) = 1;
2320 TREE_USED (decl
) = 1;
2321 TREE_READONLY (decl
) = 1;
2322 DECL_CONTEXT (decl
) = 0;
2323 DECL_ARTIFICIAL (decl
) = 1;
2325 make_decl_rtl (decl
, 0, 1);
2326 pushdecl_top_level (decl
);
2331 /* Create a class reference, but don't create a variable to reference
2335 add_class_reference (ident
)
2340 if ((chain
= cls_ref_chain
))
2345 if (ident
== TREE_VALUE (chain
))
2349 chain
= TREE_CHAIN (chain
);
2353 /* Append to the end of the list */
2354 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2357 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2360 /* Get a class reference, creating it if necessary. Also create the
2361 reference variable. */
2364 get_class_reference (ident
)
2367 if (flag_next_runtime
)
2372 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2373 if (TREE_VALUE (*chain
) == ident
)
2375 if (! TREE_PURPOSE (*chain
))
2376 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2378 return TREE_PURPOSE (*chain
);
2381 decl
= build_class_reference_decl ();
2382 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2389 add_class_reference (ident
);
2391 params
= build_tree_list (NULL_TREE
,
2392 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2393 IDENTIFIER_POINTER (ident
)));
2395 assemble_external (objc_get_class_decl
);
2396 return build_function_call (objc_get_class_decl
, params
);
2400 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2401 of identifier_node that represent the selector. It returns the
2402 offset of the selector from the beginning of the _OBJC_STRINGS
2403 pool. This offset is typically used by init_selector during code
2406 For each string section we have a chain which maps identifier nodes
2407 to decls for the strings. */
2410 add_objc_string (ident
, section
)
2412 enum string_section section
;
2416 if (section
== class_names
)
2417 chain
= &class_names_chain
;
2418 else if (section
== meth_var_names
)
2419 chain
= &meth_var_names_chain
;
2420 else if (section
== meth_var_types
)
2421 chain
= &meth_var_types_chain
;
2427 if (TREE_VALUE (*chain
) == ident
)
2428 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2430 chain
= &TREE_CHAIN (*chain
);
2433 decl
= build_objc_string_decl (section
);
2435 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2437 return build_unary_op (ADDR_EXPR
, decl
, 1);
2441 build_objc_string_decl (section
)
2442 enum string_section section
;
2446 static int class_names_idx
= 0;
2447 static int meth_var_names_idx
= 0;
2448 static int meth_var_types_idx
= 0;
2450 if (section
== class_names
)
2451 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2452 else if (section
== meth_var_names
)
2453 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2454 else if (section
== meth_var_types
)
2455 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2457 ident
= get_identifier (buf
);
2459 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2460 DECL_EXTERNAL (decl
) = 1;
2461 TREE_PUBLIC (decl
) = 1;
2462 TREE_USED (decl
) = 1;
2463 TREE_READONLY (decl
) = 1;
2464 TREE_CONSTANT (decl
) = 1;
2465 DECL_CONTEXT (decl
) = 0;
2466 DECL_ARTIFICIAL (decl
) = 1;
2468 make_decl_rtl (decl
, 0, 1);
2469 pushdecl_top_level (decl
);
2476 objc_declare_alias (alias_ident
, class_ident
)
2480 if (!doing_objc_thang
)
2483 if (is_class_name (class_ident
) != class_ident
)
2484 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2485 else if (is_class_name (alias_ident
))
2486 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2488 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2492 objc_declare_class (ident_list
)
2497 if (!doing_objc_thang
)
2500 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2502 tree ident
= TREE_VALUE (list
);
2505 if ((decl
= lookup_name (ident
)))
2507 error ("`%s' redeclared as different kind of symbol",
2508 IDENTIFIER_POINTER (ident
));
2509 error_with_decl (decl
, "previous declaration of `%s'");
2512 if (! is_class_name (ident
))
2514 tree record
= xref_tag (RECORD_TYPE
, ident
);
2515 TREE_STATIC_TEMPLATE (record
) = 1;
2516 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2522 is_class_name (ident
)
2527 if (lookup_interface (ident
))
2530 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2532 if (ident
== TREE_VALUE (chain
))
2536 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2538 if (ident
== TREE_VALUE (chain
))
2539 return TREE_PURPOSE (chain
);
2546 lookup_interface (ident
)
2551 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2553 if (ident
== CLASS_NAME (chain
))
2560 objc_copy_list (list
, head
)
2564 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2568 tail
= copy_node (list
);
2570 /* The following statement fixes a bug when inheriting instance
2571 variables that are declared to be bitfields. finish_struct
2572 expects to find the width of the bitfield in DECL_INITIAL. */
2573 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2574 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2576 newlist
= chainon (newlist
, tail
);
2577 list
= TREE_CHAIN (list
);
2584 /* Used by: build_private_template, get_class_ivars, and
2585 continue_class. COPY is 1 when called from @defs. In this case
2586 copy all fields. Otherwise don't copy leaf ivars since we rely on
2587 them being side-effected exactly once by finish_struct. */
2590 build_ivar_chain (interface
, copy
)
2594 tree my_name
, super_name
, ivar_chain
;
2596 my_name
= CLASS_NAME (interface
);
2597 super_name
= CLASS_SUPER_NAME (interface
);
2599 /* Possibly copy leaf ivars. */
2601 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2603 ivar_chain
= CLASS_IVARS (interface
);
2608 tree super_interface
= lookup_interface (super_name
);
2610 if (!super_interface
)
2612 /* fatal did not work with 2 args...should fix */
2613 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2614 IDENTIFIER_POINTER (super_name
),
2615 IDENTIFIER_POINTER (my_name
));
2616 exit (FATAL_EXIT_CODE
);
2619 if (super_interface
== interface
)
2621 fatal ("Circular inheritance in interface declaration for `%s'",
2622 IDENTIFIER_POINTER (super_name
));
2625 interface
= super_interface
;
2626 my_name
= CLASS_NAME (interface
);
2627 super_name
= CLASS_SUPER_NAME (interface
);
2629 op1
= CLASS_IVARS (interface
);
2632 tree head
, tail
= objc_copy_list (op1
, &head
);
2634 /* Prepend super class ivars...make a copy of the list, we
2635 do not want to alter the original. */
2636 TREE_CHAIN (tail
) = ivar_chain
;
2643 /* struct <classname> {
2644 struct objc_class *isa;
2649 build_private_template (class)
2654 if (CLASS_STATIC_TEMPLATE (class))
2656 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2657 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2661 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2663 ivar_context
= build_ivar_chain (class, 0);
2665 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2667 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2669 /* mark this record as class template - for class type checking */
2670 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2674 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2676 build1 (INDIRECT_REF
, NULL_TREE
,
2679 return ivar_context
;
2682 /* Begin code generation for protocols... */
2684 /* struct objc_protocol {
2685 char *protocol_name;
2686 struct objc_protocol **protocol_list;
2687 struct objc_method_desc *instance_methods;
2688 struct objc_method_desc *class_methods;
2692 build_protocol_template ()
2694 tree decl_specs
, field_decl
, field_decl_chain
;
2697 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2699 /* struct objc_class *isa; */
2701 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2702 get_identifier (UTAG_CLASS
)));
2703 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2705 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2706 field_decl_chain
= field_decl
;
2708 /* char *protocol_name; */
2710 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2712 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2714 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2715 chainon (field_decl_chain
, field_decl
);
2717 /* struct objc_protocol **protocol_list; */
2719 decl_specs
= build_tree_list (NULL_TREE
, template);
2721 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2722 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2724 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2725 chainon (field_decl_chain
, field_decl
);
2727 /* struct objc_method_list *instance_methods; */
2730 = build_tree_list (NULL_TREE
,
2731 xref_tag (RECORD_TYPE
,
2732 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2734 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2736 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2737 chainon (field_decl_chain
, field_decl
);
2739 /* struct objc_method_list *class_methods; */
2742 = build_tree_list (NULL_TREE
,
2743 xref_tag (RECORD_TYPE
,
2744 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2746 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2748 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2749 chainon (field_decl_chain
, field_decl
);
2751 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2755 build_descriptor_table_initializer (type
, entries
)
2759 tree initlist
= NULL_TREE
;
2763 tree eltlist
= NULL_TREE
;
2766 = tree_cons (NULL_TREE
,
2767 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2769 = tree_cons (NULL_TREE
,
2770 add_objc_string (METHOD_ENCODING (entries
),
2775 = tree_cons (NULL_TREE
,
2776 build_constructor (type
, nreverse (eltlist
)), initlist
);
2778 entries
= TREE_CHAIN (entries
);
2782 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2785 /* struct objc_method_prototype_list {
2787 struct objc_method_prototype {
2794 build_method_prototype_list_template (list_type
, size
)
2798 tree objc_ivar_list_record
;
2799 tree decl_specs
, field_decl
, field_decl_chain
;
2801 /* Generate an unnamed struct definition. */
2803 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2805 /* int method_count; */
2807 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2808 field_decl
= get_identifier ("method_count");
2811 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2812 field_decl_chain
= field_decl
;
2814 /* struct objc_method method_list[]; */
2816 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2817 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2818 build_int_2 (size
, 0));
2821 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2822 chainon (field_decl_chain
, field_decl
);
2824 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2826 return objc_ivar_list_record
;
2830 build_method_prototype_template ()
2833 tree decl_specs
, field_decl
, field_decl_chain
;
2836 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2838 #ifdef OBJC_INT_SELECTORS
2839 /* unsigned int _cmd; */
2841 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2842 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2843 field_decl
= get_identifier ("_cmd");
2844 #else /* OBJC_INT_SELECTORS */
2845 /* struct objc_selector *_cmd; */
2846 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2847 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2848 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2849 #endif /* OBJC_INT_SELECTORS */
2852 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2853 field_decl_chain
= field_decl
;
2855 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2857 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2859 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2860 chainon (field_decl_chain
, field_decl
);
2862 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2864 return proto_record
;
2867 /* True if last call to forwarding_offset yielded a register offset. */
2868 static int offset_is_register
;
2871 forwarding_offset (parm
)
2874 int offset_in_bytes
;
2876 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2878 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2880 /* ??? Here we assume that the parm address is indexed
2881 off the frame pointer or arg pointer.
2882 If that is not true, we produce meaningless results,
2883 but do not crash. */
2884 if (GET_CODE (addr
) == PLUS
2885 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2886 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2888 offset_in_bytes
= 0;
2890 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2891 offset_is_register
= 0;
2893 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2895 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2896 offset_in_bytes
= apply_args_register_offset (regno
);
2897 offset_is_register
= 1;
2902 /* This is the case where the parm is passed as an int or double
2903 and it is converted to a char, short or float and stored back
2904 in the parmlist. In this case, describe the parm
2905 with the variable's declared type, and adjust the address
2906 if the least significant bytes (which we are using) are not
2908 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2909 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2910 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2912 return offset_in_bytes
;
2916 encode_method_prototype (method_decl
, func_decl
)
2923 HOST_WIDE_INT max_parm_end
= 0;
2927 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2928 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2931 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2932 obstack_object_size (&util_obstack
),
2933 OBJC_ENCODE_INLINE_DEFS
);
2936 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2937 parms
= TREE_CHAIN (parms
))
2939 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2940 + int_size_in_bytes (TREE_TYPE (parms
)));
2942 if (!offset_is_register
&& max_parm_end
< parm_end
)
2943 max_parm_end
= parm_end
;
2946 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2948 sprintf (buf
, "%d", stack_size
);
2949 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2951 user_args
= METHOD_SEL_ARGS (method_decl
);
2953 /* Argument types. */
2954 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2955 parms
= TREE_CHAIN (parms
), i
++)
2957 /* Process argument qualifiers for user supplied arguments. */
2960 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2961 user_args
= TREE_CHAIN (user_args
);
2965 encode_type (TREE_TYPE (parms
),
2966 obstack_object_size (&util_obstack
),
2967 OBJC_ENCODE_INLINE_DEFS
);
2969 /* Compute offset. */
2970 sprintf (buf
, "%d", forwarding_offset (parms
));
2972 /* Indicate register. */
2973 if (offset_is_register
)
2974 obstack_1grow (&util_obstack
, '+');
2976 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2979 obstack_1grow (&util_obstack
, '\0');
2980 result
= get_identifier (obstack_finish (&util_obstack
));
2981 obstack_free (&util_obstack
, util_firstobj
);
2986 generate_descriptor_table (type
, name
, size
, list
, proto
)
2993 tree sc_spec
, decl_specs
, decl
, initlist
;
2995 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2996 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2998 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2999 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3001 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3002 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3004 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
3011 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
3014 static tree objc_method_prototype_template
;
3015 tree initlist
, chain
, method_list_template
;
3016 tree cast
, variable_length_type
;
3019 if (!objc_method_prototype_template
)
3021 objc_method_prototype_template
= build_method_prototype_template ();
3022 ggc_add_tree_root (&objc_method_prototype_template
, 1);
3025 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3026 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
3028 variable_length_type
= groktypename (cast
);
3030 chain
= PROTOCOL_CLS_METHODS (protocol
);
3033 size
= list_length (chain
);
3035 method_list_template
3036 = build_method_prototype_list_template (objc_method_prototype_template
,
3040 = build_descriptor_table_initializer (objc_method_prototype_template
,
3043 UOBJC_CLASS_METHODS_decl
3044 = generate_descriptor_table (method_list_template
,
3045 "_OBJC_PROTOCOL_CLASS_METHODS",
3046 size
, initlist
, protocol
);
3047 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3050 UOBJC_CLASS_METHODS_decl
= 0;
3052 chain
= PROTOCOL_NST_METHODS (protocol
);
3055 size
= list_length (chain
);
3057 method_list_template
3058 = build_method_prototype_list_template (objc_method_prototype_template
,
3061 = build_descriptor_table_initializer (objc_method_prototype_template
,
3064 UOBJC_INSTANCE_METHODS_decl
3065 = generate_descriptor_table (method_list_template
,
3066 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3067 size
, initlist
, protocol
);
3068 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3071 UOBJC_INSTANCE_METHODS_decl
= 0;
3075 build_tmp_function_decl ()
3077 tree decl_specs
, expr_decl
, parms
;
3081 /* struct objc_object *objc_xxx (id, SEL, ...); */
3083 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3084 push_parm_decl (build_tree_list
3085 (build_tree_list (decl_specs
,
3086 build1 (INDIRECT_REF
, NULL_TREE
,
3088 build_tree_list (NULL_TREE
, NULL_TREE
)));
3090 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3091 get_identifier (TAG_SELECTOR
)));
3092 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3094 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3095 build_tree_list (NULL_TREE
, NULL_TREE
)));
3096 parms
= get_parm_info (0);
3099 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3100 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3101 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3102 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3104 return define_decl (expr_decl
, decl_specs
);
3108 hack_method_prototype (nst_methods
, tmp_decl
)
3115 /* Hack to avoid problem with static typing of self arg. */
3116 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3117 start_method_def (nst_methods
);
3118 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3120 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
3121 parms
= get_parm_info (0); /* we have a `, ...' */
3123 parms
= get_parm_info (1); /* place a `void_at_end' */
3125 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3127 /* Usually called from store_parm_decls -> init_function_start. */
3129 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3130 current_function_decl
= tmp_decl
;
3133 /* Code taken from start_function. */
3134 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3135 /* Promote the value to int before returning it. */
3136 if (TREE_CODE (restype
) == INTEGER_TYPE
3137 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3138 restype
= integer_type_node
;
3139 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3142 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3143 DECL_CONTEXT (parm
) = tmp_decl
;
3145 init_function_start (tmp_decl
, "objc-act", 0);
3147 /* Typically called from expand_function_start for function definitions. */
3148 assign_parms (tmp_decl
);
3150 /* install return type */
3151 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3156 generate_protocol_references (plist
)
3161 /* Forward declare protocols referenced. */
3162 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3164 tree proto
= TREE_VALUE (lproto
);
3166 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3167 && PROTOCOL_NAME (proto
))
3169 if (! PROTOCOL_FORWARD_DECL (proto
))
3170 build_protocol_reference (proto
);
3172 if (PROTOCOL_LIST (proto
))
3173 generate_protocol_references (PROTOCOL_LIST (proto
));
3179 generate_protocols ()
3181 tree p
, tmp_decl
, encoding
;
3182 tree sc_spec
, decl_specs
, decl
;
3183 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3186 tmp_decl
= build_tmp_function_decl ();
3188 if (! objc_protocol_template
)
3189 objc_protocol_template
= build_protocol_template ();
3191 /* If a protocol was directly referenced, pull in indirect references. */
3192 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3193 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3194 generate_protocol_references (PROTOCOL_LIST (p
));
3196 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3198 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3199 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3201 /* If protocol wasn't referenced, don't generate any code. */
3202 if (! PROTOCOL_FORWARD_DECL (p
))
3205 /* Make sure we link in the Protocol class. */
3206 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3210 if (! METHOD_ENCODING (nst_methods
))
3212 hack_method_prototype (nst_methods
, tmp_decl
);
3213 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3214 METHOD_ENCODING (nst_methods
) = encoding
;
3216 nst_methods
= TREE_CHAIN (nst_methods
);
3221 if (! METHOD_ENCODING (cls_methods
))
3223 hack_method_prototype (cls_methods
, tmp_decl
);
3224 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3225 METHOD_ENCODING (cls_methods
) = encoding
;
3228 cls_methods
= TREE_CHAIN (cls_methods
);
3230 generate_method_descriptors (p
);
3232 if (PROTOCOL_LIST (p
))
3233 refs_decl
= generate_protocol_list (p
);
3237 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3239 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3241 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3243 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3244 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3246 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3252 (build_tree_list (build_tree_list (NULL_TREE
,
3253 objc_protocol_template
),
3254 build1 (INDIRECT_REF
, NULL_TREE
,
3255 build1 (INDIRECT_REF
, NULL_TREE
,
3258 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3259 TREE_TYPE (refs_expr
) = cast_type2
;
3262 refs_expr
= build_int_2 (0, 0);
3264 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3265 by generate_method_descriptors, which is called above. */
3266 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3267 protocol_name_expr
, refs_expr
,
3268 UOBJC_INSTANCE_METHODS_decl
,
3269 UOBJC_CLASS_METHODS_decl
);
3270 finish_decl (decl
, initlist
, NULL_TREE
);
3272 /* Mark the decl as used to avoid "defined but not used" warning. */
3273 TREE_USED (decl
) = 1;
3278 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3279 instance_methods
, class_methods
)
3283 tree instance_methods
;
3286 tree initlist
= NULL_TREE
, expr
;
3289 cast_type
= groktypename
3291 (build_tree_list (NULL_TREE
,
3292 xref_tag (RECORD_TYPE
,
3293 get_identifier (UTAG_CLASS
))),
3294 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3296 /* Filling the "isa" in with one allows the runtime system to
3297 detect that the version change...should remove before final release. */
3299 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3300 TREE_TYPE (expr
) = cast_type
;
3301 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3302 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3303 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3305 if (!instance_methods
)
3306 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3309 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3310 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3314 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3317 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3318 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3321 return build_constructor (type
, nreverse (initlist
));
3324 /* struct objc_category {
3325 char *category_name;
3327 struct objc_method_list *instance_methods;
3328 struct objc_method_list *class_methods;
3329 struct objc_protocol_list *protocols;
3333 build_category_template ()
3335 tree decl_specs
, field_decl
, field_decl_chain
;
3337 objc_category_template
= start_struct (RECORD_TYPE
,
3338 get_identifier (UTAG_CATEGORY
));
3339 /* char *category_name; */
3341 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3343 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3345 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3346 field_decl_chain
= field_decl
;
3348 /* char *class_name; */
3350 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3351 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3353 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3354 chainon (field_decl_chain
, field_decl
);
3356 /* struct objc_method_list *instance_methods; */
3358 decl_specs
= build_tree_list (NULL_TREE
,
3359 xref_tag (RECORD_TYPE
,
3360 get_identifier (UTAG_METHOD_LIST
)));
3362 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3364 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3365 chainon (field_decl_chain
, field_decl
);
3367 /* struct objc_method_list *class_methods; */
3369 decl_specs
= build_tree_list (NULL_TREE
,
3370 xref_tag (RECORD_TYPE
,
3371 get_identifier (UTAG_METHOD_LIST
)));
3373 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3375 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3376 chainon (field_decl_chain
, field_decl
);
3378 /* struct objc_protocol **protocol_list; */
3380 decl_specs
= build_tree_list (NULL_TREE
,
3381 xref_tag (RECORD_TYPE
,
3382 get_identifier (UTAG_PROTOCOL
)));
3384 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3385 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3387 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3388 chainon (field_decl_chain
, field_decl
);
3390 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3393 /* struct objc_selector {
3399 build_selector_template ()
3402 tree decl_specs
, field_decl
, field_decl_chain
;
3404 objc_selector_template
3405 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3409 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3410 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3412 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3413 field_decl_chain
= field_decl
;
3415 /* char *sel_type; */
3417 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3418 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3420 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3421 chainon (field_decl_chain
, field_decl
);
3423 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3426 /* struct objc_class {
3427 struct objc_class *isa;
3428 struct objc_class *super_class;
3433 struct objc_ivar_list *ivars;
3434 struct objc_method_list *methods;
3435 if (flag_next_runtime)
3436 struct objc_cache *cache;
3438 struct sarray *dtable;
3439 struct objc_class *subclass_list;
3440 struct objc_class *sibling_class;
3442 struct objc_protocol_list *protocols;
3443 void *gc_object_type;
3447 build_class_template ()
3449 tree decl_specs
, field_decl
, field_decl_chain
;
3452 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3454 /* struct objc_class *isa; */
3456 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3457 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3459 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3460 field_decl_chain
= field_decl
;
3462 /* struct objc_class *super_class; */
3464 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3466 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3468 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3469 chainon (field_decl_chain
, field_decl
);
3473 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3474 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3476 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3477 chainon (field_decl_chain
, field_decl
);
3481 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3482 field_decl
= get_identifier ("version");
3484 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3485 chainon (field_decl_chain
, field_decl
);
3489 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3490 field_decl
= get_identifier ("info");
3492 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3493 chainon (field_decl_chain
, field_decl
);
3495 /* long instance_size; */
3497 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3498 field_decl
= get_identifier ("instance_size");
3500 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3501 chainon (field_decl_chain
, field_decl
);
3503 /* struct objc_ivar_list *ivars; */
3505 decl_specs
= build_tree_list (NULL_TREE
,
3506 xref_tag (RECORD_TYPE
,
3507 get_identifier (UTAG_IVAR_LIST
)));
3508 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3510 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3511 chainon (field_decl_chain
, field_decl
);
3513 /* struct objc_method_list *methods; */
3515 decl_specs
= build_tree_list (NULL_TREE
,
3516 xref_tag (RECORD_TYPE
,
3517 get_identifier (UTAG_METHOD_LIST
)));
3518 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3520 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3521 chainon (field_decl_chain
, field_decl
);
3523 if (flag_next_runtime
)
3525 /* struct objc_cache *cache; */
3527 decl_specs
= build_tree_list (NULL_TREE
,
3528 xref_tag (RECORD_TYPE
,
3529 get_identifier ("objc_cache")));
3530 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3531 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3532 decl_specs
, NULL_TREE
);
3533 chainon (field_decl_chain
, field_decl
);
3537 /* struct sarray *dtable; */
3539 decl_specs
= build_tree_list (NULL_TREE
,
3540 xref_tag (RECORD_TYPE
,
3541 get_identifier ("sarray")));
3542 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3543 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3544 decl_specs
, NULL_TREE
);
3545 chainon (field_decl_chain
, field_decl
);
3547 /* struct objc_class *subclass_list; */
3549 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3551 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3552 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3553 decl_specs
, NULL_TREE
);
3554 chainon (field_decl_chain
, field_decl
);
3556 /* struct objc_class *sibling_class; */
3558 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3560 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3561 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3562 decl_specs
, NULL_TREE
);
3563 chainon (field_decl_chain
, field_decl
);
3566 /* struct objc_protocol **protocol_list; */
3568 decl_specs
= build_tree_list (NULL_TREE
,
3569 xref_tag (RECORD_TYPE
,
3570 get_identifier (UTAG_PROTOCOL
)));
3572 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3574 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3575 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3576 decl_specs
, NULL_TREE
);
3577 chainon (field_decl_chain
, field_decl
);
3581 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3582 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3584 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3585 chainon (field_decl_chain
, field_decl
);
3587 /* void *gc_object_type; */
3589 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3590 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3592 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3593 chainon (field_decl_chain
, field_decl
);
3595 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3598 /* Generate appropriate forward declarations for an implementation. */
3601 synth_forward_declarations ()
3603 tree sc_spec
, decl_specs
, an_id
;
3605 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3607 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3609 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3610 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3611 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3612 TREE_USED (UOBJC_CLASS_decl
) = 1;
3613 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3615 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3617 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3618 implementation_context
);
3620 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3621 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3622 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3624 /* Pre-build the following entities - for speed/convenience. */
3626 an_id
= get_identifier ("super_class");
3627 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3628 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3632 error_with_ivar (message
, decl
, rawdecl
)
3633 const char *message
;
3639 report_error_function (DECL_SOURCE_FILE (decl
));
3641 fprintf (stderr
, "%s:%d: ",
3642 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3643 bzero (errbuf
, BUFSIZE
);
3644 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3647 #define USERTYPE(t) \
3648 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3649 || TREE_CODE (t) == ENUMERAL_TYPE)
3652 check_ivars (inter
, imp
)
3656 tree intdecls
= CLASS_IVARS (inter
);
3657 tree impdecls
= CLASS_IVARS (imp
);
3658 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3659 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3665 if (intdecls
== 0 && impdecls
== 0)
3667 if (intdecls
== 0 || impdecls
== 0)
3669 error ("inconsistent instance variable specification");
3673 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3675 if (!comptypes (t1
, t2
))
3677 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3679 error_with_ivar ("conflicting instance variable type",
3680 impdecls
, rawimpdecls
);
3681 error_with_ivar ("previous declaration of",
3682 intdecls
, rawintdecls
);
3684 else /* both the type and the name don't match */
3686 error ("inconsistent instance variable specification");
3691 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3693 error_with_ivar ("conflicting instance variable name",
3694 impdecls
, rawimpdecls
);
3695 error_with_ivar ("previous declaration of",
3696 intdecls
, rawintdecls
);
3699 intdecls
= TREE_CHAIN (intdecls
);
3700 impdecls
= TREE_CHAIN (impdecls
);
3701 rawintdecls
= TREE_CHAIN (rawintdecls
);
3702 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3706 /* Set super_type to the data type node for struct objc_super *,
3707 first defining struct objc_super itself.
3708 This needs to be done just once per compilation. */
3711 build_super_template ()
3713 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3715 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3717 /* struct objc_object *self; */
3719 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3720 field_decl
= get_identifier ("self");
3721 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3722 field_decl
= grokfield (input_filename
, lineno
,
3723 field_decl
, decl_specs
, NULL_TREE
);
3724 field_decl_chain
= field_decl
;
3726 /* struct objc_class *class; */
3728 decl_specs
= get_identifier (UTAG_CLASS
);
3729 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3730 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3732 field_decl
= grokfield (input_filename
, lineno
,
3733 field_decl
, decl_specs
, NULL_TREE
);
3734 chainon (field_decl_chain
, field_decl
);
3736 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3738 /* `struct objc_super *' */
3739 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3741 build1 (INDIRECT_REF
,
3742 NULL_TREE
, NULL_TREE
)));
3746 /* struct objc_ivar {
3753 build_ivar_template ()
3755 tree objc_ivar_id
, objc_ivar_record
;
3756 tree decl_specs
, field_decl
, field_decl_chain
;
3758 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3759 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3761 /* char *ivar_name; */
3763 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3764 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3766 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3767 decl_specs
, NULL_TREE
);
3768 field_decl_chain
= field_decl
;
3770 /* char *ivar_type; */
3772 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3773 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3775 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3776 decl_specs
, NULL_TREE
);
3777 chainon (field_decl_chain
, field_decl
);
3779 /* int ivar_offset; */
3781 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3782 field_decl
= get_identifier ("ivar_offset");
3784 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3785 decl_specs
, NULL_TREE
);
3786 chainon (field_decl_chain
, field_decl
);
3788 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3790 return objc_ivar_record
;
3795 struct objc_ivar ivar_list[ivar_count];
3799 build_ivar_list_template (list_type
, size
)
3803 tree objc_ivar_list_record
;
3804 tree decl_specs
, field_decl
, field_decl_chain
;
3806 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3808 /* int ivar_count; */
3810 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3811 field_decl
= get_identifier ("ivar_count");
3813 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3814 decl_specs
, NULL_TREE
);
3815 field_decl_chain
= field_decl
;
3817 /* struct objc_ivar ivar_list[]; */
3819 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3820 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3821 build_int_2 (size
, 0));
3823 field_decl
= grokfield (input_filename
, lineno
,
3824 field_decl
, decl_specs
, NULL_TREE
);
3825 chainon (field_decl_chain
, field_decl
);
3827 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3829 return objc_ivar_list_record
;
3835 struct objc_method method_list[method_count];
3839 build_method_list_template (list_type
, size
)
3843 tree objc_ivar_list_record
;
3844 tree decl_specs
, field_decl
, field_decl_chain
;
3846 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3848 /* int method_next; */
3853 xref_tag (RECORD_TYPE
,
3854 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3856 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3857 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3858 decl_specs
, NULL_TREE
);
3859 field_decl_chain
= field_decl
;
3861 /* int method_count; */
3863 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3864 field_decl
= get_identifier ("method_count");
3866 field_decl
= grokfield (input_filename
, lineno
,
3867 field_decl
, decl_specs
, NULL_TREE
);
3868 chainon (field_decl_chain
, field_decl
);
3870 /* struct objc_method method_list[]; */
3872 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3873 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3874 build_int_2 (size
, 0));
3876 field_decl
= grokfield (input_filename
, lineno
,
3877 field_decl
, decl_specs
, NULL_TREE
);
3878 chainon (field_decl_chain
, field_decl
);
3880 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3882 return objc_ivar_list_record
;
3886 build_ivar_list_initializer (type
, field_decl
)
3890 tree initlist
= NULL_TREE
;
3894 tree ivar
= NULL_TREE
;
3897 if (DECL_NAME (field_decl
))
3898 ivar
= tree_cons (NULL_TREE
,
3899 add_objc_string (DECL_NAME (field_decl
),
3903 /* Unnamed bit-field ivar (yuck). */
3904 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3907 encode_field_decl (field_decl
,
3908 obstack_object_size (&util_obstack
),
3909 OBJC_ENCODE_DONT_INLINE_DEFS
);
3911 /* Null terminate string. */
3912 obstack_1grow (&util_obstack
, 0);
3916 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3919 obstack_free (&util_obstack
, util_firstobj
);
3922 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3923 initlist
= tree_cons (NULL_TREE
,
3924 build_constructor (type
, nreverse (ivar
)),
3927 field_decl
= TREE_CHAIN (field_decl
);
3931 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3935 generate_ivars_list (type
, name
, size
, list
)
3941 tree sc_spec
, decl_specs
, decl
, initlist
;
3943 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3944 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3946 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3947 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3949 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3950 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3953 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3960 generate_ivar_lists ()
3962 tree initlist
, ivar_list_template
, chain
;
3963 tree cast
, variable_length_type
;
3966 generating_instance_variables
= 1;
3968 if (!objc_ivar_template
)
3969 objc_ivar_template
= build_ivar_template ();
3973 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3974 get_identifier (UTAG_IVAR_LIST
))),
3976 variable_length_type
= groktypename (cast
);
3978 /* Only generate class variables for the root of the inheritance
3979 hierarchy since these will be the same for every class. */
3981 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3982 && (chain
= TYPE_FIELDS (objc_class_template
)))
3984 size
= list_length (chain
);
3986 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3987 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3989 UOBJC_CLASS_VARIABLES_decl
3990 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3992 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3995 UOBJC_CLASS_VARIABLES_decl
= 0;
3997 chain
= CLASS_IVARS (implementation_template
);
4000 size
= list_length (chain
);
4001 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4002 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4004 UOBJC_INSTANCE_VARIABLES_decl
4005 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
4007 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
4010 UOBJC_INSTANCE_VARIABLES_decl
= 0;
4012 generating_instance_variables
= 0;
4016 build_dispatch_table_initializer (type
, entries
)
4020 tree initlist
= NULL_TREE
;
4024 tree elemlist
= NULL_TREE
;
4026 elemlist
= tree_cons (NULL_TREE
,
4027 build_selector (METHOD_SEL_NAME (entries
)),
4030 elemlist
= tree_cons (NULL_TREE
,
4031 add_objc_string (METHOD_ENCODING (entries
),
4035 elemlist
= tree_cons (NULL_TREE
,
4036 build_unary_op (ADDR_EXPR
,
4037 METHOD_DEFINITION (entries
), 1),
4040 initlist
= tree_cons (NULL_TREE
,
4041 build_constructor (type
, nreverse (elemlist
)),
4044 entries
= TREE_CHAIN (entries
);
4048 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4051 /* To accomplish method prototyping without generating all kinds of
4052 inane warnings, the definition of the dispatch table entries were
4055 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4057 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4060 build_method_template ()
4063 tree decl_specs
, field_decl
, field_decl_chain
;
4065 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4067 #ifdef OBJC_INT_SELECTORS
4068 /* unsigned int _cmd; */
4069 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
4071 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
4072 field_decl
= get_identifier ("_cmd");
4073 #else /* not OBJC_INT_SELECTORS */
4074 /* struct objc_selector *_cmd; */
4075 decl_specs
= tree_cons (NULL_TREE
,
4076 xref_tag (RECORD_TYPE
,
4077 get_identifier (TAG_SELECTOR
)),
4079 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4080 #endif /* not OBJC_INT_SELECTORS */
4082 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4083 decl_specs
, NULL_TREE
);
4084 field_decl_chain
= field_decl
;
4086 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4087 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4088 get_identifier ("method_types"));
4089 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4090 decl_specs
, NULL_TREE
);
4091 chainon (field_decl_chain
, field_decl
);
4095 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4096 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4097 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4098 decl_specs
, NULL_TREE
);
4099 chainon (field_decl_chain
, field_decl
);
4101 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4108 generate_dispatch_table (type
, name
, size
, list
)
4114 tree sc_spec
, decl_specs
, decl
, initlist
;
4116 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4117 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4119 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4120 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4122 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4123 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4124 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4127 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4134 generate_dispatch_tables ()
4136 tree initlist
, chain
, method_list_template
;
4137 tree cast
, variable_length_type
;
4140 if (!objc_method_template
)
4141 objc_method_template
= build_method_template ();
4145 (build_tree_list (NULL_TREE
,
4146 xref_tag (RECORD_TYPE
,
4147 get_identifier (UTAG_METHOD_LIST
))),
4150 variable_length_type
= groktypename (cast
);
4152 chain
= CLASS_CLS_METHODS (implementation_context
);
4155 size
= list_length (chain
);
4157 method_list_template
4158 = build_method_list_template (objc_method_template
, size
);
4160 = build_dispatch_table_initializer (objc_method_template
, chain
);
4162 UOBJC_CLASS_METHODS_decl
4163 = generate_dispatch_table (method_list_template
,
4164 ((TREE_CODE (implementation_context
)
4165 == CLASS_IMPLEMENTATION_TYPE
)
4166 ? "_OBJC_CLASS_METHODS"
4167 : "_OBJC_CATEGORY_CLASS_METHODS"),
4169 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4172 UOBJC_CLASS_METHODS_decl
= 0;
4174 chain
= CLASS_NST_METHODS (implementation_context
);
4177 size
= list_length (chain
);
4179 method_list_template
4180 = build_method_list_template (objc_method_template
, size
);
4182 = build_dispatch_table_initializer (objc_method_template
, chain
);
4184 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4185 UOBJC_INSTANCE_METHODS_decl
4186 = generate_dispatch_table (method_list_template
,
4187 "_OBJC_INSTANCE_METHODS",
4190 /* We have a category. */
4191 UOBJC_INSTANCE_METHODS_decl
4192 = generate_dispatch_table (method_list_template
,
4193 "_OBJC_CATEGORY_INSTANCE_METHODS",
4195 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4198 UOBJC_INSTANCE_METHODS_decl
= 0;
4202 generate_protocol_list (i_or_p
)
4205 tree initlist
, decl_specs
, sc_spec
;
4206 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4210 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4211 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4212 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4213 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4214 plist
= PROTOCOL_LIST (i_or_p
);
4218 cast_type
= groktypename
4220 (build_tree_list (NULL_TREE
,
4221 xref_tag (RECORD_TYPE
,
4222 get_identifier (UTAG_PROTOCOL
))),
4223 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4226 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4227 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4228 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4231 /* Build initializer. */
4232 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4234 e
= build_int_2 (size
, 0);
4235 TREE_TYPE (e
) = cast_type
;
4236 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4238 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4240 tree pval
= TREE_VALUE (lproto
);
4242 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4243 && PROTOCOL_FORWARD_DECL (pval
))
4245 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4246 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4250 /* static struct objc_protocol *refs[n]; */
4252 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4253 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4254 get_identifier (UTAG_PROTOCOL
)),
4257 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4258 expr_decl
= build_nt (ARRAY_REF
,
4259 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4261 build_int_2 (size
+ 2, 0));
4262 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4263 expr_decl
= build_nt (ARRAY_REF
,
4264 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4266 build_int_2 (size
+ 2, 0));
4267 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4269 = build_nt (ARRAY_REF
,
4270 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4272 build_int_2 (size
+ 2, 0));
4276 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4278 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4280 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4281 nreverse (initlist
)),
4288 build_category_initializer (type
, cat_name
, class_name
,
4289 instance_methods
, class_methods
, protocol_list
)
4293 tree instance_methods
;
4297 tree initlist
= NULL_TREE
, expr
;
4299 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4300 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4302 if (!instance_methods
)
4303 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4306 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4307 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4310 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4313 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4314 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4317 /* protocol_list = */
4319 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4322 tree cast_type2
= groktypename
4324 (build_tree_list (NULL_TREE
,
4325 xref_tag (RECORD_TYPE
,
4326 get_identifier (UTAG_PROTOCOL
))),
4327 build1 (INDIRECT_REF
, NULL_TREE
,
4328 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4330 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4331 TREE_TYPE (expr
) = cast_type2
;
4332 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4335 return build_constructor (type
, nreverse (initlist
));
4338 /* struct objc_class {
4339 struct objc_class *isa;
4340 struct objc_class *super_class;
4345 struct objc_ivar_list *ivars;
4346 struct objc_method_list *methods;
4347 if (flag_next_runtime)
4348 struct objc_cache *cache;
4350 struct sarray *dtable;
4351 struct objc_class *subclass_list;
4352 struct objc_class *sibling_class;
4354 struct objc_protocol_list *protocols;
4355 void *gc_object_type;
4359 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4360 dispatch_table
, ivar_list
, protocol_list
)
4367 tree dispatch_table
;
4371 tree initlist
= NULL_TREE
, expr
;
4374 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4377 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4380 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4383 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4386 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4388 /* instance_size = */
4389 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4391 /* objc_ivar_list = */
4393 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4396 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4397 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4400 /* objc_method_list = */
4401 if (!dispatch_table
)
4402 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4405 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4406 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4409 if (flag_next_runtime
)
4410 /* method_cache = */
4411 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4415 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4417 /* subclass_list = */
4418 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4420 /* sibling_class = */
4421 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4424 /* protocol_list = */
4425 if (! protocol_list
)
4426 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4432 (build_tree_list (NULL_TREE
,
4433 xref_tag (RECORD_TYPE
,
4434 get_identifier (UTAG_PROTOCOL
))),
4435 build1 (INDIRECT_REF
, NULL_TREE
,
4436 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4438 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4439 TREE_TYPE (expr
) = cast_type2
;
4440 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4443 /* gc_object_type = NULL */
4444 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4446 return build_constructor (type
, nreverse (initlist
));
4449 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4452 generate_category (cat
)
4455 tree sc_spec
, decl_specs
, decl
;
4456 tree initlist
, cat_name_expr
, class_name_expr
;
4457 tree protocol_decl
, category
;
4459 add_class_reference (CLASS_NAME (cat
));
4460 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4462 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4464 category
= CLASS_CATEGORY_LIST (implementation_template
);
4466 /* find the category interface from the class it is associated with */
4469 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4471 category
= CLASS_CATEGORY_LIST (category
);
4474 if (category
&& CLASS_PROTOCOL_LIST (category
))
4476 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4477 protocol_decl
= generate_protocol_list (category
);
4482 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4483 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4485 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4486 implementation_context
),
4487 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4489 initlist
= build_category_initializer (TREE_TYPE (decl
),
4490 cat_name_expr
, class_name_expr
,
4491 UOBJC_INSTANCE_METHODS_decl
,
4492 UOBJC_CLASS_METHODS_decl
,
4495 TREE_USED (decl
) = 1;
4496 finish_decl (decl
, initlist
, NULL_TREE
);
4499 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4500 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4503 generate_shared_structures ()
4505 tree sc_spec
, decl_specs
, decl
;
4506 tree name_expr
, super_expr
, root_expr
;
4507 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4508 tree cast_type
, initlist
, protocol_decl
;
4510 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4513 add_class_reference (my_super_id
);
4515 /* Compute "my_root_id" - this is required for code generation.
4516 the "isa" for all meta class structures points to the root of
4517 the inheritance hierarchy (e.g. "__Object")... */
4518 my_root_id
= my_super_id
;
4521 tree my_root_int
= lookup_interface (my_root_id
);
4523 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4524 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4531 /* No super class. */
4532 my_root_id
= CLASS_NAME (implementation_template
);
4535 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4536 objc_class_template
),
4537 build1 (INDIRECT_REF
,
4538 NULL_TREE
, NULL_TREE
)));
4540 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4543 /* Install class `isa' and `super' pointers at runtime. */
4546 super_expr
= add_objc_string (my_super_id
, class_names
);
4547 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4550 super_expr
= build_int_2 (0, 0);
4552 root_expr
= add_objc_string (my_root_id
, class_names
);
4553 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4555 if (CLASS_PROTOCOL_LIST (implementation_template
))
4557 generate_protocol_references
4558 (CLASS_PROTOCOL_LIST (implementation_template
));
4559 protocol_decl
= generate_protocol_list (implementation_template
);
4564 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4566 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4567 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4569 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4570 NULL_TREE
, NULL_TREE
);
4573 = build_shared_structure_initializer
4575 root_expr
, super_expr
, name_expr
,
4576 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4578 UOBJC_CLASS_METHODS_decl
,
4579 UOBJC_CLASS_VARIABLES_decl
,
4582 finish_decl (decl
, initlist
, NULL_TREE
);
4584 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4586 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4587 NULL_TREE
, NULL_TREE
);
4590 = build_shared_structure_initializer
4592 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4593 super_expr
, name_expr
,
4594 convert (integer_type_node
,
4595 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4596 (implementation_template
))),
4598 UOBJC_INSTANCE_METHODS_decl
,
4599 UOBJC_INSTANCE_VARIABLES_decl
,
4602 finish_decl (decl
, initlist
, NULL_TREE
);
4606 synth_id_with_class_suffix (preamble
, ctxt
)
4607 const char *preamble
;
4611 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4612 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4614 const char *class_name
4615 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4616 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4617 sprintf (string
, "%s_%s", preamble
,
4618 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4620 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4621 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4623 /* We have a category. */
4624 const char *class_name
4625 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4626 const char *class_super_name
4627 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4628 string
= (char *) alloca (strlen (preamble
)
4629 + strlen (class_name
)
4630 + strlen (class_super_name
)
4632 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4634 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4636 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4638 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4639 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4644 return get_identifier (string
);
4648 is_objc_type_qualifier (node
)
4651 return (TREE_CODE (node
) == IDENTIFIER_NODE
4652 && (node
== ridpointers
[(int) RID_CONST
]
4653 || node
== ridpointers
[(int) RID_VOLATILE
]
4654 || node
== ridpointers
[(int) RID_IN
]
4655 || node
== ridpointers
[(int) RID_OUT
]
4656 || node
== ridpointers
[(int) RID_INOUT
]
4657 || node
== ridpointers
[(int) RID_BYCOPY
]
4658 || node
== ridpointers
[(int) RID_BYREF
]
4659 || node
== ridpointers
[(int) RID_ONEWAY
]));
4662 /* If type is empty or only type qualifiers are present, add default
4663 type of id (otherwise grokdeclarator will default to int). */
4666 adjust_type_for_id_default (type
)
4669 tree declspecs
, chain
;
4672 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4673 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4675 declspecs
= TREE_PURPOSE (type
);
4677 /* Determine if a typespec is present. */
4678 for (chain
= declspecs
;
4680 chain
= TREE_CHAIN (chain
))
4682 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4686 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4688 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4693 selector ':' '(' typename ')' identifier
4696 Transform an Objective-C keyword argument into
4697 the C equivalent parameter declarator.
4699 In: key_name, an "identifier_node" (optional).
4700 arg_type, a "tree_list" (optional).
4701 arg_name, an "identifier_node".
4703 Note: It would be really nice to strongly type the preceding
4704 arguments in the function prototype; however, then I
4705 could not use the "accessor" macros defined in "tree.h".
4707 Out: an instance of "keyword_decl". */
4710 build_keyword_decl (key_name
, arg_type
, arg_name
)
4717 /* If no type is specified, default to "id". */
4718 arg_type
= adjust_type_for_id_default (arg_type
);
4720 keyword_decl
= make_node (KEYWORD_DECL
);
4722 TREE_TYPE (keyword_decl
) = arg_type
;
4723 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4724 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4726 return keyword_decl
;
4729 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4732 build_keyword_selector (selector
)
4736 tree key_chain
, key_name
;
4739 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4741 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4742 key_name
= KEYWORD_KEY_NAME (key_chain
);
4743 else if (TREE_CODE (selector
) == TREE_LIST
)
4744 key_name
= TREE_PURPOSE (key_chain
);
4749 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4751 /* Just a ':' arg. */
4755 buf
= (char *)alloca (len
+ 1);
4756 bzero (buf
, len
+ 1);
4758 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4760 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4761 key_name
= KEYWORD_KEY_NAME (key_chain
);
4762 else if (TREE_CODE (selector
) == TREE_LIST
)
4763 key_name
= TREE_PURPOSE (key_chain
);
4768 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4772 return get_identifier (buf
);
4775 /* Used for declarations and definitions. */
4778 build_method_decl (code
, ret_type
, selector
, add_args
)
4779 enum tree_code code
;
4786 /* If no type is specified, default to "id". */
4787 ret_type
= adjust_type_for_id_default (ret_type
);
4789 method_decl
= make_node (code
);
4790 TREE_TYPE (method_decl
) = ret_type
;
4792 /* If we have a keyword selector, create an identifier_node that
4793 represents the full selector name (`:' included)... */
4794 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4796 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4797 METHOD_SEL_ARGS (method_decl
) = selector
;
4798 METHOD_ADD_ARGS (method_decl
) = add_args
;
4802 METHOD_SEL_NAME (method_decl
) = selector
;
4803 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4804 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4810 #define METHOD_DEF 0
4811 #define METHOD_REF 1
4813 /* Used by `build_message_expr' and `comp_method_types'. Return an
4814 argument list for method METH. CONTEXT is either METHOD_DEF or
4815 METHOD_REF, saying whether we are trying to define a method or call
4816 one. SUPERFLAG says this is for a send to super; this makes a
4817 difference for the NeXT calling sequence in which the lookup and
4818 the method call are done together. */
4821 get_arg_type_list (meth
, context
, superflag
)
4828 /* Receiver type. */
4829 if (flag_next_runtime
&& superflag
)
4830 arglist
= build_tree_list (NULL_TREE
, super_type
);
4831 else if (context
== METHOD_DEF
)
4832 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4834 arglist
= build_tree_list (NULL_TREE
, id_type
);
4836 /* Selector type - will eventually change to `int'. */
4837 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4839 /* Build a list of argument types. */
4840 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4842 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4843 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4846 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4847 /* We have a `, ...' immediately following the selector,
4848 finalize the arglist...simulate get_parm_info (0). */
4850 else if (METHOD_ADD_ARGS (meth
))
4852 /* we have a variable length selector */
4853 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4854 chainon (arglist
, add_arg_list
);
4857 /* finalize the arglist...simulate get_parm_info (1) */
4858 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4864 check_duplicates (hsh
)
4867 tree meth
= NULL_TREE
;
4875 /* We have two methods with the same name and different types. */
4877 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4879 warning ("multiple declarations for method `%s'",
4880 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4882 warn_with_method ("using", type
, meth
);
4883 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4884 warn_with_method ("also found", type
, loop
->value
);
4890 /* If RECEIVER is a class reference, return the identifier node for the
4891 referenced class. RECEIVER is created by get_class_reference, so we
4892 check the exact form created depending on which runtimes are used. */
4895 receiver_is_class_object (receiver
)
4898 tree chain
, exp
, arg
;
4899 if (flag_next_runtime
)
4901 /* The receiver is a variable created by build_class_reference_decl. */
4902 if (TREE_CODE (receiver
) == VAR_DECL
4903 && TREE_TYPE (receiver
) == objc_class_type
)
4904 /* Look up the identifier. */
4905 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4906 if (TREE_PURPOSE (chain
) == receiver
)
4907 return TREE_VALUE (chain
);
4911 /* The receiver is a function call that returns an id. Check if
4912 it is a call to objc_getClass, if so, pick up the class name. */
4913 if ((exp
= TREE_OPERAND (receiver
, 0))
4914 && TREE_CODE (exp
) == ADDR_EXPR
4915 && (exp
= TREE_OPERAND (exp
, 0))
4916 && TREE_CODE (exp
) == FUNCTION_DECL
4917 && exp
== objc_get_class_decl
4918 /* we have a call to objc_getClass! */
4919 && (arg
= TREE_OPERAND (receiver
, 1))
4920 && TREE_CODE (arg
) == TREE_LIST
4921 && (arg
= TREE_VALUE (arg
)))
4924 if (TREE_CODE (arg
) == ADDR_EXPR
4925 && (arg
= TREE_OPERAND (arg
, 0))
4926 && TREE_CODE (arg
) == STRING_CST
)
4927 /* Finally, we have the class name. */
4928 return get_identifier (TREE_STRING_POINTER (arg
));
4934 /* If we are currently building a message expr, this holds
4935 the identifier of the selector of the message. This is
4936 used when printing warnings about argument mismatches. */
4938 static tree building_objc_message_expr
= 0;
4941 maybe_building_objc_message_expr ()
4943 return building_objc_message_expr
;
4946 /* Construct an expression for sending a message.
4947 MESS has the object to send to in TREE_PURPOSE
4948 and the argument list (including selector) in TREE_VALUE.
4950 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4951 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4954 build_message_expr (mess
)
4957 tree receiver
= TREE_PURPOSE (mess
);
4958 tree selector
, self_object
;
4959 tree rtype
, sel_name
;
4960 tree args
= TREE_VALUE (mess
);
4961 tree method_params
= NULL_TREE
;
4962 tree method_prototype
= NULL_TREE
;
4964 int statically_typed
= 0, statically_allocated
= 0;
4965 tree class_ident
= 0;
4967 /* 1 if this is sending to the superclass. */
4970 if (!doing_objc_thang
)
4973 if (TREE_CODE (receiver
) == ERROR_MARK
)
4974 return error_mark_node
;
4976 /* Determine receiver type. */
4977 rtype
= TREE_TYPE (receiver
);
4978 super
= IS_SUPER (rtype
);
4982 if (TREE_STATIC_TEMPLATE (rtype
))
4983 statically_allocated
= 1;
4984 else if (TREE_CODE (rtype
) == POINTER_TYPE
4985 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4986 statically_typed
= 1;
4987 else if ((flag_next_runtime
4988 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4989 && (class_ident
= receiver_is_class_object (receiver
)))
4991 else if (! IS_ID (rtype
)
4992 /* Allow any type that matches objc_class_type. */
4993 && ! comptypes (rtype
, objc_class_type
))
4995 bzero (errbuf
, BUFSIZE
);
4996 warning ("invalid receiver type `%s'",
4997 gen_declaration (rtype
, errbuf
));
5000 if (statically_allocated
)
5001 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
5003 /* Don't evaluate the receiver twice. */
5004 receiver
= save_expr (receiver
);
5005 self_object
= receiver
;
5008 /* If sending to `super', use current self as the object. */
5009 self_object
= self_decl
;
5011 /* Obtain the full selector name. */
5013 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
5014 /* A unary selector. */
5016 else if (TREE_CODE (args
) == TREE_LIST
)
5017 sel_name
= build_keyword_selector (args
);
5021 /* Build the parameter list to give to the method. */
5023 method_params
= NULL_TREE
;
5024 if (TREE_CODE (args
) == TREE_LIST
)
5026 tree chain
= args
, prev
= NULL_TREE
;
5028 /* We have a keyword selector--check for comma expressions. */
5031 tree element
= TREE_VALUE (chain
);
5033 /* We have a comma expression, must collapse... */
5034 if (TREE_CODE (element
) == TREE_LIST
)
5037 TREE_CHAIN (prev
) = element
;
5042 chain
= TREE_CHAIN (chain
);
5044 method_params
= args
;
5047 /* Determine operation return type. */
5049 if (IS_SUPER (rtype
))
5053 if (CLASS_SUPER_NAME (implementation_template
))
5056 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5058 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5059 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5061 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5063 if (iface
&& !method_prototype
)
5064 warning ("`%s' does not respond to `%s'",
5065 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5066 IDENTIFIER_POINTER (sel_name
));
5070 error ("no super class declared in interface for `%s'",
5071 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5072 return error_mark_node
;
5076 else if (statically_allocated
)
5078 tree ctype
= TREE_TYPE (rtype
);
5079 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5082 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5084 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5086 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5089 if (!method_prototype
)
5090 warning ("`%s' does not respond to `%s'",
5091 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5092 IDENTIFIER_POINTER (sel_name
));
5094 else if (statically_typed
)
5096 tree ctype
= TREE_TYPE (rtype
);
5098 /* `self' is now statically_typed. All methods should be visible
5099 within the context of the implementation. */
5100 if (implementation_context
5101 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5104 = lookup_instance_method_static (implementation_template
,
5107 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5109 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5112 if (! method_prototype
5113 && implementation_template
!= implementation_context
)
5114 /* The method is not published in the interface. Check
5117 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5124 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5125 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5127 if (! method_prototype
)
5129 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5132 = lookup_method_in_protocol_list (protocol_list
,
5137 if (!method_prototype
)
5138 warning ("`%s' does not respond to `%s'",
5139 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5140 IDENTIFIER_POINTER (sel_name
));
5142 else if (class_ident
)
5144 if (implementation_context
5145 && CLASS_NAME (implementation_context
) == class_ident
)
5148 = lookup_class_method_static (implementation_template
, sel_name
);
5150 if (!method_prototype
5151 && implementation_template
!= implementation_context
)
5152 /* The method is not published in the interface. Check
5155 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5162 if ((iface
= lookup_interface (class_ident
)))
5163 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5166 if (!method_prototype
)
5168 warning ("cannot find class (factory) method.");
5169 warning ("return type for `%s' defaults to id",
5170 IDENTIFIER_POINTER (sel_name
));
5173 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5175 /* An anonymous object that has been qualified with a protocol. */
5177 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5179 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5182 if (!method_prototype
)
5186 warning ("method `%s' not implemented by protocol.",
5187 IDENTIFIER_POINTER (sel_name
));
5189 /* Try and find the method signature in the global pools. */
5191 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5192 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5194 if (!(method_prototype
= check_duplicates (hsh
)))
5195 warning ("return type defaults to id");
5202 /* We think we have an instance...loophole: extern id Object; */
5203 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5205 /* For various loopholes, like sending messages to self in a
5207 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5209 method_prototype
= check_duplicates (hsh
);
5210 if (!method_prototype
)
5212 warning ("cannot find method.");
5213 warning ("return type for `%s' defaults to id",
5214 IDENTIFIER_POINTER (sel_name
));
5218 /* Save the selector name for printing error messages. */
5219 building_objc_message_expr
= sel_name
;
5221 /* Build the parameters list for looking up the method.
5222 These are the object itself and the selector. */
5224 if (flag_typed_selectors
)
5225 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5227 selector
= build_selector_reference (sel_name
);
5229 retval
= build_objc_method_call (super
, method_prototype
,
5230 receiver
, self_object
,
5231 selector
, method_params
);
5233 building_objc_message_expr
= 0;
5238 /* Build a tree expression to send OBJECT the operation SELECTOR,
5239 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5240 assuming the method has prototype METHOD_PROTOTYPE.
5241 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5242 Use METHOD_PARAMS as list of args to pass to the method.
5243 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5246 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5247 selector
, method_params
)
5249 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5251 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5252 tree rcv_p
= (super_flag
5253 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5254 get_identifier (TAG_SUPER
)))
5257 if (flag_next_runtime
)
5259 if (! method_prototype
)
5261 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5262 tree_cons (NULL_TREE
, selector
,
5264 assemble_external (sender
);
5265 return build_function_call (sender
, method_params
);
5269 /* This is a real kludge, but it is used only for the Next.
5270 Clobber the data type of SENDER temporarily to accept
5271 all the arguments for this operation, and to return
5272 whatever this operation returns. */
5273 tree arglist
= NULL_TREE
;
5276 /* Save the proper contents of SENDER's data type. */
5277 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5278 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5280 /* Install this method's argument types. */
5281 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5283 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5285 /* Install this method's return type. */
5286 TREE_TYPE (TREE_TYPE (sender
))
5287 = groktypename (TREE_TYPE (method_prototype
));
5289 /* Call SENDER with all the parameters. This will do type
5290 checking using the arg types for this method. */
5291 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5292 tree_cons (NULL_TREE
, selector
,
5294 assemble_external (sender
);
5295 retval
= build_function_call (sender
, method_params
);
5297 /* Restore SENDER's return/argument types. */
5298 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5299 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5305 /* This is the portable way.
5306 First call the lookup function to get a pointer to the method,
5307 then cast the pointer, then call it with the method arguments. */
5310 /* Avoid trouble since we may evaluate each of these twice. */
5311 object
= save_expr (object
);
5312 selector
= save_expr (selector
);
5314 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5316 assemble_external (sender
);
5318 = build_function_call (sender
,
5319 tree_cons (NULL_TREE
, lookup_object
,
5320 tree_cons (NULL_TREE
, selector
,
5323 /* If we have a method prototype, construct the data type this
5324 method needs, and cast what we got from SENDER into a pointer
5326 if (method_prototype
)
5328 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5330 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5331 tree fake_function_type
= build_function_type (valtype
, arglist
);
5332 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5336 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5338 /* Pass the object to the method. */
5339 assemble_external (method
);
5340 return build_function_call (method
,
5341 tree_cons (NULL_TREE
, object
,
5342 tree_cons (NULL_TREE
, selector
,
5348 build_protocol_reference (p
)
5351 tree decl
, ident
, ptype
;
5353 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5355 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5357 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5358 objc_protocol_template
),
5361 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5362 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5365 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5366 DECL_EXTERNAL (decl
) = 1;
5367 TREE_PUBLIC (decl
) = 1;
5368 TREE_USED (decl
) = 1;
5369 DECL_ARTIFICIAL (decl
) = 1;
5371 make_decl_rtl (decl
, 0, 1);
5372 pushdecl_top_level (decl
);
5375 PROTOCOL_FORWARD_DECL (p
) = decl
;
5379 build_protocol_expr (protoname
)
5385 if (!doing_objc_thang
)
5388 p
= lookup_protocol (protoname
);
5392 error ("Cannot find protocol declaration for `%s'",
5393 IDENTIFIER_POINTER (protoname
));
5394 return error_mark_node
;
5397 if (!PROTOCOL_FORWARD_DECL (p
))
5398 build_protocol_reference (p
);
5400 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5402 TREE_TYPE (expr
) = protocol_type
;
5408 build_selector_expr (selnamelist
)
5413 if (!doing_objc_thang
)
5416 /* Obtain the full selector name. */
5417 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5418 /* A unary selector. */
5419 selname
= selnamelist
;
5420 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5421 selname
= build_keyword_selector (selnamelist
);
5425 if (flag_typed_selectors
)
5426 return build_typed_selector_reference (selname
, 0);
5428 return build_selector_reference (selname
);
5432 build_encode_expr (type
)
5438 if (!doing_objc_thang
)
5441 encode_type (type
, obstack_object_size (&util_obstack
),
5442 OBJC_ENCODE_INLINE_DEFS
);
5443 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5444 string
= obstack_finish (&util_obstack
);
5446 /* Synthesize a string that represents the encoded struct/union. */
5447 result
= my_build_string (strlen (string
) + 1, string
);
5448 obstack_free (&util_obstack
, util_firstobj
);
5453 build_ivar_reference (id
)
5456 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5458 /* Historically, a class method that produced objects (factory
5459 method) would assign `self' to the instance that it
5460 allocated. This would effectively turn the class method into
5461 an instance method. Following this assignment, the instance
5462 variables could be accessed. That practice, while safe,
5463 violates the simple rule that a class method should not refer
5464 to an instance variable. It's better to catch the cases
5465 where this is done unknowingly than to support the above
5467 warning ("instance variable `%s' accessed in class method",
5468 IDENTIFIER_POINTER (id
));
5469 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5472 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5475 #define HASH_ALLOC_LIST_SIZE 170
5476 #define ATTR_ALLOC_LIST_SIZE 170
5477 #define SIZEHASHTABLE 257
5480 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5485 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5486 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5488 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5489 perror ("unable to allocate space in objc-tree.c");
5494 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5496 nst_method_hash_list
[i
] = 0;
5497 cls_method_hash_list
[i
] = 0;
5503 hash_enter (hashlist
, method
)
5507 static hash hash_alloc_list
= 0;
5508 static int hash_alloc_index
= 0;
5510 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5512 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5514 hash_alloc_index
= 0;
5515 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5516 * HASH_ALLOC_LIST_SIZE
);
5517 if (! hash_alloc_list
)
5518 perror ("unable to allocate in objc-tree.c");
5520 obj
= &hash_alloc_list
[hash_alloc_index
++];
5522 obj
->next
= hashlist
[slot
];
5525 hashlist
[slot
] = obj
; /* append to front */
5529 hash_lookup (hashlist
, sel_name
)
5535 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5539 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5542 target
= target
->next
;
5548 hash_add_attr (entry
, value
)
5552 static attr attr_alloc_list
= 0;
5553 static int attr_alloc_index
= 0;
5556 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5558 attr_alloc_index
= 0;
5559 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5560 * ATTR_ALLOC_LIST_SIZE
);
5561 if (! attr_alloc_list
)
5562 perror ("unable to allocate in objc-tree.c");
5564 obj
= &attr_alloc_list
[attr_alloc_index
++];
5565 obj
->next
= entry
->list
;
5568 entry
->list
= obj
; /* append to front */
5572 lookup_method (mchain
, method
)
5578 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5581 key
= METHOD_SEL_NAME (method
);
5585 if (METHOD_SEL_NAME (mchain
) == key
)
5587 mchain
= TREE_CHAIN (mchain
);
5593 lookup_instance_method_static (interface
, ident
)
5597 tree inter
= interface
;
5598 tree chain
= CLASS_NST_METHODS (inter
);
5599 tree meth
= NULL_TREE
;
5603 if ((meth
= lookup_method (chain
, ident
)))
5606 if (CLASS_CATEGORY_LIST (inter
))
5608 tree category
= CLASS_CATEGORY_LIST (inter
);
5609 chain
= CLASS_NST_METHODS (category
);
5613 if ((meth
= lookup_method (chain
, ident
)))
5616 /* Check for instance methods in protocols in categories. */
5617 if (CLASS_PROTOCOL_LIST (category
))
5619 if ((meth
= (lookup_method_in_protocol_list
5620 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5624 if ((category
= CLASS_CATEGORY_LIST (category
)))
5625 chain
= CLASS_NST_METHODS (category
);
5630 if (CLASS_PROTOCOL_LIST (inter
))
5632 if ((meth
= (lookup_method_in_protocol_list
5633 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5637 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5638 chain
= CLASS_NST_METHODS (inter
);
5646 lookup_class_method_static (interface
, ident
)
5650 tree inter
= interface
;
5651 tree chain
= CLASS_CLS_METHODS (inter
);
5652 tree meth
= NULL_TREE
;
5653 tree root_inter
= NULL_TREE
;
5657 if ((meth
= lookup_method (chain
, ident
)))
5660 if (CLASS_CATEGORY_LIST (inter
))
5662 tree category
= CLASS_CATEGORY_LIST (inter
);
5663 chain
= CLASS_CLS_METHODS (category
);
5667 if ((meth
= lookup_method (chain
, ident
)))
5670 /* Check for class methods in protocols in categories. */
5671 if (CLASS_PROTOCOL_LIST (category
))
5673 if ((meth
= (lookup_method_in_protocol_list
5674 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5678 if ((category
= CLASS_CATEGORY_LIST (category
)))
5679 chain
= CLASS_CLS_METHODS (category
);
5684 /* Check for class methods in protocols. */
5685 if (CLASS_PROTOCOL_LIST (inter
))
5687 if ((meth
= (lookup_method_in_protocol_list
5688 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5693 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5694 chain
= CLASS_CLS_METHODS (inter
);
5698 /* Simulate wrap around. */
5699 return lookup_instance_method_static (root_inter
, ident
);
5703 add_class_method (class, method
)
5710 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5712 /* put method on list in reverse order */
5713 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5714 CLASS_CLS_METHODS (class) = method
;
5718 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5719 error ("duplicate definition of class method `%s'.",
5720 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5723 /* Check types; if different, complain. */
5724 if (!comp_proto_with_proto (method
, mth
))
5725 error ("duplicate declaration of class method `%s'.",
5726 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5730 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5732 /* Install on a global chain. */
5733 hash_enter (cls_method_hash_list
, method
);
5737 /* Check types; if different, add to a list. */
5738 if (!comp_proto_with_proto (method
, hsh
->key
))
5739 hash_add_attr (hsh
, method
);
5745 add_instance_method (class, method
)
5752 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5754 /* Put method on list in reverse order. */
5755 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5756 CLASS_NST_METHODS (class) = method
;
5760 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5761 error ("duplicate definition of instance method `%s'.",
5762 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5765 /* Check types; if different, complain. */
5766 if (!comp_proto_with_proto (method
, mth
))
5767 error ("duplicate declaration of instance method `%s'.",
5768 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5772 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5774 /* Install on a global chain. */
5775 hash_enter (nst_method_hash_list
, method
);
5779 /* Check types; if different, add to a list. */
5780 if (!comp_proto_with_proto (method
, hsh
->key
))
5781 hash_add_attr (hsh
, method
);
5790 /* Put interfaces on list in reverse order. */
5791 TREE_CHAIN (class) = interface_chain
;
5792 interface_chain
= class;
5793 return interface_chain
;
5797 add_category (class, category
)
5801 /* Put categories on list in reverse order. */
5802 tree cat
= CLASS_CATEGORY_LIST (class);
5806 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5807 warning ("duplicate interface declaration for category `%s(%s)'",
5808 IDENTIFIER_POINTER (CLASS_NAME (class)),
5809 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5810 cat
= CLASS_CATEGORY_LIST (cat
);
5813 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5814 CLASS_CATEGORY_LIST (class) = category
;
5817 /* Called after parsing each instance variable declaration. Necessary to
5818 preserve typedefs and implement public/private...
5820 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5823 add_instance_variable (class, public, declarator
, declspecs
, width
)
5830 tree field_decl
, raw_decl
;
5832 raw_decl
= build_tree_list (declspecs
, declarator
);
5834 if (CLASS_RAW_IVARS (class))
5835 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5837 CLASS_RAW_IVARS (class) = raw_decl
;
5839 field_decl
= grokfield (input_filename
, lineno
,
5840 declarator
, declspecs
, width
);
5842 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5846 TREE_PUBLIC (field_decl
) = 0;
5847 TREE_PRIVATE (field_decl
) = 0;
5848 TREE_PROTECTED (field_decl
) = 1;
5852 TREE_PUBLIC (field_decl
) = 1;
5853 TREE_PRIVATE (field_decl
) = 0;
5854 TREE_PROTECTED (field_decl
) = 0;
5858 TREE_PUBLIC (field_decl
) = 0;
5859 TREE_PRIVATE (field_decl
) = 1;
5860 TREE_PROTECTED (field_decl
) = 0;
5865 if (CLASS_IVARS (class))
5866 chainon (CLASS_IVARS (class), field_decl
);
5868 CLASS_IVARS (class) = field_decl
;
5874 is_ivar (decl_chain
, ident
)
5878 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5879 if (DECL_NAME (decl_chain
) == ident
)
5884 /* True if the ivar is private and we are not in its implementation. */
5890 if (TREE_PRIVATE (decl
)
5891 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5893 error ("instance variable `%s' is declared private",
5894 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5901 /* We have an instance variable reference;, check to see if it is public. */
5904 is_public (expr
, identifier
)
5908 tree basetype
= TREE_TYPE (expr
);
5909 enum tree_code code
= TREE_CODE (basetype
);
5912 if (code
== RECORD_TYPE
)
5914 if (TREE_STATIC_TEMPLATE (basetype
))
5916 if (!lookup_interface (TYPE_NAME (basetype
)))
5918 error ("Cannot find interface declaration for `%s'",
5919 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5923 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5925 if (TREE_PUBLIC (decl
))
5928 /* Important difference between the Stepstone translator:
5929 all instance variables should be public within the context
5930 of the implementation. */
5931 if (implementation_context
5932 && (((TREE_CODE (implementation_context
)
5933 == CLASS_IMPLEMENTATION_TYPE
)
5934 || (TREE_CODE (implementation_context
)
5935 == CATEGORY_IMPLEMENTATION_TYPE
))
5936 && (CLASS_NAME (implementation_context
)
5937 == TYPE_NAME (basetype
))))
5938 return ! is_private (decl
);
5940 error ("instance variable `%s' is declared %s",
5941 IDENTIFIER_POINTER (identifier
),
5942 TREE_PRIVATE (decl
) ? "private" : "protected");
5947 else if (implementation_context
&& (basetype
== objc_object_reference
))
5949 TREE_TYPE (expr
) = uprivate_record
;
5950 warning ("static access to object of type `id'");
5957 /* Implement @defs (<classname>) within struct bodies. */
5960 get_class_ivars (interface
)
5963 if (!doing_objc_thang
)
5966 return build_ivar_chain (interface
, 1);
5969 /* Make sure all entries in CHAIN are also in LIST. */
5972 check_methods (chain
, list
, mtype
)
5981 if (!lookup_method (list
, chain
))
5985 if (TREE_CODE (implementation_context
)
5986 == CLASS_IMPLEMENTATION_TYPE
)
5987 warning ("incomplete implementation of class `%s'",
5988 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5989 else if (TREE_CODE (implementation_context
)
5990 == CATEGORY_IMPLEMENTATION_TYPE
)
5991 warning ("incomplete implementation of category `%s'",
5992 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5996 warning ("method definition for `%c%s' not found",
5997 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6000 chain
= TREE_CHAIN (chain
);
6007 conforms_to_protocol (class, protocol
)
6013 tree p
= CLASS_PROTOCOL_LIST (class);
6015 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
6020 tree super
= (CLASS_SUPER_NAME (class)
6021 ? lookup_interface (CLASS_SUPER_NAME (class))
6023 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
6028 protocol
= TREE_CHAIN (protocol
);
6034 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6035 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6038 check_methods_accessible (chain
, context
, mtype
)
6045 tree base_context
= context
;
6049 context
= base_context
;
6053 list
= CLASS_CLS_METHODS (context
);
6055 list
= CLASS_NST_METHODS (context
);
6057 if (lookup_method (list
, chain
))
6060 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6061 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6062 context
= (CLASS_SUPER_NAME (context
)
6063 ? lookup_interface (CLASS_SUPER_NAME (context
))
6066 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6067 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6068 context
= (CLASS_NAME (context
)
6069 ? lookup_interface (CLASS_NAME (context
))
6075 if (context
== NULL_TREE
)
6079 if (TREE_CODE (implementation_context
)
6080 == CLASS_IMPLEMENTATION_TYPE
)
6081 warning ("incomplete implementation of class `%s'",
6083 (CLASS_NAME (implementation_context
)));
6084 else if (TREE_CODE (implementation_context
)
6085 == CATEGORY_IMPLEMENTATION_TYPE
)
6086 warning ("incomplete implementation of category `%s'",
6088 (CLASS_SUPER_NAME (implementation_context
)));
6091 warning ("method definition for `%c%s' not found",
6092 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6095 chain
= TREE_CHAIN (chain
); /* next method... */
6101 check_protocols (proto_list
, type
, name
)
6106 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6108 tree p
= TREE_VALUE (proto_list
);
6110 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6114 /* Ensure that all protocols have bodies. */
6115 if (flag_warn_protocol
) {
6116 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6117 CLASS_CLS_METHODS (implementation_context
),
6119 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6120 CLASS_NST_METHODS (implementation_context
),
6123 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6124 implementation_context
,
6126 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6127 implementation_context
,
6132 warning ("%s `%s' does not fully implement the `%s' protocol",
6133 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6138 ; /* An identifier if we could not find a protocol. */
6141 /* Check protocols recursively. */
6142 if (PROTOCOL_LIST (p
))
6145 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6146 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6147 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6152 /* Make sure that the class CLASS_NAME is defined
6153 CODE says which kind of thing CLASS_NAME ought to be.
6154 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6155 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6158 start_class (code
, class_name
, super_name
, protocol_list
)
6159 enum tree_code code
;
6166 if (!doing_objc_thang
)
6169 class = make_node (code
);
6170 TYPE_BINFO (class) = make_tree_vec (5);
6172 CLASS_NAME (class) = class_name
;
6173 CLASS_SUPER_NAME (class) = super_name
;
6174 CLASS_CLS_METHODS (class) = NULL_TREE
;
6176 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6178 error ("`%s' redeclared as different kind of symbol",
6179 IDENTIFIER_POINTER (class_name
));
6180 error_with_decl (decl
, "previous declaration of `%s'");
6183 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6186 static tree implemented_classes
= 0;
6187 tree chain
= implemented_classes
;
6188 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6189 if (TREE_VALUE (chain
) == class_name
)
6191 error ("reimplementation of class `%s'",
6192 IDENTIFIER_POINTER (class_name
));
6193 return error_mark_node
;
6195 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6196 implemented_classes
);
6199 /* Pre-build the following entities - for speed/convenience. */
6201 self_id
= get_identifier ("self");
6203 ucmd_id
= get_identifier ("_cmd");
6206 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6207 if (!objc_super_template
)
6208 objc_super_template
= build_super_template ();
6210 /* Reset for multiple classes per file. */
6213 implementation_context
= class;
6215 /* Lookup the interface for this implementation. */
6217 if (!(implementation_template
= lookup_interface (class_name
)))
6219 warning ("Cannot find interface declaration for `%s'",
6220 IDENTIFIER_POINTER (class_name
));
6221 add_class (implementation_template
= implementation_context
);
6224 /* If a super class has been specified in the implementation,
6225 insure it conforms to the one specified in the interface. */
6228 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6230 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6232 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6233 error ("conflicting super class name `%s'",
6234 IDENTIFIER_POINTER (super_name
));
6235 error ("previous declaration of `%s'", name
);
6238 else if (! super_name
)
6240 CLASS_SUPER_NAME (implementation_context
)
6241 = CLASS_SUPER_NAME (implementation_template
);
6245 else if (code
== CLASS_INTERFACE_TYPE
)
6247 if (lookup_interface (class_name
))
6248 warning ("duplicate interface declaration for class `%s'",
6249 IDENTIFIER_POINTER (class_name
));
6254 CLASS_PROTOCOL_LIST (class)
6255 = lookup_and_install_protocols (protocol_list
);
6258 else if (code
== CATEGORY_INTERFACE_TYPE
)
6260 tree class_category_is_assoc_with
;
6262 /* For a category, class_name is really the name of the class that
6263 the following set of methods will be associated with. We must
6264 find the interface so that can derive the objects template. */
6266 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6268 error ("Cannot find interface declaration for `%s'",
6269 IDENTIFIER_POINTER (class_name
));
6270 exit (FATAL_EXIT_CODE
);
6273 add_category (class_category_is_assoc_with
, class);
6276 CLASS_PROTOCOL_LIST (class)
6277 = lookup_and_install_protocols (protocol_list
);
6280 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6282 /* Pre-build the following entities for speed/convenience. */
6284 self_id
= get_identifier ("self");
6286 ucmd_id
= get_identifier ("_cmd");
6289 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6290 if (!objc_super_template
)
6291 objc_super_template
= build_super_template ();
6293 /* Reset for multiple classes per file. */
6296 implementation_context
= class;
6298 /* For a category, class_name is really the name of the class that
6299 the following set of methods will be associated with. We must
6300 find the interface so that can derive the objects template. */
6302 if (!(implementation_template
= lookup_interface (class_name
)))
6304 error ("Cannot find interface declaration for `%s'",
6305 IDENTIFIER_POINTER (class_name
));
6306 exit (FATAL_EXIT_CODE
);
6313 continue_class (class)
6316 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6317 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6319 struct imp_entry
*imp_entry
;
6322 /* Check consistency of the instance variables. */
6324 if (CLASS_IVARS (class))
6325 check_ivars (implementation_template
, class);
6327 /* code generation */
6329 ivar_context
= build_private_template (implementation_template
);
6331 if (!objc_class_template
)
6332 build_class_template ();
6335 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6336 perror ("unable to allocate in objc-tree.c");
6338 imp_entry
->next
= imp_list
;
6339 imp_entry
->imp_context
= class;
6340 imp_entry
->imp_template
= implementation_template
;
6342 synth_forward_declarations ();
6343 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6344 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6346 /* Append to front and increment count. */
6347 imp_list
= imp_entry
;
6348 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6353 return ivar_context
;
6356 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6358 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6360 if (!TYPE_FIELDS (record
))
6362 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6363 CLASS_STATIC_TEMPLATE (class) = record
;
6365 /* Mark this record as a class template for static typing. */
6366 TREE_STATIC_TEMPLATE (record
) = 1;
6373 return error_mark_node
;
6376 /* This is called once we see the "@end" in an interface/implementation. */
6379 finish_class (class)
6382 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6384 /* All code generation is done in finish_objc. */
6386 if (implementation_template
!= implementation_context
)
6388 /* Ensure that all method listed in the interface contain bodies. */
6389 check_methods (CLASS_CLS_METHODS (implementation_template
),
6390 CLASS_CLS_METHODS (implementation_context
), '+');
6391 check_methods (CLASS_NST_METHODS (implementation_template
),
6392 CLASS_NST_METHODS (implementation_context
), '-');
6394 if (CLASS_PROTOCOL_LIST (implementation_template
))
6395 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6397 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6401 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6403 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6405 /* Find the category interface from the class it is associated with. */
6408 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6410 category
= CLASS_CATEGORY_LIST (category
);
6415 /* Ensure all method listed in the interface contain bodies. */
6416 check_methods (CLASS_CLS_METHODS (category
),
6417 CLASS_CLS_METHODS (implementation_context
), '+');
6418 check_methods (CLASS_NST_METHODS (category
),
6419 CLASS_NST_METHODS (implementation_context
), '-');
6421 if (CLASS_PROTOCOL_LIST (category
))
6422 check_protocols (CLASS_PROTOCOL_LIST (category
),
6424 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6428 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6431 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6432 char *string
= (char *) alloca (strlen (class_name
) + 3);
6434 /* extern struct objc_object *_<my_name>; */
6436 sprintf (string
, "_%s", class_name
);
6438 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6439 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6440 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6446 add_protocol (protocol
)
6449 /* Put protocol on list in reverse order. */
6450 TREE_CHAIN (protocol
) = protocol_chain
;
6451 protocol_chain
= protocol
;
6452 return protocol_chain
;
6456 lookup_protocol (ident
)
6461 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6463 if (ident
== PROTOCOL_NAME (chain
))
6471 start_protocol (code
, name
, list
)
6472 enum tree_code code
;
6478 if (!doing_objc_thang
)
6481 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6482 if (!objc_protocol_template
)
6483 objc_protocol_template
= build_protocol_template ();
6485 protocol
= make_node (code
);
6486 TYPE_BINFO (protocol
) = make_tree_vec (2);
6488 PROTOCOL_NAME (protocol
) = name
;
6489 PROTOCOL_LIST (protocol
) = list
;
6491 lookup_and_install_protocols (list
);
6493 if (lookup_protocol (name
))
6494 warning ("duplicate declaration for protocol `%s'",
6495 IDENTIFIER_POINTER (name
));
6497 add_protocol (protocol
);
6499 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6505 finish_protocol (protocol
)
6506 tree protocol ATTRIBUTE_UNUSED
;
6511 /* "Encode" a data type into a string, which grows in util_obstack.
6512 ??? What is the FORMAT? Someone please document this! */
6515 encode_type_qualifiers (declspecs
)
6520 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6522 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6523 obstack_1grow (&util_obstack
, 'r');
6524 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6525 obstack_1grow (&util_obstack
, 'n');
6526 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6527 obstack_1grow (&util_obstack
, 'N');
6528 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6529 obstack_1grow (&util_obstack
, 'o');
6530 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6531 obstack_1grow (&util_obstack
, 'O');
6532 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6533 obstack_1grow (&util_obstack
, 'R');
6534 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6535 obstack_1grow (&util_obstack
, 'V');
6539 /* Encode a pointer type. */
6542 encode_pointer (type
, curtype
, format
)
6547 tree pointer_to
= TREE_TYPE (type
);
6549 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6551 if (TYPE_NAME (pointer_to
)
6552 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6554 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6556 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6558 obstack_1grow (&util_obstack
, '@');
6561 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6563 if (generating_instance_variables
)
6565 obstack_1grow (&util_obstack
, '@');
6566 obstack_1grow (&util_obstack
, '"');
6567 obstack_grow (&util_obstack
, name
, strlen (name
));
6568 obstack_1grow (&util_obstack
, '"');
6573 obstack_1grow (&util_obstack
, '@');
6577 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6579 obstack_1grow (&util_obstack
, '#');
6582 #ifndef OBJC_INT_SELECTORS
6583 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6585 obstack_1grow (&util_obstack
, ':');
6588 #endif /* OBJC_INT_SELECTORS */
6591 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6592 && TYPE_MODE (pointer_to
) == QImode
)
6594 obstack_1grow (&util_obstack
, '*');
6598 /* We have a type that does not get special treatment. */
6600 /* NeXT extension */
6601 obstack_1grow (&util_obstack
, '^');
6602 encode_type (pointer_to
, curtype
, format
);
6606 encode_array (type
, curtype
, format
)
6611 tree an_int_cst
= TYPE_SIZE (type
);
6612 tree array_of
= TREE_TYPE (type
);
6615 /* An incomplete array is treated like a pointer. */
6616 if (an_int_cst
== NULL
)
6618 encode_pointer (type
, curtype
, format
);
6622 sprintf (buffer
, "[%ld",
6623 (long) (TREE_INT_CST_LOW (an_int_cst
)
6624 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6626 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6627 encode_type (array_of
, curtype
, format
);
6628 obstack_1grow (&util_obstack
, ']');
6633 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6640 if (obstack_object_size (&util_obstack
) > 0
6641 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6643 tree name
= TYPE_NAME (type
);
6645 /* we have a reference; this is a NeXT extension. */
6647 if (obstack_object_size (&util_obstack
) - curtype
== 1
6648 && format
== OBJC_ENCODE_INLINE_DEFS
)
6650 /* Output format of struct for first level only. */
6651 tree fields
= TYPE_FIELDS (type
);
6653 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6655 obstack_1grow (&util_obstack
, left
);
6656 obstack_grow (&util_obstack
,
6657 IDENTIFIER_POINTER (name
),
6658 strlen (IDENTIFIER_POINTER (name
)));
6659 obstack_1grow (&util_obstack
, '=');
6663 obstack_1grow (&util_obstack
, left
);
6664 obstack_grow (&util_obstack
, "?=", 2);
6667 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6668 encode_field_decl (fields
, curtype
, format
);
6670 obstack_1grow (&util_obstack
, right
);
6673 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6675 obstack_1grow (&util_obstack
, left
);
6676 obstack_grow (&util_obstack
,
6677 IDENTIFIER_POINTER (name
),
6678 strlen (IDENTIFIER_POINTER (name
)));
6679 obstack_1grow (&util_obstack
, right
);
6684 /* We have an untagged structure or a typedef. */
6685 obstack_1grow (&util_obstack
, left
);
6686 obstack_1grow (&util_obstack
, '?');
6687 obstack_1grow (&util_obstack
, right
);
6693 tree name
= TYPE_NAME (type
);
6694 tree fields
= TYPE_FIELDS (type
);
6696 if (format
== OBJC_ENCODE_INLINE_DEFS
6697 || generating_instance_variables
)
6699 obstack_1grow (&util_obstack
, left
);
6700 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6701 obstack_grow (&util_obstack
,
6702 IDENTIFIER_POINTER (name
),
6703 strlen (IDENTIFIER_POINTER (name
)));
6705 obstack_1grow (&util_obstack
, '?');
6707 obstack_1grow (&util_obstack
, '=');
6709 for (; fields
; fields
= TREE_CHAIN (fields
))
6711 if (generating_instance_variables
)
6713 tree fname
= DECL_NAME (fields
);
6715 obstack_1grow (&util_obstack
, '"');
6716 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6718 obstack_grow (&util_obstack
,
6719 IDENTIFIER_POINTER (fname
),
6720 strlen (IDENTIFIER_POINTER (fname
)));
6723 obstack_1grow (&util_obstack
, '"');
6726 encode_field_decl (fields
, curtype
, format
);
6729 obstack_1grow (&util_obstack
, right
);
6734 obstack_1grow (&util_obstack
, left
);
6735 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6736 obstack_grow (&util_obstack
,
6737 IDENTIFIER_POINTER (name
),
6738 strlen (IDENTIFIER_POINTER (name
)));
6740 /* We have an untagged structure or a typedef. */
6741 obstack_1grow (&util_obstack
, '?');
6743 obstack_1grow (&util_obstack
, right
);
6749 encode_aggregate (type
, curtype
, format
)
6754 enum tree_code code
= TREE_CODE (type
);
6760 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6765 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6770 obstack_1grow (&util_obstack
, 'i');
6778 /* Support bitfields. The current version of Objective-C does not support
6779 them. The string will consist of one or more "b:n"'s where n is an
6780 integer describing the width of the bitfield. Currently, classes in
6781 the kit implement a method "-(char *)describeBitfieldStruct:" that
6782 simulates this. If they do not implement this method, the archiver
6783 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6784 according to the GNU compiler. After looking at the "kit", it appears
6785 that all classes currently rely on this default behavior, rather than
6786 hand generating this string (which is tedious). */
6789 encode_bitfield (width
)
6793 sprintf (buffer
, "b%d", width
);
6794 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6797 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6800 encode_type (type
, curtype
, format
)
6805 enum tree_code code
= TREE_CODE (type
);
6807 if (code
== INTEGER_TYPE
)
6809 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6811 /* Unsigned integer types. */
6813 if (TYPE_MODE (type
) == QImode
)
6814 obstack_1grow (&util_obstack
, 'C');
6815 else if (TYPE_MODE (type
) == HImode
)
6816 obstack_1grow (&util_obstack
, 'S');
6817 else if (TYPE_MODE (type
) == SImode
)
6819 if (type
== long_unsigned_type_node
)
6820 obstack_1grow (&util_obstack
, 'L');
6822 obstack_1grow (&util_obstack
, 'I');
6824 else if (TYPE_MODE (type
) == DImode
)
6825 obstack_1grow (&util_obstack
, 'Q');
6829 /* Signed integer types. */
6831 if (TYPE_MODE (type
) == QImode
)
6832 obstack_1grow (&util_obstack
, 'c');
6833 else if (TYPE_MODE (type
) == HImode
)
6834 obstack_1grow (&util_obstack
, 's');
6835 else if (TYPE_MODE (type
) == SImode
)
6837 if (type
== long_integer_type_node
)
6838 obstack_1grow (&util_obstack
, 'l');
6840 obstack_1grow (&util_obstack
, 'i');
6843 else if (TYPE_MODE (type
) == DImode
)
6844 obstack_1grow (&util_obstack
, 'q');
6848 else if (code
== REAL_TYPE
)
6850 /* Floating point types. */
6852 if (TYPE_MODE (type
) == SFmode
)
6853 obstack_1grow (&util_obstack
, 'f');
6854 else if (TYPE_MODE (type
) == DFmode
6855 || TYPE_MODE (type
) == TFmode
)
6856 obstack_1grow (&util_obstack
, 'd');
6859 else if (code
== VOID_TYPE
)
6860 obstack_1grow (&util_obstack
, 'v');
6862 else if (code
== ARRAY_TYPE
)
6863 encode_array (type
, curtype
, format
);
6865 else if (code
== POINTER_TYPE
)
6866 encode_pointer (type
, curtype
, format
);
6868 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6869 encode_aggregate (type
, curtype
, format
);
6871 else if (code
== FUNCTION_TYPE
) /* '?' */
6872 obstack_1grow (&util_obstack
, '?');
6876 encode_complete_bitfield (int position
, tree type
, int size
)
6878 enum tree_code code
= TREE_CODE (type
);
6880 char charType
= '?';
6882 if (code
== INTEGER_TYPE
)
6884 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6886 /* Unsigned integer types. */
6888 if (TYPE_MODE (type
) == QImode
)
6890 else if (TYPE_MODE (type
) == HImode
)
6892 else if (TYPE_MODE (type
) == SImode
)
6894 if (type
== long_unsigned_type_node
)
6899 else if (TYPE_MODE (type
) == DImode
)
6904 /* Signed integer types. */
6906 if (TYPE_MODE (type
) == QImode
)
6908 else if (TYPE_MODE (type
) == HImode
)
6910 else if (TYPE_MODE (type
) == SImode
)
6912 if (type
== long_integer_type_node
)
6918 else if (TYPE_MODE (type
) == DImode
)
6926 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6927 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6931 encode_field_decl (field_decl
, curtype
, format
)
6938 type
= TREE_TYPE (field_decl
);
6940 /* If this field is obviously a bitfield, or is a bitfield that has been
6941 clobbered to look like a ordinary integer mode, go ahead and generate
6942 the bitfield typing information. */
6943 if (flag_next_runtime
)
6945 if (DECL_BIT_FIELD (field_decl
))
6946 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6948 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6952 if (DECL_BIT_FIELD (field_decl
))
6953 encode_complete_bitfield (int_bit_position (field_decl
),
6954 DECL_BIT_FIELD_TYPE (field_decl
),
6955 tree_low_cst (DECL_SIZE (field_decl
), 1));
6957 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6962 expr_last (complex_expr
)
6968 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6969 complex_expr
= next
;
6971 return complex_expr
;
6974 /* The selector of the current method,
6975 or NULL if we aren't compiling a method. */
6978 maybe_objc_method_name (decl
)
6979 tree decl ATTRIBUTE_UNUSED
;
6982 return METHOD_SEL_NAME (method_context
);
6987 /* Transform a method definition into a function definition as follows:
6988 - synthesize the first two arguments, "self" and "_cmd". */
6991 start_method_def (method
)
6996 /* Required to implement _msgSuper. */
6997 method_context
= method
;
6998 UOBJC_SUPER_decl
= NULL_TREE
;
7000 /* Must be called BEFORE start_function. */
7003 /* Generate prototype declarations for arguments..."new-style". */
7005 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
7006 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
7008 /* Really a `struct objc_class *'. However, we allow people to
7009 assign to self, which changes its type midstream. */
7010 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
7012 push_parm_decl (build_tree_list
7013 (build_tree_list (decl_specs
,
7014 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
7015 build_tree_list (unused_list
, NULL_TREE
)));
7017 #ifdef OBJC_INT_SELECTORS
7018 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
7019 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
7020 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
7021 build_tree_list (unused_list
, NULL_TREE
)));
7022 #else /* not OBJC_INT_SELECTORS */
7023 decl_specs
= build_tree_list (NULL_TREE
,
7024 xref_tag (RECORD_TYPE
,
7025 get_identifier (TAG_SELECTOR
)));
7026 push_parm_decl (build_tree_list
7027 (build_tree_list (decl_specs
,
7028 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
7029 build_tree_list (unused_list
, NULL_TREE
)));
7030 #endif /* not OBJC_INT_SELECTORS */
7032 /* Generate argument declarations if a keyword_decl. */
7033 if (METHOD_SEL_ARGS (method
))
7035 tree arglist
= METHOD_SEL_ARGS (method
);
7038 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
7039 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
7043 tree last_expr
= expr_last (arg_decl
);
7045 /* Unite the abstract decl with its name. */
7046 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
7047 push_parm_decl (build_tree_list
7048 (build_tree_list (arg_spec
, arg_decl
),
7049 build_tree_list (NULL_TREE
, NULL_TREE
)));
7051 /* Unhook: restore the abstract declarator. */
7052 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
7056 push_parm_decl (build_tree_list
7057 (build_tree_list (arg_spec
,
7058 KEYWORD_ARG_NAME (arglist
)),
7059 build_tree_list (NULL_TREE
, NULL_TREE
)));
7061 arglist
= TREE_CHAIN (arglist
);
7066 if (METHOD_ADD_ARGS (method
) != NULL_TREE
7067 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7069 /* We have a variable length selector - in "prototype" format. */
7070 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7073 /* This must be done prior to calling pushdecl. pushdecl is
7074 going to change our chain on us. */
7075 tree nextkey
= TREE_CHAIN (akey
);
7083 warn_with_method (message
, mtype
, method
)
7084 const char *message
;
7088 if (count_error (1) == 0)
7091 report_error_function (DECL_SOURCE_FILE (method
));
7093 fprintf (stderr
, "%s:%d: warning: ",
7094 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7095 bzero (errbuf
, BUFSIZE
);
7096 fprintf (stderr
, "%s `%c%s'\n",
7097 message
, mtype
, gen_method_decl (method
, errbuf
));
7100 /* Return 1 if METHOD is consistent with PROTO. */
7103 comp_method_with_proto (method
, proto
)
7106 static tree function_type
= 0;
7108 /* Create a function_type node once. */
7111 function_type
= make_node (FUNCTION_TYPE
);
7112 ggc_add_tree_root (&function_type
, 1);
7115 /* Install argument types - normally set by build_function_type. */
7116 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7118 /* install return type */
7119 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7121 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7124 /* Return 1 if PROTO1 is consistent with PROTO2. */
7127 comp_proto_with_proto (proto0
, proto1
)
7128 tree proto0
, proto1
;
7130 static tree function_type
[2];
7132 /* Create a couple function_type node's once. */
7133 if (!function_type
[0])
7135 function_type
[0] = make_node (FUNCTION_TYPE
);
7136 function_type
[1] = make_node (FUNCTION_TYPE
);
7137 ggc_add_tree_root (function_type
, 2);
7140 /* Install argument types; normally set by build_function_type. */
7141 TYPE_ARG_TYPES (function_type
[0]) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7142 TYPE_ARG_TYPES (function_type
[1]) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7144 /* Install return type. */
7145 TREE_TYPE (function_type
[0]) = groktypename (TREE_TYPE (proto0
));
7146 TREE_TYPE (function_type
[1]) = groktypename (TREE_TYPE (proto1
));
7148 return comptypes (function_type
[0], function_type
[1]);
7151 /* - Generate an identifier for the function. the format is "_n_cls",
7152 where 1 <= n <= nMethods, and cls is the name the implementation we
7154 - Install the return type from the method declaration.
7155 - If we have a prototype, check for type consistency. */
7158 really_start_method (method
, parmlist
)
7159 tree method
, parmlist
;
7161 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7162 tree method_decl
, method_id
;
7163 const char *sel_name
, *class_name
, *cat_name
;
7166 /* Synth the storage class & assemble the return type. */
7167 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7168 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7169 decl_specs
= chainon (sc_spec
, ret_spec
);
7171 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7172 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7173 cat_name
= ((TREE_CODE (implementation_context
)
7174 == CLASS_IMPLEMENTATION_TYPE
)
7176 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7179 /* Make sure this is big enough for any plausible method label. */
7180 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7181 + (cat_name
? strlen (cat_name
) : 0));
7183 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7184 class_name
, cat_name
, sel_name
, method_slot
);
7186 method_id
= get_identifier (buf
);
7188 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7190 /* Check the declarator portion of the return type for the method. */
7191 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7193 /* Unite the complex decl (specified in the abstract decl) with the
7194 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7195 tree save_expr
= expr_last (ret_decl
);
7197 TREE_OPERAND (save_expr
, 0) = method_decl
;
7198 method_decl
= ret_decl
;
7200 /* Fool the parser into thinking it is starting a function. */
7201 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7203 /* Unhook: this has the effect of restoring the abstract declarator. */
7204 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7209 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7211 /* Fool the parser into thinking it is starting a function. */
7212 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7214 /* Unhook: this has the effect of restoring the abstract declarator. */
7215 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7218 METHOD_DEFINITION (method
) = current_function_decl
;
7220 if (implementation_template
!= implementation_context
)
7224 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7225 proto
= lookup_instance_method_static (implementation_template
,
7226 METHOD_SEL_NAME (method
));
7228 proto
= lookup_class_method_static (implementation_template
,
7229 METHOD_SEL_NAME (method
));
7231 if (proto
&& ! comp_method_with_proto (method
, proto
))
7233 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7235 warn_with_method ("conflicting types for", type
, method
);
7236 warn_with_method ("previous declaration of", type
, proto
);
7241 /* The following routine is always called...this "architecture" is to
7242 accommodate "old-style" variable length selectors.
7244 - a:a b:b // prototype ; id c; id d; // old-style. */
7247 continue_method_def ()
7251 if (METHOD_ADD_ARGS (method_context
) == objc_ellipsis_node
)
7252 /* We have a `, ...' immediately following the selector. */
7253 parmlist
= get_parm_info (0);
7255 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7257 /* Set self_decl from the first argument...this global is used by
7258 build_ivar_reference calling build_indirect_ref. */
7259 self_decl
= TREE_PURPOSE (parmlist
);
7262 really_start_method (method_context
, parmlist
);
7263 store_parm_decls ();
7266 /* Called by the parser, from the `pushlevel' production. */
7271 if (!UOBJC_SUPER_decl
)
7273 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7274 build_tree_list (NULL_TREE
,
7275 objc_super_template
),
7276 0, NULL_TREE
, NULL_TREE
);
7278 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7280 /* This prevents `unused variable' warnings when compiling with -Wall. */
7281 TREE_USED (UOBJC_SUPER_decl
) = 1;
7282 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7286 /* _n_Method (id self, SEL sel, ...)
7288 struct objc_super _S;
7289 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7293 get_super_receiver ()
7297 tree super_expr
, super_expr_list
;
7299 /* Set receiver to self. */
7300 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7301 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7302 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7304 /* Set class to begin searching. */
7305 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7306 get_identifier ("class"));
7308 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7310 /* [_cls, __cls]Super are "pre-built" in
7311 synth_forward_declarations. */
7313 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7314 ((TREE_CODE (method_context
)
7315 == INSTANCE_METHOD_DECL
)
7317 : uucls_super_ref
));
7321 /* We have a category. */
7323 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7328 error ("no super class declared in interface for `%s'",
7329 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7330 return error_mark_node
;
7333 if (flag_next_runtime
)
7335 super_class
= get_class_reference (super_name
);
7336 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7338 = build_component_ref (build_indirect_ref (super_class
, "->"),
7339 get_identifier ("isa"));
7343 add_class_reference (super_name
);
7344 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7345 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7346 assemble_external (super_class
);
7348 = build_function_call
7352 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7353 IDENTIFIER_POINTER (super_name
))));
7356 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7357 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7360 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7362 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7363 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7365 return build_compound_expr (super_expr_list
);
7369 error ("[super ...] must appear in a method context");
7370 return error_mark_node
;
7375 encode_method_def (func_decl
)
7380 HOST_WIDE_INT max_parm_end
= 0;
7385 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7386 obstack_object_size (&util_obstack
),
7387 OBJC_ENCODE_INLINE_DEFS
);
7390 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7391 parms
= TREE_CHAIN (parms
))
7393 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7394 + int_size_in_bytes (TREE_TYPE (parms
)));
7396 if (! offset_is_register
&& parm_end
> max_parm_end
)
7397 max_parm_end
= parm_end
;
7400 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7402 sprintf (buffer
, "%d", stack_size
);
7403 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7405 /* Argument types. */
7406 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7407 parms
= TREE_CHAIN (parms
))
7410 encode_type (TREE_TYPE (parms
),
7411 obstack_object_size (&util_obstack
),
7412 OBJC_ENCODE_INLINE_DEFS
);
7414 /* Compute offset. */
7415 sprintf (buffer
, "%d", forwarding_offset (parms
));
7417 /* Indicate register. */
7418 if (offset_is_register
)
7419 obstack_1grow (&util_obstack
, '+');
7421 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7424 obstack_1grow (&util_obstack
, 0);
7425 result
= get_identifier (obstack_finish (&util_obstack
));
7426 obstack_free (&util_obstack
, util_firstobj
);
7431 finish_method_def ()
7433 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7435 finish_function (0);
7437 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7438 since the optimizer may find "may be used before set" errors. */
7439 method_context
= NULL_TREE
;
7444 lang_report_error_function (decl
)
7449 fprintf (stderr
, "In method `%s'\n",
7450 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7460 is_complex_decl (type
)
7463 return (TREE_CODE (type
) == ARRAY_TYPE
7464 || TREE_CODE (type
) == FUNCTION_TYPE
7465 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7469 /* Code to convert a decl node into text for a declaration in C. */
7471 static char tmpbuf
[256];
7474 adorn_decl (decl
, str
)
7478 enum tree_code code
= TREE_CODE (decl
);
7480 if (code
== ARRAY_REF
)
7482 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7484 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7485 sprintf (str
+ strlen (str
), "[%ld]",
7486 (long) TREE_INT_CST_LOW (an_int_cst
));
7491 else if (code
== ARRAY_TYPE
)
7493 tree an_int_cst
= TYPE_SIZE (decl
);
7494 tree array_of
= TREE_TYPE (decl
);
7496 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7497 sprintf (str
+ strlen (str
), "[%ld]",
7498 (long) (TREE_INT_CST_LOW (an_int_cst
)
7499 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7504 else if (code
== CALL_EXPR
)
7506 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7511 gen_declaration (chain
, str
);
7512 chain
= TREE_CHAIN (chain
);
7519 else if (code
== FUNCTION_TYPE
)
7521 tree chain
= TYPE_ARG_TYPES (decl
);
7524 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7526 gen_declaration (TREE_VALUE (chain
), str
);
7527 chain
= TREE_CHAIN (chain
);
7528 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7534 else if (code
== INDIRECT_REF
)
7536 strcpy (tmpbuf
, "*");
7537 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7541 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7543 chain
= TREE_CHAIN (chain
))
7545 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7547 strcat (tmpbuf
, " ");
7548 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7552 strcat (tmpbuf
, " ");
7554 strcat (tmpbuf
, str
);
7555 strcpy (str
, tmpbuf
);
7558 else if (code
== POINTER_TYPE
)
7560 strcpy (tmpbuf
, "*");
7561 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7563 if (TREE_READONLY (decl
))
7564 strcat (tmpbuf
, " const");
7565 if (TYPE_VOLATILE (decl
))
7566 strcat (tmpbuf
, " volatile");
7568 strcat (tmpbuf
, " ");
7570 strcat (tmpbuf
, str
);
7571 strcpy (str
, tmpbuf
);
7576 gen_declarator (decl
, buf
, name
)
7583 enum tree_code code
= TREE_CODE (decl
);
7593 op
= TREE_OPERAND (decl
, 0);
7595 /* We have a pointer to a function or array...(*)(), (*)[] */
7596 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7597 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7600 str
= gen_declarator (op
, buf
, name
);
7604 strcpy (tmpbuf
, "(");
7605 strcat (tmpbuf
, str
);
7606 strcat (tmpbuf
, ")");
7607 strcpy (str
, tmpbuf
);
7610 adorn_decl (decl
, str
);
7619 /* This clause is done iteratively rather than recursively. */
7622 op
= (is_complex_decl (TREE_TYPE (decl
))
7623 ? TREE_TYPE (decl
) : NULL_TREE
);
7625 adorn_decl (decl
, str
);
7627 /* We have a pointer to a function or array...(*)(), (*)[] */
7628 if (code
== POINTER_TYPE
7629 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7630 || TREE_CODE (op
) == ARRAY_TYPE
))
7632 strcpy (tmpbuf
, "(");
7633 strcat (tmpbuf
, str
);
7634 strcat (tmpbuf
, ")");
7635 strcpy (str
, tmpbuf
);
7638 decl
= (is_complex_decl (TREE_TYPE (decl
))
7639 ? TREE_TYPE (decl
) : NULL_TREE
);
7642 while (decl
&& (code
= TREE_CODE (decl
)))
7647 case IDENTIFIER_NODE
:
7648 /* Will only happen if we are processing a "raw" expr-decl. */
7649 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7660 /* We have an abstract declarator or a _DECL node. */
7668 gen_declspecs (declspecs
, buf
, raw
)
7677 for (chain
= nreverse (copy_list (declspecs
));
7678 chain
; chain
= TREE_CHAIN (chain
))
7680 tree aspec
= TREE_VALUE (chain
);
7682 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7683 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7684 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7686 if (TYPE_NAME (aspec
))
7688 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7690 if (! TREE_STATIC_TEMPLATE (aspec
))
7691 strcat (buf
, "struct ");
7692 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7697 tree chain
= protocol_list
;
7704 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7705 chain
= TREE_CHAIN (chain
);
7714 strcat (buf
, "untagged struct");
7717 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7719 if (TYPE_NAME (aspec
))
7721 if (! TREE_STATIC_TEMPLATE (aspec
))
7722 strcat (buf
, "union ");
7723 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7726 strcat (buf
, "untagged union");
7729 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7731 if (TYPE_NAME (aspec
))
7733 if (! TREE_STATIC_TEMPLATE (aspec
))
7734 strcat (buf
, "enum ");
7735 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7738 strcat (buf
, "untagged enum");
7741 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7742 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7744 else if (IS_ID (aspec
))
7746 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7751 tree chain
= protocol_list
;
7758 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7759 chain
= TREE_CHAIN (chain
);
7766 if (TREE_CHAIN (chain
))
7772 /* Type qualifiers. */
7773 if (TREE_READONLY (declspecs
))
7774 strcat (buf
, "const ");
7775 if (TYPE_VOLATILE (declspecs
))
7776 strcat (buf
, "volatile ");
7778 switch (TREE_CODE (declspecs
))
7780 /* Type specifiers. */
7783 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7785 /* Signed integer types. */
7787 if (declspecs
== short_integer_type_node
)
7788 strcat (buf
, "short int ");
7789 else if (declspecs
== integer_type_node
)
7790 strcat (buf
, "int ");
7791 else if (declspecs
== long_integer_type_node
)
7792 strcat (buf
, "long int ");
7793 else if (declspecs
== long_long_integer_type_node
)
7794 strcat (buf
, "long long int ");
7795 else if (declspecs
== signed_char_type_node
7796 || declspecs
== char_type_node
)
7797 strcat (buf
, "char ");
7799 /* Unsigned integer types. */
7801 else if (declspecs
== short_unsigned_type_node
)
7802 strcat (buf
, "unsigned short ");
7803 else if (declspecs
== unsigned_type_node
)
7804 strcat (buf
, "unsigned int ");
7805 else if (declspecs
== long_unsigned_type_node
)
7806 strcat (buf
, "unsigned long ");
7807 else if (declspecs
== long_long_unsigned_type_node
)
7808 strcat (buf
, "unsigned long long ");
7809 else if (declspecs
== unsigned_char_type_node
)
7810 strcat (buf
, "unsigned char ");
7814 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7816 if (declspecs
== float_type_node
)
7817 strcat (buf
, "float ");
7818 else if (declspecs
== double_type_node
)
7819 strcat (buf
, "double ");
7820 else if (declspecs
== long_double_type_node
)
7821 strcat (buf
, "long double ");
7825 if (TYPE_NAME (declspecs
)
7826 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7828 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7830 if (! TREE_STATIC_TEMPLATE (declspecs
))
7831 strcat (buf
, "struct ");
7832 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7836 tree chain
= protocol_list
;
7843 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7844 chain
= TREE_CHAIN (chain
);
7853 strcat (buf
, "untagged struct");
7859 if (TYPE_NAME (declspecs
)
7860 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7862 strcat (buf
, "union ");
7863 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7868 strcat (buf
, "untagged union ");
7872 if (TYPE_NAME (declspecs
)
7873 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7875 strcat (buf
, "enum ");
7876 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7881 strcat (buf
, "untagged enum ");
7885 strcat (buf
, "void ");
7890 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7895 tree chain
= protocol_list
;
7902 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7903 chain
= TREE_CHAIN (chain
);
7920 gen_declaration (atype_or_adecl
, buf
)
7921 tree atype_or_adecl
;
7926 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7928 tree declspecs
; /* "identifier_node", "record_type" */
7929 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7931 /* We have a "raw", abstract declarator (typename). */
7932 declarator
= TREE_VALUE (atype_or_adecl
);
7933 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7935 gen_declspecs (declspecs
, buf
, 1);
7939 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7946 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7947 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7949 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7950 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7951 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7952 atype
= TREE_TYPE (atype_or_adecl
);
7954 /* Assume we have a *_type node. */
7955 atype
= atype_or_adecl
;
7957 if (is_complex_decl (atype
))
7961 /* Get the declaration specifier; it is at the end of the list. */
7962 declarator
= chain
= atype
;
7964 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7965 while (is_complex_decl (chain
));
7972 declarator
= NULL_TREE
;
7975 gen_declspecs (declspecs
, buf
, 0);
7977 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7978 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7979 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7981 const char *decl_name
=
7982 (DECL_NAME (atype_or_adecl
)
7983 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7988 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7991 else if (decl_name
[0])
7994 strcat (buf
, decl_name
);
7997 else if (declarator
)
8000 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
8007 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8010 gen_method_decl (method
, buf
)
8016 if (RAW_TYPESPEC (method
) != objc_object_reference
)
8019 gen_declaration (TREE_TYPE (method
), buf
);
8023 chain
= METHOD_SEL_ARGS (method
);
8026 /* We have a chain of keyword_decls. */
8029 if (KEYWORD_KEY_NAME (chain
))
8030 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8033 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
8036 gen_declaration (TREE_TYPE (chain
), buf
);
8040 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8041 if ((chain
= TREE_CHAIN (chain
)))
8046 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
8047 strcat (buf
, ", ...");
8048 else if (METHOD_ADD_ARGS (method
))
8050 /* We have a tree list node as generate by get_parm_info. */
8051 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8053 /* Know we have a chain of parm_decls. */
8057 gen_declaration (chain
, buf
);
8058 chain
= TREE_CHAIN (chain
);
8064 /* We have a unary selector. */
8065 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8073 dump_interface (fp
, chain
)
8077 char *buf
= (char *)xmalloc (256);
8078 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8079 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8080 tree nst_methods
= CLASS_NST_METHODS (chain
);
8081 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8083 fprintf (fp
, "\n@interface %s", my_name
);
8085 if (CLASS_SUPER_NAME (chain
))
8087 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8088 fprintf (fp
, " : %s\n", super_name
);
8095 fprintf (fp
, "{\n");
8099 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8100 ivar_decls
= TREE_CHAIN (ivar_decls
);
8103 fprintf (fp
, "}\n");
8109 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8110 nst_methods
= TREE_CHAIN (nst_methods
);
8116 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8117 cls_methods
= TREE_CHAIN (cls_methods
);
8119 fprintf (fp
, "\n@end");
8122 /* Demangle function for Objective-C */
8124 objc_demangle (mangled
)
8125 const char *mangled
;
8127 char *demangled
, *cp
;
8129 if (mangled
[0] == '_' &&
8130 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8133 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8134 if (mangled
[1] == 'i')
8135 *cp
++ = '-'; /* for instance method */
8137 *cp
++ = '+'; /* for class method */
8138 *cp
++ = '['; /* opening left brace */
8139 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8140 while (*cp
&& *cp
== '_')
8141 cp
++; /* skip any initial underbars in class name */
8142 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8145 free(demangled
); /* not mangled name */
8148 if (cp
[1] == '_') /* easy case: no category name */
8150 *cp
++ = ' '; /* replace two '_' with one ' ' */
8151 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8155 *cp
++ = '('; /* less easy case: category name */
8156 cp
= strchr(cp
, '_');
8159 free(demangled
); /* not mangled name */
8163 *cp
++ = ' '; /* overwriting 1st char of method name... */
8164 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8166 while (*cp
&& *cp
== '_')
8167 cp
++; /* skip any initial underbars in method name */
8170 *cp
= ':'; /* replace remaining '_' with ':' */
8171 *cp
++ = ']'; /* closing right brace */
8172 *cp
++ = 0; /* string terminator */
8176 return mangled
; /* not an objc mangled name */
8180 objc_printable_name (decl
, kind
)
8182 int kind ATTRIBUTE_UNUSED
;
8184 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8190 /* Add the special tree codes of Objective C to the tables. */
8192 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8194 gcc_obstack_init (&util_obstack
);
8195 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8197 memcpy (tree_code_type
+ (int) LAST_CODE
,
8198 objc_tree_code_type
,
8199 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8200 memcpy (tree_code_length
+ (int) LAST_CODE
,
8201 objc_tree_code_length
,
8202 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8203 memcpy (tree_code_name
+ (int) LAST_CODE
,
8204 objc_tree_code_name
,
8205 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8207 errbuf
= (char *)xmalloc (BUFSIZE
);
8209 synth_module_prologue ();
8211 /* Change the default error function */
8212 decl_printable_name
= objc_printable_name
;
8218 struct imp_entry
*impent
;
8220 /* The internally generated initializers appear to have missing braces.
8221 Don't warn about this. */
8222 int save_warn_missing_braces
= warn_missing_braces
;
8223 warn_missing_braces
= 0;
8225 generate_forward_declaration_to_string_table ();
8227 #ifdef OBJC_PROLOGUE
8231 /* Process the static instances here because initialization of objc_symtab
8233 if (objc_static_instances
)
8234 generate_static_references ();
8236 if (implementation_context
|| class_names_chain
8237 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8238 generate_objc_symtab_decl ();
8240 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8242 implementation_context
= impent
->imp_context
;
8243 implementation_template
= impent
->imp_template
;
8245 UOBJC_CLASS_decl
= impent
->class_decl
;
8246 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8248 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8250 /* all of the following reference the string pool... */
8251 generate_ivar_lists ();
8252 generate_dispatch_tables ();
8253 generate_shared_structures ();
8257 generate_dispatch_tables ();
8258 generate_category (implementation_context
);
8262 /* If we are using an array of selectors, we must always
8263 finish up the array decl even if no selectors were used. */
8264 if (! flag_next_runtime
|| sel_ref_chain
)
8265 build_selector_translation_table ();
8268 generate_protocols ();
8270 if (implementation_context
|| class_names_chain
|| objc_static_instances
8271 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8273 /* Arrange for Objc data structures to be initialized at run time. */
8274 const char *init_name
= build_module_descriptor ();
8276 assemble_constructor (init_name
);
8279 /* Dump the class references. This forces the appropriate classes
8280 to be linked into the executable image, preserving unix archive
8281 semantics. This can be removed when we move to a more dynamically
8282 linked environment. */
8284 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8286 handle_class_ref (chain
);
8287 if (TREE_PURPOSE (chain
))
8288 generate_classref_translation_entry (chain
);
8291 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8292 handle_impent (impent
);
8294 /* Dump the string table last. */
8296 generate_strings ();
8298 if (flag_gen_declaration
)
8300 add_class (implementation_context
);
8301 dump_interface (gen_declaration_file
, implementation_context
);
8309 /* Run through the selector hash tables and print a warning for any
8310 selector which has multiple methods. */
8312 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8313 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8316 tree meth
= hsh
->key
;
8317 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8321 warning ("potential selector conflict for method `%s'",
8322 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8323 warn_with_method ("found", type
, meth
);
8324 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8325 warn_with_method ("found", type
, loop
->value
);
8328 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8329 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8332 tree meth
= hsh
->key
;
8333 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8337 warning ("potential selector conflict for method `%s'",
8338 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8339 warn_with_method ("found", type
, meth
);
8340 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8341 warn_with_method ("found", type
, loop
->value
);
8345 warn_missing_braces
= save_warn_missing_braces
;
8348 /* Subroutines of finish_objc. */
8351 generate_classref_translation_entry (chain
)
8354 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8357 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8359 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8360 expr
= build_c_cast (type
, expr
); /* cast! */
8362 name
= DECL_NAME (TREE_PURPOSE (chain
));
8364 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8366 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8367 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8369 /* The decl that is returned from start_decl is the one that we
8370 forward declared in build_class_reference. */
8371 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8372 finish_decl (decl
, expr
, NULL_TREE
);
8377 handle_class_ref (chain
)
8380 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8381 if (! flag_next_runtime
)
8384 char *string
= (char *) alloca (strlen (name
) + 30);
8387 sprintf (string
, "%sobjc_class_name_%s",
8388 (flag_next_runtime
? "." : "__"), name
);
8390 /* Make a decl for this name, so we can use its address in a tree. */
8391 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8392 DECL_EXTERNAL (decl
) = 1;
8393 TREE_PUBLIC (decl
) = 1;
8396 rest_of_decl_compilation (decl
, 0, 0, 0);
8398 /* Make following constant read-only (why not)? */
8399 readonly_data_section ();
8401 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8403 /* Align the section properly. */
8404 assemble_constant_align (exp
);
8406 /* Inform the assembler about this new external thing. */
8407 assemble_external (decl
);
8409 /* Output a constant to reference this address. */
8410 output_constant (exp
, int_size_in_bytes (string_type_node
));
8414 /* This overreliance on our assembler (i.e. lack of portability)
8415 should be dealt with at some point. The GNU strategy (above)
8416 won't work either, but it is a start. */
8417 char *string
= (char *) alloca (strlen (name
) + 30);
8418 sprintf (string
, ".reference .objc_class_name_%s", name
);
8419 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8424 handle_impent (impent
)
8425 struct imp_entry
*impent
;
8427 implementation_context
= impent
->imp_context
;
8428 implementation_template
= impent
->imp_template
;
8430 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8432 const char *class_name
=
8433 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8434 char *string
= (char *) alloca (strlen (class_name
) + 30);
8436 if (flag_next_runtime
)
8438 /* Grossly unportable.
8439 People should know better than to assume
8440 such things about assembler syntax! */
8441 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8442 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8444 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8445 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8450 sprintf (string
, "%sobjc_class_name_%s",
8451 (flag_next_runtime
? "." : "__"), class_name
);
8452 assemble_global (string
);
8453 assemble_label (string
);
8457 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8459 const char *class_name
=
8460 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8461 const char *class_super_name
=
8462 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8463 char *string
= (char *) alloca (strlen (class_name
)
8464 + strlen (class_super_name
) + 30);
8466 /* Do the same for categories. Even though no references to these
8467 symbols are generated automatically by the compiler, it gives
8468 you a handle to pull them into an archive by hand. */
8469 if (flag_next_runtime
)
8471 /* Grossly unportable. */
8472 sprintf (string
, ".objc_category_name_%s_%s=0",
8473 class_name
, class_super_name
);
8474 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8476 sprintf (string
, ".globl .objc_category_name_%s_%s",
8477 class_name
, class_super_name
);
8478 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8483 sprintf (string
, "%sobjc_category_name_%s_%s",
8484 (flag_next_runtime
? "." : "__"),
8485 class_name
, class_super_name
);
8486 assemble_global (string
);
8487 assemble_label (string
);
8498 char *buf
= (char *)xmalloc (256);
8500 { /* dump function prototypes */
8501 tree loop
= UOBJC_MODULES_decl
;
8503 fprintf (fp
, "\n\nfunction prototypes:\n");
8506 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8508 /* We have a function definition: generate prototype. */
8509 bzero (errbuf
, BUFSIZE
);
8510 gen_declaration (loop
, errbuf
);
8511 fprintf (fp
, "%s;\n", errbuf
);
8513 loop
= TREE_CHAIN (loop
);
8517 /* Dump global chains. */
8519 int i
, index
= 0, offset
= 0;
8522 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8524 if (hashlist
= nst_method_hash_list
[i
])
8526 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8530 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8531 hashlist
= hashlist
->next
;
8537 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8539 if (hashlist
= cls_method_hash_list
[i
])
8541 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8545 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8546 hashlist
= hashlist
->next
;
8552 fprintf (fp
, "\nsel_refdef_chain:\n");
8553 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8555 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8556 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8558 /* add one for the '\0' character */
8559 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8562 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8568 print_lang_statistics ()
8573 ggc_mark_imp_list (arg
)
8576 struct imp_entry
*impent
;
8578 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8580 ggc_mark_tree (impent
->imp_context
);
8581 ggc_mark_tree (impent
->imp_template
);
8582 ggc_mark_tree (impent
->class_decl
);
8583 ggc_mark_tree (impent
->meta_decl
);
8588 ggc_mark_hash_table (arg
)
8591 hash
*hash_table
= *(hash
**)arg
;
8596 if (hash_table
== NULL
)
8598 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8599 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8601 ggc_mark_tree (hst
->key
);
8602 for (list
= hst
->list
; list
; list
= list
->next
)
8603 ggc_mark_tree (list
->value
);
8607 /* Add GC roots for variables local to this file. */
8609 objc_act_parse_init ()
8611 ggc_add_tree_root (&objc_ellipsis_node
, 1);
8612 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8613 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8614 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8615 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);