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));
345 /*** Private Interface (data) ***/
347 /* Reserved tag definitions. */
350 #define TAG_OBJECT "objc_object"
351 #define TAG_CLASS "objc_class"
352 #define TAG_SUPER "objc_super"
353 #define TAG_SELECTOR "objc_selector"
355 #define UTAG_CLASS "_objc_class"
356 #define UTAG_IVAR "_objc_ivar"
357 #define UTAG_IVAR_LIST "_objc_ivar_list"
358 #define UTAG_METHOD "_objc_method"
359 #define UTAG_METHOD_LIST "_objc_method_list"
360 #define UTAG_CATEGORY "_objc_category"
361 #define UTAG_MODULE "_objc_module"
362 #define UTAG_STATICS "_objc_statics"
363 #define UTAG_SYMTAB "_objc_symtab"
364 #define UTAG_SUPER "_objc_super"
365 #define UTAG_SELECTOR "_objc_selector"
367 #define UTAG_PROTOCOL "_objc_protocol"
368 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
369 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
370 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
372 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
373 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
375 static const char *TAG_GETCLASS
;
376 static const char *TAG_GETMETACLASS
;
377 static const char *TAG_MSGSEND
;
378 static const char *TAG_MSGSENDSUPER
;
379 static const char *TAG_EXECCLASS
;
381 /* Set by `continue_class' and checked by `is_public'. */
383 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
384 #define TYPED_OBJECT(type) \
385 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
387 tree objc_ellipsis_node
;
392 OCTI_STATIC_NST_DECL
,
398 OCTI_UMSG_SUPER_DECL
,
400 OCTI_GET_MCLASS_DECL
,
414 OCTI_CLS_NAMES_CHAIN
,
415 OCTI_METH_VAR_NAMES_CHAIN
,
416 OCTI_METH_VAR_TYPES_CHAIN
,
438 OCTI_UUCLS_SUPER_REF
,
456 static tree objc_global_trees
[OCTI_MAX
];
458 /* List of classes with list of their static instances. */
459 #define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
461 /* The declaration of the array administrating the static instances. */
462 #define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
464 /* Some commonly used instances of "identifier_node". */
466 #define self_id objc_global_trees[OCTI_SELF_ID]
467 #define ucmd_id objc_global_trees[OCTI_UCMD_ID]
468 #define unused_list objc_global_trees[OCTI_UNUSED_LIST]
470 #define self_decl objc_global_trees[OCTI_SELF_DECL]
471 #define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
472 #define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
473 #define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
474 #define objc_get_meta_class_decl \
475 objc_global_trees[OCTI_GET_MCLASS_DECL]
477 #define super_type objc_global_trees[OCTI_SUPER_TYPE]
478 #define selector_type objc_global_trees[OCTI_SEL_TYPE]
479 #define id_type objc_global_trees[OCTI_ID_TYPE]
480 #define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
481 #define instance_type objc_global_trees[OCTI_NST_TYPE]
482 #define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
484 /* Type checking macros. */
486 #define IS_ID(TYPE) \
487 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
488 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
489 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
490 #define IS_SUPER(TYPE) \
491 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
493 #define class_chain objc_global_trees[OCTI_CLS_CHAIN]
494 #define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
495 #define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
496 #define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
498 /* Chains to manage selectors that are referenced and defined in the
501 #define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
502 #define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
504 /* Chains to manage uniquing of strings. */
506 #define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
507 #define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
508 #define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
510 /* Hash tables to manage the global pool of method prototypes. */
512 static hash
*nst_method_hash_list
= 0;
513 static hash
*cls_method_hash_list
= 0;
515 /* Backend data declarations. */
517 #define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
518 #define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
519 #define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
520 #define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
521 #define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
522 #define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
523 #define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
524 #define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
525 #define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
526 #define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
528 /* The following are used when compiling a class implementation.
529 implementation_template will normally be an interface, however if
530 none exists this will be equal to implementation_context...it is
531 set in start_class. */
533 #define implementation_context objc_global_trees[OCTI_IMPL_CTX]
534 #define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
538 struct imp_entry
*next
;
541 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
542 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
545 static void handle_impent
PARAMS ((struct imp_entry
*));
547 static struct imp_entry
*imp_list
= 0;
548 static int imp_count
= 0; /* `@implementation' */
549 static int cat_count
= 0; /* `@category' */
551 #define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
552 #define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
553 #define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
554 #define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
555 #define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
556 #define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
557 #define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
559 #define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
560 #define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
561 #define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
562 #define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
563 #define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
564 #define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
566 #define objc_object_id objc_global_trees[OCTI_OBJ_ID]
567 #define objc_class_id objc_global_trees[OCTI_CLS_ID]
568 #define objc_id_id objc_global_trees[OCTI_ID_ID]
569 #define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
570 #define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
571 #define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
573 #define method_context objc_global_trees[OCTI_METH_CTX]
574 static int method_slot
= 0; /* Used by start_method_def, */
578 static char *errbuf
; /* Buffer for error diagnostics */
580 /* Data imported from tree.c. */
582 extern enum debug_info_type write_symbols
;
584 /* Data imported from toplev.c. */
586 extern const char *dump_base_name
;
588 /* Generate code for GNU or NeXT runtime environment. */
590 #ifdef NEXT_OBJC_RUNTIME
591 int flag_next_runtime
= 1;
593 int flag_next_runtime
= 0;
596 int flag_typed_selectors
;
598 /* Open and close the file for outputting class declarations, if requested. */
600 int flag_gen_declaration
= 0;
602 FILE *gen_declaration_file
;
604 /* Warn if multiple methods are seen for the same selector, but with
605 different argument types. */
607 int warn_selector
= 0;
609 /* Warn if methods required by a protocol are not implemented in the
610 class adopting it. When turned off, methods inherited to that
611 class are also considered implemented */
613 int flag_warn_protocol
= 1;
615 /* Tells "encode_pointer/encode_aggregate" whether we are generating
616 type descriptors for instance variables (as opposed to methods).
617 Type descriptors for instance variables contain more information
618 than methods (for static typing and embedded structures). This
619 was added to support features being planned for dbkit2. */
621 static int generating_instance_variables
= 0;
623 /* Tells the compiler that this is a special run. Do not perform
624 any compiling, instead we are to test some platform dependent
625 features and output a C header file with appropriate definitions. */
627 static int print_struct_values
= 0;
629 /* Some platforms pass small structures through registers versus through
630 an invisible pointer. Determine at what size structure is the
631 transition point between the two possibilities. */
634 generate_struct_by_value_array ()
637 tree field_decl
, field_decl_chain
;
639 int aggregate_in_mem
[32];
642 /* Presumbaly no platform passes 32 byte structures in a register. */
643 for (i
= 1; i
< 32; i
++)
647 /* Create an unnamed struct that has `i' character components */
648 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
650 strcpy (buffer
, "c1");
651 field_decl
= create_builtin_decl (FIELD_DECL
,
654 field_decl_chain
= field_decl
;
656 for (j
= 1; j
< i
; j
++)
658 sprintf (buffer
, "c%d", j
+ 1);
659 field_decl
= create_builtin_decl (FIELD_DECL
,
662 chainon (field_decl_chain
, field_decl
);
664 finish_struct (type
, field_decl_chain
, NULL_TREE
);
666 aggregate_in_mem
[i
] = aggregate_value_p (type
);
667 if (!aggregate_in_mem
[i
])
671 /* We found some structures that are returned in registers instead of memory
672 so output the necessary data. */
675 for (i
= 31; i
>= 0; i
--)
676 if (!aggregate_in_mem
[i
])
678 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
680 /* The first member of the structure is always 0 because we don't handle
681 structures with 0 members */
682 printf ("static int struct_forward_array[] = {\n 0");
684 for (j
= 1; j
<= i
; j
++)
685 printf (", %d", aggregate_in_mem
[j
]);
700 cpp_reader_init (&parse_in
);
701 parse_in
.opts
= &parse_options
;
702 cpp_options_init (&parse_options
);
710 /* The beginning of the file is a new line; check for #.
711 With luck, we discover the real source file's name from that
712 and put it in input_filename. */
713 ungetc (check_newline (), finput
);
719 /* The line number can be -1 if we had -g3 and the input file
720 had a directive specifying line 0. But we want predefined
721 functions to have a line number of 0, not -1. */
725 /* If gen_declaration desired, open the output file. */
726 if (flag_gen_declaration
)
728 register char * const dumpname
= concat (dumpname
, ".decl", NULL
);
729 gen_declaration_file
= fopen (dumpname
, "w");
730 if (gen_declaration_file
== 0)
731 pfatal_with_name (dumpname
);
735 if (flag_next_runtime
)
737 TAG_GETCLASS
= "objc_getClass";
738 TAG_GETMETACLASS
= "objc_getMetaClass";
739 TAG_MSGSEND
= "objc_msgSend";
740 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
741 TAG_EXECCLASS
= "__objc_execClass";
745 TAG_GETCLASS
= "objc_get_class";
746 TAG_GETMETACLASS
= "objc_get_meta_class";
747 TAG_MSGSEND
= "objc_msg_lookup";
748 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
749 TAG_EXECCLASS
= "__objc_exec_class";
750 flag_typed_selectors
= 1;
753 objc_ellipsis_node
= make_node (ERROR_MARK
);
755 if (doing_objc_thang
)
758 if (print_struct_values
)
759 generate_struct_by_value_array ();
761 objc_act_parse_init ();
768 fatal ("Objective-C text in C source file");
774 if (doing_objc_thang
)
775 finish_objc (); /* Objective-C finalization */
777 if (gen_declaration_file
)
778 fclose (gen_declaration_file
);
793 lang_decode_option (argc
, argv
)
797 const char *p
= argv
[0];
798 if (!strcmp (p
, "-lang-objc"))
799 doing_objc_thang
= 1;
800 else if (!strcmp (p
, "-gen-decls"))
801 flag_gen_declaration
= 1;
802 else if (!strcmp (p
, "-Wselector"))
804 else if (!strcmp (p
, "-Wno-selector"))
806 else if (!strcmp (p
, "-Wprotocol"))
807 flag_warn_protocol
= 1;
808 else if (!strcmp (p
, "-Wno-protocol"))
809 flag_warn_protocol
= 0;
810 else if (!strcmp (p
, "-fgnu-runtime"))
811 flag_next_runtime
= 0;
812 else if (!strcmp (p
, "-fno-next-runtime"))
813 flag_next_runtime
= 0;
814 else if (!strcmp (p
, "-fno-gnu-runtime"))
815 flag_next_runtime
= 1;
816 else if (!strcmp (p
, "-fnext-runtime"))
817 flag_next_runtime
= 1;
818 else if (!strcmp (p
, "-print-objc-runtime-info"))
819 print_struct_values
= 1;
821 return c_decode_option (argc
, argv
);
826 /* used by print-tree.c */
829 lang_print_xnode (file
, node
, indent
)
830 FILE *file ATTRIBUTE_UNUSED
;
831 tree node ATTRIBUTE_UNUSED
;
832 int indent ATTRIBUTE_UNUSED
;
838 define_decl (declarator
, declspecs
)
842 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
843 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
847 /* Return 1 if LHS and RHS are compatible types for assignment or
848 various other operations. Return 0 if they are incompatible, and
849 return -1 if we choose to not decide. When the operation is
850 REFLEXIVE, check for compatibility in either direction.
852 For statically typed objects, an assignment of the form `a' = `b'
856 `a' and `b' are the same class type, or
857 `a' and `b' are of class types A and B such that B is a descendant of A. */
860 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
864 if (doing_objc_thang
)
865 return objc_comptypes (lhs
, rhs
, reflexive
);
870 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
878 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
880 p
= TREE_VALUE (rproto
);
882 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
884 if ((fnd
= lookup_method (class_meth
885 ? PROTOCOL_CLS_METHODS (p
)
886 : PROTOCOL_NST_METHODS (p
), sel_name
)))
888 else if (PROTOCOL_LIST (p
))
889 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
890 sel_name
, class_meth
);
894 ; /* An identifier...if we could not find a protocol. */
905 lookup_protocol_in_reflist (rproto_list
, lproto
)
911 /* Make sure the protocol is support by the object on the rhs. */
912 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
915 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
917 p
= TREE_VALUE (rproto
);
919 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
924 else if (PROTOCOL_LIST (p
))
925 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
934 ; /* An identifier...if we could not find a protocol. */
940 /* Return 1 if LHS and RHS are compatible types for assignment
941 or various other operations. Return 0 if they are incompatible,
942 and return -1 if we choose to not decide. When the operation
943 is REFLEXIVE, check for compatibility in either direction. */
946 objc_comptypes (lhs
, rhs
, reflexive
)
951 /* New clause for protocols. */
953 if (TREE_CODE (lhs
) == POINTER_TYPE
954 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
955 && TREE_CODE (rhs
) == POINTER_TYPE
956 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
958 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
959 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
963 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
964 tree rproto
, rproto_list
;
969 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
971 /* Make sure the protocol is supported by the object
973 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
975 p
= TREE_VALUE (lproto
);
976 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
979 warning ("object does not conform to the `%s' protocol",
980 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
983 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
985 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
988 /* Make sure the protocol is supported by the object
990 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
992 p
= TREE_VALUE (lproto
);
994 rinter
= lookup_interface (rname
);
996 while (rinter
&& !rproto
)
1000 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
1001 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
1003 /* Check for protocols adopted by categories. */
1004 cat
= CLASS_CATEGORY_LIST (rinter
);
1005 while (cat
&& !rproto
)
1007 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
1008 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
1010 cat
= CLASS_CATEGORY_LIST (cat
);
1013 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
1017 warning ("class `%s' does not implement the `%s' protocol",
1018 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
1019 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1023 /* May change...based on whether there was any mismatch */
1026 else if (rhs_is_proto
)
1027 /* Lhs is not a protocol...warn if it is statically typed */
1028 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
1031 /* Defer to comptypes .*/
1035 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
1036 ; /* Fall thru. This is the case we have been handling all along */
1038 /* Defer to comptypes. */
1041 /* `id' = `<class> *', `<class> *' = `id' */
1043 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
1044 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
1047 /* `id' = `Class', `Class' = `id' */
1049 else if ((TYPE_NAME (lhs
) == objc_object_id
1050 && TYPE_NAME (rhs
) == objc_class_id
)
1051 || (TYPE_NAME (lhs
) == objc_class_id
1052 && TYPE_NAME (rhs
) == objc_object_id
))
1055 /* `<class> *' = `<class> *' */
1057 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1059 tree lname
= TYPE_NAME (lhs
);
1060 tree rname
= TYPE_NAME (rhs
);
1066 /* If the left hand side is a super class of the right hand side,
1068 for (inter
= lookup_interface (rname
); inter
;
1069 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1070 if (lname
== CLASS_SUPER_NAME (inter
))
1073 /* Allow the reverse when reflexive. */
1075 for (inter
= lookup_interface (lname
); inter
;
1076 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1077 if (rname
== CLASS_SUPER_NAME (inter
))
1083 /* Defer to comptypes. */
1087 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
1090 objc_check_decl (decl
)
1093 tree type
= TREE_TYPE (decl
);
1095 if (TREE_CODE (type
) == RECORD_TYPE
1096 && TREE_STATIC_TEMPLATE (type
)
1097 && type
!= constant_string_type
)
1099 error_with_decl (decl
, "`%s' cannot be statically allocated");
1100 fatal ("statically allocated objects not supported");
1105 maybe_objc_check_decl (decl
)
1108 if (doing_objc_thang
)
1109 objc_check_decl (decl
);
1112 /* Implement static typing. At this point, we know we have an interface. */
1115 get_static_reference (interface
, protocols
)
1119 tree type
= xref_tag (RECORD_TYPE
, interface
);
1123 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1125 t
= copy_node (type
);
1126 TYPE_BINFO (t
) = make_tree_vec (2);
1128 /* Add this type to the chain of variants of TYPE. */
1129 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1130 TYPE_NEXT_VARIANT (m
) = t
;
1132 /* Look up protocols and install in lang specific list. */
1133 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1135 /* This forces a new pointer type to be created later
1136 (in build_pointer_type)...so that the new template
1137 we just created will actually be used...what a hack! */
1138 if (TYPE_POINTER_TO (t
))
1139 TYPE_POINTER_TO (t
) = 0;
1148 get_object_reference (protocols
)
1151 tree type_decl
= lookup_name (objc_id_id
);
1154 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1156 type
= TREE_TYPE (type_decl
);
1157 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1158 warning ("Unexpected type for `id' (%s)",
1159 gen_declaration (type
, errbuf
));
1162 fatal ("Undefined type `id', please import <objc/objc.h>");
1164 /* This clause creates a new pointer type that is qualified with
1165 the protocol specification...this info is used later to do more
1166 elaborate type checking. */
1170 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1172 t
= copy_node (type
);
1173 TYPE_BINFO (t
) = make_tree_vec (2);
1175 /* Add this type to the chain of variants of TYPE. */
1176 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1177 TYPE_NEXT_VARIANT (m
) = t
;
1179 /* Look up protocols...and install in lang specific list */
1180 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1182 /* This forces a new pointer type to be created later
1183 (in build_pointer_type)...so that the new template
1184 we just created will actually be used...what a hack! */
1185 if (TYPE_POINTER_TO (t
))
1186 TYPE_POINTER_TO (t
) = NULL
;
1194 lookup_and_install_protocols (protocols
)
1199 tree return_value
= protocols
;
1201 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1203 tree ident
= TREE_VALUE (proto
);
1204 tree p
= lookup_protocol (ident
);
1208 error ("Cannot find protocol declaration for `%s'",
1209 IDENTIFIER_POINTER (ident
));
1211 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1213 return_value
= TREE_CHAIN (proto
);
1217 /* Replace identifier with actual protocol node. */
1218 TREE_VALUE (proto
) = p
;
1223 return return_value
;
1226 /* Create and push a decl for a built-in external variable or field NAME.
1228 TYPE is its data type. */
1231 create_builtin_decl (code
, type
, name
)
1232 enum tree_code code
;
1236 tree decl
= build_decl (code
, get_identifier (name
), type
);
1238 if (code
== VAR_DECL
)
1240 TREE_STATIC (decl
) = 1;
1241 make_decl_rtl (decl
, 0, 1);
1245 DECL_ARTIFICIAL (decl
) = 1;
1249 /* Purpose: "play" parser, creating/installing representations
1250 of the declarations that are required by Objective-C.
1254 type_spec--------->sc_spec
1255 (tree_list) (tree_list)
1258 identifier_node identifier_node */
1261 synth_module_prologue ()
1266 /* Defined in `objc.h' */
1267 objc_object_id
= get_identifier (TAG_OBJECT
);
1269 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1271 id_type
= build_pointer_type (objc_object_reference
);
1273 objc_id_id
= get_identifier (TYPE_ID
);
1274 objc_class_id
= get_identifier (TAG_CLASS
);
1276 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1277 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1278 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1280 /* Declare type of selector-objects that represent an operation name. */
1282 #ifdef OBJC_INT_SELECTORS
1283 /* `unsigned int' */
1284 selector_type
= unsigned_type_node
;
1286 /* `struct objc_selector *' */
1288 = build_pointer_type (xref_tag (RECORD_TYPE
,
1289 get_identifier (TAG_SELECTOR
)));
1290 #endif /* not OBJC_INT_SELECTORS */
1292 /* Forward declare type, or else the prototype for msgSendSuper will
1295 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1296 get_identifier (TAG_SUPER
)));
1299 /* id objc_msgSend (id, SEL, ...); */
1302 = build_function_type (id_type
,
1303 tree_cons (NULL_TREE
, id_type
,
1304 tree_cons (NULL_TREE
, selector_type
,
1307 if (! flag_next_runtime
)
1309 umsg_decl
= build_decl (FUNCTION_DECL
,
1310 get_identifier (TAG_MSGSEND
), temp_type
);
1311 DECL_EXTERNAL (umsg_decl
) = 1;
1312 TREE_PUBLIC (umsg_decl
) = 1;
1313 DECL_INLINE (umsg_decl
) = 1;
1314 DECL_ARTIFICIAL (umsg_decl
) = 1;
1316 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1317 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1319 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1320 pushdecl (umsg_decl
);
1323 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1325 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1328 = build_function_type (id_type
,
1329 tree_cons (NULL_TREE
, super_p
,
1330 tree_cons (NULL_TREE
, selector_type
,
1333 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1334 temp_type
, 0, NOT_BUILT_IN
, 0);
1336 /* id objc_getClass (const char *); */
1338 temp_type
= build_function_type (id_type
,
1339 tree_cons (NULL_TREE
,
1340 const_string_type_node
,
1341 tree_cons (NULL_TREE
, void_type_node
,
1345 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1347 /* id objc_getMetaClass (const char *); */
1349 objc_get_meta_class_decl
1350 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1352 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1354 if (! flag_next_runtime
)
1356 if (flag_typed_selectors
)
1358 /* Suppress outputting debug symbols, because
1359 dbxout_init hasn'r been called yet. */
1360 enum debug_info_type save_write_symbols
= write_symbols
;
1361 write_symbols
= NO_DEBUG
;
1363 build_selector_template ();
1364 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1366 write_symbols
= save_write_symbols
;
1369 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1371 layout_type (temp_type
);
1372 UOBJC_SELECTOR_TABLE_decl
1373 = create_builtin_decl (VAR_DECL
, temp_type
,
1374 "_OBJC_SELECTOR_TABLE");
1376 /* Avoid warning when not sending messages. */
1377 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1380 generate_forward_declaration_to_string_table ();
1382 /* Forward declare constant_string_id and constant_string_type. */
1383 constant_string_id
= get_identifier (STRING_OBJECT_CLASS_NAME
);
1384 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1387 /* Custom build_string which sets TREE_TYPE! */
1390 my_build_string (len
, str
)
1395 tree a_string
= build_string (len
, str
);
1397 /* Some code from combine_strings, which is local to c-parse.y. */
1398 if (TREE_TYPE (a_string
) == int_array_type_node
)
1401 TREE_TYPE (a_string
)
1402 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1403 build_index_type (build_int_2 (len
- 1, 0)));
1405 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1406 TREE_STATIC (a_string
) = 1;
1411 /* Return a newly constructed OBJC_STRING_CST node whose value is
1412 the LEN characters at STR.
1413 The TREE_TYPE is not initialized. */
1416 build_objc_string (len
, str
)
1420 tree s
= build_string (len
, str
);
1422 TREE_SET_CODE (s
, OBJC_STRING_CST
);
1426 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1427 NXConstanString which points at the concatenation of those strings.
1428 We place the string object in the __string_objects section of the
1429 __OBJC segment. The Objective-C runtime will initialize the isa
1430 pointers of the string objects to point at the NXConstandString class
1434 build_objc_string_object (strings
)
1437 tree string
, initlist
, constructor
;
1440 if (!doing_objc_thang
)
1443 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1445 error ("Cannot find interface declaration for `%s'",
1446 IDENTIFIER_POINTER (constant_string_id
));
1447 return error_mark_node
;
1450 add_class_reference (constant_string_id
);
1452 /* Combine_strings will work for OBJC_STRING_CST's too. */
1453 string
= combine_strings (strings
);
1454 TREE_SET_CODE (string
, STRING_CST
);
1455 length
= TREE_STRING_LENGTH (string
) - 1;
1457 /* & ((NXConstantString) {0, string, length}) */
1459 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1461 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1463 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1464 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1466 if (!flag_next_runtime
)
1469 = objc_add_static_instance (constructor
, constant_string_type
);
1472 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1475 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1478 objc_add_static_instance (constructor
, class_decl
)
1479 tree constructor
, class_decl
;
1481 static int num_static_inst
;
1485 /* Find the list of static instances for the CLASS_DECL. Create one if
1487 for (chain
= &objc_static_instances
;
1488 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1489 chain
= &TREE_CHAIN (*chain
));
1492 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1493 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1496 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1497 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1498 DECL_COMMON (decl
) = 1;
1499 TREE_STATIC (decl
) = 1;
1500 DECL_ARTIFICIAL (decl
) = 1;
1501 pushdecl_top_level (decl
);
1502 rest_of_decl_compilation (decl
, 0, 1, 0);
1504 /* Do this here so it gets output later instead of possibly
1505 inside something else we are writing. */
1506 DECL_INITIAL (decl
) = constructor
;
1508 /* Add the DECL to the head of this CLASS' list. */
1509 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1514 /* Build a static constant CONSTRUCTOR
1515 with type TYPE and elements ELTS. */
1518 build_constructor (type
, elts
)
1521 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1523 TREE_CONSTANT (constructor
) = 1;
1524 TREE_STATIC (constructor
) = 1;
1525 TREE_READONLY (constructor
) = 1;
1530 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1532 /* Predefine the following data type:
1540 void *defs[cls_def_cnt + cat_def_cnt];
1544 build_objc_symtab_template ()
1546 tree field_decl
, field_decl_chain
, index
;
1548 objc_symtab_template
1549 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1551 /* long sel_ref_cnt; */
1553 field_decl
= create_builtin_decl (FIELD_DECL
,
1554 long_integer_type_node
,
1556 field_decl_chain
= field_decl
;
1560 field_decl
= create_builtin_decl (FIELD_DECL
,
1561 build_pointer_type (selector_type
),
1563 chainon (field_decl_chain
, field_decl
);
1565 /* short cls_def_cnt; */
1567 field_decl
= create_builtin_decl (FIELD_DECL
,
1568 short_integer_type_node
,
1570 chainon (field_decl_chain
, field_decl
);
1572 /* short cat_def_cnt; */
1574 field_decl
= create_builtin_decl (FIELD_DECL
,
1575 short_integer_type_node
,
1577 chainon (field_decl_chain
, field_decl
);
1579 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1581 if (!flag_next_runtime
)
1582 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1584 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1585 imp_count
== 0 && cat_count
== 0
1587 field_decl
= create_builtin_decl (FIELD_DECL
,
1588 build_array_type (ptr_type_node
, index
),
1590 chainon (field_decl_chain
, field_decl
);
1592 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1595 /* Create the initial value for the `defs' field of _objc_symtab.
1596 This is a CONSTRUCTOR. */
1599 init_def_list (type
)
1602 tree expr
, initlist
= NULL_TREE
;
1603 struct imp_entry
*impent
;
1606 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1608 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1610 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1611 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1616 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1618 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1620 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1621 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1625 if (!flag_next_runtime
)
1627 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1630 if (static_instances_decl
)
1631 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1633 expr
= build_int_2 (0, 0);
1635 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1638 return build_constructor (type
, nreverse (initlist
));
1641 /* Construct the initial value for all of _objc_symtab. */
1644 init_objc_symtab (type
)
1649 /* sel_ref_cnt = { ..., 5, ... } */
1651 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1653 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1655 if (flag_next_runtime
|| ! sel_ref_chain
)
1656 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1658 initlist
= tree_cons (NULL_TREE
,
1659 build_unary_op (ADDR_EXPR
,
1660 UOBJC_SELECTOR_TABLE_decl
, 1),
1663 /* cls_def_cnt = { ..., 5, ... } */
1665 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1667 /* cat_def_cnt = { ..., 5, ... } */
1669 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1671 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1673 if (imp_count
|| cat_count
|| static_instances_decl
)
1676 tree field
= TYPE_FIELDS (type
);
1677 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1679 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1683 return build_constructor (type
, nreverse (initlist
));
1686 /* Push forward-declarations of all the categories
1687 so that init_def_list can use them in a CONSTRUCTOR. */
1690 forward_declare_categories ()
1692 struct imp_entry
*impent
;
1693 tree sav
= implementation_context
;
1695 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1697 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1699 /* Set an invisible arg to synth_id_with_class_suffix. */
1700 implementation_context
= impent
->imp_context
;
1702 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1703 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1706 implementation_context
= sav
;
1709 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1710 and initialized appropriately. */
1713 generate_objc_symtab_decl ()
1717 if (!objc_category_template
)
1718 build_category_template ();
1720 /* forward declare categories */
1722 forward_declare_categories ();
1724 if (!objc_symtab_template
)
1725 build_objc_symtab_template ();
1727 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1729 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1730 tree_cons (NULL_TREE
,
1731 objc_symtab_template
, sc_spec
),
1733 NULL_TREE
, NULL_TREE
);
1735 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1736 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1737 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1738 finish_decl (UOBJC_SYMBOLS_decl
,
1739 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1744 init_module_descriptor (type
)
1747 tree initlist
, expr
;
1749 /* version = { 1, ... } */
1751 expr
= build_int_2 (OBJC_VERSION
, 0);
1752 initlist
= build_tree_list (NULL_TREE
, expr
);
1754 /* size = { ..., sizeof (struct objc_module), ... } */
1756 expr
= size_in_bytes (objc_module_template
);
1757 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1759 /* name = { ..., "foo.m", ... } */
1761 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1762 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1764 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1766 if (UOBJC_SYMBOLS_decl
)
1767 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1769 expr
= build_int_2 (0, 0);
1770 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1772 return build_constructor (type
, nreverse (initlist
));
1775 /* Write out the data structures to describe Objective C classes defined.
1776 If appropriate, compile and output a setup function to initialize them.
1777 Return a string which is the name of a function to call to initialize
1778 the Objective C data structures for this file (and perhaps for other files
1781 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1784 build_module_descriptor ()
1786 tree decl_specs
, field_decl
, field_decl_chain
;
1788 objc_module_template
1789 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1793 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1794 field_decl
= get_identifier ("version");
1796 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1797 field_decl_chain
= field_decl
;
1801 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1802 field_decl
= get_identifier ("size");
1804 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1805 chainon (field_decl_chain
, field_decl
);
1809 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1810 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1812 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1813 chainon (field_decl_chain
, field_decl
);
1815 /* struct objc_symtab *symtab; */
1817 decl_specs
= get_identifier (UTAG_SYMTAB
);
1818 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1819 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1821 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1822 chainon (field_decl_chain
, field_decl
);
1824 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1826 /* Create an instance of "objc_module". */
1828 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1829 build_tree_list (NULL_TREE
,
1830 ridpointers
[(int) RID_STATIC
]));
1832 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1833 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1835 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1836 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1837 finish_decl (UOBJC_MODULES_decl
,
1838 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1841 /* Mark the decl to avoid "defined but not used" warning. */
1842 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1844 /* Generate a constructor call for the module descriptor.
1845 This code was generated by reading the grammar rules
1846 of c-parse.in; Therefore, it may not be the most efficient
1847 way of generating the requisite code. */
1849 if (flag_next_runtime
)
1853 tree parms
, function_decl
, decelerator
, void_list_node_1
;
1855 tree init_function_name
= get_file_function_name ('I');
1857 /* Declare void __objc_execClass (void *); */
1859 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1861 = build_function_type (void_type_node
,
1862 tree_cons (NULL_TREE
, ptr_type_node
,
1864 function_decl
= build_decl (FUNCTION_DECL
,
1865 get_identifier (TAG_EXECCLASS
),
1867 DECL_EXTERNAL (function_decl
) = 1;
1868 DECL_ARTIFICIAL (function_decl
) = 1;
1869 TREE_PUBLIC (function_decl
) = 1;
1871 pushdecl (function_decl
);
1872 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1875 = build_tree_list (NULL_TREE
,
1876 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1877 decelerator
= build_function_call (function_decl
, parms
);
1879 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1881 start_function (void_list_node_1
,
1882 build_parse_node (CALL_EXPR
, init_function_name
,
1883 /* This has the format of the output
1884 of get_parm_info. */
1885 tree_cons (NULL_TREE
, NULL_TREE
,
1888 NULL_TREE
, NULL_TREE
);
1889 #if 0 /* This should be turned back on later
1890 for the systems where collect is not needed. */
1891 /* Make these functions nonglobal
1892 so each file can use the same name. */
1893 TREE_PUBLIC (current_function_decl
) = 0;
1895 TREE_USED (current_function_decl
) = 1;
1896 store_parm_decls ();
1898 assemble_external (function_decl
);
1899 c_expand_expr_stmt (decelerator
);
1901 TREE_PUBLIC (current_function_decl
) = 1;
1903 function_decl
= current_function_decl
;
1904 finish_function (0);
1906 /* Return the name of the constructor function. */
1907 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1911 /* extern const char _OBJC_STRINGS[]; */
1914 generate_forward_declaration_to_string_table ()
1916 tree sc_spec
, decl_specs
, expr_decl
;
1918 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1919 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1922 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1924 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1927 /* Return the DECL of the string IDENT in the SECTION. */
1930 get_objc_string_decl (ident
, section
)
1932 enum string_section section
;
1936 if (section
== class_names
)
1937 chain
= class_names_chain
;
1938 else if (section
== meth_var_names
)
1939 chain
= meth_var_names_chain
;
1940 else if (section
== meth_var_types
)
1941 chain
= meth_var_types_chain
;
1945 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1946 if (TREE_VALUE (chain
) == ident
)
1947 return (TREE_PURPOSE (chain
));
1953 /* Output references to all statically allocated objects. Return the DECL
1954 for the array built. */
1957 generate_static_references ()
1959 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1960 tree class_name
, class, decl
, initlist
;
1961 tree cl_chain
, in_chain
, type
;
1962 int num_inst
, num_class
;
1965 if (flag_next_runtime
)
1968 for (cl_chain
= objc_static_instances
, num_class
= 0;
1969 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1971 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1972 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1974 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1975 ident
= get_identifier (buf
);
1977 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1978 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1979 build_tree_list (NULL_TREE
,
1980 ridpointers
[(int) RID_STATIC
]));
1981 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1982 DECL_CONTEXT (decl
) = 0;
1983 DECL_ARTIFICIAL (decl
) = 1;
1985 /* Output {class_name, ...}. */
1986 class = TREE_VALUE (cl_chain
);
1987 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1988 initlist
= build_tree_list (NULL_TREE
,
1989 build_unary_op (ADDR_EXPR
, class_name
, 1));
1991 /* Output {..., instance, ...}. */
1992 for (in_chain
= TREE_PURPOSE (cl_chain
);
1993 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1995 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1996 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1999 /* Output {..., NULL}. */
2000 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2002 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
2003 finish_decl (decl
, expr
, NULL_TREE
);
2004 TREE_USED (decl
) = 1;
2006 type
= build_array_type (build_pointer_type (void_type_node
), 0);
2007 decl
= build_decl (VAR_DECL
, ident
, type
);
2008 make_decl_rtl (decl
, 0, 1);
2009 TREE_USED (decl
) = 1;
2011 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
2014 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
2015 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
2016 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
2017 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
2018 build_tree_list (NULL_TREE
,
2019 ridpointers
[(int) RID_STATIC
]));
2020 static_instances_decl
2021 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
2022 TREE_USED (static_instances_decl
) = 1;
2023 DECL_CONTEXT (static_instances_decl
) = 0;
2024 DECL_ARTIFICIAL (static_instances_decl
) = 1;
2025 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
2027 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
2030 /* Output all strings. */
2035 tree sc_spec
, decl_specs
, expr_decl
;
2036 tree chain
, string_expr
;
2039 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2041 string
= TREE_VALUE (chain
);
2042 decl
= TREE_PURPOSE (chain
);
2044 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2045 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2046 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2047 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2048 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2049 IDENTIFIER_POINTER (string
));
2050 finish_decl (decl
, string_expr
, NULL_TREE
);
2053 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2055 string
= TREE_VALUE (chain
);
2056 decl
= TREE_PURPOSE (chain
);
2058 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2059 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2060 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2061 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2062 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2063 IDENTIFIER_POINTER (string
));
2064 finish_decl (decl
, string_expr
, NULL_TREE
);
2067 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2069 string
= TREE_VALUE (chain
);
2070 decl
= TREE_PURPOSE (chain
);
2072 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2073 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
2074 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
2075 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2076 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2077 IDENTIFIER_POINTER (string
));
2078 finish_decl (decl
, string_expr
, NULL_TREE
);
2083 build_selector_reference_decl ()
2089 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2091 ident
= get_identifier (buf
);
2093 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2094 DECL_EXTERNAL (decl
) = 1;
2095 TREE_PUBLIC (decl
) = 1;
2096 TREE_USED (decl
) = 1;
2097 TREE_READONLY (decl
) = 1;
2098 DECL_ARTIFICIAL (decl
) = 1;
2099 DECL_CONTEXT (decl
) = 0;
2101 make_decl_rtl (decl
, 0, 1);
2102 pushdecl_top_level (decl
);
2107 /* Just a handy wrapper for add_objc_string. */
2110 build_selector (ident
)
2113 tree expr
= add_objc_string (ident
, meth_var_names
);
2114 if (flag_typed_selectors
)
2117 return build_c_cast (selector_type
, expr
); /* cast! */
2120 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2121 The cast stops the compiler from issuing the following message:
2122 grok.m: warning: initialization of non-const * pointer from const *
2123 grok.m: warning: initialization between incompatible pointer types. */
2127 build_msg_pool_reference (offset
)
2130 tree expr
= build_int_2 (offset
, 0);
2133 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2134 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2136 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2137 ridpointers
[(int) RID_CHAR
]),
2138 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2139 TREE_TYPE (expr
) = groktypename (cast
);
2144 init_selector (offset
)
2147 tree expr
= build_msg_pool_reference (offset
);
2148 TREE_TYPE (expr
) = selector_type
;
2154 build_selector_translation_table ()
2156 tree sc_spec
, decl_specs
;
2157 tree chain
, initlist
= NULL_TREE
;
2159 tree decl
= NULL_TREE
, var_decl
, name
;
2161 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2165 expr
= build_selector (TREE_VALUE (chain
));
2167 if (flag_next_runtime
)
2169 name
= DECL_NAME (TREE_PURPOSE (chain
));
2171 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2173 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2174 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2178 /* The `decl' that is returned from start_decl is the one that we
2179 forward declared in `build_selector_reference' */
2180 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2183 /* add one for the '\0' character */
2184 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2186 if (flag_next_runtime
)
2187 finish_decl (decl
, expr
, NULL_TREE
);
2190 if (flag_typed_selectors
)
2192 tree eltlist
= NULL_TREE
;
2193 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2194 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2195 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2196 expr
= build_constructor (objc_selector_template
,
2197 nreverse (eltlist
));
2199 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2204 if (! flag_next_runtime
)
2206 /* Cause the variable and its initial value to be actually output. */
2207 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2208 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2209 /* NULL terminate the list and fix the decl for output. */
2210 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2211 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2212 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2213 nreverse (initlist
));
2214 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2215 current_function_decl
= NULL_TREE
;
2220 get_proto_encoding (proto
)
2228 if (! METHOD_ENCODING (proto
))
2230 tmp_decl
= build_tmp_function_decl ();
2231 hack_method_prototype (proto
, tmp_decl
);
2232 encoding
= encode_method_prototype (proto
, tmp_decl
);
2233 METHOD_ENCODING (proto
) = encoding
;
2236 encoding
= METHOD_ENCODING (proto
);
2238 return add_objc_string (encoding
, meth_var_types
);
2241 return build_int_2 (0, 0);
2244 /* sel_ref_chain is a list whose "value" fields will be instances of
2245 identifier_node that represent the selector. */
2248 build_typed_selector_reference (ident
, proto
)
2251 tree
*chain
= &sel_ref_chain
;
2257 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2258 goto return_at_index
;
2261 chain
= &TREE_CHAIN (*chain
);
2264 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2267 expr
= build_unary_op (ADDR_EXPR
,
2268 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2269 build_int_2 (index
, 0)),
2271 return build_c_cast (selector_type
, expr
);
2275 build_selector_reference (ident
)
2278 tree
*chain
= &sel_ref_chain
;
2284 if (TREE_VALUE (*chain
) == ident
)
2285 return (flag_next_runtime
2286 ? TREE_PURPOSE (*chain
)
2287 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2288 build_int_2 (index
, 0)));
2291 chain
= &TREE_CHAIN (*chain
);
2294 expr
= build_selector_reference_decl ();
2296 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2298 return (flag_next_runtime
2300 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2301 build_int_2 (index
, 0)));
2305 build_class_reference_decl ()
2311 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2313 ident
= get_identifier (buf
);
2315 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2316 DECL_EXTERNAL (decl
) = 1;
2317 TREE_PUBLIC (decl
) = 1;
2318 TREE_USED (decl
) = 1;
2319 TREE_READONLY (decl
) = 1;
2320 DECL_CONTEXT (decl
) = 0;
2321 DECL_ARTIFICIAL (decl
) = 1;
2323 make_decl_rtl (decl
, 0, 1);
2324 pushdecl_top_level (decl
);
2329 /* Create a class reference, but don't create a variable to reference
2333 add_class_reference (ident
)
2338 if ((chain
= cls_ref_chain
))
2343 if (ident
== TREE_VALUE (chain
))
2347 chain
= TREE_CHAIN (chain
);
2351 /* Append to the end of the list */
2352 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2355 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2358 /* Get a class reference, creating it if necessary. Also create the
2359 reference variable. */
2362 get_class_reference (ident
)
2365 if (flag_next_runtime
)
2370 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2371 if (TREE_VALUE (*chain
) == ident
)
2373 if (! TREE_PURPOSE (*chain
))
2374 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2376 return TREE_PURPOSE (*chain
);
2379 decl
= build_class_reference_decl ();
2380 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2387 add_class_reference (ident
);
2389 params
= build_tree_list (NULL_TREE
,
2390 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2391 IDENTIFIER_POINTER (ident
)));
2393 assemble_external (objc_get_class_decl
);
2394 return build_function_call (objc_get_class_decl
, params
);
2398 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2399 of identifier_node that represent the selector. It returns the
2400 offset of the selector from the beginning of the _OBJC_STRINGS
2401 pool. This offset is typically used by init_selector during code
2404 For each string section we have a chain which maps identifier nodes
2405 to decls for the strings. */
2408 add_objc_string (ident
, section
)
2410 enum string_section section
;
2414 if (section
== class_names
)
2415 chain
= &class_names_chain
;
2416 else if (section
== meth_var_names
)
2417 chain
= &meth_var_names_chain
;
2418 else if (section
== meth_var_types
)
2419 chain
= &meth_var_types_chain
;
2425 if (TREE_VALUE (*chain
) == ident
)
2426 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2428 chain
= &TREE_CHAIN (*chain
);
2431 decl
= build_objc_string_decl (section
);
2433 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2435 return build_unary_op (ADDR_EXPR
, decl
, 1);
2439 build_objc_string_decl (section
)
2440 enum string_section section
;
2444 static int class_names_idx
= 0;
2445 static int meth_var_names_idx
= 0;
2446 static int meth_var_types_idx
= 0;
2448 if (section
== class_names
)
2449 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2450 else if (section
== meth_var_names
)
2451 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2452 else if (section
== meth_var_types
)
2453 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2455 ident
= get_identifier (buf
);
2457 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2458 DECL_EXTERNAL (decl
) = 1;
2459 TREE_PUBLIC (decl
) = 1;
2460 TREE_USED (decl
) = 1;
2461 TREE_READONLY (decl
) = 1;
2462 TREE_CONSTANT (decl
) = 1;
2463 DECL_CONTEXT (decl
) = 0;
2464 DECL_ARTIFICIAL (decl
) = 1;
2466 make_decl_rtl (decl
, 0, 1);
2467 pushdecl_top_level (decl
);
2474 objc_declare_alias (alias_ident
, class_ident
)
2478 if (!doing_objc_thang
)
2481 if (is_class_name (class_ident
) != class_ident
)
2482 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2483 else if (is_class_name (alias_ident
))
2484 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2486 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2490 objc_declare_class (ident_list
)
2495 if (!doing_objc_thang
)
2498 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2500 tree ident
= TREE_VALUE (list
);
2503 if ((decl
= lookup_name (ident
)))
2505 error ("`%s' redeclared as different kind of symbol",
2506 IDENTIFIER_POINTER (ident
));
2507 error_with_decl (decl
, "previous declaration of `%s'");
2510 if (! is_class_name (ident
))
2512 tree record
= xref_tag (RECORD_TYPE
, ident
);
2513 TREE_STATIC_TEMPLATE (record
) = 1;
2514 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2520 is_class_name (ident
)
2525 if (lookup_interface (ident
))
2528 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2530 if (ident
== TREE_VALUE (chain
))
2534 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2536 if (ident
== TREE_VALUE (chain
))
2537 return TREE_PURPOSE (chain
);
2544 lookup_interface (ident
)
2549 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2551 if (ident
== CLASS_NAME (chain
))
2558 objc_copy_list (list
, head
)
2562 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2566 tail
= copy_node (list
);
2568 /* The following statement fixes a bug when inheriting instance
2569 variables that are declared to be bitfields. finish_struct
2570 expects to find the width of the bitfield in DECL_INITIAL. */
2571 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2572 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2574 newlist
= chainon (newlist
, tail
);
2575 list
= TREE_CHAIN (list
);
2582 /* Used by: build_private_template, get_class_ivars, and
2583 continue_class. COPY is 1 when called from @defs. In this case
2584 copy all fields. Otherwise don't copy leaf ivars since we rely on
2585 them being side-effected exactly once by finish_struct. */
2588 build_ivar_chain (interface
, copy
)
2592 tree my_name
, super_name
, ivar_chain
;
2594 my_name
= CLASS_NAME (interface
);
2595 super_name
= CLASS_SUPER_NAME (interface
);
2597 /* Possibly copy leaf ivars. */
2599 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2601 ivar_chain
= CLASS_IVARS (interface
);
2606 tree super_interface
= lookup_interface (super_name
);
2608 if (!super_interface
)
2610 /* fatal did not work with 2 args...should fix */
2611 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2612 IDENTIFIER_POINTER (super_name
),
2613 IDENTIFIER_POINTER (my_name
));
2614 exit (FATAL_EXIT_CODE
);
2617 if (super_interface
== interface
)
2619 fatal ("Circular inheritance in interface declaration for `%s'",
2620 IDENTIFIER_POINTER (super_name
));
2623 interface
= super_interface
;
2624 my_name
= CLASS_NAME (interface
);
2625 super_name
= CLASS_SUPER_NAME (interface
);
2627 op1
= CLASS_IVARS (interface
);
2630 tree head
, tail
= objc_copy_list (op1
, &head
);
2632 /* Prepend super class ivars...make a copy of the list, we
2633 do not want to alter the original. */
2634 TREE_CHAIN (tail
) = ivar_chain
;
2641 /* struct <classname> {
2642 struct objc_class *isa;
2647 build_private_template (class)
2652 if (CLASS_STATIC_TEMPLATE (class))
2654 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2655 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2659 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2661 ivar_context
= build_ivar_chain (class, 0);
2663 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2665 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2667 /* mark this record as class template - for class type checking */
2668 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2672 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2674 build1 (INDIRECT_REF
, NULL_TREE
,
2677 return ivar_context
;
2680 /* Begin code generation for protocols... */
2682 /* struct objc_protocol {
2683 char *protocol_name;
2684 struct objc_protocol **protocol_list;
2685 struct objc_method_desc *instance_methods;
2686 struct objc_method_desc *class_methods;
2690 build_protocol_template ()
2692 tree decl_specs
, field_decl
, field_decl_chain
;
2695 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2697 /* struct objc_class *isa; */
2699 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2700 get_identifier (UTAG_CLASS
)));
2701 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2703 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2704 field_decl_chain
= field_decl
;
2706 /* char *protocol_name; */
2708 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2710 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2712 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2713 chainon (field_decl_chain
, field_decl
);
2715 /* struct objc_protocol **protocol_list; */
2717 decl_specs
= build_tree_list (NULL_TREE
, template);
2719 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2720 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2722 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2723 chainon (field_decl_chain
, field_decl
);
2725 /* struct objc_method_list *instance_methods; */
2728 = build_tree_list (NULL_TREE
,
2729 xref_tag (RECORD_TYPE
,
2730 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2732 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2734 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2735 chainon (field_decl_chain
, field_decl
);
2737 /* struct objc_method_list *class_methods; */
2740 = build_tree_list (NULL_TREE
,
2741 xref_tag (RECORD_TYPE
,
2742 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2744 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2746 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2747 chainon (field_decl_chain
, field_decl
);
2749 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2753 build_descriptor_table_initializer (type
, entries
)
2757 tree initlist
= NULL_TREE
;
2761 tree eltlist
= NULL_TREE
;
2764 = tree_cons (NULL_TREE
,
2765 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2767 = tree_cons (NULL_TREE
,
2768 add_objc_string (METHOD_ENCODING (entries
),
2773 = tree_cons (NULL_TREE
,
2774 build_constructor (type
, nreverse (eltlist
)), initlist
);
2776 entries
= TREE_CHAIN (entries
);
2780 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2783 /* struct objc_method_prototype_list {
2785 struct objc_method_prototype {
2792 build_method_prototype_list_template (list_type
, size
)
2796 tree objc_ivar_list_record
;
2797 tree decl_specs
, field_decl
, field_decl_chain
;
2799 /* Generate an unnamed struct definition. */
2801 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2803 /* int method_count; */
2805 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2806 field_decl
= get_identifier ("method_count");
2809 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2810 field_decl_chain
= field_decl
;
2812 /* struct objc_method method_list[]; */
2814 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2815 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2816 build_int_2 (size
, 0));
2819 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2820 chainon (field_decl_chain
, field_decl
);
2822 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2824 return objc_ivar_list_record
;
2828 build_method_prototype_template ()
2831 tree decl_specs
, field_decl
, field_decl_chain
;
2834 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2836 #ifdef OBJC_INT_SELECTORS
2837 /* unsigned int _cmd; */
2839 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2840 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2841 field_decl
= get_identifier ("_cmd");
2842 #else /* OBJC_INT_SELECTORS */
2843 /* struct objc_selector *_cmd; */
2844 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2845 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2846 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2847 #endif /* OBJC_INT_SELECTORS */
2850 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2851 field_decl_chain
= field_decl
;
2853 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2855 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2857 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2858 chainon (field_decl_chain
, field_decl
);
2860 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2862 return proto_record
;
2865 /* True if last call to forwarding_offset yielded a register offset. */
2866 static int offset_is_register
;
2869 forwarding_offset (parm
)
2872 int offset_in_bytes
;
2874 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2876 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2878 /* ??? Here we assume that the parm address is indexed
2879 off the frame pointer or arg pointer.
2880 If that is not true, we produce meaningless results,
2881 but do not crash. */
2882 if (GET_CODE (addr
) == PLUS
2883 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2884 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2886 offset_in_bytes
= 0;
2888 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2889 offset_is_register
= 0;
2891 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2893 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2894 offset_in_bytes
= apply_args_register_offset (regno
);
2895 offset_is_register
= 1;
2900 /* This is the case where the parm is passed as an int or double
2901 and it is converted to a char, short or float and stored back
2902 in the parmlist. In this case, describe the parm
2903 with the variable's declared type, and adjust the address
2904 if the least significant bytes (which we are using) are not
2906 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2907 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2908 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2910 return offset_in_bytes
;
2914 encode_method_prototype (method_decl
, func_decl
)
2921 HOST_WIDE_INT max_parm_end
= 0;
2925 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2926 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2929 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2930 obstack_object_size (&util_obstack
),
2931 OBJC_ENCODE_INLINE_DEFS
);
2934 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2935 parms
= TREE_CHAIN (parms
))
2937 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2938 + int_size_in_bytes (TREE_TYPE (parms
)));
2940 if (!offset_is_register
&& max_parm_end
< parm_end
)
2941 max_parm_end
= parm_end
;
2944 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2946 sprintf (buf
, "%d", stack_size
);
2947 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2949 user_args
= METHOD_SEL_ARGS (method_decl
);
2951 /* Argument types. */
2952 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2953 parms
= TREE_CHAIN (parms
), i
++)
2955 /* Process argument qualifiers for user supplied arguments. */
2958 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2959 user_args
= TREE_CHAIN (user_args
);
2963 encode_type (TREE_TYPE (parms
),
2964 obstack_object_size (&util_obstack
),
2965 OBJC_ENCODE_INLINE_DEFS
);
2967 /* Compute offset. */
2968 sprintf (buf
, "%d", forwarding_offset (parms
));
2970 /* Indicate register. */
2971 if (offset_is_register
)
2972 obstack_1grow (&util_obstack
, '+');
2974 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2977 obstack_1grow (&util_obstack
, '\0');
2978 result
= get_identifier (obstack_finish (&util_obstack
));
2979 obstack_free (&util_obstack
, util_firstobj
);
2984 generate_descriptor_table (type
, name
, size
, list
, proto
)
2991 tree sc_spec
, decl_specs
, decl
, initlist
;
2993 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2994 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2996 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2997 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2999 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3000 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3002 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
3009 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
3012 static tree objc_method_prototype_template
;
3013 tree initlist
, chain
, method_list_template
;
3014 tree cast
, variable_length_type
;
3017 if (!objc_method_prototype_template
)
3018 objc_method_prototype_template
= build_method_prototype_template ();
3020 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3021 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
3023 variable_length_type
= groktypename (cast
);
3025 chain
= PROTOCOL_CLS_METHODS (protocol
);
3028 size
= list_length (chain
);
3030 method_list_template
3031 = build_method_prototype_list_template (objc_method_prototype_template
,
3035 = build_descriptor_table_initializer (objc_method_prototype_template
,
3038 UOBJC_CLASS_METHODS_decl
3039 = generate_descriptor_table (method_list_template
,
3040 "_OBJC_PROTOCOL_CLASS_METHODS",
3041 size
, initlist
, protocol
);
3042 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3045 UOBJC_CLASS_METHODS_decl
= 0;
3047 chain
= PROTOCOL_NST_METHODS (protocol
);
3050 size
= list_length (chain
);
3052 method_list_template
3053 = build_method_prototype_list_template (objc_method_prototype_template
,
3056 = build_descriptor_table_initializer (objc_method_prototype_template
,
3059 UOBJC_INSTANCE_METHODS_decl
3060 = generate_descriptor_table (method_list_template
,
3061 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3062 size
, initlist
, protocol
);
3063 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3066 UOBJC_INSTANCE_METHODS_decl
= 0;
3070 build_tmp_function_decl ()
3072 tree decl_specs
, expr_decl
, parms
;
3076 /* struct objc_object *objc_xxx (id, SEL, ...); */
3078 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3079 push_parm_decl (build_tree_list
3080 (build_tree_list (decl_specs
,
3081 build1 (INDIRECT_REF
, NULL_TREE
,
3083 build_tree_list (NULL_TREE
, NULL_TREE
)));
3085 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3086 get_identifier (TAG_SELECTOR
)));
3087 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3089 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3090 build_tree_list (NULL_TREE
, NULL_TREE
)));
3091 parms
= get_parm_info (0);
3094 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3095 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3096 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3097 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3099 return define_decl (expr_decl
, decl_specs
);
3103 hack_method_prototype (nst_methods
, tmp_decl
)
3110 /* Hack to avoid problem with static typing of self arg. */
3111 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3112 start_method_def (nst_methods
);
3113 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3115 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
3116 parms
= get_parm_info (0); /* we have a `, ...' */
3118 parms
= get_parm_info (1); /* place a `void_at_end' */
3120 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3122 /* Usually called from store_parm_decls -> init_function_start. */
3124 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3125 current_function_decl
= tmp_decl
;
3128 /* Code taken from start_function. */
3129 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3130 /* Promote the value to int before returning it. */
3131 if (TREE_CODE (restype
) == INTEGER_TYPE
3132 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3133 restype
= integer_type_node
;
3134 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3137 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3138 DECL_CONTEXT (parm
) = tmp_decl
;
3140 init_function_start (tmp_decl
, "objc-act", 0);
3142 /* Typically called from expand_function_start for function definitions. */
3143 assign_parms (tmp_decl
);
3145 /* install return type */
3146 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3151 generate_protocol_references (plist
)
3156 /* Forward declare protocols referenced. */
3157 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3159 tree proto
= TREE_VALUE (lproto
);
3161 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3162 && PROTOCOL_NAME (proto
))
3164 if (! PROTOCOL_FORWARD_DECL (proto
))
3165 build_protocol_reference (proto
);
3167 if (PROTOCOL_LIST (proto
))
3168 generate_protocol_references (PROTOCOL_LIST (proto
));
3174 generate_protocols ()
3176 tree p
, tmp_decl
, encoding
;
3177 tree sc_spec
, decl_specs
, decl
;
3178 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3179 tree cast_type2
= 0;
3181 tmp_decl
= build_tmp_function_decl ();
3183 if (! objc_protocol_template
)
3184 objc_protocol_template
= build_protocol_template ();
3186 /* If a protocol was directly referenced, pull in indirect references. */
3187 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3188 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3189 generate_protocol_references (PROTOCOL_LIST (p
));
3191 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3193 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3194 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3196 /* If protocol wasn't referenced, don't generate any code. */
3197 if (! PROTOCOL_FORWARD_DECL (p
))
3200 /* Make sure we link in the Protocol class. */
3201 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3205 if (! METHOD_ENCODING (nst_methods
))
3207 hack_method_prototype (nst_methods
, tmp_decl
);
3208 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3209 METHOD_ENCODING (nst_methods
) = encoding
;
3211 nst_methods
= TREE_CHAIN (nst_methods
);
3216 if (! METHOD_ENCODING (cls_methods
))
3218 hack_method_prototype (cls_methods
, tmp_decl
);
3219 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3220 METHOD_ENCODING (cls_methods
) = encoding
;
3223 cls_methods
= TREE_CHAIN (cls_methods
);
3225 generate_method_descriptors (p
);
3227 if (PROTOCOL_LIST (p
))
3228 refs_decl
= generate_protocol_list (p
);
3232 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3234 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3236 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3238 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3239 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3241 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3248 (build_tree_list (build_tree_list (NULL_TREE
,
3249 objc_protocol_template
),
3250 build1 (INDIRECT_REF
, NULL_TREE
,
3251 build1 (INDIRECT_REF
, NULL_TREE
,
3254 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3255 TREE_TYPE (refs_expr
) = cast_type2
;
3258 refs_expr
= build_int_2 (0, 0);
3260 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3261 by generate_method_descriptors, which is called above. */
3262 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3263 protocol_name_expr
, refs_expr
,
3264 UOBJC_INSTANCE_METHODS_decl
,
3265 UOBJC_CLASS_METHODS_decl
);
3266 finish_decl (decl
, initlist
, NULL_TREE
);
3268 /* Mark the decl as used to avoid "defined but not used" warning. */
3269 TREE_USED (decl
) = 1;
3274 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3275 instance_methods
, class_methods
)
3279 tree instance_methods
;
3282 tree initlist
= NULL_TREE
, expr
;
3283 static tree cast_type
= 0;
3289 (build_tree_list (NULL_TREE
,
3290 xref_tag (RECORD_TYPE
,
3291 get_identifier (UTAG_CLASS
))),
3292 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3294 /* Filling the "isa" in with one allows the runtime system to
3295 detect that the version change...should remove before final release. */
3297 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3298 TREE_TYPE (expr
) = cast_type
;
3299 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3300 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3301 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3303 if (!instance_methods
)
3304 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3307 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3308 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3312 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3315 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3316 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3319 return build_constructor (type
, nreverse (initlist
));
3322 /* struct objc_category {
3323 char *category_name;
3325 struct objc_method_list *instance_methods;
3326 struct objc_method_list *class_methods;
3327 struct objc_protocol_list *protocols;
3331 build_category_template ()
3333 tree decl_specs
, field_decl
, field_decl_chain
;
3335 objc_category_template
= start_struct (RECORD_TYPE
,
3336 get_identifier (UTAG_CATEGORY
));
3337 /* char *category_name; */
3339 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3341 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3343 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3344 field_decl_chain
= field_decl
;
3346 /* char *class_name; */
3348 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3349 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3351 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3352 chainon (field_decl_chain
, field_decl
);
3354 /* struct objc_method_list *instance_methods; */
3356 decl_specs
= build_tree_list (NULL_TREE
,
3357 xref_tag (RECORD_TYPE
,
3358 get_identifier (UTAG_METHOD_LIST
)));
3360 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3362 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3363 chainon (field_decl_chain
, field_decl
);
3365 /* struct objc_method_list *class_methods; */
3367 decl_specs
= build_tree_list (NULL_TREE
,
3368 xref_tag (RECORD_TYPE
,
3369 get_identifier (UTAG_METHOD_LIST
)));
3371 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3373 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3374 chainon (field_decl_chain
, field_decl
);
3376 /* struct objc_protocol **protocol_list; */
3378 decl_specs
= build_tree_list (NULL_TREE
,
3379 xref_tag (RECORD_TYPE
,
3380 get_identifier (UTAG_PROTOCOL
)));
3382 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3383 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3385 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3386 chainon (field_decl_chain
, field_decl
);
3388 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3391 /* struct objc_selector {
3397 build_selector_template ()
3400 tree decl_specs
, field_decl
, field_decl_chain
;
3402 objc_selector_template
3403 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3407 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3408 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3410 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3411 field_decl_chain
= field_decl
;
3413 /* char *sel_type; */
3415 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3416 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3418 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3419 chainon (field_decl_chain
, field_decl
);
3421 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3424 /* struct objc_class {
3425 struct objc_class *isa;
3426 struct objc_class *super_class;
3431 struct objc_ivar_list *ivars;
3432 struct objc_method_list *methods;
3433 if (flag_next_runtime)
3434 struct objc_cache *cache;
3436 struct sarray *dtable;
3437 struct objc_class *subclass_list;
3438 struct objc_class *sibling_class;
3440 struct objc_protocol_list *protocols;
3441 void *gc_object_type;
3445 build_class_template ()
3447 tree decl_specs
, field_decl
, field_decl_chain
;
3450 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3452 /* struct objc_class *isa; */
3454 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3455 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3457 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3458 field_decl_chain
= field_decl
;
3460 /* struct objc_class *super_class; */
3462 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3464 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3466 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3467 chainon (field_decl_chain
, field_decl
);
3471 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3472 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3474 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3475 chainon (field_decl_chain
, field_decl
);
3479 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3480 field_decl
= get_identifier ("version");
3482 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3483 chainon (field_decl_chain
, field_decl
);
3487 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3488 field_decl
= get_identifier ("info");
3490 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3491 chainon (field_decl_chain
, field_decl
);
3493 /* long instance_size; */
3495 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3496 field_decl
= get_identifier ("instance_size");
3498 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3499 chainon (field_decl_chain
, field_decl
);
3501 /* struct objc_ivar_list *ivars; */
3503 decl_specs
= build_tree_list (NULL_TREE
,
3504 xref_tag (RECORD_TYPE
,
3505 get_identifier (UTAG_IVAR_LIST
)));
3506 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3508 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3509 chainon (field_decl_chain
, field_decl
);
3511 /* struct objc_method_list *methods; */
3513 decl_specs
= build_tree_list (NULL_TREE
,
3514 xref_tag (RECORD_TYPE
,
3515 get_identifier (UTAG_METHOD_LIST
)));
3516 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3518 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3519 chainon (field_decl_chain
, field_decl
);
3521 if (flag_next_runtime
)
3523 /* struct objc_cache *cache; */
3525 decl_specs
= build_tree_list (NULL_TREE
,
3526 xref_tag (RECORD_TYPE
,
3527 get_identifier ("objc_cache")));
3528 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3529 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3530 decl_specs
, NULL_TREE
);
3531 chainon (field_decl_chain
, field_decl
);
3535 /* struct sarray *dtable; */
3537 decl_specs
= build_tree_list (NULL_TREE
,
3538 xref_tag (RECORD_TYPE
,
3539 get_identifier ("sarray")));
3540 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3541 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3542 decl_specs
, NULL_TREE
);
3543 chainon (field_decl_chain
, field_decl
);
3545 /* struct objc_class *subclass_list; */
3547 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3549 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3550 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3551 decl_specs
, NULL_TREE
);
3552 chainon (field_decl_chain
, field_decl
);
3554 /* struct objc_class *sibling_class; */
3556 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3558 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3559 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3560 decl_specs
, NULL_TREE
);
3561 chainon (field_decl_chain
, field_decl
);
3564 /* struct objc_protocol **protocol_list; */
3566 decl_specs
= build_tree_list (NULL_TREE
,
3567 xref_tag (RECORD_TYPE
,
3568 get_identifier (UTAG_PROTOCOL
)));
3570 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3572 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3573 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3574 decl_specs
, NULL_TREE
);
3575 chainon (field_decl_chain
, field_decl
);
3579 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3580 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3582 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3583 chainon (field_decl_chain
, field_decl
);
3585 /* void *gc_object_type; */
3587 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3588 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3590 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3591 chainon (field_decl_chain
, field_decl
);
3593 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3596 /* Generate appropriate forward declarations for an implementation. */
3599 synth_forward_declarations ()
3601 tree sc_spec
, decl_specs
, an_id
;
3603 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3605 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3607 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3608 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3609 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3610 TREE_USED (UOBJC_CLASS_decl
) = 1;
3611 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3613 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3615 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3616 implementation_context
);
3618 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3619 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3620 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3622 /* Pre-build the following entities - for speed/convenience. */
3624 an_id
= get_identifier ("super_class");
3625 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3626 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3630 error_with_ivar (message
, decl
, rawdecl
)
3631 const char *message
;
3637 report_error_function (DECL_SOURCE_FILE (decl
));
3639 fprintf (stderr
, "%s:%d: ",
3640 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3641 bzero (errbuf
, BUFSIZE
);
3642 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3645 #define USERTYPE(t) \
3646 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3647 || TREE_CODE (t) == ENUMERAL_TYPE)
3650 check_ivars (inter
, imp
)
3654 tree intdecls
= CLASS_IVARS (inter
);
3655 tree impdecls
= CLASS_IVARS (imp
);
3656 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3657 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3663 if (intdecls
== 0 && impdecls
== 0)
3665 if (intdecls
== 0 || impdecls
== 0)
3667 error ("inconsistent instance variable specification");
3671 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3673 if (!comptypes (t1
, t2
))
3675 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3677 error_with_ivar ("conflicting instance variable type",
3678 impdecls
, rawimpdecls
);
3679 error_with_ivar ("previous declaration of",
3680 intdecls
, rawintdecls
);
3682 else /* both the type and the name don't match */
3684 error ("inconsistent instance variable specification");
3689 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3691 error_with_ivar ("conflicting instance variable name",
3692 impdecls
, rawimpdecls
);
3693 error_with_ivar ("previous declaration of",
3694 intdecls
, rawintdecls
);
3697 intdecls
= TREE_CHAIN (intdecls
);
3698 impdecls
= TREE_CHAIN (impdecls
);
3699 rawintdecls
= TREE_CHAIN (rawintdecls
);
3700 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3704 /* Set super_type to the data type node for struct objc_super *,
3705 first defining struct objc_super itself.
3706 This needs to be done just once per compilation. */
3709 build_super_template ()
3711 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3713 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3715 /* struct objc_object *self; */
3717 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3718 field_decl
= get_identifier ("self");
3719 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3720 field_decl
= grokfield (input_filename
, lineno
,
3721 field_decl
, decl_specs
, NULL_TREE
);
3722 field_decl_chain
= field_decl
;
3724 /* struct objc_class *class; */
3726 decl_specs
= get_identifier (UTAG_CLASS
);
3727 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3728 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3730 field_decl
= grokfield (input_filename
, lineno
,
3731 field_decl
, decl_specs
, NULL_TREE
);
3732 chainon (field_decl_chain
, field_decl
);
3734 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3736 /* `struct objc_super *' */
3737 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3739 build1 (INDIRECT_REF
,
3740 NULL_TREE
, NULL_TREE
)));
3744 /* struct objc_ivar {
3751 build_ivar_template ()
3753 tree objc_ivar_id
, objc_ivar_record
;
3754 tree decl_specs
, field_decl
, field_decl_chain
;
3756 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3757 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3759 /* char *ivar_name; */
3761 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3762 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3764 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3765 decl_specs
, NULL_TREE
);
3766 field_decl_chain
= field_decl
;
3768 /* char *ivar_type; */
3770 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3771 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3773 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3774 decl_specs
, NULL_TREE
);
3775 chainon (field_decl_chain
, field_decl
);
3777 /* int ivar_offset; */
3779 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3780 field_decl
= get_identifier ("ivar_offset");
3782 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3783 decl_specs
, NULL_TREE
);
3784 chainon (field_decl_chain
, field_decl
);
3786 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3788 return objc_ivar_record
;
3793 struct objc_ivar ivar_list[ivar_count];
3797 build_ivar_list_template (list_type
, size
)
3801 tree objc_ivar_list_record
;
3802 tree decl_specs
, field_decl
, field_decl_chain
;
3804 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3806 /* int ivar_count; */
3808 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3809 field_decl
= get_identifier ("ivar_count");
3811 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3812 decl_specs
, NULL_TREE
);
3813 field_decl_chain
= field_decl
;
3815 /* struct objc_ivar ivar_list[]; */
3817 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3818 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3819 build_int_2 (size
, 0));
3821 field_decl
= grokfield (input_filename
, lineno
,
3822 field_decl
, decl_specs
, NULL_TREE
);
3823 chainon (field_decl_chain
, field_decl
);
3825 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3827 return objc_ivar_list_record
;
3833 struct objc_method method_list[method_count];
3837 build_method_list_template (list_type
, size
)
3841 tree objc_ivar_list_record
;
3842 tree decl_specs
, field_decl
, field_decl_chain
;
3844 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3846 /* int method_next; */
3851 xref_tag (RECORD_TYPE
,
3852 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3854 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3855 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3856 decl_specs
, NULL_TREE
);
3857 field_decl_chain
= field_decl
;
3859 /* int method_count; */
3861 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3862 field_decl
= get_identifier ("method_count");
3864 field_decl
= grokfield (input_filename
, lineno
,
3865 field_decl
, decl_specs
, NULL_TREE
);
3866 chainon (field_decl_chain
, field_decl
);
3868 /* struct objc_method method_list[]; */
3870 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3871 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3872 build_int_2 (size
, 0));
3874 field_decl
= grokfield (input_filename
, lineno
,
3875 field_decl
, decl_specs
, NULL_TREE
);
3876 chainon (field_decl_chain
, field_decl
);
3878 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3880 return objc_ivar_list_record
;
3884 build_ivar_list_initializer (type
, field_decl
)
3888 tree initlist
= NULL_TREE
;
3892 tree ivar
= NULL_TREE
;
3895 if (DECL_NAME (field_decl
))
3896 ivar
= tree_cons (NULL_TREE
,
3897 add_objc_string (DECL_NAME (field_decl
),
3901 /* Unnamed bit-field ivar (yuck). */
3902 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3905 encode_field_decl (field_decl
,
3906 obstack_object_size (&util_obstack
),
3907 OBJC_ENCODE_DONT_INLINE_DEFS
);
3909 /* Null terminate string. */
3910 obstack_1grow (&util_obstack
, 0);
3914 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3917 obstack_free (&util_obstack
, util_firstobj
);
3920 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3921 initlist
= tree_cons (NULL_TREE
,
3922 build_constructor (type
, nreverse (ivar
)),
3925 field_decl
= TREE_CHAIN (field_decl
);
3929 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3933 generate_ivars_list (type
, name
, size
, list
)
3939 tree sc_spec
, decl_specs
, decl
, initlist
;
3941 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3942 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3944 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3945 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3947 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3948 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3951 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3958 generate_ivar_lists ()
3960 tree initlist
, ivar_list_template
, chain
;
3961 tree cast
, variable_length_type
;
3964 generating_instance_variables
= 1;
3966 if (!objc_ivar_template
)
3967 objc_ivar_template
= build_ivar_template ();
3971 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3972 get_identifier (UTAG_IVAR_LIST
))),
3974 variable_length_type
= groktypename (cast
);
3976 /* Only generate class variables for the root of the inheritance
3977 hierarchy since these will be the same for every class. */
3979 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3980 && (chain
= TYPE_FIELDS (objc_class_template
)))
3982 size
= list_length (chain
);
3984 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3985 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3987 UOBJC_CLASS_VARIABLES_decl
3988 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3990 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3993 UOBJC_CLASS_VARIABLES_decl
= 0;
3995 chain
= CLASS_IVARS (implementation_template
);
3998 size
= list_length (chain
);
3999 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4000 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4002 UOBJC_INSTANCE_VARIABLES_decl
4003 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
4005 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
4008 UOBJC_INSTANCE_VARIABLES_decl
= 0;
4010 generating_instance_variables
= 0;
4014 build_dispatch_table_initializer (type
, entries
)
4018 tree initlist
= NULL_TREE
;
4022 tree elemlist
= NULL_TREE
;
4024 elemlist
= tree_cons (NULL_TREE
,
4025 build_selector (METHOD_SEL_NAME (entries
)),
4028 elemlist
= tree_cons (NULL_TREE
,
4029 add_objc_string (METHOD_ENCODING (entries
),
4033 elemlist
= tree_cons (NULL_TREE
,
4034 build_unary_op (ADDR_EXPR
,
4035 METHOD_DEFINITION (entries
), 1),
4038 initlist
= tree_cons (NULL_TREE
,
4039 build_constructor (type
, nreverse (elemlist
)),
4042 entries
= TREE_CHAIN (entries
);
4046 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4049 /* To accomplish method prototyping without generating all kinds of
4050 inane warnings, the definition of the dispatch table entries were
4053 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4055 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4058 build_method_template ()
4061 tree decl_specs
, field_decl
, field_decl_chain
;
4063 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4065 #ifdef OBJC_INT_SELECTORS
4066 /* unsigned int _cmd; */
4067 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
4069 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
4070 field_decl
= get_identifier ("_cmd");
4071 #else /* not OBJC_INT_SELECTORS */
4072 /* struct objc_selector *_cmd; */
4073 decl_specs
= tree_cons (NULL_TREE
,
4074 xref_tag (RECORD_TYPE
,
4075 get_identifier (TAG_SELECTOR
)),
4077 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4078 #endif /* not OBJC_INT_SELECTORS */
4080 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4081 decl_specs
, NULL_TREE
);
4082 field_decl_chain
= field_decl
;
4084 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4085 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4086 get_identifier ("method_types"));
4087 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4088 decl_specs
, NULL_TREE
);
4089 chainon (field_decl_chain
, field_decl
);
4093 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4094 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4095 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4096 decl_specs
, NULL_TREE
);
4097 chainon (field_decl_chain
, field_decl
);
4099 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4106 generate_dispatch_table (type
, name
, size
, list
)
4112 tree sc_spec
, decl_specs
, decl
, initlist
;
4114 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4115 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4117 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4118 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4120 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4121 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4122 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4125 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4132 generate_dispatch_tables ()
4134 tree initlist
, chain
, method_list_template
;
4135 tree cast
, variable_length_type
;
4138 if (!objc_method_template
)
4139 objc_method_template
= build_method_template ();
4143 (build_tree_list (NULL_TREE
,
4144 xref_tag (RECORD_TYPE
,
4145 get_identifier (UTAG_METHOD_LIST
))),
4148 variable_length_type
= groktypename (cast
);
4150 chain
= CLASS_CLS_METHODS (implementation_context
);
4153 size
= list_length (chain
);
4155 method_list_template
4156 = build_method_list_template (objc_method_template
, size
);
4158 = build_dispatch_table_initializer (objc_method_template
, chain
);
4160 UOBJC_CLASS_METHODS_decl
4161 = generate_dispatch_table (method_list_template
,
4162 ((TREE_CODE (implementation_context
)
4163 == CLASS_IMPLEMENTATION_TYPE
)
4164 ? "_OBJC_CLASS_METHODS"
4165 : "_OBJC_CATEGORY_CLASS_METHODS"),
4167 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4170 UOBJC_CLASS_METHODS_decl
= 0;
4172 chain
= CLASS_NST_METHODS (implementation_context
);
4175 size
= list_length (chain
);
4177 method_list_template
4178 = build_method_list_template (objc_method_template
, size
);
4180 = build_dispatch_table_initializer (objc_method_template
, chain
);
4182 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4183 UOBJC_INSTANCE_METHODS_decl
4184 = generate_dispatch_table (method_list_template
,
4185 "_OBJC_INSTANCE_METHODS",
4188 /* We have a category. */
4189 UOBJC_INSTANCE_METHODS_decl
4190 = generate_dispatch_table (method_list_template
,
4191 "_OBJC_CATEGORY_INSTANCE_METHODS",
4193 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4196 UOBJC_INSTANCE_METHODS_decl
= 0;
4200 generate_protocol_list (i_or_p
)
4203 static tree cast_type
= 0;
4204 tree initlist
, decl_specs
, sc_spec
;
4205 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4208 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4209 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4210 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4211 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4212 plist
= PROTOCOL_LIST (i_or_p
);
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 static tree cast_type2
;
4328 (build_tree_list (NULL_TREE
,
4329 xref_tag (RECORD_TYPE
,
4330 get_identifier (UTAG_PROTOCOL
))),
4331 build1 (INDIRECT_REF
, NULL_TREE
,
4332 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4334 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4335 TREE_TYPE (expr
) = cast_type2
;
4336 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4339 return build_constructor (type
, nreverse (initlist
));
4342 /* struct objc_class {
4343 struct objc_class *isa;
4344 struct objc_class *super_class;
4349 struct objc_ivar_list *ivars;
4350 struct objc_method_list *methods;
4351 if (flag_next_runtime)
4352 struct objc_cache *cache;
4354 struct sarray *dtable;
4355 struct objc_class *subclass_list;
4356 struct objc_class *sibling_class;
4358 struct objc_protocol_list *protocols;
4359 void *gc_object_type;
4363 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4364 dispatch_table
, ivar_list
, protocol_list
)
4371 tree dispatch_table
;
4375 tree initlist
= NULL_TREE
, expr
;
4378 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4381 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4384 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4387 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4390 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4392 /* instance_size = */
4393 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4395 /* objc_ivar_list = */
4397 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4400 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4401 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4404 /* objc_method_list = */
4405 if (!dispatch_table
)
4406 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4409 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4410 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4413 if (flag_next_runtime
)
4414 /* method_cache = */
4415 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4419 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4421 /* subclass_list = */
4422 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4424 /* sibling_class = */
4425 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4428 /* protocol_list = */
4429 if (! protocol_list
)
4430 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4433 static tree cast_type2
;
4439 (build_tree_list (NULL_TREE
,
4440 xref_tag (RECORD_TYPE
,
4441 get_identifier (UTAG_PROTOCOL
))),
4442 build1 (INDIRECT_REF
, NULL_TREE
,
4443 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4445 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4446 TREE_TYPE (expr
) = cast_type2
;
4447 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4450 /* gc_object_type = NULL */
4451 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4453 return build_constructor (type
, nreverse (initlist
));
4456 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4459 generate_category (cat
)
4462 tree sc_spec
, decl_specs
, decl
;
4463 tree initlist
, cat_name_expr
, class_name_expr
;
4464 tree protocol_decl
, category
;
4466 add_class_reference (CLASS_NAME (cat
));
4467 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4469 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4471 category
= CLASS_CATEGORY_LIST (implementation_template
);
4473 /* find the category interface from the class it is associated with */
4476 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4478 category
= CLASS_CATEGORY_LIST (category
);
4481 if (category
&& CLASS_PROTOCOL_LIST (category
))
4483 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4484 protocol_decl
= generate_protocol_list (category
);
4489 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4490 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4492 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4493 implementation_context
),
4494 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4496 initlist
= build_category_initializer (TREE_TYPE (decl
),
4497 cat_name_expr
, class_name_expr
,
4498 UOBJC_INSTANCE_METHODS_decl
,
4499 UOBJC_CLASS_METHODS_decl
,
4502 TREE_USED (decl
) = 1;
4503 finish_decl (decl
, initlist
, NULL_TREE
);
4506 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4507 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4510 generate_shared_structures ()
4512 tree sc_spec
, decl_specs
, decl
;
4513 tree name_expr
, super_expr
, root_expr
;
4514 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4515 tree cast_type
, initlist
, protocol_decl
;
4517 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4520 add_class_reference (my_super_id
);
4522 /* Compute "my_root_id" - this is required for code generation.
4523 the "isa" for all meta class structures points to the root of
4524 the inheritance hierarchy (e.g. "__Object")... */
4525 my_root_id
= my_super_id
;
4528 tree my_root_int
= lookup_interface (my_root_id
);
4530 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4531 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4538 /* No super class. */
4539 my_root_id
= CLASS_NAME (implementation_template
);
4542 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4543 objc_class_template
),
4544 build1 (INDIRECT_REF
,
4545 NULL_TREE
, NULL_TREE
)));
4547 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4550 /* Install class `isa' and `super' pointers at runtime. */
4553 super_expr
= add_objc_string (my_super_id
, class_names
);
4554 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4557 super_expr
= build_int_2 (0, 0);
4559 root_expr
= add_objc_string (my_root_id
, class_names
);
4560 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4562 if (CLASS_PROTOCOL_LIST (implementation_template
))
4564 generate_protocol_references
4565 (CLASS_PROTOCOL_LIST (implementation_template
));
4566 protocol_decl
= generate_protocol_list (implementation_template
);
4571 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4573 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4574 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4576 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4577 NULL_TREE
, NULL_TREE
);
4580 = build_shared_structure_initializer
4582 root_expr
, super_expr
, name_expr
,
4583 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4585 UOBJC_CLASS_METHODS_decl
,
4586 UOBJC_CLASS_VARIABLES_decl
,
4589 finish_decl (decl
, initlist
, NULL_TREE
);
4591 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4593 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4594 NULL_TREE
, NULL_TREE
);
4597 = build_shared_structure_initializer
4599 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4600 super_expr
, name_expr
,
4601 convert (integer_type_node
,
4602 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4603 (implementation_template
))),
4605 UOBJC_INSTANCE_METHODS_decl
,
4606 UOBJC_INSTANCE_VARIABLES_decl
,
4609 finish_decl (decl
, initlist
, NULL_TREE
);
4613 synth_id_with_class_suffix (preamble
, ctxt
)
4614 const char *preamble
;
4618 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4619 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4621 const char *class_name
4622 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4623 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4624 sprintf (string
, "%s_%s", preamble
,
4625 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4627 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4628 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4630 /* We have a category. */
4631 const char *class_name
4632 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4633 const char *class_super_name
4634 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4635 string
= (char *) alloca (strlen (preamble
)
4636 + strlen (class_name
)
4637 + strlen (class_super_name
)
4639 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4641 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4643 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4645 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4646 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4651 return get_identifier (string
);
4655 is_objc_type_qualifier (node
)
4658 return (TREE_CODE (node
) == IDENTIFIER_NODE
4659 && (node
== ridpointers
[(int) RID_CONST
]
4660 || node
== ridpointers
[(int) RID_VOLATILE
]
4661 || node
== ridpointers
[(int) RID_IN
]
4662 || node
== ridpointers
[(int) RID_OUT
]
4663 || node
== ridpointers
[(int) RID_INOUT
]
4664 || node
== ridpointers
[(int) RID_BYCOPY
]
4665 || node
== ridpointers
[(int) RID_BYREF
]
4666 || node
== ridpointers
[(int) RID_ONEWAY
]));
4669 /* If type is empty or only type qualifiers are present, add default
4670 type of id (otherwise grokdeclarator will default to int). */
4673 adjust_type_for_id_default (type
)
4676 tree declspecs
, chain
;
4679 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4680 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4682 declspecs
= TREE_PURPOSE (type
);
4684 /* Determine if a typespec is present. */
4685 for (chain
= declspecs
;
4687 chain
= TREE_CHAIN (chain
))
4689 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4693 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4695 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4700 selector ':' '(' typename ')' identifier
4703 Transform an Objective-C keyword argument into
4704 the C equivalent parameter declarator.
4706 In: key_name, an "identifier_node" (optional).
4707 arg_type, a "tree_list" (optional).
4708 arg_name, an "identifier_node".
4710 Note: It would be really nice to strongly type the preceding
4711 arguments in the function prototype; however, then I
4712 could not use the "accessor" macros defined in "tree.h".
4714 Out: an instance of "keyword_decl". */
4717 build_keyword_decl (key_name
, arg_type
, arg_name
)
4724 /* If no type is specified, default to "id". */
4725 arg_type
= adjust_type_for_id_default (arg_type
);
4727 keyword_decl
= make_node (KEYWORD_DECL
);
4729 TREE_TYPE (keyword_decl
) = arg_type
;
4730 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4731 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4733 return keyword_decl
;
4736 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4739 build_keyword_selector (selector
)
4743 tree key_chain
, key_name
;
4746 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4748 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4749 key_name
= KEYWORD_KEY_NAME (key_chain
);
4750 else if (TREE_CODE (selector
) == TREE_LIST
)
4751 key_name
= TREE_PURPOSE (key_chain
);
4756 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4758 /* Just a ':' arg. */
4762 buf
= (char *)alloca (len
+ 1);
4763 bzero (buf
, len
+ 1);
4765 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4767 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4768 key_name
= KEYWORD_KEY_NAME (key_chain
);
4769 else if (TREE_CODE (selector
) == TREE_LIST
)
4770 key_name
= TREE_PURPOSE (key_chain
);
4775 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4779 return get_identifier (buf
);
4782 /* Used for declarations and definitions. */
4785 build_method_decl (code
, ret_type
, selector
, add_args
)
4786 enum tree_code code
;
4793 /* If no type is specified, default to "id". */
4794 ret_type
= adjust_type_for_id_default (ret_type
);
4796 method_decl
= make_node (code
);
4797 TREE_TYPE (method_decl
) = ret_type
;
4799 /* If we have a keyword selector, create an identifier_node that
4800 represents the full selector name (`:' included)... */
4801 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4803 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4804 METHOD_SEL_ARGS (method_decl
) = selector
;
4805 METHOD_ADD_ARGS (method_decl
) = add_args
;
4809 METHOD_SEL_NAME (method_decl
) = selector
;
4810 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4811 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4817 #define METHOD_DEF 0
4818 #define METHOD_REF 1
4820 /* Used by `build_message_expr' and `comp_method_types'. Return an
4821 argument list for method METH. CONTEXT is either METHOD_DEF or
4822 METHOD_REF, saying whether we are trying to define a method or call
4823 one. SUPERFLAG says this is for a send to super; this makes a
4824 difference for the NeXT calling sequence in which the lookup and
4825 the method call are done together. */
4828 get_arg_type_list (meth
, context
, superflag
)
4835 /* Receiver type. */
4836 if (flag_next_runtime
&& superflag
)
4837 arglist
= build_tree_list (NULL_TREE
, super_type
);
4838 else if (context
== METHOD_DEF
)
4839 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4841 arglist
= build_tree_list (NULL_TREE
, id_type
);
4843 /* Selector type - will eventually change to `int'. */
4844 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4846 /* Build a list of argument types. */
4847 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4849 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4850 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4853 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4854 /* We have a `, ...' immediately following the selector,
4855 finalize the arglist...simulate get_parm_info (0). */
4857 else if (METHOD_ADD_ARGS (meth
))
4859 /* we have a variable length selector */
4860 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4861 chainon (arglist
, add_arg_list
);
4864 /* finalize the arglist...simulate get_parm_info (1) */
4865 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4871 check_duplicates (hsh
)
4874 tree meth
= NULL_TREE
;
4882 /* We have two methods with the same name and different types. */
4884 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4886 warning ("multiple declarations for method `%s'",
4887 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4889 warn_with_method ("using", type
, meth
);
4890 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4891 warn_with_method ("also found", type
, loop
->value
);
4897 /* If RECEIVER is a class reference, return the identifier node for the
4898 referenced class. RECEIVER is created by get_class_reference, so we
4899 check the exact form created depending on which runtimes are used. */
4902 receiver_is_class_object (receiver
)
4905 tree chain
, exp
, arg
;
4906 if (flag_next_runtime
)
4908 /* The receiver is a variable created by build_class_reference_decl. */
4909 if (TREE_CODE (receiver
) == VAR_DECL
4910 && TREE_TYPE (receiver
) == objc_class_type
)
4911 /* Look up the identifier. */
4912 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4913 if (TREE_PURPOSE (chain
) == receiver
)
4914 return TREE_VALUE (chain
);
4918 /* The receiver is a function call that returns an id. Check if
4919 it is a call to objc_getClass, if so, pick up the class name. */
4920 if ((exp
= TREE_OPERAND (receiver
, 0))
4921 && TREE_CODE (exp
) == ADDR_EXPR
4922 && (exp
= TREE_OPERAND (exp
, 0))
4923 && TREE_CODE (exp
) == FUNCTION_DECL
4924 && exp
== objc_get_class_decl
4925 /* we have a call to objc_getClass! */
4926 && (arg
= TREE_OPERAND (receiver
, 1))
4927 && TREE_CODE (arg
) == TREE_LIST
4928 && (arg
= TREE_VALUE (arg
)))
4931 if (TREE_CODE (arg
) == ADDR_EXPR
4932 && (arg
= TREE_OPERAND (arg
, 0))
4933 && TREE_CODE (arg
) == STRING_CST
)
4934 /* Finally, we have the class name. */
4935 return get_identifier (TREE_STRING_POINTER (arg
));
4941 /* If we are currently building a message expr, this holds
4942 the identifier of the selector of the message. This is
4943 used when printing warnings about argument mismatches. */
4945 static tree building_objc_message_expr
= 0;
4948 maybe_building_objc_message_expr ()
4950 return building_objc_message_expr
;
4953 /* Construct an expression for sending a message.
4954 MESS has the object to send to in TREE_PURPOSE
4955 and the argument list (including selector) in TREE_VALUE.
4957 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4958 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4961 build_message_expr (mess
)
4964 tree receiver
= TREE_PURPOSE (mess
);
4965 tree selector
, self_object
;
4966 tree rtype
, sel_name
;
4967 tree args
= TREE_VALUE (mess
);
4968 tree method_params
= NULL_TREE
;
4969 tree method_prototype
= NULL_TREE
;
4971 int statically_typed
= 0, statically_allocated
= 0;
4972 tree class_ident
= 0;
4974 /* 1 if this is sending to the superclass. */
4977 if (!doing_objc_thang
)
4980 if (TREE_CODE (receiver
) == ERROR_MARK
)
4981 return error_mark_node
;
4983 /* Determine receiver type. */
4984 rtype
= TREE_TYPE (receiver
);
4985 super
= IS_SUPER (rtype
);
4989 if (TREE_STATIC_TEMPLATE (rtype
))
4990 statically_allocated
= 1;
4991 else if (TREE_CODE (rtype
) == POINTER_TYPE
4992 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4993 statically_typed
= 1;
4994 else if ((flag_next_runtime
4995 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4996 && (class_ident
= receiver_is_class_object (receiver
)))
4998 else if (! IS_ID (rtype
)
4999 /* Allow any type that matches objc_class_type. */
5000 && ! comptypes (rtype
, objc_class_type
))
5002 bzero (errbuf
, BUFSIZE
);
5003 warning ("invalid receiver type `%s'",
5004 gen_declaration (rtype
, errbuf
));
5007 if (statically_allocated
)
5008 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
5010 /* Don't evaluate the receiver twice. */
5011 receiver
= save_expr (receiver
);
5012 self_object
= receiver
;
5015 /* If sending to `super', use current self as the object. */
5016 self_object
= self_decl
;
5018 /* Obtain the full selector name. */
5020 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
5021 /* A unary selector. */
5023 else if (TREE_CODE (args
) == TREE_LIST
)
5024 sel_name
= build_keyword_selector (args
);
5028 /* Build the parameter list to give to the method. */
5030 method_params
= NULL_TREE
;
5031 if (TREE_CODE (args
) == TREE_LIST
)
5033 tree chain
= args
, prev
= NULL_TREE
;
5035 /* We have a keyword selector--check for comma expressions. */
5038 tree element
= TREE_VALUE (chain
);
5040 /* We have a comma expression, must collapse... */
5041 if (TREE_CODE (element
) == TREE_LIST
)
5044 TREE_CHAIN (prev
) = element
;
5049 chain
= TREE_CHAIN (chain
);
5051 method_params
= args
;
5054 /* Determine operation return type. */
5056 if (IS_SUPER (rtype
))
5060 if (CLASS_SUPER_NAME (implementation_template
))
5063 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5065 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5066 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5068 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5070 if (iface
&& !method_prototype
)
5071 warning ("`%s' does not respond to `%s'",
5072 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5073 IDENTIFIER_POINTER (sel_name
));
5077 error ("no super class declared in interface for `%s'",
5078 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5079 return error_mark_node
;
5083 else if (statically_allocated
)
5085 tree ctype
= TREE_TYPE (rtype
);
5086 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5089 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5091 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5093 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5096 if (!method_prototype
)
5097 warning ("`%s' does not respond to `%s'",
5098 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5099 IDENTIFIER_POINTER (sel_name
));
5101 else if (statically_typed
)
5103 tree ctype
= TREE_TYPE (rtype
);
5105 /* `self' is now statically_typed. All methods should be visible
5106 within the context of the implementation. */
5107 if (implementation_context
5108 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5111 = lookup_instance_method_static (implementation_template
,
5114 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5116 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5119 if (! method_prototype
5120 && implementation_template
!= implementation_context
)
5121 /* The method is not published in the interface. Check
5124 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5131 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5132 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5134 if (! method_prototype
)
5136 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5139 = lookup_method_in_protocol_list (protocol_list
,
5144 if (!method_prototype
)
5145 warning ("`%s' does not respond to `%s'",
5146 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5147 IDENTIFIER_POINTER (sel_name
));
5149 else if (class_ident
)
5151 if (implementation_context
5152 && CLASS_NAME (implementation_context
) == class_ident
)
5155 = lookup_class_method_static (implementation_template
, sel_name
);
5157 if (!method_prototype
5158 && implementation_template
!= implementation_context
)
5159 /* The method is not published in the interface. Check
5162 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5169 if ((iface
= lookup_interface (class_ident
)))
5170 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5173 if (!method_prototype
)
5175 warning ("cannot find class (factory) method.");
5176 warning ("return type for `%s' defaults to id",
5177 IDENTIFIER_POINTER (sel_name
));
5180 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5182 /* An anonymous object that has been qualified with a protocol. */
5184 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5186 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5189 if (!method_prototype
)
5193 warning ("method `%s' not implemented by protocol.",
5194 IDENTIFIER_POINTER (sel_name
));
5196 /* Try and find the method signature in the global pools. */
5198 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5199 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5201 if (!(method_prototype
= check_duplicates (hsh
)))
5202 warning ("return type defaults to id");
5209 /* We think we have an instance...loophole: extern id Object; */
5210 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5212 /* For various loopholes, like sending messages to self in a
5214 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5216 method_prototype
= check_duplicates (hsh
);
5217 if (!method_prototype
)
5219 warning ("cannot find method.");
5220 warning ("return type for `%s' defaults to id",
5221 IDENTIFIER_POINTER (sel_name
));
5225 /* Save the selector name for printing error messages. */
5226 building_objc_message_expr
= sel_name
;
5228 /* Build the parameters list for looking up the method.
5229 These are the object itself and the selector. */
5231 if (flag_typed_selectors
)
5232 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5234 selector
= build_selector_reference (sel_name
);
5236 retval
= build_objc_method_call (super
, method_prototype
,
5237 receiver
, self_object
,
5238 selector
, method_params
);
5240 building_objc_message_expr
= 0;
5245 /* Build a tree expression to send OBJECT the operation SELECTOR,
5246 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5247 assuming the method has prototype METHOD_PROTOTYPE.
5248 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5249 Use METHOD_PARAMS as list of args to pass to the method.
5250 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5253 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5254 selector
, method_params
)
5256 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5258 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5259 tree rcv_p
= (super_flag
5260 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5261 get_identifier (TAG_SUPER
)))
5264 if (flag_next_runtime
)
5266 if (! method_prototype
)
5268 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5269 tree_cons (NULL_TREE
, selector
,
5271 assemble_external (sender
);
5272 return build_function_call (sender
, method_params
);
5276 /* This is a real kludge, but it is used only for the Next.
5277 Clobber the data type of SENDER temporarily to accept
5278 all the arguments for this operation, and to return
5279 whatever this operation returns. */
5280 tree arglist
= NULL_TREE
;
5283 /* Save the proper contents of SENDER's data type. */
5284 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5285 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5287 /* Install this method's argument types. */
5288 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5290 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5292 /* Install this method's return type. */
5293 TREE_TYPE (TREE_TYPE (sender
))
5294 = groktypename (TREE_TYPE (method_prototype
));
5296 /* Call SENDER with all the parameters. This will do type
5297 checking using the arg types for this method. */
5298 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5299 tree_cons (NULL_TREE
, selector
,
5301 assemble_external (sender
);
5302 retval
= build_function_call (sender
, method_params
);
5304 /* Restore SENDER's return/argument types. */
5305 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5306 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5312 /* This is the portable way.
5313 First call the lookup function to get a pointer to the method,
5314 then cast the pointer, then call it with the method arguments. */
5317 /* Avoid trouble since we may evaluate each of these twice. */
5318 object
= save_expr (object
);
5319 selector
= save_expr (selector
);
5321 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5323 assemble_external (sender
);
5325 = build_function_call (sender
,
5326 tree_cons (NULL_TREE
, lookup_object
,
5327 tree_cons (NULL_TREE
, selector
,
5330 /* If we have a method prototype, construct the data type this
5331 method needs, and cast what we got from SENDER into a pointer
5333 if (method_prototype
)
5335 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5337 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5338 tree fake_function_type
= build_function_type (valtype
, arglist
);
5339 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5343 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5345 /* Pass the object to the method. */
5346 assemble_external (method
);
5347 return build_function_call (method
,
5348 tree_cons (NULL_TREE
, object
,
5349 tree_cons (NULL_TREE
, selector
,
5355 build_protocol_reference (p
)
5358 tree decl
, ident
, ptype
;
5360 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5362 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5364 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5365 objc_protocol_template
),
5368 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5369 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5372 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5373 DECL_EXTERNAL (decl
) = 1;
5374 TREE_PUBLIC (decl
) = 1;
5375 TREE_USED (decl
) = 1;
5376 DECL_ARTIFICIAL (decl
) = 1;
5378 make_decl_rtl (decl
, 0, 1);
5379 pushdecl_top_level (decl
);
5382 PROTOCOL_FORWARD_DECL (p
) = decl
;
5386 build_protocol_expr (protoname
)
5392 if (!doing_objc_thang
)
5395 p
= lookup_protocol (protoname
);
5399 error ("Cannot find protocol declaration for `%s'",
5400 IDENTIFIER_POINTER (protoname
));
5401 return error_mark_node
;
5404 if (!PROTOCOL_FORWARD_DECL (p
))
5405 build_protocol_reference (p
);
5407 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5409 TREE_TYPE (expr
) = protocol_type
;
5415 build_selector_expr (selnamelist
)
5420 if (!doing_objc_thang
)
5423 /* Obtain the full selector name. */
5424 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5425 /* A unary selector. */
5426 selname
= selnamelist
;
5427 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5428 selname
= build_keyword_selector (selnamelist
);
5432 if (flag_typed_selectors
)
5433 return build_typed_selector_reference (selname
, 0);
5435 return build_selector_reference (selname
);
5439 build_encode_expr (type
)
5445 if (!doing_objc_thang
)
5448 encode_type (type
, obstack_object_size (&util_obstack
),
5449 OBJC_ENCODE_INLINE_DEFS
);
5450 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5451 string
= obstack_finish (&util_obstack
);
5453 /* Synthesize a string that represents the encoded struct/union. */
5454 result
= my_build_string (strlen (string
) + 1, string
);
5455 obstack_free (&util_obstack
, util_firstobj
);
5460 build_ivar_reference (id
)
5463 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5465 /* Historically, a class method that produced objects (factory
5466 method) would assign `self' to the instance that it
5467 allocated. This would effectively turn the class method into
5468 an instance method. Following this assignment, the instance
5469 variables could be accessed. That practice, while safe,
5470 violates the simple rule that a class method should not refer
5471 to an instance variable. It's better to catch the cases
5472 where this is done unknowingly than to support the above
5474 warning ("instance variable `%s' accessed in class method",
5475 IDENTIFIER_POINTER (id
));
5476 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5479 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5482 #define HASH_ALLOC_LIST_SIZE 170
5483 #define ATTR_ALLOC_LIST_SIZE 170
5484 #define SIZEHASHTABLE 257
5487 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5492 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5493 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5495 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5496 perror ("unable to allocate space in objc-tree.c");
5501 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5503 nst_method_hash_list
[i
] = 0;
5504 cls_method_hash_list
[i
] = 0;
5510 hash_enter (hashlist
, method
)
5514 static hash hash_alloc_list
= 0;
5515 static int hash_alloc_index
= 0;
5517 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5519 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5521 hash_alloc_index
= 0;
5522 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5523 * HASH_ALLOC_LIST_SIZE
);
5524 if (! hash_alloc_list
)
5525 perror ("unable to allocate in objc-tree.c");
5527 obj
= &hash_alloc_list
[hash_alloc_index
++];
5529 obj
->next
= hashlist
[slot
];
5532 hashlist
[slot
] = obj
; /* append to front */
5536 hash_lookup (hashlist
, sel_name
)
5542 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5546 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5549 target
= target
->next
;
5555 hash_add_attr (entry
, value
)
5559 static attr attr_alloc_list
= 0;
5560 static int attr_alloc_index
= 0;
5563 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5565 attr_alloc_index
= 0;
5566 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5567 * ATTR_ALLOC_LIST_SIZE
);
5568 if (! attr_alloc_list
)
5569 perror ("unable to allocate in objc-tree.c");
5571 obj
= &attr_alloc_list
[attr_alloc_index
++];
5572 obj
->next
= entry
->list
;
5575 entry
->list
= obj
; /* append to front */
5579 lookup_method (mchain
, method
)
5585 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5588 key
= METHOD_SEL_NAME (method
);
5592 if (METHOD_SEL_NAME (mchain
) == key
)
5594 mchain
= TREE_CHAIN (mchain
);
5600 lookup_instance_method_static (interface
, ident
)
5604 tree inter
= interface
;
5605 tree chain
= CLASS_NST_METHODS (inter
);
5606 tree meth
= NULL_TREE
;
5610 if ((meth
= lookup_method (chain
, ident
)))
5613 if (CLASS_CATEGORY_LIST (inter
))
5615 tree category
= CLASS_CATEGORY_LIST (inter
);
5616 chain
= CLASS_NST_METHODS (category
);
5620 if ((meth
= lookup_method (chain
, ident
)))
5623 /* Check for instance methods in protocols in categories. */
5624 if (CLASS_PROTOCOL_LIST (category
))
5626 if ((meth
= (lookup_method_in_protocol_list
5627 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5631 if ((category
= CLASS_CATEGORY_LIST (category
)))
5632 chain
= CLASS_NST_METHODS (category
);
5637 if (CLASS_PROTOCOL_LIST (inter
))
5639 if ((meth
= (lookup_method_in_protocol_list
5640 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5644 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5645 chain
= CLASS_NST_METHODS (inter
);
5653 lookup_class_method_static (interface
, ident
)
5657 tree inter
= interface
;
5658 tree chain
= CLASS_CLS_METHODS (inter
);
5659 tree meth
= NULL_TREE
;
5660 tree root_inter
= NULL_TREE
;
5664 if ((meth
= lookup_method (chain
, ident
)))
5667 if (CLASS_CATEGORY_LIST (inter
))
5669 tree category
= CLASS_CATEGORY_LIST (inter
);
5670 chain
= CLASS_CLS_METHODS (category
);
5674 if ((meth
= lookup_method (chain
, ident
)))
5677 /* Check for class methods in protocols in categories. */
5678 if (CLASS_PROTOCOL_LIST (category
))
5680 if ((meth
= (lookup_method_in_protocol_list
5681 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5685 if ((category
= CLASS_CATEGORY_LIST (category
)))
5686 chain
= CLASS_CLS_METHODS (category
);
5691 /* Check for class methods in protocols. */
5692 if (CLASS_PROTOCOL_LIST (inter
))
5694 if ((meth
= (lookup_method_in_protocol_list
5695 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5700 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5701 chain
= CLASS_CLS_METHODS (inter
);
5705 /* Simulate wrap around. */
5706 return lookup_instance_method_static (root_inter
, ident
);
5710 add_class_method (class, method
)
5717 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5719 /* put method on list in reverse order */
5720 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5721 CLASS_CLS_METHODS (class) = method
;
5725 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5726 error ("duplicate definition of class method `%s'.",
5727 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5730 /* Check types; if different, complain. */
5731 if (!comp_proto_with_proto (method
, mth
))
5732 error ("duplicate declaration of class method `%s'.",
5733 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5737 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5739 /* Install on a global chain. */
5740 hash_enter (cls_method_hash_list
, method
);
5744 /* Check types; if different, add to a list. */
5745 if (!comp_proto_with_proto (method
, hsh
->key
))
5746 hash_add_attr (hsh
, method
);
5752 add_instance_method (class, method
)
5759 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5761 /* Put method on list in reverse order. */
5762 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5763 CLASS_NST_METHODS (class) = method
;
5767 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5768 error ("duplicate definition of instance method `%s'.",
5769 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5772 /* Check types; if different, complain. */
5773 if (!comp_proto_with_proto (method
, mth
))
5774 error ("duplicate declaration of instance method `%s'.",
5775 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5779 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5781 /* Install on a global chain. */
5782 hash_enter (nst_method_hash_list
, method
);
5786 /* Check types; if different, add to a list. */
5787 if (!comp_proto_with_proto (method
, hsh
->key
))
5788 hash_add_attr (hsh
, method
);
5797 /* Put interfaces on list in reverse order. */
5798 TREE_CHAIN (class) = interface_chain
;
5799 interface_chain
= class;
5800 return interface_chain
;
5804 add_category (class, category
)
5808 /* Put categories on list in reverse order. */
5809 tree cat
= CLASS_CATEGORY_LIST (class);
5813 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5814 warning ("duplicate interface declaration for category `%s(%s)'",
5815 IDENTIFIER_POINTER (CLASS_NAME (class)),
5816 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5817 cat
= CLASS_CATEGORY_LIST (cat
);
5820 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5821 CLASS_CATEGORY_LIST (class) = category
;
5824 /* Called after parsing each instance variable declaration. Necessary to
5825 preserve typedefs and implement public/private...
5827 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5830 add_instance_variable (class, public, declarator
, declspecs
, width
)
5837 tree field_decl
, raw_decl
;
5839 raw_decl
= build_tree_list (declspecs
, declarator
);
5841 if (CLASS_RAW_IVARS (class))
5842 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5844 CLASS_RAW_IVARS (class) = raw_decl
;
5846 field_decl
= grokfield (input_filename
, lineno
,
5847 declarator
, declspecs
, width
);
5849 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5853 TREE_PUBLIC (field_decl
) = 0;
5854 TREE_PRIVATE (field_decl
) = 0;
5855 TREE_PROTECTED (field_decl
) = 1;
5859 TREE_PUBLIC (field_decl
) = 1;
5860 TREE_PRIVATE (field_decl
) = 0;
5861 TREE_PROTECTED (field_decl
) = 0;
5865 TREE_PUBLIC (field_decl
) = 0;
5866 TREE_PRIVATE (field_decl
) = 1;
5867 TREE_PROTECTED (field_decl
) = 0;
5872 if (CLASS_IVARS (class))
5873 chainon (CLASS_IVARS (class), field_decl
);
5875 CLASS_IVARS (class) = field_decl
;
5881 is_ivar (decl_chain
, ident
)
5885 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5886 if (DECL_NAME (decl_chain
) == ident
)
5891 /* True if the ivar is private and we are not in its implementation. */
5897 if (TREE_PRIVATE (decl
)
5898 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5900 error ("instance variable `%s' is declared private",
5901 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5908 /* We have an instance variable reference;, check to see if it is public. */
5911 is_public (expr
, identifier
)
5915 tree basetype
= TREE_TYPE (expr
);
5916 enum tree_code code
= TREE_CODE (basetype
);
5919 if (code
== RECORD_TYPE
)
5921 if (TREE_STATIC_TEMPLATE (basetype
))
5923 if (!lookup_interface (TYPE_NAME (basetype
)))
5925 error ("Cannot find interface declaration for `%s'",
5926 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5930 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5932 if (TREE_PUBLIC (decl
))
5935 /* Important difference between the Stepstone translator:
5936 all instance variables should be public within the context
5937 of the implementation. */
5938 if (implementation_context
5939 && (((TREE_CODE (implementation_context
)
5940 == CLASS_IMPLEMENTATION_TYPE
)
5941 || (TREE_CODE (implementation_context
)
5942 == CATEGORY_IMPLEMENTATION_TYPE
))
5943 && (CLASS_NAME (implementation_context
)
5944 == TYPE_NAME (basetype
))))
5945 return ! is_private (decl
);
5947 error ("instance variable `%s' is declared %s",
5948 IDENTIFIER_POINTER (identifier
),
5949 TREE_PRIVATE (decl
) ? "private" : "protected");
5954 else if (implementation_context
&& (basetype
== objc_object_reference
))
5956 TREE_TYPE (expr
) = uprivate_record
;
5957 warning ("static access to object of type `id'");
5964 /* Implement @defs (<classname>) within struct bodies. */
5967 get_class_ivars (interface
)
5970 if (!doing_objc_thang
)
5973 return build_ivar_chain (interface
, 1);
5976 /* Make sure all entries in CHAIN are also in LIST. */
5979 check_methods (chain
, list
, mtype
)
5988 if (!lookup_method (list
, chain
))
5992 if (TREE_CODE (implementation_context
)
5993 == CLASS_IMPLEMENTATION_TYPE
)
5994 warning ("incomplete implementation of class `%s'",
5995 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5996 else if (TREE_CODE (implementation_context
)
5997 == CATEGORY_IMPLEMENTATION_TYPE
)
5998 warning ("incomplete implementation of category `%s'",
5999 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6003 warning ("method definition for `%c%s' not found",
6004 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6007 chain
= TREE_CHAIN (chain
);
6014 conforms_to_protocol (class, protocol
)
6020 tree p
= CLASS_PROTOCOL_LIST (class);
6022 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
6027 tree super
= (CLASS_SUPER_NAME (class)
6028 ? lookup_interface (CLASS_SUPER_NAME (class))
6030 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
6035 protocol
= TREE_CHAIN (protocol
);
6041 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6042 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6045 check_methods_accessible (chain
, context
, mtype
)
6052 tree base_context
= context
;
6056 context
= base_context
;
6060 list
= CLASS_CLS_METHODS (context
);
6062 list
= CLASS_NST_METHODS (context
);
6064 if (lookup_method (list
, chain
))
6067 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6068 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6069 context
= (CLASS_SUPER_NAME (context
)
6070 ? lookup_interface (CLASS_SUPER_NAME (context
))
6073 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6074 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6075 context
= (CLASS_NAME (context
)
6076 ? lookup_interface (CLASS_NAME (context
))
6082 if (context
== NULL_TREE
)
6086 if (TREE_CODE (implementation_context
)
6087 == CLASS_IMPLEMENTATION_TYPE
)
6088 warning ("incomplete implementation of class `%s'",
6090 (CLASS_NAME (implementation_context
)));
6091 else if (TREE_CODE (implementation_context
)
6092 == CATEGORY_IMPLEMENTATION_TYPE
)
6093 warning ("incomplete implementation of category `%s'",
6095 (CLASS_SUPER_NAME (implementation_context
)));
6098 warning ("method definition for `%c%s' not found",
6099 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6102 chain
= TREE_CHAIN (chain
); /* next method... */
6108 check_protocols (proto_list
, type
, name
)
6113 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6115 tree p
= TREE_VALUE (proto_list
);
6117 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6121 /* Ensure that all protocols have bodies. */
6122 if (flag_warn_protocol
) {
6123 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6124 CLASS_CLS_METHODS (implementation_context
),
6126 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6127 CLASS_NST_METHODS (implementation_context
),
6130 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6131 implementation_context
,
6133 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6134 implementation_context
,
6139 warning ("%s `%s' does not fully implement the `%s' protocol",
6140 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6145 ; /* An identifier if we could not find a protocol. */
6148 /* Check protocols recursively. */
6149 if (PROTOCOL_LIST (p
))
6152 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6153 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6154 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6159 /* Make sure that the class CLASS_NAME is defined
6160 CODE says which kind of thing CLASS_NAME ought to be.
6161 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6162 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6165 start_class (code
, class_name
, super_name
, protocol_list
)
6166 enum tree_code code
;
6173 if (!doing_objc_thang
)
6176 class = make_node (code
);
6177 TYPE_BINFO (class) = make_tree_vec (5);
6179 CLASS_NAME (class) = class_name
;
6180 CLASS_SUPER_NAME (class) = super_name
;
6181 CLASS_CLS_METHODS (class) = NULL_TREE
;
6183 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6185 error ("`%s' redeclared as different kind of symbol",
6186 IDENTIFIER_POINTER (class_name
));
6187 error_with_decl (decl
, "previous declaration of `%s'");
6190 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6193 static tree implemented_classes
= 0;
6194 tree chain
= implemented_classes
;
6195 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6196 if (TREE_VALUE (chain
) == class_name
)
6198 error ("reimplementation of class `%s'",
6199 IDENTIFIER_POINTER (class_name
));
6200 return error_mark_node
;
6202 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6203 implemented_classes
);
6206 /* Pre-build the following entities - for speed/convenience. */
6208 self_id
= get_identifier ("self");
6210 ucmd_id
= get_identifier ("_cmd");
6213 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6214 if (!objc_super_template
)
6215 objc_super_template
= build_super_template ();
6217 /* Reset for multiple classes per file. */
6220 implementation_context
= class;
6222 /* Lookup the interface for this implementation. */
6224 if (!(implementation_template
= lookup_interface (class_name
)))
6226 warning ("Cannot find interface declaration for `%s'",
6227 IDENTIFIER_POINTER (class_name
));
6228 add_class (implementation_template
= implementation_context
);
6231 /* If a super class has been specified in the implementation,
6232 insure it conforms to the one specified in the interface. */
6235 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6237 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6239 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6240 error ("conflicting super class name `%s'",
6241 IDENTIFIER_POINTER (super_name
));
6242 error ("previous declaration of `%s'", name
);
6245 else if (! super_name
)
6247 CLASS_SUPER_NAME (implementation_context
)
6248 = CLASS_SUPER_NAME (implementation_template
);
6252 else if (code
== CLASS_INTERFACE_TYPE
)
6254 if (lookup_interface (class_name
))
6255 warning ("duplicate interface declaration for class `%s'",
6256 IDENTIFIER_POINTER (class_name
));
6261 CLASS_PROTOCOL_LIST (class)
6262 = lookup_and_install_protocols (protocol_list
);
6265 else if (code
== CATEGORY_INTERFACE_TYPE
)
6267 tree class_category_is_assoc_with
;
6269 /* For a category, class_name is really the name of the class that
6270 the following set of methods will be associated with. We must
6271 find the interface so that can derive the objects template. */
6273 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6275 error ("Cannot find interface declaration for `%s'",
6276 IDENTIFIER_POINTER (class_name
));
6277 exit (FATAL_EXIT_CODE
);
6280 add_category (class_category_is_assoc_with
, class);
6283 CLASS_PROTOCOL_LIST (class)
6284 = lookup_and_install_protocols (protocol_list
);
6287 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6289 /* Pre-build the following entities for speed/convenience. */
6291 self_id
= get_identifier ("self");
6293 ucmd_id
= get_identifier ("_cmd");
6296 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6297 if (!objc_super_template
)
6298 objc_super_template
= build_super_template ();
6300 /* Reset for multiple classes per file. */
6303 implementation_context
= class;
6305 /* For a category, class_name is really the name of the class that
6306 the following set of methods will be associated with. We must
6307 find the interface so that can derive the objects template. */
6309 if (!(implementation_template
= lookup_interface (class_name
)))
6311 error ("Cannot find interface declaration for `%s'",
6312 IDENTIFIER_POINTER (class_name
));
6313 exit (FATAL_EXIT_CODE
);
6320 continue_class (class)
6323 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6324 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6326 struct imp_entry
*imp_entry
;
6329 /* Check consistency of the instance variables. */
6331 if (CLASS_IVARS (class))
6332 check_ivars (implementation_template
, class);
6334 /* code generation */
6336 ivar_context
= build_private_template (implementation_template
);
6338 if (!objc_class_template
)
6339 build_class_template ();
6342 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6343 perror ("unable to allocate in objc-tree.c");
6345 imp_entry
->next
= imp_list
;
6346 imp_entry
->imp_context
= class;
6347 imp_entry
->imp_template
= implementation_template
;
6349 synth_forward_declarations ();
6350 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6351 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6353 /* Append to front and increment count. */
6354 imp_list
= imp_entry
;
6355 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6360 return ivar_context
;
6363 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6365 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6367 if (!TYPE_FIELDS (record
))
6369 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6370 CLASS_STATIC_TEMPLATE (class) = record
;
6372 /* Mark this record as a class template for static typing. */
6373 TREE_STATIC_TEMPLATE (record
) = 1;
6380 return error_mark_node
;
6383 /* This is called once we see the "@end" in an interface/implementation. */
6386 finish_class (class)
6389 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6391 /* All code generation is done in finish_objc. */
6393 if (implementation_template
!= implementation_context
)
6395 /* Ensure that all method listed in the interface contain bodies. */
6396 check_methods (CLASS_CLS_METHODS (implementation_template
),
6397 CLASS_CLS_METHODS (implementation_context
), '+');
6398 check_methods (CLASS_NST_METHODS (implementation_template
),
6399 CLASS_NST_METHODS (implementation_context
), '-');
6401 if (CLASS_PROTOCOL_LIST (implementation_template
))
6402 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6404 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6408 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6410 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6412 /* Find the category interface from the class it is associated with. */
6415 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6417 category
= CLASS_CATEGORY_LIST (category
);
6422 /* Ensure all method listed in the interface contain bodies. */
6423 check_methods (CLASS_CLS_METHODS (category
),
6424 CLASS_CLS_METHODS (implementation_context
), '+');
6425 check_methods (CLASS_NST_METHODS (category
),
6426 CLASS_NST_METHODS (implementation_context
), '-');
6428 if (CLASS_PROTOCOL_LIST (category
))
6429 check_protocols (CLASS_PROTOCOL_LIST (category
),
6431 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6435 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6438 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6439 char *string
= (char *) alloca (strlen (class_name
) + 3);
6441 /* extern struct objc_object *_<my_name>; */
6443 sprintf (string
, "_%s", class_name
);
6445 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6446 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6447 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6453 add_protocol (protocol
)
6456 /* Put protocol on list in reverse order. */
6457 TREE_CHAIN (protocol
) = protocol_chain
;
6458 protocol_chain
= protocol
;
6459 return protocol_chain
;
6463 lookup_protocol (ident
)
6468 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6470 if (ident
== PROTOCOL_NAME (chain
))
6478 start_protocol (code
, name
, list
)
6479 enum tree_code code
;
6485 if (!doing_objc_thang
)
6488 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6489 if (!objc_protocol_template
)
6490 objc_protocol_template
= build_protocol_template ();
6492 protocol
= make_node (code
);
6493 TYPE_BINFO (protocol
) = make_tree_vec (2);
6495 PROTOCOL_NAME (protocol
) = name
;
6496 PROTOCOL_LIST (protocol
) = list
;
6498 lookup_and_install_protocols (list
);
6500 if (lookup_protocol (name
))
6501 warning ("duplicate declaration for protocol `%s'",
6502 IDENTIFIER_POINTER (name
));
6504 add_protocol (protocol
);
6506 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6512 finish_protocol (protocol
)
6513 tree protocol ATTRIBUTE_UNUSED
;
6518 /* "Encode" a data type into a string, which grows in util_obstack.
6519 ??? What is the FORMAT? Someone please document this! */
6522 encode_type_qualifiers (declspecs
)
6527 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6529 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6530 obstack_1grow (&util_obstack
, 'r');
6531 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6532 obstack_1grow (&util_obstack
, 'n');
6533 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6534 obstack_1grow (&util_obstack
, 'N');
6535 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6536 obstack_1grow (&util_obstack
, 'o');
6537 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6538 obstack_1grow (&util_obstack
, 'O');
6539 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6540 obstack_1grow (&util_obstack
, 'R');
6541 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6542 obstack_1grow (&util_obstack
, 'V');
6546 /* Encode a pointer type. */
6549 encode_pointer (type
, curtype
, format
)
6554 tree pointer_to
= TREE_TYPE (type
);
6556 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6558 if (TYPE_NAME (pointer_to
)
6559 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6561 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6563 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6565 obstack_1grow (&util_obstack
, '@');
6568 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6570 if (generating_instance_variables
)
6572 obstack_1grow (&util_obstack
, '@');
6573 obstack_1grow (&util_obstack
, '"');
6574 obstack_grow (&util_obstack
, name
, strlen (name
));
6575 obstack_1grow (&util_obstack
, '"');
6580 obstack_1grow (&util_obstack
, '@');
6584 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6586 obstack_1grow (&util_obstack
, '#');
6589 #ifndef OBJC_INT_SELECTORS
6590 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6592 obstack_1grow (&util_obstack
, ':');
6595 #endif /* OBJC_INT_SELECTORS */
6598 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6599 && TYPE_MODE (pointer_to
) == QImode
)
6601 obstack_1grow (&util_obstack
, '*');
6605 /* We have a type that does not get special treatment. */
6607 /* NeXT extension */
6608 obstack_1grow (&util_obstack
, '^');
6609 encode_type (pointer_to
, curtype
, format
);
6613 encode_array (type
, curtype
, format
)
6618 tree an_int_cst
= TYPE_SIZE (type
);
6619 tree array_of
= TREE_TYPE (type
);
6622 /* An incomplete array is treated like a pointer. */
6623 if (an_int_cst
== NULL
)
6625 encode_pointer (type
, curtype
, format
);
6629 sprintf (buffer
, "[%ld",
6630 (long) (TREE_INT_CST_LOW (an_int_cst
)
6631 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6633 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6634 encode_type (array_of
, curtype
, format
);
6635 obstack_1grow (&util_obstack
, ']');
6640 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6647 if (obstack_object_size (&util_obstack
) > 0
6648 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6650 tree name
= TYPE_NAME (type
);
6652 /* we have a reference; this is a NeXT extension. */
6654 if (obstack_object_size (&util_obstack
) - curtype
== 1
6655 && format
== OBJC_ENCODE_INLINE_DEFS
)
6657 /* Output format of struct for first level only. */
6658 tree fields
= TYPE_FIELDS (type
);
6660 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6662 obstack_1grow (&util_obstack
, left
);
6663 obstack_grow (&util_obstack
,
6664 IDENTIFIER_POINTER (name
),
6665 strlen (IDENTIFIER_POINTER (name
)));
6666 obstack_1grow (&util_obstack
, '=');
6670 obstack_1grow (&util_obstack
, left
);
6671 obstack_grow (&util_obstack
, "?=", 2);
6674 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6675 encode_field_decl (fields
, curtype
, format
);
6677 obstack_1grow (&util_obstack
, right
);
6680 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6682 obstack_1grow (&util_obstack
, left
);
6683 obstack_grow (&util_obstack
,
6684 IDENTIFIER_POINTER (name
),
6685 strlen (IDENTIFIER_POINTER (name
)));
6686 obstack_1grow (&util_obstack
, right
);
6691 /* We have an untagged structure or a typedef. */
6692 obstack_1grow (&util_obstack
, left
);
6693 obstack_1grow (&util_obstack
, '?');
6694 obstack_1grow (&util_obstack
, right
);
6700 tree name
= TYPE_NAME (type
);
6701 tree fields
= TYPE_FIELDS (type
);
6703 if (format
== OBJC_ENCODE_INLINE_DEFS
6704 || generating_instance_variables
)
6706 obstack_1grow (&util_obstack
, left
);
6707 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6708 obstack_grow (&util_obstack
,
6709 IDENTIFIER_POINTER (name
),
6710 strlen (IDENTIFIER_POINTER (name
)));
6712 obstack_1grow (&util_obstack
, '?');
6714 obstack_1grow (&util_obstack
, '=');
6716 for (; fields
; fields
= TREE_CHAIN (fields
))
6718 if (generating_instance_variables
)
6720 tree fname
= DECL_NAME (fields
);
6722 obstack_1grow (&util_obstack
, '"');
6723 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6725 obstack_grow (&util_obstack
,
6726 IDENTIFIER_POINTER (fname
),
6727 strlen (IDENTIFIER_POINTER (fname
)));
6730 obstack_1grow (&util_obstack
, '"');
6733 encode_field_decl (fields
, curtype
, format
);
6736 obstack_1grow (&util_obstack
, right
);
6741 obstack_1grow (&util_obstack
, left
);
6742 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6743 obstack_grow (&util_obstack
,
6744 IDENTIFIER_POINTER (name
),
6745 strlen (IDENTIFIER_POINTER (name
)));
6747 /* We have an untagged structure or a typedef. */
6748 obstack_1grow (&util_obstack
, '?');
6750 obstack_1grow (&util_obstack
, right
);
6756 encode_aggregate (type
, curtype
, format
)
6761 enum tree_code code
= TREE_CODE (type
);
6767 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6772 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6777 obstack_1grow (&util_obstack
, 'i');
6785 /* Support bitfields. The current version of Objective-C does not support
6786 them. The string will consist of one or more "b:n"'s where n is an
6787 integer describing the width of the bitfield. Currently, classes in
6788 the kit implement a method "-(char *)describeBitfieldStruct:" that
6789 simulates this. If they do not implement this method, the archiver
6790 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6791 according to the GNU compiler. After looking at the "kit", it appears
6792 that all classes currently rely on this default behavior, rather than
6793 hand generating this string (which is tedious). */
6796 encode_bitfield (width
)
6800 sprintf (buffer
, "b%d", width
);
6801 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6804 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6807 encode_type (type
, curtype
, format
)
6812 enum tree_code code
= TREE_CODE (type
);
6814 if (code
== INTEGER_TYPE
)
6816 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6818 /* Unsigned integer types. */
6820 if (TYPE_MODE (type
) == QImode
)
6821 obstack_1grow (&util_obstack
, 'C');
6822 else if (TYPE_MODE (type
) == HImode
)
6823 obstack_1grow (&util_obstack
, 'S');
6824 else if (TYPE_MODE (type
) == SImode
)
6826 if (type
== long_unsigned_type_node
)
6827 obstack_1grow (&util_obstack
, 'L');
6829 obstack_1grow (&util_obstack
, 'I');
6831 else if (TYPE_MODE (type
) == DImode
)
6832 obstack_1grow (&util_obstack
, 'Q');
6836 /* Signed integer types. */
6838 if (TYPE_MODE (type
) == QImode
)
6839 obstack_1grow (&util_obstack
, 'c');
6840 else if (TYPE_MODE (type
) == HImode
)
6841 obstack_1grow (&util_obstack
, 's');
6842 else if (TYPE_MODE (type
) == SImode
)
6844 if (type
== long_integer_type_node
)
6845 obstack_1grow (&util_obstack
, 'l');
6847 obstack_1grow (&util_obstack
, 'i');
6850 else if (TYPE_MODE (type
) == DImode
)
6851 obstack_1grow (&util_obstack
, 'q');
6855 else if (code
== REAL_TYPE
)
6857 /* Floating point types. */
6859 if (TYPE_MODE (type
) == SFmode
)
6860 obstack_1grow (&util_obstack
, 'f');
6861 else if (TYPE_MODE (type
) == DFmode
6862 || TYPE_MODE (type
) == TFmode
)
6863 obstack_1grow (&util_obstack
, 'd');
6866 else if (code
== VOID_TYPE
)
6867 obstack_1grow (&util_obstack
, 'v');
6869 else if (code
== ARRAY_TYPE
)
6870 encode_array (type
, curtype
, format
);
6872 else if (code
== POINTER_TYPE
)
6873 encode_pointer (type
, curtype
, format
);
6875 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6876 encode_aggregate (type
, curtype
, format
);
6878 else if (code
== FUNCTION_TYPE
) /* '?' */
6879 obstack_1grow (&util_obstack
, '?');
6883 encode_complete_bitfield (int position
, tree type
, int size
)
6885 enum tree_code code
= TREE_CODE (type
);
6887 char charType
= '?';
6889 if (code
== INTEGER_TYPE
)
6891 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6893 /* Unsigned integer types. */
6895 if (TYPE_MODE (type
) == QImode
)
6897 else if (TYPE_MODE (type
) == HImode
)
6899 else if (TYPE_MODE (type
) == SImode
)
6901 if (type
== long_unsigned_type_node
)
6906 else if (TYPE_MODE (type
) == DImode
)
6911 /* Signed integer types. */
6913 if (TYPE_MODE (type
) == QImode
)
6915 else if (TYPE_MODE (type
) == HImode
)
6917 else if (TYPE_MODE (type
) == SImode
)
6919 if (type
== long_integer_type_node
)
6925 else if (TYPE_MODE (type
) == DImode
)
6933 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6934 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6938 encode_field_decl (field_decl
, curtype
, format
)
6945 type
= TREE_TYPE (field_decl
);
6947 /* If this field is obviously a bitfield, or is a bitfield that has been
6948 clobbered to look like a ordinary integer mode, go ahead and generate
6949 the bitfield typing information. */
6950 if (flag_next_runtime
)
6952 if (DECL_BIT_FIELD (field_decl
))
6953 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6955 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6959 if (DECL_BIT_FIELD (field_decl
))
6960 encode_complete_bitfield (int_bit_position (field_decl
),
6961 DECL_BIT_FIELD_TYPE (field_decl
),
6962 tree_low_cst (DECL_SIZE (field_decl
), 1));
6964 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6969 expr_last (complex_expr
)
6975 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6976 complex_expr
= next
;
6978 return complex_expr
;
6981 /* The selector of the current method,
6982 or NULL if we aren't compiling a method. */
6985 maybe_objc_method_name (decl
)
6986 tree decl ATTRIBUTE_UNUSED
;
6989 return METHOD_SEL_NAME (method_context
);
6994 /* Transform a method definition into a function definition as follows:
6995 - synthesize the first two arguments, "self" and "_cmd". */
6998 start_method_def (method
)
7003 /* Required to implement _msgSuper. */
7004 method_context
= method
;
7005 UOBJC_SUPER_decl
= NULL_TREE
;
7007 /* Must be called BEFORE start_function. */
7010 /* Generate prototype declarations for arguments..."new-style". */
7012 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
7013 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
7015 /* Really a `struct objc_class *'. However, we allow people to
7016 assign to self, which changes its type midstream. */
7017 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
7019 push_parm_decl (build_tree_list
7020 (build_tree_list (decl_specs
,
7021 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
7022 build_tree_list (unused_list
, NULL_TREE
)));
7024 #ifdef OBJC_INT_SELECTORS
7025 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
7026 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
7027 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
7028 build_tree_list (unused_list
, NULL_TREE
)));
7029 #else /* not OBJC_INT_SELECTORS */
7030 decl_specs
= build_tree_list (NULL_TREE
,
7031 xref_tag (RECORD_TYPE
,
7032 get_identifier (TAG_SELECTOR
)));
7033 push_parm_decl (build_tree_list
7034 (build_tree_list (decl_specs
,
7035 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
7036 build_tree_list (unused_list
, NULL_TREE
)));
7037 #endif /* not OBJC_INT_SELECTORS */
7039 /* Generate argument declarations if a keyword_decl. */
7040 if (METHOD_SEL_ARGS (method
))
7042 tree arglist
= METHOD_SEL_ARGS (method
);
7045 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
7046 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
7050 tree last_expr
= expr_last (arg_decl
);
7052 /* Unite the abstract decl with its name. */
7053 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
7054 push_parm_decl (build_tree_list
7055 (build_tree_list (arg_spec
, arg_decl
),
7056 build_tree_list (NULL_TREE
, NULL_TREE
)));
7058 /* Unhook: restore the abstract declarator. */
7059 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
7063 push_parm_decl (build_tree_list
7064 (build_tree_list (arg_spec
,
7065 KEYWORD_ARG_NAME (arglist
)),
7066 build_tree_list (NULL_TREE
, NULL_TREE
)));
7068 arglist
= TREE_CHAIN (arglist
);
7073 if (METHOD_ADD_ARGS (method
) != NULL_TREE
7074 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
7076 /* We have a variable length selector - in "prototype" format. */
7077 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7080 /* This must be done prior to calling pushdecl. pushdecl is
7081 going to change our chain on us. */
7082 tree nextkey
= TREE_CHAIN (akey
);
7090 warn_with_method (message
, mtype
, method
)
7091 const char *message
;
7095 if (count_error (1) == 0)
7098 report_error_function (DECL_SOURCE_FILE (method
));
7100 fprintf (stderr
, "%s:%d: warning: ",
7101 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7102 bzero (errbuf
, BUFSIZE
);
7103 fprintf (stderr
, "%s `%c%s'\n",
7104 message
, mtype
, gen_method_decl (method
, errbuf
));
7107 /* Return 1 if METHOD is consistent with PROTO. */
7110 comp_method_with_proto (method
, proto
)
7113 static tree function_type
= 0;
7115 /* Create a function_type node once. */
7117 function_type
= make_node (FUNCTION_TYPE
);
7119 /* Install argument types - normally set by build_function_type. */
7120 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7122 /* install return type */
7123 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7125 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7128 /* Return 1 if PROTO1 is consistent with PROTO2. */
7131 comp_proto_with_proto (proto1
, proto2
)
7132 tree proto1
, proto2
;
7134 static tree function_type1
= 0, function_type2
= 0;
7136 /* Create a couple function_type node's once. */
7137 if (!function_type1
)
7139 function_type1
= make_node (FUNCTION_TYPE
);
7140 function_type2
= make_node (FUNCTION_TYPE
);
7143 /* Install argument types; normally set by build_function_type. */
7144 TYPE_ARG_TYPES (function_type1
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7145 TYPE_ARG_TYPES (function_type2
) = get_arg_type_list (proto2
, METHOD_REF
, 0);
7147 /* Install return type. */
7148 TREE_TYPE (function_type1
) = groktypename (TREE_TYPE (proto1
));
7149 TREE_TYPE (function_type2
) = groktypename (TREE_TYPE (proto2
));
7151 return comptypes (function_type1
, function_type2
);
7154 /* - Generate an identifier for the function. the format is "_n_cls",
7155 where 1 <= n <= nMethods, and cls is the name the implementation we
7157 - Install the return type from the method declaration.
7158 - If we have a prototype, check for type consistency. */
7161 really_start_method (method
, parmlist
)
7162 tree method
, parmlist
;
7164 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7165 tree method_decl
, method_id
;
7166 const char *sel_name
, *class_name
, *cat_name
;
7169 /* Synth the storage class & assemble the return type. */
7170 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7171 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7172 decl_specs
= chainon (sc_spec
, ret_spec
);
7174 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7175 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7176 cat_name
= ((TREE_CODE (implementation_context
)
7177 == CLASS_IMPLEMENTATION_TYPE
)
7179 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7182 /* Make sure this is big enough for any plausible method label. */
7183 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7184 + (cat_name
? strlen (cat_name
) : 0));
7186 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7187 class_name
, cat_name
, sel_name
, method_slot
);
7189 method_id
= get_identifier (buf
);
7191 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7193 /* Check the declarator portion of the return type for the method. */
7194 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7196 /* Unite the complex decl (specified in the abstract decl) with the
7197 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7198 tree save_expr
= expr_last (ret_decl
);
7200 TREE_OPERAND (save_expr
, 0) = method_decl
;
7201 method_decl
= ret_decl
;
7203 /* Fool the parser into thinking it is starting a function. */
7204 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7206 /* Unhook: this has the effect of restoring the abstract declarator. */
7207 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7212 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7214 /* Fool the parser into thinking it is starting a function. */
7215 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7217 /* Unhook: this has the effect of restoring the abstract declarator. */
7218 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7221 METHOD_DEFINITION (method
) = current_function_decl
;
7223 if (implementation_template
!= implementation_context
)
7227 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7228 proto
= lookup_instance_method_static (implementation_template
,
7229 METHOD_SEL_NAME (method
));
7231 proto
= lookup_class_method_static (implementation_template
,
7232 METHOD_SEL_NAME (method
));
7234 if (proto
&& ! comp_method_with_proto (method
, proto
))
7236 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7238 warn_with_method ("conflicting types for", type
, method
);
7239 warn_with_method ("previous declaration of", type
, proto
);
7244 /* The following routine is always called...this "architecture" is to
7245 accommodate "old-style" variable length selectors.
7247 - a:a b:b // prototype ; id c; id d; // old-style. */
7250 continue_method_def ()
7254 if (METHOD_ADD_ARGS (method_context
) == objc_ellipsis_node
)
7255 /* We have a `, ...' immediately following the selector. */
7256 parmlist
= get_parm_info (0);
7258 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7260 /* Set self_decl from the first argument...this global is used by
7261 build_ivar_reference calling build_indirect_ref. */
7262 self_decl
= TREE_PURPOSE (parmlist
);
7265 really_start_method (method_context
, parmlist
);
7266 store_parm_decls ();
7269 /* Called by the parser, from the `pushlevel' production. */
7274 if (!UOBJC_SUPER_decl
)
7276 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7277 build_tree_list (NULL_TREE
,
7278 objc_super_template
),
7279 0, NULL_TREE
, NULL_TREE
);
7281 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7283 /* This prevents `unused variable' warnings when compiling with -Wall. */
7284 TREE_USED (UOBJC_SUPER_decl
) = 1;
7285 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7289 /* _n_Method (id self, SEL sel, ...)
7291 struct objc_super _S;
7292 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7296 get_super_receiver ()
7300 tree super_expr
, super_expr_list
;
7302 /* Set receiver to self. */
7303 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7304 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7305 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7307 /* Set class to begin searching. */
7308 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7309 get_identifier ("class"));
7311 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7313 /* [_cls, __cls]Super are "pre-built" in
7314 synth_forward_declarations. */
7316 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7317 ((TREE_CODE (method_context
)
7318 == INSTANCE_METHOD_DECL
)
7320 : uucls_super_ref
));
7324 /* We have a category. */
7326 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7331 error ("no super class declared in interface for `%s'",
7332 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7333 return error_mark_node
;
7336 if (flag_next_runtime
)
7338 super_class
= get_class_reference (super_name
);
7339 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7341 = build_component_ref (build_indirect_ref (super_class
, "->"),
7342 get_identifier ("isa"));
7346 add_class_reference (super_name
);
7347 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7348 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7349 assemble_external (super_class
);
7351 = build_function_call
7355 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7356 IDENTIFIER_POINTER (super_name
))));
7359 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7360 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7363 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7365 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7366 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7368 return build_compound_expr (super_expr_list
);
7372 error ("[super ...] must appear in a method context");
7373 return error_mark_node
;
7378 encode_method_def (func_decl
)
7383 HOST_WIDE_INT max_parm_end
= 0;
7388 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7389 obstack_object_size (&util_obstack
),
7390 OBJC_ENCODE_INLINE_DEFS
);
7393 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7394 parms
= TREE_CHAIN (parms
))
7396 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7397 + int_size_in_bytes (TREE_TYPE (parms
)));
7399 if (! offset_is_register
&& parm_end
> max_parm_end
)
7400 max_parm_end
= parm_end
;
7403 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7405 sprintf (buffer
, "%d", stack_size
);
7406 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7408 /* Argument types. */
7409 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7410 parms
= TREE_CHAIN (parms
))
7413 encode_type (TREE_TYPE (parms
),
7414 obstack_object_size (&util_obstack
),
7415 OBJC_ENCODE_INLINE_DEFS
);
7417 /* Compute offset. */
7418 sprintf (buffer
, "%d", forwarding_offset (parms
));
7420 /* Indicate register. */
7421 if (offset_is_register
)
7422 obstack_1grow (&util_obstack
, '+');
7424 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7427 obstack_1grow (&util_obstack
, 0);
7428 result
= get_identifier (obstack_finish (&util_obstack
));
7429 obstack_free (&util_obstack
, util_firstobj
);
7434 finish_method_def ()
7436 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7438 finish_function (0);
7440 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7441 since the optimizer may find "may be used before set" errors. */
7442 method_context
= NULL_TREE
;
7447 lang_report_error_function (decl
)
7452 fprintf (stderr
, "In method `%s'\n",
7453 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7463 is_complex_decl (type
)
7466 return (TREE_CODE (type
) == ARRAY_TYPE
7467 || TREE_CODE (type
) == FUNCTION_TYPE
7468 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7472 /* Code to convert a decl node into text for a declaration in C. */
7474 static char tmpbuf
[256];
7477 adorn_decl (decl
, str
)
7481 enum tree_code code
= TREE_CODE (decl
);
7483 if (code
== ARRAY_REF
)
7485 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7487 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7488 sprintf (str
+ strlen (str
), "[%ld]",
7489 (long) TREE_INT_CST_LOW (an_int_cst
));
7494 else if (code
== ARRAY_TYPE
)
7496 tree an_int_cst
= TYPE_SIZE (decl
);
7497 tree array_of
= TREE_TYPE (decl
);
7499 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7500 sprintf (str
+ strlen (str
), "[%ld]",
7501 (long) (TREE_INT_CST_LOW (an_int_cst
)
7502 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7507 else if (code
== CALL_EXPR
)
7509 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7514 gen_declaration (chain
, str
);
7515 chain
= TREE_CHAIN (chain
);
7522 else if (code
== FUNCTION_TYPE
)
7524 tree chain
= TYPE_ARG_TYPES (decl
);
7527 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7529 gen_declaration (TREE_VALUE (chain
), str
);
7530 chain
= TREE_CHAIN (chain
);
7531 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7537 else if (code
== INDIRECT_REF
)
7539 strcpy (tmpbuf
, "*");
7540 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7544 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7546 chain
= TREE_CHAIN (chain
))
7548 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7550 strcat (tmpbuf
, " ");
7551 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7555 strcat (tmpbuf
, " ");
7557 strcat (tmpbuf
, str
);
7558 strcpy (str
, tmpbuf
);
7561 else if (code
== POINTER_TYPE
)
7563 strcpy (tmpbuf
, "*");
7564 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7566 if (TREE_READONLY (decl
))
7567 strcat (tmpbuf
, " const");
7568 if (TYPE_VOLATILE (decl
))
7569 strcat (tmpbuf
, " volatile");
7571 strcat (tmpbuf
, " ");
7573 strcat (tmpbuf
, str
);
7574 strcpy (str
, tmpbuf
);
7579 gen_declarator (decl
, buf
, name
)
7586 enum tree_code code
= TREE_CODE (decl
);
7596 op
= TREE_OPERAND (decl
, 0);
7598 /* We have a pointer to a function or array...(*)(), (*)[] */
7599 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7600 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7603 str
= gen_declarator (op
, buf
, name
);
7607 strcpy (tmpbuf
, "(");
7608 strcat (tmpbuf
, str
);
7609 strcat (tmpbuf
, ")");
7610 strcpy (str
, tmpbuf
);
7613 adorn_decl (decl
, str
);
7622 /* This clause is done iteratively rather than recursively. */
7625 op
= (is_complex_decl (TREE_TYPE (decl
))
7626 ? TREE_TYPE (decl
) : NULL_TREE
);
7628 adorn_decl (decl
, str
);
7630 /* We have a pointer to a function or array...(*)(), (*)[] */
7631 if (code
== POINTER_TYPE
7632 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7633 || TREE_CODE (op
) == ARRAY_TYPE
))
7635 strcpy (tmpbuf
, "(");
7636 strcat (tmpbuf
, str
);
7637 strcat (tmpbuf
, ")");
7638 strcpy (str
, tmpbuf
);
7641 decl
= (is_complex_decl (TREE_TYPE (decl
))
7642 ? TREE_TYPE (decl
) : NULL_TREE
);
7645 while (decl
&& (code
= TREE_CODE (decl
)))
7650 case IDENTIFIER_NODE
:
7651 /* Will only happen if we are processing a "raw" expr-decl. */
7652 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7663 /* We have an abstract declarator or a _DECL node. */
7671 gen_declspecs (declspecs
, buf
, raw
)
7680 for (chain
= nreverse (copy_list (declspecs
));
7681 chain
; chain
= TREE_CHAIN (chain
))
7683 tree aspec
= TREE_VALUE (chain
);
7685 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7686 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7687 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7689 if (TYPE_NAME (aspec
))
7691 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7693 if (! TREE_STATIC_TEMPLATE (aspec
))
7694 strcat (buf
, "struct ");
7695 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7700 tree chain
= protocol_list
;
7707 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7708 chain
= TREE_CHAIN (chain
);
7717 strcat (buf
, "untagged struct");
7720 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7722 if (TYPE_NAME (aspec
))
7724 if (! TREE_STATIC_TEMPLATE (aspec
))
7725 strcat (buf
, "union ");
7726 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7729 strcat (buf
, "untagged union");
7732 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7734 if (TYPE_NAME (aspec
))
7736 if (! TREE_STATIC_TEMPLATE (aspec
))
7737 strcat (buf
, "enum ");
7738 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7741 strcat (buf
, "untagged enum");
7744 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7745 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7747 else if (IS_ID (aspec
))
7749 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7754 tree chain
= protocol_list
;
7761 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7762 chain
= TREE_CHAIN (chain
);
7769 if (TREE_CHAIN (chain
))
7775 /* Type qualifiers. */
7776 if (TREE_READONLY (declspecs
))
7777 strcat (buf
, "const ");
7778 if (TYPE_VOLATILE (declspecs
))
7779 strcat (buf
, "volatile ");
7781 switch (TREE_CODE (declspecs
))
7783 /* Type specifiers. */
7786 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7788 /* Signed integer types. */
7790 if (declspecs
== short_integer_type_node
)
7791 strcat (buf
, "short int ");
7792 else if (declspecs
== integer_type_node
)
7793 strcat (buf
, "int ");
7794 else if (declspecs
== long_integer_type_node
)
7795 strcat (buf
, "long int ");
7796 else if (declspecs
== long_long_integer_type_node
)
7797 strcat (buf
, "long long int ");
7798 else if (declspecs
== signed_char_type_node
7799 || declspecs
== char_type_node
)
7800 strcat (buf
, "char ");
7802 /* Unsigned integer types. */
7804 else if (declspecs
== short_unsigned_type_node
)
7805 strcat (buf
, "unsigned short ");
7806 else if (declspecs
== unsigned_type_node
)
7807 strcat (buf
, "unsigned int ");
7808 else if (declspecs
== long_unsigned_type_node
)
7809 strcat (buf
, "unsigned long ");
7810 else if (declspecs
== long_long_unsigned_type_node
)
7811 strcat (buf
, "unsigned long long ");
7812 else if (declspecs
== unsigned_char_type_node
)
7813 strcat (buf
, "unsigned char ");
7817 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7819 if (declspecs
== float_type_node
)
7820 strcat (buf
, "float ");
7821 else if (declspecs
== double_type_node
)
7822 strcat (buf
, "double ");
7823 else if (declspecs
== long_double_type_node
)
7824 strcat (buf
, "long double ");
7828 if (TYPE_NAME (declspecs
)
7829 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7831 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7833 if (! TREE_STATIC_TEMPLATE (declspecs
))
7834 strcat (buf
, "struct ");
7835 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7839 tree chain
= protocol_list
;
7846 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7847 chain
= TREE_CHAIN (chain
);
7856 strcat (buf
, "untagged struct");
7862 if (TYPE_NAME (declspecs
)
7863 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7865 strcat (buf
, "union ");
7866 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7871 strcat (buf
, "untagged union ");
7875 if (TYPE_NAME (declspecs
)
7876 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7878 strcat (buf
, "enum ");
7879 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7884 strcat (buf
, "untagged enum ");
7888 strcat (buf
, "void ");
7893 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7898 tree chain
= protocol_list
;
7905 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7906 chain
= TREE_CHAIN (chain
);
7923 gen_declaration (atype_or_adecl
, buf
)
7924 tree atype_or_adecl
;
7929 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7931 tree declspecs
; /* "identifier_node", "record_type" */
7932 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7934 /* We have a "raw", abstract declarator (typename). */
7935 declarator
= TREE_VALUE (atype_or_adecl
);
7936 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7938 gen_declspecs (declspecs
, buf
, 1);
7942 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7949 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7950 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7952 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7953 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7954 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7955 atype
= TREE_TYPE (atype_or_adecl
);
7957 /* Assume we have a *_type node. */
7958 atype
= atype_or_adecl
;
7960 if (is_complex_decl (atype
))
7964 /* Get the declaration specifier; it is at the end of the list. */
7965 declarator
= chain
= atype
;
7967 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7968 while (is_complex_decl (chain
));
7975 declarator
= NULL_TREE
;
7978 gen_declspecs (declspecs
, buf
, 0);
7980 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7981 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7982 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7984 const char *decl_name
=
7985 (DECL_NAME (atype_or_adecl
)
7986 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7991 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7994 else if (decl_name
[0])
7997 strcat (buf
, decl_name
);
8000 else if (declarator
)
8003 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
8010 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8013 gen_method_decl (method
, buf
)
8019 if (RAW_TYPESPEC (method
) != objc_object_reference
)
8022 gen_declaration (TREE_TYPE (method
), buf
);
8026 chain
= METHOD_SEL_ARGS (method
);
8029 /* We have a chain of keyword_decls. */
8032 if (KEYWORD_KEY_NAME (chain
))
8033 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8036 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
8039 gen_declaration (TREE_TYPE (chain
), buf
);
8043 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8044 if ((chain
= TREE_CHAIN (chain
)))
8049 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
8050 strcat (buf
, ", ...");
8051 else if (METHOD_ADD_ARGS (method
))
8053 /* We have a tree list node as generate by get_parm_info. */
8054 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8056 /* Know we have a chain of parm_decls. */
8060 gen_declaration (chain
, buf
);
8061 chain
= TREE_CHAIN (chain
);
8067 /* We have a unary selector. */
8068 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8076 dump_interface (fp
, chain
)
8080 char *buf
= (char *)xmalloc (256);
8081 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8082 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8083 tree nst_methods
= CLASS_NST_METHODS (chain
);
8084 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8086 fprintf (fp
, "\n@interface %s", my_name
);
8088 if (CLASS_SUPER_NAME (chain
))
8090 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8091 fprintf (fp
, " : %s\n", super_name
);
8098 fprintf (fp
, "{\n");
8102 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8103 ivar_decls
= TREE_CHAIN (ivar_decls
);
8106 fprintf (fp
, "}\n");
8112 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8113 nst_methods
= TREE_CHAIN (nst_methods
);
8119 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8120 cls_methods
= TREE_CHAIN (cls_methods
);
8122 fprintf (fp
, "\n@end");
8125 /* Demangle function for Objective-C */
8127 objc_demangle (mangled
)
8128 const char *mangled
;
8130 char *demangled
, *cp
;
8132 if (mangled
[0] == '_' &&
8133 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8136 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8137 if (mangled
[1] == 'i')
8138 *cp
++ = '-'; /* for instance method */
8140 *cp
++ = '+'; /* for class method */
8141 *cp
++ = '['; /* opening left brace */
8142 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8143 while (*cp
&& *cp
== '_')
8144 cp
++; /* skip any initial underbars in class name */
8145 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8148 free(demangled
); /* not mangled name */
8151 if (cp
[1] == '_') /* easy case: no category name */
8153 *cp
++ = ' '; /* replace two '_' with one ' ' */
8154 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8158 *cp
++ = '('; /* less easy case: category name */
8159 cp
= strchr(cp
, '_');
8162 free(demangled
); /* not mangled name */
8166 *cp
++ = ' '; /* overwriting 1st char of method name... */
8167 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8169 while (*cp
&& *cp
== '_')
8170 cp
++; /* skip any initial underbars in method name */
8173 *cp
= ':'; /* replace remaining '_' with ':' */
8174 *cp
++ = ']'; /* closing right brace */
8175 *cp
++ = 0; /* string terminator */
8179 return mangled
; /* not an objc mangled name */
8183 objc_printable_name (decl
, kind
)
8185 int kind ATTRIBUTE_UNUSED
;
8187 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8193 /* Add the special tree codes of Objective C to the tables. */
8195 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8197 gcc_obstack_init (&util_obstack
);
8198 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8200 memcpy (tree_code_type
+ (int) LAST_CODE
,
8201 objc_tree_code_type
,
8202 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8203 memcpy (tree_code_length
+ (int) LAST_CODE
,
8204 objc_tree_code_length
,
8205 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8206 memcpy (tree_code_name
+ (int) LAST_CODE
,
8207 objc_tree_code_name
,
8208 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8210 errbuf
= (char *)xmalloc (BUFSIZE
);
8212 synth_module_prologue ();
8214 /* Change the default error function */
8215 decl_printable_name
= objc_printable_name
;
8221 struct imp_entry
*impent
;
8223 /* The internally generated initializers appear to have missing braces.
8224 Don't warn about this. */
8225 int save_warn_missing_braces
= warn_missing_braces
;
8226 warn_missing_braces
= 0;
8228 generate_forward_declaration_to_string_table ();
8230 #ifdef OBJC_PROLOGUE
8234 /* Process the static instances here because initialization of objc_symtab
8236 if (objc_static_instances
)
8237 generate_static_references ();
8239 if (implementation_context
|| class_names_chain
8240 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8241 generate_objc_symtab_decl ();
8243 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8245 implementation_context
= impent
->imp_context
;
8246 implementation_template
= impent
->imp_template
;
8248 UOBJC_CLASS_decl
= impent
->class_decl
;
8249 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8251 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8253 /* all of the following reference the string pool... */
8254 generate_ivar_lists ();
8255 generate_dispatch_tables ();
8256 generate_shared_structures ();
8260 generate_dispatch_tables ();
8261 generate_category (implementation_context
);
8265 /* If we are using an array of selectors, we must always
8266 finish up the array decl even if no selectors were used. */
8267 if (! flag_next_runtime
|| sel_ref_chain
)
8268 build_selector_translation_table ();
8271 generate_protocols ();
8273 if (implementation_context
|| class_names_chain
|| objc_static_instances
8274 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8276 /* Arrange for Objc data structures to be initialized at run time. */
8277 const char *init_name
= build_module_descriptor ();
8279 assemble_constructor (init_name
);
8282 /* Dump the class references. This forces the appropriate classes
8283 to be linked into the executable image, preserving unix archive
8284 semantics. This can be removed when we move to a more dynamically
8285 linked environment. */
8287 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8289 handle_class_ref (chain
);
8290 if (TREE_PURPOSE (chain
))
8291 generate_classref_translation_entry (chain
);
8294 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8295 handle_impent (impent
);
8297 /* Dump the string table last. */
8299 generate_strings ();
8301 if (flag_gen_declaration
)
8303 add_class (implementation_context
);
8304 dump_interface (gen_declaration_file
, implementation_context
);
8312 /* Run through the selector hash tables and print a warning for any
8313 selector which has multiple methods. */
8315 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8316 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8319 tree meth
= hsh
->key
;
8320 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8324 warning ("potential selector conflict for method `%s'",
8325 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8326 warn_with_method ("found", type
, meth
);
8327 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8328 warn_with_method ("found", type
, loop
->value
);
8331 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8332 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8335 tree meth
= hsh
->key
;
8336 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8340 warning ("potential selector conflict for method `%s'",
8341 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8342 warn_with_method ("found", type
, meth
);
8343 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8344 warn_with_method ("found", type
, loop
->value
);
8348 warn_missing_braces
= save_warn_missing_braces
;
8351 /* Subroutines of finish_objc. */
8354 generate_classref_translation_entry (chain
)
8357 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8360 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8362 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8363 expr
= build_c_cast (type
, expr
); /* cast! */
8365 name
= DECL_NAME (TREE_PURPOSE (chain
));
8367 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8369 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8370 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8372 /* The decl that is returned from start_decl is the one that we
8373 forward declared in build_class_reference. */
8374 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8375 finish_decl (decl
, expr
, NULL_TREE
);
8380 handle_class_ref (chain
)
8383 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8384 if (! flag_next_runtime
)
8387 char *string
= (char *) alloca (strlen (name
) + 30);
8390 sprintf (string
, "%sobjc_class_name_%s",
8391 (flag_next_runtime
? "." : "__"), name
);
8393 /* Make a decl for this name, so we can use its address in a tree. */
8394 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8395 DECL_EXTERNAL (decl
) = 1;
8396 TREE_PUBLIC (decl
) = 1;
8399 rest_of_decl_compilation (decl
, 0, 0, 0);
8401 /* Make following constant read-only (why not)? */
8402 readonly_data_section ();
8404 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8406 /* Align the section properly. */
8407 assemble_constant_align (exp
);
8409 /* Inform the assembler about this new external thing. */
8410 assemble_external (decl
);
8412 /* Output a constant to reference this address. */
8413 output_constant (exp
, int_size_in_bytes (string_type_node
));
8417 /* This overreliance on our assembler (i.e. lack of portability)
8418 should be dealt with at some point. The GNU strategy (above)
8419 won't work either, but it is a start. */
8420 char *string
= (char *) alloca (strlen (name
) + 30);
8421 sprintf (string
, ".reference .objc_class_name_%s", name
);
8422 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8427 handle_impent (impent
)
8428 struct imp_entry
*impent
;
8430 implementation_context
= impent
->imp_context
;
8431 implementation_template
= impent
->imp_template
;
8433 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8435 const char *class_name
=
8436 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8437 char *string
= (char *) alloca (strlen (class_name
) + 30);
8439 if (flag_next_runtime
)
8441 /* Grossly unportable.
8442 People should know better than to assume
8443 such things about assembler syntax! */
8444 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8445 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8447 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8448 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8453 sprintf (string
, "%sobjc_class_name_%s",
8454 (flag_next_runtime
? "." : "__"), class_name
);
8455 assemble_global (string
);
8456 assemble_label (string
);
8460 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8462 const char *class_name
=
8463 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8464 const char *class_super_name
=
8465 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8466 char *string
= (char *) alloca (strlen (class_name
)
8467 + strlen (class_super_name
) + 30);
8469 /* Do the same for categories. Even though no references to these
8470 symbols are generated automatically by the compiler, it gives
8471 you a handle to pull them into an archive by hand. */
8472 if (flag_next_runtime
)
8474 /* Grossly unportable. */
8475 sprintf (string
, ".objc_category_name_%s_%s=0",
8476 class_name
, class_super_name
);
8477 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8479 sprintf (string
, ".globl .objc_category_name_%s_%s",
8480 class_name
, class_super_name
);
8481 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8486 sprintf (string
, "%sobjc_category_name_%s_%s",
8487 (flag_next_runtime
? "." : "__"),
8488 class_name
, class_super_name
);
8489 assemble_global (string
);
8490 assemble_label (string
);
8501 char *buf
= (char *)xmalloc (256);
8503 { /* dump function prototypes */
8504 tree loop
= UOBJC_MODULES_decl
;
8506 fprintf (fp
, "\n\nfunction prototypes:\n");
8509 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8511 /* We have a function definition: generate prototype. */
8512 bzero (errbuf
, BUFSIZE
);
8513 gen_declaration (loop
, errbuf
);
8514 fprintf (fp
, "%s;\n", errbuf
);
8516 loop
= TREE_CHAIN (loop
);
8520 /* Dump global chains. */
8522 int i
, index
= 0, offset
= 0;
8525 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8527 if (hashlist
= nst_method_hash_list
[i
])
8529 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8533 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8534 hashlist
= hashlist
->next
;
8540 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8542 if (hashlist
= cls_method_hash_list
[i
])
8544 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8548 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8549 hashlist
= hashlist
->next
;
8555 fprintf (fp
, "\nsel_refdef_chain:\n");
8556 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8558 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8559 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8561 /* add one for the '\0' character */
8562 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8565 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8571 print_lang_statistics ()
8576 ggc_mark_imp_list (arg
)
8579 struct imp_entry
*impent
;
8581 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8583 ggc_mark_tree (impent
->imp_context
);
8584 ggc_mark_tree (impent
->imp_template
);
8585 ggc_mark_tree (impent
->class_decl
);
8586 ggc_mark_tree (impent
->meta_decl
);
8591 ggc_mark_hash_table (arg
)
8594 hash
*hash_table
= *(hash
**)arg
;
8599 if (hash_table
== NULL
)
8601 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8602 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8604 ggc_mark_tree (hst
->key
);
8605 for (list
= hst
->list
; list
; list
= list
->next
)
8606 ggc_mark_tree (list
->value
);
8610 /* Add GC roots for variables local to this file. */
8612 objc_act_parse_init ()
8614 ggc_add_tree_root (&objc_ellipsis_node
, 1);
8615 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8616 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8617 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8618 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);