1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
3 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':
62 #include "langhooks.h"
63 #include "langhooks-def.h"
65 /* This is the default way of generating a method name. */
66 /* I am not sure it is really correct.
67 Perhaps there's a danger that it will make name conflicts
68 if method names contain underscores. -- rms. */
69 #ifndef OBJC_GEN_METHOD_LABEL
70 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
73 sprintf ((BUF), "_%s_%s_%s_%s", \
74 ((IS_INST) ? "i" : "c"), \
76 ((CAT_NAME)? (CAT_NAME) : ""), \
78 for (temp = (BUF); *temp; temp++) \
79 if (*temp == ':') *temp = '_'; \
83 /* These need specifying. */
84 #ifndef OBJC_FORWARDING_STACK_OFFSET
85 #define OBJC_FORWARDING_STACK_OFFSET 0
88 #ifndef OBJC_FORWARDING_MIN_OFFSET
89 #define OBJC_FORWARDING_MIN_OFFSET 0
92 /* Define the special tree codes that we use. */
94 /* Table indexed by tree code giving a string containing a character
95 classifying the tree code. */
97 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
99 static const char objc_tree_code_type
[] = {
101 #include "objc-tree.def"
105 /* Table indexed by tree code giving number of expression
106 operands beyond the fixed part of the node structure.
107 Not used for types or decls. */
109 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
111 static const int objc_tree_code_length
[] = {
113 #include "objc-tree.def"
117 /* Names of tree components.
118 Used for printing out the tree and error messages. */
119 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
121 static const char * const objc_tree_code_name
[] = {
123 #include "objc-tree.def"
127 /* Set up for use of obstacks. */
131 #define obstack_chunk_alloc xmalloc
132 #define obstack_chunk_free free
134 /* This obstack is used to accumulate the encoding of a data type. */
135 static struct obstack util_obstack
;
136 /* This points to the beginning of obstack contents,
137 so we can free the whole contents. */
140 /* for encode_method_def */
143 /* The version identifies which language generation and runtime
144 the module (file) was compiled for, and is recorded in the
145 module descriptor. */
147 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
148 #define PROTOCOL_VERSION 2
150 /* (Decide if these can ever be validly changed.) */
151 #define OBJC_ENCODE_INLINE_DEFS 0
152 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
154 /*** Private Interface (procedures) ***/
156 /* Used by compile_file. */
158 static void init_objc
PARAMS ((void));
159 static void finish_objc
PARAMS ((void));
160 static const char *objc_init
PARAMS ((const char *));
161 static void objc_init_options
PARAMS ((void));
162 static int objc_decode_option
PARAMS ((int, char **));
163 static void objc_post_options
PARAMS ((void));
165 /* Code generation. */
167 static void synth_module_prologue
PARAMS ((void));
168 static tree build_constructor
PARAMS ((tree
, tree
));
169 static rtx build_module_descriptor
PARAMS ((void));
170 static tree init_module_descriptor
PARAMS ((tree
));
171 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
173 static void generate_strings
PARAMS ((void));
174 static tree get_proto_encoding
PARAMS ((tree
));
175 static void build_selector_translation_table
PARAMS ((void));
176 static tree build_ivar_chain
PARAMS ((tree
, int));
178 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
180 static tree build_ivar_template
PARAMS ((void));
181 static tree build_method_template
PARAMS ((void));
182 static tree build_private_template
PARAMS ((tree
));
183 static void build_class_template
PARAMS ((void));
184 static void build_selector_template
PARAMS ((void));
185 static void build_category_template
PARAMS ((void));
186 static tree build_super_template
PARAMS ((void));
187 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
189 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
192 static void synth_forward_declarations
PARAMS ((void));
193 static void generate_ivar_lists
PARAMS ((void));
194 static void generate_dispatch_tables
PARAMS ((void));
195 static void generate_shared_structures
PARAMS ((void));
196 static tree generate_protocol_list
PARAMS ((tree
));
197 static void generate_forward_declaration_to_string_table
PARAMS ((void));
198 static void build_protocol_reference
PARAMS ((tree
));
200 static tree build_keyword_selector
PARAMS ((tree
));
201 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
203 static void generate_static_references
PARAMS ((void));
204 static int check_methods_accessible
PARAMS ((tree
, tree
,
206 static void encode_aggregate_within
PARAMS ((tree
, int, int,
208 static const char *objc_demangle
PARAMS ((const char *));
209 static const char *objc_printable_name
PARAMS ((tree
, int));
210 static void objc_expand_function_end
PARAMS ((void));
212 /* Hash tables to manage the global pool of method prototypes. */
214 hash
*nst_method_hash_list
= 0;
215 hash
*cls_method_hash_list
= 0;
217 static void hash_init
PARAMS ((void));
218 static void hash_enter
PARAMS ((hash
*, tree
));
219 static hash hash_lookup
PARAMS ((hash
*, tree
));
220 static void hash_add_attr
PARAMS ((hash
, tree
));
221 static tree lookup_method
PARAMS ((tree
, tree
));
222 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
223 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
224 static tree add_class
PARAMS ((tree
));
225 static void add_category
PARAMS ((tree
, tree
));
229 class_names
, /* class, category, protocol, module names */
230 meth_var_names
, /* method and variable names */
231 meth_var_types
/* method and variable type descriptors */
234 static tree add_objc_string
PARAMS ((tree
,
235 enum string_section
));
236 static tree get_objc_string_decl
PARAMS ((tree
,
237 enum string_section
));
238 static tree build_objc_string_decl
PARAMS ((enum string_section
));
239 static tree build_selector_reference_decl
PARAMS ((void));
241 /* Protocol additions. */
243 static tree add_protocol
PARAMS ((tree
));
244 static tree lookup_protocol
PARAMS ((tree
));
245 static void check_protocol_recursively
PARAMS ((tree
, tree
));
246 static tree lookup_and_install_protocols
PARAMS ((tree
));
250 static void encode_type_qualifiers
PARAMS ((tree
));
251 static void encode_pointer
PARAMS ((tree
, int, int));
252 static void encode_array
PARAMS ((tree
, int, int));
253 static void encode_aggregate
PARAMS ((tree
, int, int));
254 static void encode_bitfield
PARAMS ((int));
255 static void encode_type
PARAMS ((tree
, int, int));
256 static void encode_field_decl
PARAMS ((tree
, int, int));
258 static void really_start_method
PARAMS ((tree
, tree
));
259 static int comp_method_with_proto
PARAMS ((tree
, tree
));
260 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
261 static tree get_arg_type_list
PARAMS ((tree
, int, int));
262 static tree expr_last
PARAMS ((tree
));
264 /* Utilities for debugging and error diagnostics. */
266 static void warn_with_method
PARAMS ((const char *, int, tree
));
267 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
268 static char *gen_method_decl
PARAMS ((tree
, char *));
269 static char *gen_declaration
PARAMS ((tree
, char *));
270 static void gen_declaration_1
PARAMS ((tree
, char *));
271 static char *gen_declarator
PARAMS ((tree
, char *,
273 static int is_complex_decl
PARAMS ((tree
));
274 static void adorn_decl
PARAMS ((tree
, char *));
275 static void dump_interface
PARAMS ((FILE *, tree
));
277 /* Everything else. */
279 static tree define_decl
PARAMS ((tree
, tree
));
280 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
281 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
282 static tree create_builtin_decl
PARAMS ((enum tree_code
,
283 tree
, const char *));
284 static void setup_string_decl
PARAMS ((void));
285 static tree my_build_string
PARAMS ((int, const char *));
286 static void build_objc_symtab_template
PARAMS ((void));
287 static tree init_def_list
PARAMS ((tree
));
288 static tree init_objc_symtab
PARAMS ((tree
));
289 static void forward_declare_categories
PARAMS ((void));
290 static void generate_objc_symtab_decl
PARAMS ((void));
291 static tree build_selector
PARAMS ((tree
));
292 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
293 static tree build_selector_reference
PARAMS ((tree
));
294 static tree build_class_reference_decl
PARAMS ((void));
295 static void add_class_reference
PARAMS ((tree
));
296 static tree objc_copy_list
PARAMS ((tree
, tree
*));
297 static tree build_protocol_template
PARAMS ((void));
298 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
299 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
300 static tree build_method_prototype_template
PARAMS ((void));
301 static int forwarding_offset
PARAMS ((tree
));
302 static tree encode_method_prototype
PARAMS ((tree
, tree
));
303 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
305 static void generate_method_descriptors
PARAMS ((tree
));
306 static tree build_tmp_function_decl
PARAMS ((void));
307 static void hack_method_prototype
PARAMS ((tree
, tree
));
308 static void generate_protocol_references
PARAMS ((tree
));
309 static void generate_protocols
PARAMS ((void));
310 static void check_ivars
PARAMS ((tree
, tree
));
311 static tree build_ivar_list_template
PARAMS ((tree
, int));
312 static tree build_method_list_template
PARAMS ((tree
, int));
313 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
314 static tree generate_ivars_list
PARAMS ((tree
, const char *,
316 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
317 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
319 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
320 tree
, int, tree
, tree
,
322 static void generate_category
PARAMS ((tree
));
323 static int is_objc_type_qualifier
PARAMS ((tree
));
324 static tree adjust_type_for_id_default
PARAMS ((tree
));
325 static tree check_duplicates
PARAMS ((hash
));
326 static tree receiver_is_class_object
PARAMS ((tree
));
327 static int check_methods
PARAMS ((tree
, tree
, int));
328 static int conforms_to_protocol
PARAMS ((tree
, tree
));
329 static void check_protocol
PARAMS ((tree
, const char *,
331 static void check_protocols
PARAMS ((tree
, const char *,
333 static tree encode_method_def
PARAMS ((tree
));
334 static void gen_declspecs
PARAMS ((tree
, char *, int));
335 static void generate_classref_translation_entry
PARAMS ((tree
));
336 static void handle_class_ref
PARAMS ((tree
));
337 static void generate_struct_by_value_array
PARAMS ((void))
339 static void objc_act_parse_init
PARAMS ((void));
340 static void ggc_mark_imp_list
PARAMS ((void *));
341 static void ggc_mark_hash_table
PARAMS ((void *));
343 /*** Private Interface (data) ***/
345 /* Reserved tag definitions. */
348 #define TAG_OBJECT "objc_object"
349 #define TAG_CLASS "objc_class"
350 #define TAG_SUPER "objc_super"
351 #define TAG_SELECTOR "objc_selector"
353 #define UTAG_CLASS "_objc_class"
354 #define UTAG_IVAR "_objc_ivar"
355 #define UTAG_IVAR_LIST "_objc_ivar_list"
356 #define UTAG_METHOD "_objc_method"
357 #define UTAG_METHOD_LIST "_objc_method_list"
358 #define UTAG_CATEGORY "_objc_category"
359 #define UTAG_MODULE "_objc_module"
360 #define UTAG_STATICS "_objc_statics"
361 #define UTAG_SYMTAB "_objc_symtab"
362 #define UTAG_SUPER "_objc_super"
363 #define UTAG_SELECTOR "_objc_selector"
365 #define UTAG_PROTOCOL "_objc_protocol"
366 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
367 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
368 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
370 #ifdef NEXT_OBJC_RUNTIME
371 #define STRING_OBJECT_CLASS_NAME "NSConstantString"
373 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
375 /* Note that the string object global name is only needed for the
377 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
379 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
381 static const char *constant_string_class_name
= NULL
;
383 static const char *TAG_GETCLASS
;
384 static const char *TAG_GETMETACLASS
;
385 static const char *TAG_MSGSEND
;
386 static const char *TAG_MSGSENDSUPER
;
387 static const char *TAG_EXECCLASS
;
389 /* The OCTI_... enumeration itself in in objc/objc-act.h. */
390 tree objc_global_trees
[OCTI_MAX
];
392 int objc_receiver_context
;
394 static void handle_impent
PARAMS ((struct imp_entry
*));
396 struct imp_entry
*imp_list
= 0;
397 int imp_count
= 0; /* `@implementation' */
398 int cat_count
= 0; /* `@category' */
400 static int method_slot
= 0; /* Used by start_method_def, */
404 static char *errbuf
; /* Buffer for error diagnostics */
406 /* Data imported from tree.c. */
408 extern enum debug_info_type write_symbols
;
410 /* Data imported from toplev.c. */
412 extern const char *dump_base_name
;
414 /* Generate code for GNU or NeXT runtime environment. */
416 #ifdef NEXT_OBJC_RUNTIME
417 int flag_next_runtime
= 1;
419 int flag_next_runtime
= 0;
422 int flag_typed_selectors
;
424 /* Open and close the file for outputting class declarations, if requested. */
426 int flag_gen_declaration
= 0;
428 FILE *gen_declaration_file
;
430 /* Warn if multiple methods are seen for the same selector, but with
431 different argument types. */
433 int warn_selector
= 0;
435 /* Warn if methods required by a protocol are not implemented in the
436 class adopting it. When turned off, methods inherited to that
437 class are also considered implemented */
439 int flag_warn_protocol
= 1;
441 /* Tells "encode_pointer/encode_aggregate" whether we are generating
442 type descriptors for instance variables (as opposed to methods).
443 Type descriptors for instance variables contain more information
444 than methods (for static typing and embedded structures). This
445 was added to support features being planned for dbkit2. */
447 static int generating_instance_variables
= 0;
449 /* Tells the compiler that this is a special run. Do not perform
450 any compiling, instead we are to test some platform dependent
451 features and output a C header file with appropriate definitions. */
453 static int print_struct_values
= 0;
455 #undef LANG_HOOKS_NAME
456 #define LANG_HOOKS_NAME "GNU Objective-C"
457 #undef LANG_HOOKS_INIT
458 #define LANG_HOOKS_INIT objc_init
459 #undef LANG_HOOKS_FINISH
460 #define LANG_HOOKS_FINISH c_common_finish
461 #undef LANG_HOOKS_INIT_OPTIONS
462 #define LANG_HOOKS_INIT_OPTIONS objc_init_options
463 #undef LANG_HOOKS_DECODE_OPTION
464 #define LANG_HOOKS_DECODE_OPTION objc_decode_option
465 #undef LANG_HOOKS_POST_OPTIONS
466 #define LANG_HOOKS_POST_OPTIONS objc_post_options
467 #undef LANG_HOOKS_PRINT_IDENTIFIER
468 #define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier
469 #undef LANG_HOOKS_SET_YYDEBUG
470 #define LANG_HOOKS_SET_YYDEBUG c_set_yydebug
471 /* Inlining hooks same as the C front end. */
472 #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
473 #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
474 c_cannot_inline_tree_fn
475 #undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
476 #define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
477 c_disregard_inline_limits
478 #undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
479 #define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
482 /* Each front end provides its own. */
483 const struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
485 static varray_type deferred_fns
;
487 /* Post-switch processing. */
491 c_common_post_options ();
494 /* Some platforms pass small structures through registers versus through
495 an invisible pointer. Determine at what size structure is the
496 transition point between the two possibilities. */
499 generate_struct_by_value_array ()
502 tree field_decl
, field_decl_chain
;
504 int aggregate_in_mem
[32];
507 /* Presumably no platform passes 32 byte structures in a register. */
508 for (i
= 1; i
< 32; i
++)
512 /* Create an unnamed struct that has `i' character components */
513 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
515 strcpy (buffer
, "c1");
516 field_decl
= create_builtin_decl (FIELD_DECL
,
519 field_decl_chain
= field_decl
;
521 for (j
= 1; j
< i
; j
++)
523 sprintf (buffer
, "c%d", j
+ 1);
524 field_decl
= create_builtin_decl (FIELD_DECL
,
527 chainon (field_decl_chain
, field_decl
);
529 finish_struct (type
, field_decl_chain
, NULL_TREE
);
531 aggregate_in_mem
[i
] = aggregate_value_p (type
);
532 if (!aggregate_in_mem
[i
])
536 /* We found some structures that are returned in registers instead of memory
537 so output the necessary data. */
540 for (i
= 31; i
>= 0; i
--)
541 if (!aggregate_in_mem
[i
])
543 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
545 /* The first member of the structure is always 0 because we don't handle
546 structures with 0 members */
547 printf ("static int struct_forward_array[] = {\n 0");
549 for (j
= 1; j
<= i
; j
++)
550 printf (", %d", aggregate_in_mem
[j
]);
560 c_common_init_options (clk_objective_c
);
565 const char *filename
;
567 filename
= c_objc_common_init (filename
);
569 decl_printable_name
= objc_printable_name
;
571 /* Force the line number back to 0; check_newline will have
572 raised it to 1, which will make the builtin functions appear
573 not to be built in. */
576 /* If gen_declaration desired, open the output file. */
577 if (flag_gen_declaration
)
579 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
580 gen_declaration_file
= fopen (dumpname
, "w");
581 if (gen_declaration_file
== 0)
582 fatal_io_error ("can't open %s", dumpname
);
586 if (flag_next_runtime
)
588 TAG_GETCLASS
= "objc_getClass";
589 TAG_GETMETACLASS
= "objc_getMetaClass";
590 TAG_MSGSEND
= "objc_msgSend";
591 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
592 TAG_EXECCLASS
= "__objc_execClass";
596 TAG_GETCLASS
= "objc_get_class";
597 TAG_GETMETACLASS
= "objc_get_meta_class";
598 TAG_MSGSEND
= "objc_msg_lookup";
599 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
600 TAG_EXECCLASS
= "__objc_exec_class";
601 flag_typed_selectors
= 1;
604 objc_ellipsis_node
= make_node (ERROR_MARK
);
608 if (print_struct_values
)
609 generate_struct_by_value_array ();
611 objc_act_parse_init ();
613 VARRAY_TREE_INIT (deferred_fns
, 32, "deferred_fns");
614 ggc_add_tree_varray_root (&deferred_fns
, 1);
619 /* Register a function tree, so that its optimization and conversion
620 to RTL is only done at the end of the compilation. */
626 VARRAY_PUSH_TREE (deferred_fns
, fn
);
636 for (i
= 0; i
< VARRAY_ACTIVE_SIZE (deferred_fns
); i
++)
637 /* Don't output the same function twice. We may run into such
638 situations when an extern inline function is later given a
639 non-extern-inline definition. */
640 if (! TREE_ASM_WRITTEN (VARRAY_TREE (deferred_fns
, i
)))
641 c_expand_deferred_function (VARRAY_TREE (deferred_fns
, i
));
642 VARRAY_FREE (deferred_fns
);
644 finish_objc (); /* Objective-C finalization */
646 if (gen_declaration_file
)
647 fclose (gen_declaration_file
);
651 objc_decode_option (argc
, argv
)
655 const char *p
= argv
[0];
657 if (!strcmp (p
, "-gen-decls"))
658 flag_gen_declaration
= 1;
659 else if (!strcmp (p
, "-Wselector"))
661 else if (!strcmp (p
, "-Wno-selector"))
663 else if (!strcmp (p
, "-Wprotocol"))
664 flag_warn_protocol
= 1;
665 else if (!strcmp (p
, "-Wno-protocol"))
666 flag_warn_protocol
= 0;
667 else if (!strcmp (p
, "-fgnu-runtime"))
668 flag_next_runtime
= 0;
669 else if (!strcmp (p
, "-fno-next-runtime"))
670 flag_next_runtime
= 0;
671 else if (!strcmp (p
, "-fno-gnu-runtime"))
672 flag_next_runtime
= 1;
673 else if (!strcmp (p
, "-fnext-runtime"))
674 flag_next_runtime
= 1;
675 else if (!strcmp (p
, "-print-objc-runtime-info"))
676 print_struct_values
= 1;
677 #define CSTSTRCLASS "-fconstant-string-class="
678 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
679 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
680 error ("no class name specified as argument to -fconstant-string-class");
681 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
685 return c_decode_option (argc
, argv
);
692 define_decl (declarator
, declspecs
)
696 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
697 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
701 /* Return 1 if LHS and RHS are compatible types for assignment or
702 various other operations. Return 0 if they are incompatible, and
703 return -1 if we choose to not decide. When the operation is
704 REFLEXIVE, check for compatibility in either direction.
706 For statically typed objects, an assignment of the form `a' = `b'
710 `a' and `b' are the same class type, or
711 `a' and `b' are of class types A and B such that B is a descendant of A. */
714 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
718 return objc_comptypes (lhs
, rhs
, reflexive
);
722 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
730 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
732 p
= TREE_VALUE (rproto
);
734 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
736 if ((fnd
= lookup_method (class_meth
737 ? PROTOCOL_CLS_METHODS (p
)
738 : PROTOCOL_NST_METHODS (p
), sel_name
)))
740 else if (PROTOCOL_LIST (p
))
741 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
742 sel_name
, class_meth
);
746 ; /* An identifier...if we could not find a protocol. */
757 lookup_protocol_in_reflist (rproto_list
, lproto
)
763 /* Make sure the protocol is supported by the object on the rhs. */
764 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
767 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
769 p
= TREE_VALUE (rproto
);
771 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
776 else if (PROTOCOL_LIST (p
))
777 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
786 ; /* An identifier...if we could not find a protocol. */
792 /* Return 1 if LHS and RHS are compatible types for assignment
793 or various other operations. Return 0 if they are incompatible,
794 and return -1 if we choose to not decide. When the operation
795 is REFLEXIVE, check for compatibility in either direction. */
798 objc_comptypes (lhs
, rhs
, reflexive
)
803 /* New clause for protocols. */
805 if (TREE_CODE (lhs
) == POINTER_TYPE
806 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
807 && TREE_CODE (rhs
) == POINTER_TYPE
808 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
810 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
811 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
815 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
816 tree rproto
, rproto_list
;
821 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
823 /* Make sure the protocol is supported by the object
825 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
827 p
= TREE_VALUE (lproto
);
828 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
831 warning ("object does not conform to the `%s' protocol",
832 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
835 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
837 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
840 /* Make sure the protocol is supported by the object
842 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
844 p
= TREE_VALUE (lproto
);
846 rinter
= lookup_interface (rname
);
848 while (rinter
&& !rproto
)
852 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
853 /* If the underlying ObjC class does not have
854 protocols attached to it, perhaps there are
855 "one-off" protocols attached to the rhs?
856 E.g., 'id<MyProt> foo;'. */
858 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
859 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
861 /* Check for protocols adopted by categories. */
862 cat
= CLASS_CATEGORY_LIST (rinter
);
863 while (cat
&& !rproto
)
865 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
866 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
868 cat
= CLASS_CATEGORY_LIST (cat
);
871 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
875 warning ("class `%s' does not implement the `%s' protocol",
876 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
877 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
881 /* May change...based on whether there was any mismatch */
884 else if (rhs_is_proto
)
885 /* Lhs is not a protocol...warn if it is statically typed */
886 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
889 /* Defer to comptypes. */
893 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
894 ; /* Fall thru. This is the case we have been handling all along */
896 /* Defer to comptypes. */
899 /* `id' = `<class> *', `<class> *' = `id' */
901 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
902 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
905 /* `id' = `Class', `Class' = `id' */
907 else if ((TYPE_NAME (lhs
) == objc_object_id
908 && TYPE_NAME (rhs
) == objc_class_id
)
909 || (TYPE_NAME (lhs
) == objc_class_id
910 && TYPE_NAME (rhs
) == objc_object_id
))
913 /* `<class> *' = `<class> *' */
915 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
917 tree lname
= TYPE_NAME (lhs
);
918 tree rname
= TYPE_NAME (rhs
);
924 /* If the left hand side is a super class of the right hand side,
926 for (inter
= lookup_interface (rname
); inter
;
927 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
928 if (lname
== CLASS_SUPER_NAME (inter
))
931 /* Allow the reverse when reflexive. */
933 for (inter
= lookup_interface (lname
); inter
;
934 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
935 if (rname
== CLASS_SUPER_NAME (inter
))
941 /* Defer to comptypes. */
945 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
948 objc_check_decl (decl
)
951 tree type
= TREE_TYPE (decl
);
953 if (TREE_CODE (type
) == RECORD_TYPE
954 && TREE_STATIC_TEMPLATE (type
)
955 && type
!= constant_string_type
)
956 error_with_decl (decl
, "`%s' cannot be statically allocated");
960 maybe_objc_check_decl (decl
)
963 objc_check_decl (decl
);
966 /* Implement static typing. At this point, we know we have an interface. */
969 get_static_reference (interface
, protocols
)
973 tree type
= xref_tag (RECORD_TYPE
, interface
);
977 tree t
, m
= TYPE_MAIN_VARIANT (type
);
979 t
= copy_node (type
);
980 TYPE_BINFO (t
) = make_tree_vec (2);
982 /* Add this type to the chain of variants of TYPE. */
983 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
984 TYPE_NEXT_VARIANT (m
) = t
;
986 /* Look up protocols and install in lang specific list. Note
987 that the protocol list can have a different lifetime than T! */
988 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
990 /* This forces a new pointer type to be created later
991 (in build_pointer_type)...so that the new template
992 we just created will actually be used...what a hack! */
993 if (TYPE_POINTER_TO (t
))
994 TYPE_POINTER_TO (t
) = NULL_TREE
;
1003 get_object_reference (protocols
)
1006 tree type_decl
= lookup_name (objc_id_id
);
1009 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1011 type
= TREE_TYPE (type_decl
);
1012 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1013 warning ("unexpected type for `id' (%s)",
1014 gen_declaration (type
, errbuf
));
1018 error ("undefined type `id', please import <objc/objc.h>");
1019 return error_mark_node
;
1022 /* This clause creates a new pointer type that is qualified with
1023 the protocol specification...this info is used later to do more
1024 elaborate type checking. */
1028 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1030 t
= copy_node (type
);
1031 TYPE_BINFO (t
) = make_tree_vec (2);
1033 /* Add this type to the chain of variants of TYPE. */
1034 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1035 TYPE_NEXT_VARIANT (m
) = t
;
1037 /* Look up protocols...and install in lang specific list */
1038 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1040 /* This forces a new pointer type to be created later
1041 (in build_pointer_type)...so that the new template
1042 we just created will actually be used...what a hack! */
1043 if (TYPE_POINTER_TO (t
))
1044 TYPE_POINTER_TO (t
) = NULL_TREE
;
1051 /* Check for circular dependencies in protocols. The arguments are
1052 PROTO, the protocol to check, and LIST, a list of protocol it
1056 check_protocol_recursively (proto
, list
)
1062 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1064 tree pp
= TREE_VALUE (p
);
1066 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1067 pp
= lookup_protocol (pp
);
1070 fatal_error ("protocol `%s' has circular dependency",
1071 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1073 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1078 lookup_and_install_protocols (protocols
)
1083 tree return_value
= protocols
;
1085 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1087 tree ident
= TREE_VALUE (proto
);
1088 tree p
= lookup_protocol (ident
);
1092 error ("cannot find protocol declaration for `%s'",
1093 IDENTIFIER_POINTER (ident
));
1095 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1097 return_value
= TREE_CHAIN (proto
);
1101 /* Replace identifier with actual protocol node. */
1102 TREE_VALUE (proto
) = p
;
1107 return return_value
;
1110 /* Create and push a decl for a built-in external variable or field NAME.
1112 TYPE is its data type. */
1115 create_builtin_decl (code
, type
, name
)
1116 enum tree_code code
;
1120 tree decl
= build_decl (code
, get_identifier (name
), type
);
1122 if (code
== VAR_DECL
)
1124 TREE_STATIC (decl
) = 1;
1125 make_decl_rtl (decl
, 0);
1129 DECL_ARTIFICIAL (decl
) = 1;
1133 /* Find the decl for the constant string class. */
1136 setup_string_decl ()
1138 if (!string_class_decl
)
1140 if (!constant_string_global_id
)
1141 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1142 string_class_decl
= lookup_name (constant_string_global_id
);
1146 /* Purpose: "play" parser, creating/installing representations
1147 of the declarations that are required by Objective-C.
1151 type_spec--------->sc_spec
1152 (tree_list) (tree_list)
1155 identifier_node identifier_node */
1158 synth_module_prologue ()
1163 /* Defined in `objc.h' */
1164 objc_object_id
= get_identifier (TAG_OBJECT
);
1166 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1168 id_type
= build_pointer_type (objc_object_reference
);
1170 objc_id_id
= get_identifier (TYPE_ID
);
1171 objc_class_id
= get_identifier (TAG_CLASS
);
1173 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1174 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1175 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1177 /* Declare type of selector-objects that represent an operation name. */
1179 /* `struct objc_selector *' */
1181 = build_pointer_type (xref_tag (RECORD_TYPE
,
1182 get_identifier (TAG_SELECTOR
)));
1184 /* Forward declare type, or else the prototype for msgSendSuper will
1187 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1188 get_identifier (TAG_SUPER
)));
1191 /* id objc_msgSend (id, SEL, ...); */
1194 = build_function_type (id_type
,
1195 tree_cons (NULL_TREE
, id_type
,
1196 tree_cons (NULL_TREE
, selector_type
,
1199 if (! flag_next_runtime
)
1201 umsg_decl
= build_decl (FUNCTION_DECL
,
1202 get_identifier (TAG_MSGSEND
), temp_type
);
1203 DECL_EXTERNAL (umsg_decl
) = 1;
1204 TREE_PUBLIC (umsg_decl
) = 1;
1205 DECL_INLINE (umsg_decl
) = 1;
1206 DECL_ARTIFICIAL (umsg_decl
) = 1;
1208 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1209 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1211 make_decl_rtl (umsg_decl
, NULL
);
1212 pushdecl (umsg_decl
);
1215 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1217 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1220 = build_function_type (id_type
,
1221 tree_cons (NULL_TREE
, super_p
,
1222 tree_cons (NULL_TREE
, selector_type
,
1225 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1226 temp_type
, 0, NOT_BUILT_IN
, 0);
1228 /* id objc_getClass (const char *); */
1230 temp_type
= build_function_type (id_type
,
1231 tree_cons (NULL_TREE
,
1232 const_string_type_node
,
1233 tree_cons (NULL_TREE
, void_type_node
,
1237 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1239 /* id objc_getMetaClass (const char *); */
1241 objc_get_meta_class_decl
1242 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1244 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1246 if (! flag_next_runtime
)
1248 if (flag_typed_selectors
)
1250 /* Suppress outputting debug symbols, because
1251 dbxout_init hasn'r been called yet. */
1252 enum debug_info_type save_write_symbols
= write_symbols
;
1253 struct gcc_debug_hooks
*save_hooks
= debug_hooks
;
1254 write_symbols
= NO_DEBUG
;
1255 debug_hooks
= &do_nothing_debug_hooks
;
1257 build_selector_template ();
1258 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1260 write_symbols
= save_write_symbols
;
1261 debug_hooks
= save_hooks
;
1264 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1266 layout_type (temp_type
);
1267 UOBJC_SELECTOR_TABLE_decl
1268 = create_builtin_decl (VAR_DECL
, temp_type
,
1269 "_OBJC_SELECTOR_TABLE");
1271 /* Avoid warning when not sending messages. */
1272 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1275 generate_forward_declaration_to_string_table ();
1277 /* Forward declare constant_string_id and constant_string_type. */
1278 if (!constant_string_class_name
)
1279 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1281 constant_string_id
= get_identifier (constant_string_class_name
);
1282 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1285 /* Custom build_string which sets TREE_TYPE! */
1288 my_build_string (len
, str
)
1293 tree a_string
= build_string (len
, str
);
1295 /* Some code from combine_strings, which is local to c-parse.y. */
1296 if (TREE_TYPE (a_string
) == int_array_type_node
)
1299 TREE_TYPE (a_string
)
1300 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1301 build_index_type (build_int_2 (len
- 1, 0)));
1303 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1304 TREE_STATIC (a_string
) = 1;
1309 /* Given a chain of STRING_CST's, build a static instance of
1310 NXConstantString which points at the concatenation of those strings.
1311 We place the string object in the __string_objects section of the
1312 __OBJC segment. The Objective-C runtime will initialize the isa
1313 pointers of the string objects to point at the NXConstantString
1317 build_objc_string_object (strings
)
1320 tree string
, initlist
, constructor
;
1323 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1325 error ("cannot find interface declaration for `%s'",
1326 IDENTIFIER_POINTER (constant_string_id
));
1327 return error_mark_node
;
1330 add_class_reference (constant_string_id
);
1332 string
= combine_strings (strings
);
1333 TREE_SET_CODE (string
, STRING_CST
);
1334 length
= TREE_STRING_LENGTH (string
) - 1;
1336 /* & ((NXConstantString) {0, string, length}) */
1338 if (flag_next_runtime
)
1340 /* For the NeXT runtime, we can generate a literal reference
1341 to the string class, don't need to run a constructor. */
1342 setup_string_decl ();
1343 if (string_class_decl
== NULL_TREE
)
1345 error ("cannot find reference tag for class `%s'",
1346 IDENTIFIER_POINTER (constant_string_id
));
1347 return error_mark_node
;
1349 initlist
= build_tree_list
1351 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1355 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1359 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1361 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1362 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1364 if (!flag_next_runtime
)
1367 = objc_add_static_instance (constructor
, constant_string_type
);
1370 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1373 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1376 objc_add_static_instance (constructor
, class_decl
)
1377 tree constructor
, class_decl
;
1379 static int num_static_inst
;
1383 /* Find the list of static instances for the CLASS_DECL. Create one if
1385 for (chain
= &objc_static_instances
;
1386 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1387 chain
= &TREE_CHAIN (*chain
));
1390 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1391 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1394 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1395 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1396 DECL_COMMON (decl
) = 1;
1397 TREE_STATIC (decl
) = 1;
1398 DECL_ARTIFICIAL (decl
) = 1;
1399 DECL_INITIAL (decl
) = constructor
;
1401 /* We may be writing something else just now.
1402 Postpone till end of input. */
1403 DECL_DEFER_OUTPUT (decl
) = 1;
1404 pushdecl_top_level (decl
);
1405 rest_of_decl_compilation (decl
, 0, 1, 0);
1407 /* Add the DECL to the head of this CLASS' list. */
1408 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1413 /* Build a static constant CONSTRUCTOR
1414 with type TYPE and elements ELTS. */
1417 build_constructor (type
, elts
)
1420 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1422 TREE_CONSTANT (constructor
) = 1;
1423 TREE_STATIC (constructor
) = 1;
1424 TREE_READONLY (constructor
) = 1;
1429 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1431 /* Predefine the following data type:
1439 void *defs[cls_def_cnt + cat_def_cnt];
1443 build_objc_symtab_template ()
1445 tree field_decl
, field_decl_chain
, index
;
1447 objc_symtab_template
1448 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1450 /* long sel_ref_cnt; */
1452 field_decl
= create_builtin_decl (FIELD_DECL
,
1453 long_integer_type_node
,
1455 field_decl_chain
= field_decl
;
1459 field_decl
= create_builtin_decl (FIELD_DECL
,
1460 build_pointer_type (selector_type
),
1462 chainon (field_decl_chain
, field_decl
);
1464 /* short cls_def_cnt; */
1466 field_decl
= create_builtin_decl (FIELD_DECL
,
1467 short_integer_type_node
,
1469 chainon (field_decl_chain
, field_decl
);
1471 /* short cat_def_cnt; */
1473 field_decl
= create_builtin_decl (FIELD_DECL
,
1474 short_integer_type_node
,
1476 chainon (field_decl_chain
, field_decl
);
1478 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1480 if (!flag_next_runtime
)
1481 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1483 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1484 imp_count
== 0 && cat_count
== 0
1486 field_decl
= create_builtin_decl (FIELD_DECL
,
1487 build_array_type (ptr_type_node
, index
),
1489 chainon (field_decl_chain
, field_decl
);
1491 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1494 /* Create the initial value for the `defs' field of _objc_symtab.
1495 This is a CONSTRUCTOR. */
1498 init_def_list (type
)
1501 tree expr
, initlist
= NULL_TREE
;
1502 struct imp_entry
*impent
;
1505 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1507 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1509 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1510 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1515 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1517 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1519 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1520 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1524 if (!flag_next_runtime
)
1526 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1529 if (static_instances_decl
)
1530 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1532 expr
= build_int_2 (0, 0);
1534 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1537 return build_constructor (type
, nreverse (initlist
));
1540 /* Construct the initial value for all of _objc_symtab. */
1543 init_objc_symtab (type
)
1548 /* sel_ref_cnt = { ..., 5, ... } */
1550 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1552 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1554 if (flag_next_runtime
|| ! sel_ref_chain
)
1555 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1557 initlist
= tree_cons (NULL_TREE
,
1558 build_unary_op (ADDR_EXPR
,
1559 UOBJC_SELECTOR_TABLE_decl
, 1),
1562 /* cls_def_cnt = { ..., 5, ... } */
1564 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1566 /* cat_def_cnt = { ..., 5, ... } */
1568 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1570 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1572 if (imp_count
|| cat_count
|| static_instances_decl
)
1575 tree field
= TYPE_FIELDS (type
);
1576 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1578 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1582 return build_constructor (type
, nreverse (initlist
));
1585 /* Push forward-declarations of all the categories
1586 so that init_def_list can use them in a CONSTRUCTOR. */
1589 forward_declare_categories ()
1591 struct imp_entry
*impent
;
1592 tree sav
= objc_implementation_context
;
1594 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1596 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1598 /* Set an invisible arg to synth_id_with_class_suffix. */
1599 objc_implementation_context
= impent
->imp_context
;
1601 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1602 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1605 objc_implementation_context
= sav
;
1608 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1609 and initialized appropriately. */
1612 generate_objc_symtab_decl ()
1616 if (!objc_category_template
)
1617 build_category_template ();
1619 /* forward declare categories */
1621 forward_declare_categories ();
1623 if (!objc_symtab_template
)
1624 build_objc_symtab_template ();
1626 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1628 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1629 tree_cons (NULL_TREE
,
1630 objc_symtab_template
, sc_spec
),
1634 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1635 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1636 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1637 finish_decl (UOBJC_SYMBOLS_decl
,
1638 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1643 init_module_descriptor (type
)
1646 tree initlist
, expr
;
1648 /* version = { 1, ... } */
1650 expr
= build_int_2 (OBJC_VERSION
, 0);
1651 initlist
= build_tree_list (NULL_TREE
, expr
);
1653 /* size = { ..., sizeof (struct objc_module), ... } */
1655 expr
= size_in_bytes (objc_module_template
);
1656 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1658 /* name = { ..., "foo.m", ... } */
1660 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1661 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1663 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1665 if (UOBJC_SYMBOLS_decl
)
1666 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1668 expr
= build_int_2 (0, 0);
1669 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1671 return build_constructor (type
, nreverse (initlist
));
1674 /* Write out the data structures to describe Objective C classes defined.
1675 If appropriate, compile and output a setup function to initialize them.
1676 Return a symbol_ref to the function to call to initialize the Objective C
1677 data structures for this file (and perhaps for other files also).
1679 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1682 build_module_descriptor ()
1684 tree decl_specs
, field_decl
, field_decl_chain
;
1686 objc_module_template
1687 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1691 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1692 field_decl
= get_identifier ("version");
1694 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1695 field_decl_chain
= field_decl
;
1699 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1700 field_decl
= get_identifier ("size");
1702 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1703 chainon (field_decl_chain
, field_decl
);
1707 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1708 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1710 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1711 chainon (field_decl_chain
, field_decl
);
1713 /* struct objc_symtab *symtab; */
1715 decl_specs
= get_identifier (UTAG_SYMTAB
);
1716 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1717 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1719 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1720 chainon (field_decl_chain
, field_decl
);
1722 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1724 /* Create an instance of "objc_module". */
1726 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1727 build_tree_list (NULL_TREE
,
1728 ridpointers
[(int) RID_STATIC
]));
1730 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1731 decl_specs
, 1, NULL_TREE
);
1733 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1734 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1735 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1737 finish_decl (UOBJC_MODULES_decl
,
1738 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1741 /* Mark the decl to avoid "defined but not used" warning. */
1742 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1744 /* Generate a constructor call for the module descriptor.
1745 This code was generated by reading the grammar rules
1746 of c-parse.in; Therefore, it may not be the most efficient
1747 way of generating the requisite code. */
1749 if (flag_next_runtime
)
1753 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1754 tree init_function_name
, init_function_decl
;
1756 /* Declare void __objc_execClass (void *); */
1758 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1759 execclass_decl
= build_decl (FUNCTION_DECL
,
1760 get_identifier (TAG_EXECCLASS
),
1761 build_function_type (void_type_node
,
1762 tree_cons (NULL_TREE
, ptr_type_node
,
1763 void_list_node_1
)));
1764 DECL_EXTERNAL (execclass_decl
) = 1;
1765 DECL_ARTIFICIAL (execclass_decl
) = 1;
1766 TREE_PUBLIC (execclass_decl
) = 1;
1767 pushdecl (execclass_decl
);
1768 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1769 assemble_external (execclass_decl
);
1771 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1773 init_function_name
= get_file_function_name ('I');
1774 start_function (void_list_node_1
,
1775 build_nt (CALL_EXPR
, init_function_name
,
1776 tree_cons (NULL_TREE
, NULL_TREE
,
1780 store_parm_decls ();
1782 init_function_decl
= current_function_decl
;
1783 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1784 TREE_USED (init_function_decl
) = 1;
1785 current_function_cannot_inline
1786 = "static constructors and destructors cannot be inlined";
1789 = build_tree_list (NULL_TREE
,
1790 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1791 decelerator
= build_function_call (execclass_decl
, parms
);
1793 c_expand_expr_stmt (decelerator
);
1795 finish_function (0);
1797 return XEXP (DECL_RTL (init_function_decl
), 0);
1801 /* extern const char _OBJC_STRINGS[]; */
1804 generate_forward_declaration_to_string_table ()
1806 tree sc_spec
, decl_specs
, expr_decl
;
1808 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1809 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1812 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1814 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1817 /* Return the DECL of the string IDENT in the SECTION. */
1820 get_objc_string_decl (ident
, section
)
1822 enum string_section section
;
1826 if (section
== class_names
)
1827 chain
= class_names_chain
;
1828 else if (section
== meth_var_names
)
1829 chain
= meth_var_names_chain
;
1830 else if (section
== meth_var_types
)
1831 chain
= meth_var_types_chain
;
1835 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1836 if (TREE_VALUE (chain
) == ident
)
1837 return (TREE_PURPOSE (chain
));
1843 /* Output references to all statically allocated objects. Return the DECL
1844 for the array built. */
1847 generate_static_references ()
1849 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1850 tree class_name
, class, decl
, initlist
;
1851 tree cl_chain
, in_chain
, type
;
1852 int num_inst
, num_class
;
1855 if (flag_next_runtime
)
1858 for (cl_chain
= objc_static_instances
, num_class
= 0;
1859 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1861 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1862 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1864 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1865 ident
= get_identifier (buf
);
1867 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1868 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1869 build_tree_list (NULL_TREE
,
1870 ridpointers
[(int) RID_STATIC
]));
1871 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1872 DECL_CONTEXT (decl
) = 0;
1873 DECL_ARTIFICIAL (decl
) = 1;
1875 /* Output {class_name, ...}. */
1876 class = TREE_VALUE (cl_chain
);
1877 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1878 initlist
= build_tree_list (NULL_TREE
,
1879 build_unary_op (ADDR_EXPR
, class_name
, 1));
1881 /* Output {..., instance, ...}. */
1882 for (in_chain
= TREE_PURPOSE (cl_chain
);
1883 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1885 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1886 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1889 /* Output {..., NULL}. */
1890 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1892 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1893 finish_decl (decl
, expr
, NULL_TREE
);
1894 TREE_USED (decl
) = 1;
1896 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1897 decl
= build_decl (VAR_DECL
, ident
, type
);
1898 TREE_USED (decl
) = 1;
1899 TREE_STATIC (decl
) = 1;
1901 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1904 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1905 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1906 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1907 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1908 build_tree_list (NULL_TREE
,
1909 ridpointers
[(int) RID_STATIC
]));
1910 static_instances_decl
1911 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1912 TREE_USED (static_instances_decl
) = 1;
1913 DECL_CONTEXT (static_instances_decl
) = 0;
1914 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1915 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1917 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1920 /* Output all strings. */
1925 tree sc_spec
, decl_specs
, expr_decl
;
1926 tree chain
, string_expr
;
1929 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1931 string
= TREE_VALUE (chain
);
1932 decl
= TREE_PURPOSE (chain
);
1934 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1935 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1936 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1937 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1938 DECL_CONTEXT (decl
) = NULL_TREE
;
1939 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1940 IDENTIFIER_POINTER (string
));
1941 finish_decl (decl
, string_expr
, NULL_TREE
);
1944 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1946 string
= TREE_VALUE (chain
);
1947 decl
= TREE_PURPOSE (chain
);
1949 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1950 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1951 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1952 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1953 DECL_CONTEXT (decl
) = NULL_TREE
;
1954 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1955 IDENTIFIER_POINTER (string
));
1956 finish_decl (decl
, string_expr
, NULL_TREE
);
1959 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1961 string
= TREE_VALUE (chain
);
1962 decl
= TREE_PURPOSE (chain
);
1964 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1965 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1966 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1967 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1968 DECL_CONTEXT (decl
) = NULL_TREE
;
1969 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1970 IDENTIFIER_POINTER (string
));
1971 finish_decl (decl
, string_expr
, NULL_TREE
);
1976 build_selector_reference_decl ()
1982 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1984 ident
= get_identifier (buf
);
1986 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1987 DECL_EXTERNAL (decl
) = 1;
1988 TREE_PUBLIC (decl
) = 1;
1989 TREE_USED (decl
) = 1;
1990 TREE_READONLY (decl
) = 1;
1991 DECL_ARTIFICIAL (decl
) = 1;
1992 DECL_CONTEXT (decl
) = 0;
1994 make_decl_rtl (decl
, 0);
1995 pushdecl_top_level (decl
);
2000 /* Just a handy wrapper for add_objc_string. */
2003 build_selector (ident
)
2006 tree expr
= add_objc_string (ident
, meth_var_names
);
2007 if (flag_typed_selectors
)
2010 return build_c_cast (selector_type
, expr
); /* cast! */
2014 build_selector_translation_table ()
2016 tree sc_spec
, decl_specs
;
2017 tree chain
, initlist
= NULL_TREE
;
2019 tree decl
= NULL_TREE
, var_decl
, name
;
2021 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2025 expr
= build_selector (TREE_VALUE (chain
));
2027 if (flag_next_runtime
)
2029 name
= DECL_NAME (TREE_PURPOSE (chain
));
2031 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2033 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2034 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2038 /* The `decl' that is returned from start_decl is the one that we
2039 forward declared in `build_selector_reference' */
2040 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2043 /* add one for the '\0' character */
2044 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2046 if (flag_next_runtime
)
2047 finish_decl (decl
, expr
, NULL_TREE
);
2050 if (flag_typed_selectors
)
2052 tree eltlist
= NULL_TREE
;
2053 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2054 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2055 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2056 expr
= build_constructor (objc_selector_template
,
2057 nreverse (eltlist
));
2059 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2064 if (! flag_next_runtime
)
2066 /* Cause the variable and its initial value to be actually output. */
2067 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2068 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2069 /* NULL terminate the list and fix the decl for output. */
2070 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2071 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2072 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2073 nreverse (initlist
));
2074 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2075 current_function_decl
= NULL_TREE
;
2080 get_proto_encoding (proto
)
2088 if (! METHOD_ENCODING (proto
))
2090 tmp_decl
= build_tmp_function_decl ();
2091 hack_method_prototype (proto
, tmp_decl
);
2092 encoding
= encode_method_prototype (proto
, tmp_decl
);
2093 METHOD_ENCODING (proto
) = encoding
;
2096 encoding
= METHOD_ENCODING (proto
);
2098 return add_objc_string (encoding
, meth_var_types
);
2101 return build_int_2 (0, 0);
2104 /* sel_ref_chain is a list whose "value" fields will be instances of
2105 identifier_node that represent the selector. */
2108 build_typed_selector_reference (ident
, proto
)
2111 tree
*chain
= &sel_ref_chain
;
2117 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2118 goto return_at_index
;
2121 chain
= &TREE_CHAIN (*chain
);
2124 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2127 expr
= build_unary_op (ADDR_EXPR
,
2128 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2129 build_int_2 (index
, 0)),
2131 return build_c_cast (selector_type
, expr
);
2135 build_selector_reference (ident
)
2138 tree
*chain
= &sel_ref_chain
;
2144 if (TREE_VALUE (*chain
) == ident
)
2145 return (flag_next_runtime
2146 ? TREE_PURPOSE (*chain
)
2147 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2148 build_int_2 (index
, 0)));
2151 chain
= &TREE_CHAIN (*chain
);
2154 expr
= build_selector_reference_decl ();
2156 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2158 return (flag_next_runtime
2160 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2161 build_int_2 (index
, 0)));
2165 build_class_reference_decl ()
2171 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2173 ident
= get_identifier (buf
);
2175 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2176 DECL_EXTERNAL (decl
) = 1;
2177 TREE_PUBLIC (decl
) = 1;
2178 TREE_USED (decl
) = 1;
2179 TREE_READONLY (decl
) = 1;
2180 DECL_CONTEXT (decl
) = 0;
2181 DECL_ARTIFICIAL (decl
) = 1;
2183 make_decl_rtl (decl
, 0);
2184 pushdecl_top_level (decl
);
2189 /* Create a class reference, but don't create a variable to reference
2193 add_class_reference (ident
)
2198 if ((chain
= cls_ref_chain
))
2203 if (ident
== TREE_VALUE (chain
))
2207 chain
= TREE_CHAIN (chain
);
2211 /* Append to the end of the list */
2212 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2215 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2218 /* Get a class reference, creating it if necessary. Also create the
2219 reference variable. */
2222 get_class_reference (ident
)
2225 if (flag_next_runtime
)
2230 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2231 if (TREE_VALUE (*chain
) == ident
)
2233 if (! TREE_PURPOSE (*chain
))
2234 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2236 return TREE_PURPOSE (*chain
);
2239 decl
= build_class_reference_decl ();
2240 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2247 add_class_reference (ident
);
2249 params
= build_tree_list (NULL_TREE
,
2250 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2251 IDENTIFIER_POINTER (ident
)));
2253 assemble_external (objc_get_class_decl
);
2254 return build_function_call (objc_get_class_decl
, params
);
2258 /* For each string section we have a chain which maps identifier nodes
2259 to decls for the strings. */
2262 add_objc_string (ident
, section
)
2264 enum string_section section
;
2268 if (section
== class_names
)
2269 chain
= &class_names_chain
;
2270 else if (section
== meth_var_names
)
2271 chain
= &meth_var_names_chain
;
2272 else if (section
== meth_var_types
)
2273 chain
= &meth_var_types_chain
;
2279 if (TREE_VALUE (*chain
) == ident
)
2280 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2282 chain
= &TREE_CHAIN (*chain
);
2285 decl
= build_objc_string_decl (section
);
2287 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2289 return build_unary_op (ADDR_EXPR
, decl
, 1);
2293 build_objc_string_decl (section
)
2294 enum string_section section
;
2298 static int class_names_idx
= 0;
2299 static int meth_var_names_idx
= 0;
2300 static int meth_var_types_idx
= 0;
2302 if (section
== class_names
)
2303 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2304 else if (section
== meth_var_names
)
2305 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2306 else if (section
== meth_var_types
)
2307 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2309 ident
= get_identifier (buf
);
2311 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2312 DECL_EXTERNAL (decl
) = 1;
2313 TREE_PUBLIC (decl
) = 1;
2314 TREE_USED (decl
) = 1;
2315 TREE_READONLY (decl
) = 1;
2316 TREE_CONSTANT (decl
) = 1;
2317 DECL_CONTEXT (decl
) = 0;
2318 DECL_ARTIFICIAL (decl
) = 1;
2320 make_decl_rtl (decl
, 0);
2321 pushdecl_top_level (decl
);
2328 objc_declare_alias (alias_ident
, class_ident
)
2332 if (is_class_name (class_ident
) != class_ident
)
2333 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2334 else if (is_class_name (alias_ident
))
2335 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2337 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2341 objc_declare_class (ident_list
)
2346 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2348 tree ident
= TREE_VALUE (list
);
2351 if ((decl
= lookup_name (ident
)))
2353 error ("`%s' redeclared as different kind of symbol",
2354 IDENTIFIER_POINTER (ident
));
2355 error_with_decl (decl
, "previous declaration of `%s'");
2358 if (! is_class_name (ident
))
2360 tree record
= xref_tag (RECORD_TYPE
, ident
);
2361 TREE_STATIC_TEMPLATE (record
) = 1;
2362 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2368 is_class_name (ident
)
2373 if (lookup_interface (ident
))
2376 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2378 if (ident
== TREE_VALUE (chain
))
2382 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2384 if (ident
== TREE_VALUE (chain
))
2385 return TREE_PURPOSE (chain
);
2392 lookup_interface (ident
)
2397 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2399 if (ident
== CLASS_NAME (chain
))
2406 objc_copy_list (list
, head
)
2410 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2414 tail
= copy_node (list
);
2416 /* The following statement fixes a bug when inheriting instance
2417 variables that are declared to be bitfields. finish_struct
2418 expects to find the width of the bitfield in DECL_INITIAL. */
2419 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2420 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2422 newlist
= chainon (newlist
, tail
);
2423 list
= TREE_CHAIN (list
);
2430 /* Used by: build_private_template, get_class_ivars, and
2431 continue_class. COPY is 1 when called from @defs. In this case
2432 copy all fields. Otherwise don't copy leaf ivars since we rely on
2433 them being side-effected exactly once by finish_struct. */
2436 build_ivar_chain (interface
, copy
)
2440 tree my_name
, super_name
, ivar_chain
;
2442 my_name
= CLASS_NAME (interface
);
2443 super_name
= CLASS_SUPER_NAME (interface
);
2445 /* Possibly copy leaf ivars. */
2447 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2449 ivar_chain
= CLASS_IVARS (interface
);
2454 tree super_interface
= lookup_interface (super_name
);
2456 if (!super_interface
)
2458 /* fatal did not work with 2 args...should fix */
2459 error ("cannot find interface declaration for `%s', superclass of `%s'",
2460 IDENTIFIER_POINTER (super_name
),
2461 IDENTIFIER_POINTER (my_name
));
2462 exit (FATAL_EXIT_CODE
);
2465 if (super_interface
== interface
)
2466 fatal_error ("circular inheritance in interface declaration for `%s'",
2467 IDENTIFIER_POINTER (super_name
));
2469 interface
= super_interface
;
2470 my_name
= CLASS_NAME (interface
);
2471 super_name
= CLASS_SUPER_NAME (interface
);
2473 op1
= CLASS_IVARS (interface
);
2476 tree head
, tail
= objc_copy_list (op1
, &head
);
2478 /* Prepend super class ivars...make a copy of the list, we
2479 do not want to alter the original. */
2480 TREE_CHAIN (tail
) = ivar_chain
;
2487 /* struct <classname> {
2488 struct objc_class *isa;
2493 build_private_template (class)
2498 if (CLASS_STATIC_TEMPLATE (class))
2500 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2501 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2505 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2507 ivar_context
= build_ivar_chain (class, 0);
2509 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2511 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2513 /* mark this record as class template - for class type checking */
2514 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2518 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2520 build1 (INDIRECT_REF
, NULL_TREE
,
2523 return ivar_context
;
2526 /* Begin code generation for protocols... */
2528 /* struct objc_protocol {
2529 char *protocol_name;
2530 struct objc_protocol **protocol_list;
2531 struct objc_method_desc *instance_methods;
2532 struct objc_method_desc *class_methods;
2536 build_protocol_template ()
2538 tree decl_specs
, field_decl
, field_decl_chain
;
2541 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2543 /* struct objc_class *isa; */
2545 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2546 get_identifier (UTAG_CLASS
)));
2547 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2549 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2550 field_decl_chain
= field_decl
;
2552 /* char *protocol_name; */
2554 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2556 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2558 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2559 chainon (field_decl_chain
, field_decl
);
2561 /* struct objc_protocol **protocol_list; */
2563 decl_specs
= build_tree_list (NULL_TREE
, template);
2565 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2566 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2568 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2569 chainon (field_decl_chain
, field_decl
);
2571 /* struct objc_method_list *instance_methods; */
2574 = build_tree_list (NULL_TREE
,
2575 xref_tag (RECORD_TYPE
,
2576 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2578 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2580 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2581 chainon (field_decl_chain
, field_decl
);
2583 /* struct objc_method_list *class_methods; */
2586 = build_tree_list (NULL_TREE
,
2587 xref_tag (RECORD_TYPE
,
2588 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2590 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2592 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2593 chainon (field_decl_chain
, field_decl
);
2595 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2599 build_descriptor_table_initializer (type
, entries
)
2603 tree initlist
= NULL_TREE
;
2607 tree eltlist
= NULL_TREE
;
2610 = tree_cons (NULL_TREE
,
2611 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2613 = tree_cons (NULL_TREE
,
2614 add_objc_string (METHOD_ENCODING (entries
),
2619 = tree_cons (NULL_TREE
,
2620 build_constructor (type
, nreverse (eltlist
)), initlist
);
2622 entries
= TREE_CHAIN (entries
);
2626 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2629 /* struct objc_method_prototype_list {
2631 struct objc_method_prototype {
2638 build_method_prototype_list_template (list_type
, size
)
2642 tree objc_ivar_list_record
;
2643 tree decl_specs
, field_decl
, field_decl_chain
;
2645 /* Generate an unnamed struct definition. */
2647 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2649 /* int method_count; */
2651 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2652 field_decl
= get_identifier ("method_count");
2655 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2656 field_decl_chain
= field_decl
;
2658 /* struct objc_method method_list[]; */
2660 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2661 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2662 build_int_2 (size
, 0));
2665 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2666 chainon (field_decl_chain
, field_decl
);
2668 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2670 return objc_ivar_list_record
;
2674 build_method_prototype_template ()
2677 tree decl_specs
, field_decl
, field_decl_chain
;
2680 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2682 /* struct objc_selector *_cmd; */
2683 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2684 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2685 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2688 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2689 field_decl_chain
= field_decl
;
2691 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2693 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2695 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2696 chainon (field_decl_chain
, field_decl
);
2698 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2700 return proto_record
;
2703 /* True if last call to forwarding_offset yielded a register offset. */
2704 static int offset_is_register
;
2707 forwarding_offset (parm
)
2710 int offset_in_bytes
;
2712 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2714 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2716 /* ??? Here we assume that the parm address is indexed
2717 off the frame pointer or arg pointer.
2718 If that is not true, we produce meaningless results,
2719 but do not crash. */
2720 if (GET_CODE (addr
) == PLUS
2721 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2722 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2724 offset_in_bytes
= 0;
2726 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2727 offset_is_register
= 0;
2729 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2731 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2732 offset_in_bytes
= apply_args_register_offset (regno
);
2733 offset_is_register
= 1;
2738 /* This is the case where the parm is passed as an int or double
2739 and it is converted to a char, short or float and stored back
2740 in the parmlist. In this case, describe the parm
2741 with the variable's declared type, and adjust the address
2742 if the least significant bytes (which we are using) are not
2744 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2745 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2746 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2748 return offset_in_bytes
;
2752 encode_method_prototype (method_decl
, func_decl
)
2759 HOST_WIDE_INT max_parm_end
= 0;
2763 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2764 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2767 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2768 obstack_object_size (&util_obstack
),
2769 OBJC_ENCODE_INLINE_DEFS
);
2772 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2773 parms
= TREE_CHAIN (parms
))
2775 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2776 + int_size_in_bytes (TREE_TYPE (parms
)));
2778 if (!offset_is_register
&& max_parm_end
< parm_end
)
2779 max_parm_end
= parm_end
;
2782 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2784 sprintf (buf
, "%d", stack_size
);
2785 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2787 user_args
= METHOD_SEL_ARGS (method_decl
);
2789 /* Argument types. */
2790 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2791 parms
= TREE_CHAIN (parms
), i
++)
2793 /* Process argument qualifiers for user supplied arguments. */
2796 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2797 user_args
= TREE_CHAIN (user_args
);
2801 encode_type (TREE_TYPE (parms
),
2802 obstack_object_size (&util_obstack
),
2803 OBJC_ENCODE_INLINE_DEFS
);
2805 /* Compute offset. */
2806 sprintf (buf
, "%d", forwarding_offset (parms
));
2808 /* Indicate register. */
2809 if (offset_is_register
)
2810 obstack_1grow (&util_obstack
, '+');
2812 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2815 obstack_1grow (&util_obstack
, '\0');
2816 result
= get_identifier (obstack_finish (&util_obstack
));
2817 obstack_free (&util_obstack
, util_firstobj
);
2822 generate_descriptor_table (type
, name
, size
, list
, proto
)
2829 tree sc_spec
, decl_specs
, decl
, initlist
;
2831 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2832 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2834 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2835 decl_specs
, 1, NULL_TREE
);
2836 DECL_CONTEXT (decl
) = NULL_TREE
;
2838 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2839 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2841 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2848 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2851 tree initlist
, chain
, method_list_template
;
2852 tree cast
, variable_length_type
;
2855 if (!objc_method_prototype_template
)
2857 objc_method_prototype_template
= build_method_prototype_template ();
2860 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2861 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2863 variable_length_type
= groktypename (cast
);
2865 chain
= PROTOCOL_CLS_METHODS (protocol
);
2868 size
= list_length (chain
);
2870 method_list_template
2871 = build_method_prototype_list_template (objc_method_prototype_template
,
2875 = build_descriptor_table_initializer (objc_method_prototype_template
,
2878 UOBJC_CLASS_METHODS_decl
2879 = generate_descriptor_table (method_list_template
,
2880 "_OBJC_PROTOCOL_CLASS_METHODS",
2881 size
, initlist
, protocol
);
2882 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2885 UOBJC_CLASS_METHODS_decl
= 0;
2887 chain
= PROTOCOL_NST_METHODS (protocol
);
2890 size
= list_length (chain
);
2892 method_list_template
2893 = build_method_prototype_list_template (objc_method_prototype_template
,
2896 = build_descriptor_table_initializer (objc_method_prototype_template
,
2899 UOBJC_INSTANCE_METHODS_decl
2900 = generate_descriptor_table (method_list_template
,
2901 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2902 size
, initlist
, protocol
);
2903 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2906 UOBJC_INSTANCE_METHODS_decl
= 0;
2909 /* Generate a temporary FUNCTION_DECL node to be used in
2910 hack_method_prototype below. */
2913 build_tmp_function_decl ()
2915 tree decl_specs
, expr_decl
, parms
;
2919 /* struct objc_object *objc_xxx (id, SEL, ...); */
2921 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2922 push_parm_decl (build_tree_list
2923 (build_tree_list (decl_specs
,
2924 build1 (INDIRECT_REF
, NULL_TREE
,
2928 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2929 get_identifier (TAG_SELECTOR
)));
2930 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2932 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2934 parms
= get_parm_info (0);
2937 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2938 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2939 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2940 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2942 return define_decl (expr_decl
, decl_specs
);
2945 /* Generate the prototypes for protocol methods. This is used to
2946 generate method encodings for these.
2948 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2949 a decl node to be used. This is also where the return value is
2953 hack_method_prototype (nst_methods
, tmp_decl
)
2960 /* Hack to avoid problem with static typing of self arg. */
2961 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2962 start_method_def (nst_methods
);
2963 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2965 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2966 parms
= get_parm_info (0); /* we have a `, ...' */
2968 parms
= get_parm_info (1); /* place a `void_at_end' */
2970 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2972 /* Usually called from store_parm_decls -> init_function_start. */
2974 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2975 current_function_decl
= tmp_decl
;
2978 /* Code taken from start_function. */
2979 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2980 /* Promote the value to int before returning it. */
2981 if (TREE_CODE (restype
) == INTEGER_TYPE
2982 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2983 restype
= integer_type_node
;
2984 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2987 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2988 DECL_CONTEXT (parm
) = tmp_decl
;
2990 init_function_start (tmp_decl
, "objc-act", 0);
2992 /* Typically called from expand_function_start for function definitions. */
2993 assign_parms (tmp_decl
);
2995 /* install return type */
2996 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3001 generate_protocol_references (plist
)
3006 /* Forward declare protocols referenced. */
3007 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3009 tree proto
= TREE_VALUE (lproto
);
3011 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3012 && PROTOCOL_NAME (proto
))
3014 if (! PROTOCOL_FORWARD_DECL (proto
))
3015 build_protocol_reference (proto
);
3017 if (PROTOCOL_LIST (proto
))
3018 generate_protocol_references (PROTOCOL_LIST (proto
));
3024 generate_protocols ()
3026 tree p
, tmp_decl
, encoding
;
3027 tree sc_spec
, decl_specs
, decl
;
3028 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3031 tmp_decl
= build_tmp_function_decl ();
3033 if (! objc_protocol_template
)
3034 objc_protocol_template
= build_protocol_template ();
3036 /* If a protocol was directly referenced, pull in indirect references. */
3037 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3038 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3039 generate_protocol_references (PROTOCOL_LIST (p
));
3041 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3043 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3044 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3046 /* If protocol wasn't referenced, don't generate any code. */
3047 if (! PROTOCOL_FORWARD_DECL (p
))
3050 /* Make sure we link in the Protocol class. */
3051 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3055 if (! METHOD_ENCODING (nst_methods
))
3057 hack_method_prototype (nst_methods
, tmp_decl
);
3058 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3059 METHOD_ENCODING (nst_methods
) = encoding
;
3061 nst_methods
= TREE_CHAIN (nst_methods
);
3066 if (! METHOD_ENCODING (cls_methods
))
3068 hack_method_prototype (cls_methods
, tmp_decl
);
3069 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3070 METHOD_ENCODING (cls_methods
) = encoding
;
3073 cls_methods
= TREE_CHAIN (cls_methods
);
3075 generate_method_descriptors (p
);
3077 if (PROTOCOL_LIST (p
))
3078 refs_decl
= generate_protocol_list (p
);
3082 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3084 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3086 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3088 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3089 decl_specs
, 1, NULL_TREE
);
3091 DECL_CONTEXT (decl
) = NULL_TREE
;
3093 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3099 (build_tree_list (build_tree_list (NULL_TREE
,
3100 objc_protocol_template
),
3101 build1 (INDIRECT_REF
, NULL_TREE
,
3102 build1 (INDIRECT_REF
, NULL_TREE
,
3105 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3106 TREE_TYPE (refs_expr
) = cast_type2
;
3109 refs_expr
= build_int_2 (0, 0);
3111 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3112 by generate_method_descriptors, which is called above. */
3113 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3114 protocol_name_expr
, refs_expr
,
3115 UOBJC_INSTANCE_METHODS_decl
,
3116 UOBJC_CLASS_METHODS_decl
);
3117 finish_decl (decl
, initlist
, NULL_TREE
);
3119 /* Mark the decl as used to avoid "defined but not used" warning. */
3120 TREE_USED (decl
) = 1;
3125 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3126 instance_methods
, class_methods
)
3130 tree instance_methods
;
3133 tree initlist
= NULL_TREE
, expr
;
3136 cast_type
= groktypename
3138 (build_tree_list (NULL_TREE
,
3139 xref_tag (RECORD_TYPE
,
3140 get_identifier (UTAG_CLASS
))),
3141 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3143 /* Filling the "isa" in with one allows the runtime system to
3144 detect that the version change...should remove before final release. */
3146 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3147 TREE_TYPE (expr
) = cast_type
;
3148 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3149 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3150 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3152 if (!instance_methods
)
3153 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3156 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3157 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3161 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3164 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3165 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3168 return build_constructor (type
, nreverse (initlist
));
3171 /* struct objc_category {
3172 char *category_name;
3174 struct objc_method_list *instance_methods;
3175 struct objc_method_list *class_methods;
3176 struct objc_protocol_list *protocols;
3180 build_category_template ()
3182 tree decl_specs
, field_decl
, field_decl_chain
;
3184 objc_category_template
= start_struct (RECORD_TYPE
,
3185 get_identifier (UTAG_CATEGORY
));
3186 /* char *category_name; */
3188 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3190 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3192 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3193 field_decl_chain
= field_decl
;
3195 /* char *class_name; */
3197 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3198 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3200 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3201 chainon (field_decl_chain
, field_decl
);
3203 /* struct objc_method_list *instance_methods; */
3205 decl_specs
= build_tree_list (NULL_TREE
,
3206 xref_tag (RECORD_TYPE
,
3207 get_identifier (UTAG_METHOD_LIST
)));
3209 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3211 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3212 chainon (field_decl_chain
, field_decl
);
3214 /* struct objc_method_list *class_methods; */
3216 decl_specs
= build_tree_list (NULL_TREE
,
3217 xref_tag (RECORD_TYPE
,
3218 get_identifier (UTAG_METHOD_LIST
)));
3220 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3222 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3223 chainon (field_decl_chain
, field_decl
);
3225 /* struct objc_protocol **protocol_list; */
3227 decl_specs
= build_tree_list (NULL_TREE
,
3228 xref_tag (RECORD_TYPE
,
3229 get_identifier (UTAG_PROTOCOL
)));
3231 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3232 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3234 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3235 chainon (field_decl_chain
, field_decl
);
3237 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3240 /* struct objc_selector {
3246 build_selector_template ()
3249 tree decl_specs
, field_decl
, field_decl_chain
;
3251 objc_selector_template
3252 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3256 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3257 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3259 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3260 field_decl_chain
= field_decl
;
3262 /* char *sel_type; */
3264 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3265 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3267 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3268 chainon (field_decl_chain
, field_decl
);
3270 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3273 /* struct objc_class {
3274 struct objc_class *isa;
3275 struct objc_class *super_class;
3280 struct objc_ivar_list *ivars;
3281 struct objc_method_list *methods;
3282 if (flag_next_runtime)
3283 struct objc_cache *cache;
3285 struct sarray *dtable;
3286 struct objc_class *subclass_list;
3287 struct objc_class *sibling_class;
3289 struct objc_protocol_list *protocols;
3290 void *gc_object_type;
3294 build_class_template ()
3296 tree decl_specs
, field_decl
, field_decl_chain
;
3299 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3301 /* struct objc_class *isa; */
3303 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3304 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3306 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3307 field_decl_chain
= field_decl
;
3309 /* struct objc_class *super_class; */
3311 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3313 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3315 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3316 chainon (field_decl_chain
, field_decl
);
3320 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3321 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3323 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3324 chainon (field_decl_chain
, field_decl
);
3328 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3329 field_decl
= get_identifier ("version");
3331 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3332 chainon (field_decl_chain
, field_decl
);
3336 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3337 field_decl
= get_identifier ("info");
3339 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3340 chainon (field_decl_chain
, field_decl
);
3342 /* long instance_size; */
3344 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3345 field_decl
= get_identifier ("instance_size");
3347 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3348 chainon (field_decl_chain
, field_decl
);
3350 /* struct objc_ivar_list *ivars; */
3352 decl_specs
= build_tree_list (NULL_TREE
,
3353 xref_tag (RECORD_TYPE
,
3354 get_identifier (UTAG_IVAR_LIST
)));
3355 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3357 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3358 chainon (field_decl_chain
, field_decl
);
3360 /* struct objc_method_list *methods; */
3362 decl_specs
= build_tree_list (NULL_TREE
,
3363 xref_tag (RECORD_TYPE
,
3364 get_identifier (UTAG_METHOD_LIST
)));
3365 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3367 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3368 chainon (field_decl_chain
, field_decl
);
3370 if (flag_next_runtime
)
3372 /* struct objc_cache *cache; */
3374 decl_specs
= build_tree_list (NULL_TREE
,
3375 xref_tag (RECORD_TYPE
,
3376 get_identifier ("objc_cache")));
3377 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3378 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3379 decl_specs
, NULL_TREE
);
3380 chainon (field_decl_chain
, field_decl
);
3384 /* struct sarray *dtable; */
3386 decl_specs
= build_tree_list (NULL_TREE
,
3387 xref_tag (RECORD_TYPE
,
3388 get_identifier ("sarray")));
3389 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3390 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3391 decl_specs
, NULL_TREE
);
3392 chainon (field_decl_chain
, field_decl
);
3394 /* struct objc_class *subclass_list; */
3396 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3398 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3399 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3400 decl_specs
, NULL_TREE
);
3401 chainon (field_decl_chain
, field_decl
);
3403 /* struct objc_class *sibling_class; */
3405 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3407 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3408 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3409 decl_specs
, NULL_TREE
);
3410 chainon (field_decl_chain
, field_decl
);
3413 /* struct objc_protocol **protocol_list; */
3415 decl_specs
= build_tree_list (NULL_TREE
,
3416 xref_tag (RECORD_TYPE
,
3417 get_identifier (UTAG_PROTOCOL
)));
3419 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3421 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3422 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3423 decl_specs
, NULL_TREE
);
3424 chainon (field_decl_chain
, field_decl
);
3428 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3429 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3431 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3432 chainon (field_decl_chain
, field_decl
);
3434 /* void *gc_object_type; */
3436 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3437 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3439 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3440 chainon (field_decl_chain
, field_decl
);
3442 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3445 /* Generate appropriate forward declarations for an implementation. */
3448 synth_forward_declarations ()
3450 tree sc_spec
, decl_specs
, an_id
;
3452 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3454 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3456 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3457 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3458 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3459 TREE_USED (UOBJC_CLASS_decl
) = 1;
3460 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3462 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3464 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3465 objc_implementation_context
);
3467 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3468 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3469 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3471 /* Pre-build the following entities - for speed/convenience. */
3473 an_id
= get_identifier ("super_class");
3474 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3475 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3479 error_with_ivar (message
, decl
, rawdecl
)
3480 const char *message
;
3486 report_error_function (DECL_SOURCE_FILE (decl
));
3488 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3489 DECL_SOURCE_LINE (decl
),
3491 message
, gen_declaration (rawdecl
, errbuf
));
3495 #define USERTYPE(t) \
3496 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3497 || TREE_CODE (t) == ENUMERAL_TYPE)
3500 check_ivars (inter
, imp
)
3504 tree intdecls
= CLASS_IVARS (inter
);
3505 tree impdecls
= CLASS_IVARS (imp
);
3506 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3507 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3513 if (intdecls
== 0 && impdecls
== 0)
3515 if (intdecls
== 0 || impdecls
== 0)
3517 error ("inconsistent instance variable specification");
3521 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3523 if (!comptypes (t1
, t2
))
3525 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3527 error_with_ivar ("conflicting instance variable type",
3528 impdecls
, rawimpdecls
);
3529 error_with_ivar ("previous declaration of",
3530 intdecls
, rawintdecls
);
3532 else /* both the type and the name don't match */
3534 error ("inconsistent instance variable specification");
3539 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3541 error_with_ivar ("conflicting instance variable name",
3542 impdecls
, rawimpdecls
);
3543 error_with_ivar ("previous declaration of",
3544 intdecls
, rawintdecls
);
3547 intdecls
= TREE_CHAIN (intdecls
);
3548 impdecls
= TREE_CHAIN (impdecls
);
3549 rawintdecls
= TREE_CHAIN (rawintdecls
);
3550 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3554 /* Set super_type to the data type node for struct objc_super *,
3555 first defining struct objc_super itself.
3556 This needs to be done just once per compilation. */
3559 build_super_template ()
3561 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3563 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3565 /* struct objc_object *self; */
3567 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3568 field_decl
= get_identifier ("self");
3569 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3570 field_decl
= grokfield (input_filename
, lineno
,
3571 field_decl
, decl_specs
, NULL_TREE
);
3572 field_decl_chain
= field_decl
;
3574 /* struct objc_class *class; */
3576 decl_specs
= get_identifier (UTAG_CLASS
);
3577 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3578 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3580 field_decl
= grokfield (input_filename
, lineno
,
3581 field_decl
, decl_specs
, NULL_TREE
);
3582 chainon (field_decl_chain
, field_decl
);
3584 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3586 /* `struct objc_super *' */
3587 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3589 build1 (INDIRECT_REF
,
3590 NULL_TREE
, NULL_TREE
)));
3594 /* struct objc_ivar {
3601 build_ivar_template ()
3603 tree objc_ivar_id
, objc_ivar_record
;
3604 tree decl_specs
, field_decl
, field_decl_chain
;
3606 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3607 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3609 /* char *ivar_name; */
3611 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3612 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3614 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3615 decl_specs
, NULL_TREE
);
3616 field_decl_chain
= field_decl
;
3618 /* char *ivar_type; */
3620 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3621 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3623 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3624 decl_specs
, NULL_TREE
);
3625 chainon (field_decl_chain
, field_decl
);
3627 /* int ivar_offset; */
3629 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3630 field_decl
= get_identifier ("ivar_offset");
3632 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3633 decl_specs
, NULL_TREE
);
3634 chainon (field_decl_chain
, field_decl
);
3636 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3638 return objc_ivar_record
;
3643 struct objc_ivar ivar_list[ivar_count];
3647 build_ivar_list_template (list_type
, size
)
3651 tree objc_ivar_list_record
;
3652 tree decl_specs
, field_decl
, field_decl_chain
;
3654 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3656 /* int ivar_count; */
3658 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3659 field_decl
= get_identifier ("ivar_count");
3661 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3662 decl_specs
, NULL_TREE
);
3663 field_decl_chain
= field_decl
;
3665 /* struct objc_ivar ivar_list[]; */
3667 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3668 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3669 build_int_2 (size
, 0));
3671 field_decl
= grokfield (input_filename
, lineno
,
3672 field_decl
, decl_specs
, NULL_TREE
);
3673 chainon (field_decl_chain
, field_decl
);
3675 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3677 return objc_ivar_list_record
;
3683 struct objc_method method_list[method_count];
3687 build_method_list_template (list_type
, size
)
3691 tree objc_ivar_list_record
;
3692 tree decl_specs
, field_decl
, field_decl_chain
;
3694 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3696 /* int method_next; */
3701 xref_tag (RECORD_TYPE
,
3702 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3704 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3705 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3706 decl_specs
, NULL_TREE
);
3707 field_decl_chain
= field_decl
;
3709 /* int method_count; */
3711 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3712 field_decl
= get_identifier ("method_count");
3714 field_decl
= grokfield (input_filename
, lineno
,
3715 field_decl
, decl_specs
, NULL_TREE
);
3716 chainon (field_decl_chain
, field_decl
);
3718 /* struct objc_method method_list[]; */
3720 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3721 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3722 build_int_2 (size
, 0));
3724 field_decl
= grokfield (input_filename
, lineno
,
3725 field_decl
, decl_specs
, NULL_TREE
);
3726 chainon (field_decl_chain
, field_decl
);
3728 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3730 return objc_ivar_list_record
;
3734 build_ivar_list_initializer (type
, field_decl
)
3738 tree initlist
= NULL_TREE
;
3742 tree ivar
= NULL_TREE
;
3745 if (DECL_NAME (field_decl
))
3746 ivar
= tree_cons (NULL_TREE
,
3747 add_objc_string (DECL_NAME (field_decl
),
3751 /* Unnamed bit-field ivar (yuck). */
3752 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3755 encode_field_decl (field_decl
,
3756 obstack_object_size (&util_obstack
),
3757 OBJC_ENCODE_DONT_INLINE_DEFS
);
3759 /* Null terminate string. */
3760 obstack_1grow (&util_obstack
, 0);
3764 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3767 obstack_free (&util_obstack
, util_firstobj
);
3770 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3771 initlist
= tree_cons (NULL_TREE
,
3772 build_constructor (type
, nreverse (ivar
)),
3775 field_decl
= TREE_CHAIN (field_decl
);
3779 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3783 generate_ivars_list (type
, name
, size
, list
)
3789 tree sc_spec
, decl_specs
, decl
, initlist
;
3791 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3792 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3794 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3795 decl_specs
, 1, NULL_TREE
);
3797 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3798 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3801 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3808 generate_ivar_lists ()
3810 tree initlist
, ivar_list_template
, chain
;
3811 tree cast
, variable_length_type
;
3814 generating_instance_variables
= 1;
3816 if (!objc_ivar_template
)
3817 objc_ivar_template
= build_ivar_template ();
3821 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3822 get_identifier (UTAG_IVAR_LIST
))),
3824 variable_length_type
= groktypename (cast
);
3826 /* Only generate class variables for the root of the inheritance
3827 hierarchy since these will be the same for every class. */
3829 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3830 && (chain
= TYPE_FIELDS (objc_class_template
)))
3832 size
= list_length (chain
);
3834 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3835 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3837 UOBJC_CLASS_VARIABLES_decl
3838 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3840 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3843 UOBJC_CLASS_VARIABLES_decl
= 0;
3845 chain
= CLASS_IVARS (implementation_template
);
3848 size
= list_length (chain
);
3849 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3850 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3852 UOBJC_INSTANCE_VARIABLES_decl
3853 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3855 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3858 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3860 generating_instance_variables
= 0;
3864 build_dispatch_table_initializer (type
, entries
)
3868 tree initlist
= NULL_TREE
;
3872 tree elemlist
= NULL_TREE
;
3874 elemlist
= tree_cons (NULL_TREE
,
3875 build_selector (METHOD_SEL_NAME (entries
)),
3878 elemlist
= tree_cons (NULL_TREE
,
3879 add_objc_string (METHOD_ENCODING (entries
),
3883 elemlist
= tree_cons (NULL_TREE
,
3884 build_unary_op (ADDR_EXPR
,
3885 METHOD_DEFINITION (entries
), 1),
3888 initlist
= tree_cons (NULL_TREE
,
3889 build_constructor (type
, nreverse (elemlist
)),
3892 entries
= TREE_CHAIN (entries
);
3896 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3899 /* To accomplish method prototyping without generating all kinds of
3900 inane warnings, the definition of the dispatch table entries were
3903 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3905 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3908 build_method_template ()
3911 tree decl_specs
, field_decl
, field_decl_chain
;
3913 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3915 /* struct objc_selector *_cmd; */
3916 decl_specs
= tree_cons (NULL_TREE
,
3917 xref_tag (RECORD_TYPE
,
3918 get_identifier (TAG_SELECTOR
)),
3920 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3922 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3923 decl_specs
, NULL_TREE
);
3924 field_decl_chain
= field_decl
;
3926 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3927 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3928 get_identifier ("method_types"));
3929 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3930 decl_specs
, NULL_TREE
);
3931 chainon (field_decl_chain
, field_decl
);
3935 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3936 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3937 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3938 decl_specs
, NULL_TREE
);
3939 chainon (field_decl_chain
, field_decl
);
3941 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3948 generate_dispatch_table (type
, name
, size
, list
)
3954 tree sc_spec
, decl_specs
, decl
, initlist
;
3956 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3957 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3959 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3960 decl_specs
, 1, NULL_TREE
);
3962 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3963 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3964 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3967 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3974 generate_dispatch_tables ()
3976 tree initlist
, chain
, method_list_template
;
3977 tree cast
, variable_length_type
;
3980 if (!objc_method_template
)
3981 objc_method_template
= build_method_template ();
3985 (build_tree_list (NULL_TREE
,
3986 xref_tag (RECORD_TYPE
,
3987 get_identifier (UTAG_METHOD_LIST
))),
3990 variable_length_type
= groktypename (cast
);
3992 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3995 size
= list_length (chain
);
3997 method_list_template
3998 = build_method_list_template (objc_method_template
, size
);
4000 = build_dispatch_table_initializer (objc_method_template
, chain
);
4002 UOBJC_CLASS_METHODS_decl
4003 = generate_dispatch_table (method_list_template
,
4004 ((TREE_CODE (objc_implementation_context
)
4005 == CLASS_IMPLEMENTATION_TYPE
)
4006 ? "_OBJC_CLASS_METHODS"
4007 : "_OBJC_CATEGORY_CLASS_METHODS"),
4009 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4012 UOBJC_CLASS_METHODS_decl
= 0;
4014 chain
= CLASS_NST_METHODS (objc_implementation_context
);
4017 size
= list_length (chain
);
4019 method_list_template
4020 = build_method_list_template (objc_method_template
, size
);
4022 = build_dispatch_table_initializer (objc_method_template
, chain
);
4024 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4025 UOBJC_INSTANCE_METHODS_decl
4026 = generate_dispatch_table (method_list_template
,
4027 "_OBJC_INSTANCE_METHODS",
4030 /* We have a category. */
4031 UOBJC_INSTANCE_METHODS_decl
4032 = generate_dispatch_table (method_list_template
,
4033 "_OBJC_CATEGORY_INSTANCE_METHODS",
4035 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4038 UOBJC_INSTANCE_METHODS_decl
= 0;
4042 generate_protocol_list (i_or_p
)
4045 tree initlist
, decl_specs
, sc_spec
;
4046 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4050 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4051 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4052 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4053 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4054 plist
= PROTOCOL_LIST (i_or_p
);
4058 cast_type
= groktypename
4060 (build_tree_list (NULL_TREE
,
4061 xref_tag (RECORD_TYPE
,
4062 get_identifier (UTAG_PROTOCOL
))),
4063 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4066 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4067 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4068 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4071 /* Build initializer. */
4072 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4074 e
= build_int_2 (size
, 0);
4075 TREE_TYPE (e
) = cast_type
;
4076 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4078 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4080 tree pval
= TREE_VALUE (lproto
);
4082 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4083 && PROTOCOL_FORWARD_DECL (pval
))
4085 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4086 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4090 /* static struct objc_protocol *refs[n]; */
4092 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4093 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4094 get_identifier (UTAG_PROTOCOL
)),
4097 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4098 expr_decl
= build_nt (ARRAY_REF
,
4099 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4101 build_int_2 (size
+ 2, 0));
4102 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4103 expr_decl
= build_nt (ARRAY_REF
,
4104 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4106 build_int_2 (size
+ 2, 0));
4107 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4109 = build_nt (ARRAY_REF
,
4110 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4112 build_int_2 (size
+ 2, 0));
4116 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4118 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4119 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4121 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4122 nreverse (initlist
)),
4129 build_category_initializer (type
, cat_name
, class_name
,
4130 instance_methods
, class_methods
, protocol_list
)
4134 tree instance_methods
;
4138 tree initlist
= NULL_TREE
, expr
;
4140 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4141 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4143 if (!instance_methods
)
4144 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4147 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4148 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4151 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4154 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4155 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4158 /* protocol_list = */
4160 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4163 tree cast_type2
= groktypename
4165 (build_tree_list (NULL_TREE
,
4166 xref_tag (RECORD_TYPE
,
4167 get_identifier (UTAG_PROTOCOL
))),
4168 build1 (INDIRECT_REF
, NULL_TREE
,
4169 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4171 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4172 TREE_TYPE (expr
) = cast_type2
;
4173 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4176 return build_constructor (type
, nreverse (initlist
));
4179 /* struct objc_class {
4180 struct objc_class *isa;
4181 struct objc_class *super_class;
4186 struct objc_ivar_list *ivars;
4187 struct objc_method_list *methods;
4188 if (flag_next_runtime)
4189 struct objc_cache *cache;
4191 struct sarray *dtable;
4192 struct objc_class *subclass_list;
4193 struct objc_class *sibling_class;
4195 struct objc_protocol_list *protocols;
4196 void *gc_object_type;
4200 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4201 dispatch_table
, ivar_list
, protocol_list
)
4208 tree dispatch_table
;
4212 tree initlist
= NULL_TREE
, expr
;
4215 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4218 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4221 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4224 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4227 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4229 /* instance_size = */
4230 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4232 /* objc_ivar_list = */
4234 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4237 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4238 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4241 /* objc_method_list = */
4242 if (!dispatch_table
)
4243 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4246 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4247 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4250 if (flag_next_runtime
)
4251 /* method_cache = */
4252 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4256 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4258 /* subclass_list = */
4259 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4261 /* sibling_class = */
4262 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4265 /* protocol_list = */
4266 if (! protocol_list
)
4267 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4273 (build_tree_list (NULL_TREE
,
4274 xref_tag (RECORD_TYPE
,
4275 get_identifier (UTAG_PROTOCOL
))),
4276 build1 (INDIRECT_REF
, NULL_TREE
,
4277 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4279 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4280 TREE_TYPE (expr
) = cast_type2
;
4281 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4284 /* gc_object_type = NULL */
4285 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4287 return build_constructor (type
, nreverse (initlist
));
4290 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4293 generate_category (cat
)
4296 tree sc_spec
, decl_specs
, decl
;
4297 tree initlist
, cat_name_expr
, class_name_expr
;
4298 tree protocol_decl
, category
;
4300 add_class_reference (CLASS_NAME (cat
));
4301 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4303 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4305 category
= CLASS_CATEGORY_LIST (implementation_template
);
4307 /* find the category interface from the class it is associated with */
4310 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4312 category
= CLASS_CATEGORY_LIST (category
);
4315 if (category
&& CLASS_PROTOCOL_LIST (category
))
4317 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4318 protocol_decl
= generate_protocol_list (category
);
4323 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4324 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4326 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4327 objc_implementation_context
),
4328 decl_specs
, 1, NULL_TREE
);
4330 initlist
= build_category_initializer (TREE_TYPE (decl
),
4331 cat_name_expr
, class_name_expr
,
4332 UOBJC_INSTANCE_METHODS_decl
,
4333 UOBJC_CLASS_METHODS_decl
,
4336 TREE_USED (decl
) = 1;
4337 finish_decl (decl
, initlist
, NULL_TREE
);
4340 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4341 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4344 generate_shared_structures ()
4346 tree sc_spec
, decl_specs
, decl
;
4347 tree name_expr
, super_expr
, root_expr
;
4348 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4349 tree cast_type
, initlist
, protocol_decl
;
4351 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4354 add_class_reference (my_super_id
);
4356 /* Compute "my_root_id" - this is required for code generation.
4357 the "isa" for all meta class structures points to the root of
4358 the inheritance hierarchy (e.g. "__Object")... */
4359 my_root_id
= my_super_id
;
4362 tree my_root_int
= lookup_interface (my_root_id
);
4364 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4365 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4372 /* No super class. */
4373 my_root_id
= CLASS_NAME (implementation_template
);
4376 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4377 objc_class_template
),
4378 build1 (INDIRECT_REF
,
4379 NULL_TREE
, NULL_TREE
)));
4381 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4384 /* Install class `isa' and `super' pointers at runtime. */
4387 super_expr
= add_objc_string (my_super_id
, class_names
);
4388 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4391 super_expr
= build_int_2 (0, 0);
4393 root_expr
= add_objc_string (my_root_id
, class_names
);
4394 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4396 if (CLASS_PROTOCOL_LIST (implementation_template
))
4398 generate_protocol_references
4399 (CLASS_PROTOCOL_LIST (implementation_template
));
4400 protocol_decl
= generate_protocol_list (implementation_template
);
4405 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4407 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4408 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4410 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4414 = build_shared_structure_initializer
4416 root_expr
, super_expr
, name_expr
,
4417 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4419 UOBJC_CLASS_METHODS_decl
,
4420 UOBJC_CLASS_VARIABLES_decl
,
4423 finish_decl (decl
, initlist
, NULL_TREE
);
4425 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4427 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4431 = build_shared_structure_initializer
4433 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4434 super_expr
, name_expr
,
4435 convert (integer_type_node
,
4436 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4437 (implementation_template
))),
4439 UOBJC_INSTANCE_METHODS_decl
,
4440 UOBJC_INSTANCE_VARIABLES_decl
,
4443 finish_decl (decl
, initlist
, NULL_TREE
);
4447 synth_id_with_class_suffix (preamble
, ctxt
)
4448 const char *preamble
;
4452 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4453 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4455 const char *const class_name
4456 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4457 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4458 sprintf (string
, "%s_%s", preamble
,
4459 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4461 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4462 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4464 /* We have a category. */
4465 const char *const class_name
4466 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4467 const char *const class_super_name
4468 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4469 string
= (char *) alloca (strlen (preamble
)
4470 + strlen (class_name
)
4471 + strlen (class_super_name
)
4473 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4475 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4477 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4479 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4480 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4485 return get_identifier (string
);
4489 is_objc_type_qualifier (node
)
4492 return (TREE_CODE (node
) == IDENTIFIER_NODE
4493 && (node
== ridpointers
[(int) RID_CONST
]
4494 || node
== ridpointers
[(int) RID_VOLATILE
]
4495 || node
== ridpointers
[(int) RID_IN
]
4496 || node
== ridpointers
[(int) RID_OUT
]
4497 || node
== ridpointers
[(int) RID_INOUT
]
4498 || node
== ridpointers
[(int) RID_BYCOPY
]
4499 || node
== ridpointers
[(int) RID_BYREF
]
4500 || node
== ridpointers
[(int) RID_ONEWAY
]));
4503 /* If type is empty or only type qualifiers are present, add default
4504 type of id (otherwise grokdeclarator will default to int). */
4507 adjust_type_for_id_default (type
)
4510 tree declspecs
, chain
;
4513 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4514 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4516 declspecs
= TREE_PURPOSE (type
);
4518 /* Determine if a typespec is present. */
4519 for (chain
= declspecs
;
4521 chain
= TREE_CHAIN (chain
))
4523 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4527 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4529 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4534 selector ':' '(' typename ')' identifier
4537 Transform an Objective-C keyword argument into
4538 the C equivalent parameter declarator.
4540 In: key_name, an "identifier_node" (optional).
4541 arg_type, a "tree_list" (optional).
4542 arg_name, an "identifier_node".
4544 Note: It would be really nice to strongly type the preceding
4545 arguments in the function prototype; however, then I
4546 could not use the "accessor" macros defined in "tree.h".
4548 Out: an instance of "keyword_decl". */
4551 build_keyword_decl (key_name
, arg_type
, arg_name
)
4558 /* If no type is specified, default to "id". */
4559 arg_type
= adjust_type_for_id_default (arg_type
);
4561 keyword_decl
= make_node (KEYWORD_DECL
);
4563 TREE_TYPE (keyword_decl
) = arg_type
;
4564 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4565 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4567 return keyword_decl
;
4570 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4573 build_keyword_selector (selector
)
4577 tree key_chain
, key_name
;
4580 /* Scan the selector to see how much space we'll need. */
4581 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4583 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4584 key_name
= KEYWORD_KEY_NAME (key_chain
);
4585 else if (TREE_CODE (selector
) == TREE_LIST
)
4586 key_name
= TREE_PURPOSE (key_chain
);
4591 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4593 /* Just a ':' arg. */
4597 buf
= (char *) alloca (len
+ 1);
4598 /* Start the buffer out as an empty string. */
4601 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4603 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4604 key_name
= KEYWORD_KEY_NAME (key_chain
);
4605 else if (TREE_CODE (selector
) == TREE_LIST
)
4606 key_name
= TREE_PURPOSE (key_chain
);
4611 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4615 return get_identifier (buf
);
4618 /* Used for declarations and definitions. */
4621 build_method_decl (code
, ret_type
, selector
, add_args
)
4622 enum tree_code code
;
4629 /* If no type is specified, default to "id". */
4630 ret_type
= adjust_type_for_id_default (ret_type
);
4632 method_decl
= make_node (code
);
4633 TREE_TYPE (method_decl
) = ret_type
;
4635 /* If we have a keyword selector, create an identifier_node that
4636 represents the full selector name (`:' included)... */
4637 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4639 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4640 METHOD_SEL_ARGS (method_decl
) = selector
;
4641 METHOD_ADD_ARGS (method_decl
) = add_args
;
4645 METHOD_SEL_NAME (method_decl
) = selector
;
4646 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4647 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4653 #define METHOD_DEF 0
4654 #define METHOD_REF 1
4656 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4657 an argument list for method METH. CONTEXT is either METHOD_DEF or
4658 METHOD_REF, saying whether we are trying to define a method or call
4659 one. SUPERFLAG says this is for a send to super; this makes a
4660 difference for the NeXT calling sequence in which the lookup and
4661 the method call are done together. */
4664 get_arg_type_list (meth
, context
, superflag
)
4671 /* Receiver type. */
4672 if (flag_next_runtime
&& superflag
)
4673 arglist
= build_tree_list (NULL_TREE
, super_type
);
4674 else if (context
== METHOD_DEF
)
4675 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4677 arglist
= build_tree_list (NULL_TREE
, id_type
);
4679 /* Selector type - will eventually change to `int'. */
4680 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4682 /* Build a list of argument types. */
4683 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4685 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4686 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4689 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4690 /* We have a `, ...' immediately following the selector,
4691 finalize the arglist...simulate get_parm_info (0). */
4693 else if (METHOD_ADD_ARGS (meth
))
4695 /* we have a variable length selector */
4696 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4697 chainon (arglist
, add_arg_list
);
4700 /* finalize the arglist...simulate get_parm_info (1) */
4701 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4707 check_duplicates (hsh
)
4710 tree meth
= NULL_TREE
;
4718 /* We have two methods with the same name and different types. */
4720 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4722 warning ("multiple declarations for method `%s'",
4723 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4725 warn_with_method ("using", type
, meth
);
4726 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4727 warn_with_method ("also found", type
, loop
->value
);
4733 /* If RECEIVER is a class reference, return the identifier node for
4734 the referenced class. RECEIVER is created by get_class_reference,
4735 so we check the exact form created depending on which runtimes are
4739 receiver_is_class_object (receiver
)
4742 tree chain
, exp
, arg
;
4744 /* The receiver is 'self' in the context of a class method. */
4745 if (objc_method_context
4746 && receiver
== self_decl
4747 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4749 return CLASS_NAME (objc_implementation_context
);
4752 if (flag_next_runtime
)
4754 /* The receiver is a variable created by
4755 build_class_reference_decl. */
4756 if (TREE_CODE (receiver
) == VAR_DECL
4757 && TREE_TYPE (receiver
) == objc_class_type
)
4758 /* Look up the identifier. */
4759 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4760 if (TREE_PURPOSE (chain
) == receiver
)
4761 return TREE_VALUE (chain
);
4765 /* The receiver is a function call that returns an id. Check if
4766 it is a call to objc_getClass, if so, pick up the class name. */
4767 if (TREE_CODE (receiver
) == CALL_EXPR
4768 && (exp
= TREE_OPERAND (receiver
, 0))
4769 && TREE_CODE (exp
) == ADDR_EXPR
4770 && (exp
= TREE_OPERAND (exp
, 0))
4771 && TREE_CODE (exp
) == FUNCTION_DECL
4772 && exp
== objc_get_class_decl
4773 /* We have a call to objc_getClass! */
4774 && (arg
= TREE_OPERAND (receiver
, 1))
4775 && TREE_CODE (arg
) == TREE_LIST
4776 && (arg
= TREE_VALUE (arg
)))
4779 if (TREE_CODE (arg
) == ADDR_EXPR
4780 && (arg
= TREE_OPERAND (arg
, 0))
4781 && TREE_CODE (arg
) == STRING_CST
)
4782 /* Finally, we have the class name. */
4783 return get_identifier (TREE_STRING_POINTER (arg
));
4789 /* If we are currently building a message expr, this holds
4790 the identifier of the selector of the message. This is
4791 used when printing warnings about argument mismatches. */
4793 static tree building_objc_message_expr
= 0;
4796 maybe_building_objc_message_expr ()
4798 return building_objc_message_expr
;
4801 /* Construct an expression for sending a message.
4802 MESS has the object to send to in TREE_PURPOSE
4803 and the argument list (including selector) in TREE_VALUE.
4805 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4806 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4809 build_message_expr (mess
)
4812 tree receiver
= TREE_PURPOSE (mess
);
4814 tree args
= TREE_VALUE (mess
);
4815 tree method_params
= NULL_TREE
;
4817 if (TREE_CODE (receiver
) == ERROR_MARK
)
4818 return error_mark_node
;
4820 /* Obtain the full selector name. */
4821 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4822 /* A unary selector. */
4824 else if (TREE_CODE (args
) == TREE_LIST
)
4825 sel_name
= build_keyword_selector (args
);
4829 /* Build the parameter list to give to the method. */
4830 if (TREE_CODE (args
) == TREE_LIST
)
4832 tree chain
= args
, prev
= NULL_TREE
;
4834 /* We have a keyword selector--check for comma expressions. */
4837 tree element
= TREE_VALUE (chain
);
4839 /* We have a comma expression, must collapse... */
4840 if (TREE_CODE (element
) == TREE_LIST
)
4843 TREE_CHAIN (prev
) = element
;
4848 chain
= TREE_CHAIN (chain
);
4850 method_params
= args
;
4853 return finish_message_expr (receiver
, sel_name
, method_params
);
4856 /* The 'finish_message_expr' routine is called from within
4857 'build_message_expr' for non-template functions. In the case of
4858 C++ template functions, it is called from 'build_expr_from_tree'
4859 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4862 finish_message_expr (receiver
, sel_name
, method_params
)
4863 tree receiver
, sel_name
, method_params
;
4865 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4866 tree selector
, self_object
, retval
;
4867 int statically_typed
= 0, statically_allocated
= 0;
4869 /* Determine receiver type. */
4870 tree rtype
= TREE_TYPE (receiver
);
4871 int super
= IS_SUPER (rtype
);
4875 if (TREE_STATIC_TEMPLATE (rtype
))
4876 statically_allocated
= 1;
4877 else if (TREE_CODE (rtype
) == POINTER_TYPE
4878 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4879 statically_typed
= 1;
4880 else if ((flag_next_runtime
4882 && (class_ident
= receiver_is_class_object (receiver
)))))
4884 else if (! IS_ID (rtype
)
4885 /* Allow any type that matches objc_class_type. */
4886 && ! comptypes (rtype
, objc_class_type
))
4888 warning ("invalid receiver type `%s'",
4889 gen_declaration (rtype
, errbuf
));
4891 if (statically_allocated
)
4892 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4894 /* Don't evaluate the receiver twice. */
4895 receiver
= save_expr (receiver
);
4896 self_object
= receiver
;
4899 /* If sending to `super', use current self as the object. */
4900 self_object
= self_decl
;
4902 /* Determine operation return type. */
4908 if (CLASS_SUPER_NAME (implementation_template
))
4911 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4913 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4914 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4916 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4918 if (iface
&& !method_prototype
)
4919 warning ("`%s' does not respond to `%s'",
4920 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4921 IDENTIFIER_POINTER (sel_name
));
4925 error ("no super class declared in interface for `%s'",
4926 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4927 return error_mark_node
;
4931 else if (statically_allocated
)
4933 tree ctype
= TREE_TYPE (rtype
);
4934 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4937 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4939 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4941 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4944 if (!method_prototype
)
4945 warning ("`%s' does not respond to `%s'",
4946 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4947 IDENTIFIER_POINTER (sel_name
));
4949 else if (statically_typed
)
4951 tree ctype
= TREE_TYPE (rtype
);
4953 /* `self' is now statically_typed. All methods should be visible
4954 within the context of the implementation. */
4955 if (objc_implementation_context
4956 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4959 = lookup_instance_method_static (implementation_template
,
4962 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4964 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4967 if (! method_prototype
4968 && implementation_template
!= objc_implementation_context
)
4969 /* The method is not published in the interface. Check
4972 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4979 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4980 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4982 if (! method_prototype
)
4984 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4987 = lookup_method_in_protocol_list (protocol_list
,
4992 if (!method_prototype
)
4993 warning ("`%s' does not respond to `%s'",
4994 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4995 IDENTIFIER_POINTER (sel_name
));
4997 else if (class_ident
)
4999 if (objc_implementation_context
5000 && CLASS_NAME (objc_implementation_context
) == class_ident
)
5003 = lookup_class_method_static (implementation_template
, sel_name
);
5005 if (!method_prototype
5006 && implementation_template
!= objc_implementation_context
)
5007 /* The method is not published in the interface. Check
5010 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
5017 if ((iface
= lookup_interface (class_ident
)))
5018 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5021 if (!method_prototype
)
5023 warning ("cannot find class (factory) method");
5024 warning ("return type for `%s' defaults to id",
5025 IDENTIFIER_POINTER (sel_name
));
5028 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5030 /* An anonymous object that has been qualified with a protocol. */
5032 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5034 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5037 if (!method_prototype
)
5041 warning ("method `%s' not implemented by protocol",
5042 IDENTIFIER_POINTER (sel_name
));
5044 /* Try and find the method signature in the global pools. */
5046 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5047 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5049 if (!(method_prototype
= check_duplicates (hsh
)))
5050 warning ("return type defaults to id");
5057 /* We think we have an instance...loophole: extern id Object; */
5058 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5061 /* For various loopholes */
5062 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5064 method_prototype
= check_duplicates (hsh
);
5065 if (!method_prototype
)
5067 warning ("cannot find method");
5068 warning ("return type for `%s' defaults to id",
5069 IDENTIFIER_POINTER (sel_name
));
5073 /* Save the selector name for printing error messages. */
5074 building_objc_message_expr
= sel_name
;
5076 /* Build the parameters list for looking up the method.
5077 These are the object itself and the selector. */
5079 if (flag_typed_selectors
)
5080 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5082 selector
= build_selector_reference (sel_name
);
5084 retval
= build_objc_method_call (super
, method_prototype
,
5085 receiver
, self_object
,
5086 selector
, method_params
);
5088 building_objc_message_expr
= 0;
5093 /* Build a tree expression to send OBJECT the operation SELECTOR,
5094 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5095 assuming the method has prototype METHOD_PROTOTYPE.
5096 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5097 Use METHOD_PARAMS as list of args to pass to the method.
5098 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5101 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5102 selector
, method_params
)
5104 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5106 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5107 tree rcv_p
= (super_flag
5108 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5109 get_identifier (TAG_SUPER
)))
5112 if (flag_next_runtime
)
5114 if (! method_prototype
)
5116 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5117 tree_cons (NULL_TREE
, selector
,
5119 assemble_external (sender
);
5120 return build_function_call (sender
, method_params
);
5124 /* This is a real kludge, but it is used only for the Next.
5125 Clobber the data type of SENDER temporarily to accept
5126 all the arguments for this operation, and to return
5127 whatever this operation returns. */
5128 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5129 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5131 /* Save the proper contents of SENDER's data type. */
5132 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5133 savret
= TREE_TYPE (TREE_TYPE (sender
));
5135 /* Install this method's argument types. */
5136 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5138 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5140 /* Install this method's return type. */
5141 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5143 /* Call SENDER with all the parameters. This will do type
5144 checking using the arg types for this method. */
5145 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5146 tree_cons (NULL_TREE
, selector
,
5148 assemble_external (sender
);
5149 retval
= build_function_call (sender
, method_params
);
5151 /* Restore SENDER's return/argument types. */
5152 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5153 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5159 /* This is the portable way.
5160 First call the lookup function to get a pointer to the method,
5161 then cast the pointer, then call it with the method arguments. */
5164 /* Avoid trouble since we may evaluate each of these twice. */
5165 object
= save_expr (object
);
5166 selector
= save_expr (selector
);
5168 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5170 assemble_external (sender
);
5172 = build_function_call (sender
,
5173 tree_cons (NULL_TREE
, lookup_object
,
5174 tree_cons (NULL_TREE
, selector
,
5177 /* If we have a method prototype, construct the data type this
5178 method needs, and cast what we got from SENDER into a pointer
5180 if (method_prototype
)
5182 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5184 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5185 tree fake_function_type
= build_function_type (valtype
, arglist
);
5186 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5190 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5192 /* Pass the object to the method. */
5193 assemble_external (method
);
5194 return build_function_call (method
,
5195 tree_cons (NULL_TREE
, object
,
5196 tree_cons (NULL_TREE
, selector
,
5202 build_protocol_reference (p
)
5205 tree decl
, ident
, ptype
;
5207 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5209 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5211 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5212 objc_protocol_template
),
5215 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5216 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5219 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5220 DECL_EXTERNAL (decl
) = 1;
5221 TREE_PUBLIC (decl
) = 1;
5222 TREE_USED (decl
) = 1;
5223 DECL_ARTIFICIAL (decl
) = 1;
5225 make_decl_rtl (decl
, 0);
5226 pushdecl_top_level (decl
);
5229 PROTOCOL_FORWARD_DECL (p
) = decl
;
5233 build_protocol_expr (protoname
)
5237 tree p
= lookup_protocol (protoname
);
5241 error ("cannot find protocol declaration for `%s'",
5242 IDENTIFIER_POINTER (protoname
));
5243 return error_mark_node
;
5246 if (!PROTOCOL_FORWARD_DECL (p
))
5247 build_protocol_reference (p
);
5249 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5251 TREE_TYPE (expr
) = protocol_type
;
5257 build_selector_expr (selnamelist
)
5262 /* Obtain the full selector name. */
5263 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5264 /* A unary selector. */
5265 selname
= selnamelist
;
5266 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5267 selname
= build_keyword_selector (selnamelist
);
5271 if (flag_typed_selectors
)
5272 return build_typed_selector_reference (selname
, 0);
5274 return build_selector_reference (selname
);
5278 build_encode_expr (type
)
5284 encode_type (type
, obstack_object_size (&util_obstack
),
5285 OBJC_ENCODE_INLINE_DEFS
);
5286 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5287 string
= obstack_finish (&util_obstack
);
5289 /* Synthesize a string that represents the encoded struct/union. */
5290 result
= my_build_string (strlen (string
) + 1, string
);
5291 obstack_free (&util_obstack
, util_firstobj
);
5296 build_ivar_reference (id
)
5299 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5301 /* Historically, a class method that produced objects (factory
5302 method) would assign `self' to the instance that it
5303 allocated. This would effectively turn the class method into
5304 an instance method. Following this assignment, the instance
5305 variables could be accessed. That practice, while safe,
5306 violates the simple rule that a class method should not refer
5307 to an instance variable. It's better to catch the cases
5308 where this is done unknowingly than to support the above
5310 warning ("instance variable `%s' accessed in class method",
5311 IDENTIFIER_POINTER (id
));
5312 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5315 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5317 \f/* Make the hash value positive. */
5318 #define HASHFUNCTION(key) ((size_t) key & 0x7fffffff)
5323 nst_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5324 cls_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5327 /* WARNING!!!! hash_enter is called with a method, and will peek
5328 inside to find its selector! But hash_lookup is given a selector
5329 directly, and looks for the selector that's inside the found
5330 entry's key (method) for comparison. */
5333 hash_enter (hashlist
, method
)
5337 static hash hash_alloc_list
= 0;
5338 static int hash_alloc_index
= 0;
5340 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5342 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5344 hash_alloc_index
= 0;
5345 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5346 * HASH_ALLOC_LIST_SIZE
);
5348 obj
= &hash_alloc_list
[hash_alloc_index
++];
5350 obj
->next
= hashlist
[slot
];
5353 hashlist
[slot
] = obj
; /* append to front */
5357 hash_lookup (hashlist
, sel_name
)
5363 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5367 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5370 target
= target
->next
;
5376 hash_add_attr (entry
, value
)
5380 static attr attr_alloc_list
= 0;
5381 static int attr_alloc_index
= 0;
5384 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5386 attr_alloc_index
= 0;
5387 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5388 * ATTR_ALLOC_LIST_SIZE
);
5390 obj
= &attr_alloc_list
[attr_alloc_index
++];
5391 obj
->next
= entry
->list
;
5394 entry
->list
= obj
; /* append to front */
5398 lookup_method (mchain
, method
)
5404 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5407 key
= METHOD_SEL_NAME (method
);
5411 if (METHOD_SEL_NAME (mchain
) == key
)
5413 mchain
= TREE_CHAIN (mchain
);
5419 lookup_instance_method_static (interface
, ident
)
5423 tree inter
= interface
;
5424 tree chain
= CLASS_NST_METHODS (inter
);
5425 tree meth
= NULL_TREE
;
5429 if ((meth
= lookup_method (chain
, ident
)))
5432 if (CLASS_CATEGORY_LIST (inter
))
5434 tree category
= CLASS_CATEGORY_LIST (inter
);
5435 chain
= CLASS_NST_METHODS (category
);
5439 if ((meth
= lookup_method (chain
, ident
)))
5442 /* Check for instance methods in protocols in categories. */
5443 if (CLASS_PROTOCOL_LIST (category
))
5445 if ((meth
= (lookup_method_in_protocol_list
5446 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5450 if ((category
= CLASS_CATEGORY_LIST (category
)))
5451 chain
= CLASS_NST_METHODS (category
);
5456 if (CLASS_PROTOCOL_LIST (inter
))
5458 if ((meth
= (lookup_method_in_protocol_list
5459 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5463 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5464 chain
= CLASS_NST_METHODS (inter
);
5472 lookup_class_method_static (interface
, ident
)
5476 tree inter
= interface
;
5477 tree chain
= CLASS_CLS_METHODS (inter
);
5478 tree meth
= NULL_TREE
;
5479 tree root_inter
= NULL_TREE
;
5483 if ((meth
= lookup_method (chain
, ident
)))
5486 if (CLASS_CATEGORY_LIST (inter
))
5488 tree category
= CLASS_CATEGORY_LIST (inter
);
5489 chain
= CLASS_CLS_METHODS (category
);
5493 if ((meth
= lookup_method (chain
, ident
)))
5496 /* Check for class methods in protocols in categories. */
5497 if (CLASS_PROTOCOL_LIST (category
))
5499 if ((meth
= (lookup_method_in_protocol_list
5500 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5504 if ((category
= CLASS_CATEGORY_LIST (category
)))
5505 chain
= CLASS_CLS_METHODS (category
);
5510 /* Check for class methods in protocols. */
5511 if (CLASS_PROTOCOL_LIST (inter
))
5513 if ((meth
= (lookup_method_in_protocol_list
5514 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5519 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5520 chain
= CLASS_CLS_METHODS (inter
);
5524 /* If no class (factory) method was found, check if an _instance_
5525 method of the same name exists in the root class. This is what
5526 the Objective-C runtime will do. */
5527 return lookup_instance_method_static (root_inter
, ident
);
5531 add_class_method (class, method
)
5538 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5540 /* put method on list in reverse order */
5541 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5542 CLASS_CLS_METHODS (class) = method
;
5546 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5547 error ("duplicate definition of class method `%s'",
5548 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5551 /* Check types; if different, complain. */
5552 if (!comp_proto_with_proto (method
, mth
))
5553 error ("duplicate declaration of class method `%s'",
5554 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5558 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5560 /* Install on a global chain. */
5561 hash_enter (cls_method_hash_list
, method
);
5565 /* Check types; if different, add to a list. */
5566 if (!comp_proto_with_proto (method
, hsh
->key
))
5567 hash_add_attr (hsh
, method
);
5573 add_instance_method (class, method
)
5580 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5582 /* Put method on list in reverse order. */
5583 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5584 CLASS_NST_METHODS (class) = method
;
5588 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5589 error ("duplicate definition of instance method `%s'",
5590 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5593 /* Check types; if different, complain. */
5594 if (!comp_proto_with_proto (method
, mth
))
5595 error ("duplicate declaration of instance method `%s'",
5596 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5600 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5602 /* Install on a global chain. */
5603 hash_enter (nst_method_hash_list
, method
);
5607 /* Check types; if different, add to a list. */
5608 if (!comp_proto_with_proto (method
, hsh
->key
))
5609 hash_add_attr (hsh
, method
);
5618 /* Put interfaces on list in reverse order. */
5619 TREE_CHAIN (class) = interface_chain
;
5620 interface_chain
= class;
5621 return interface_chain
;
5625 add_category (class, category
)
5629 /* Put categories on list in reverse order. */
5630 tree cat
= CLASS_CATEGORY_LIST (class);
5634 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5635 warning ("duplicate interface declaration for category `%s(%s)'",
5636 IDENTIFIER_POINTER (CLASS_NAME (class)),
5637 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5638 cat
= CLASS_CATEGORY_LIST (cat
);
5641 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5642 CLASS_CATEGORY_LIST (class) = category
;
5645 /* Called after parsing each instance variable declaration. Necessary to
5646 preserve typedefs and implement public/private...
5648 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5651 add_instance_variable (class, public, declarator
, declspecs
, width
)
5658 tree field_decl
, raw_decl
;
5660 raw_decl
= build_tree_list (declspecs
, declarator
);
5662 if (CLASS_RAW_IVARS (class))
5663 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5665 CLASS_RAW_IVARS (class) = raw_decl
;
5667 field_decl
= grokfield (input_filename
, lineno
,
5668 declarator
, declspecs
, width
);
5670 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5674 TREE_PUBLIC (field_decl
) = 0;
5675 TREE_PRIVATE (field_decl
) = 0;
5676 TREE_PROTECTED (field_decl
) = 1;
5680 TREE_PUBLIC (field_decl
) = 1;
5681 TREE_PRIVATE (field_decl
) = 0;
5682 TREE_PROTECTED (field_decl
) = 0;
5686 TREE_PUBLIC (field_decl
) = 0;
5687 TREE_PRIVATE (field_decl
) = 1;
5688 TREE_PROTECTED (field_decl
) = 0;
5693 if (CLASS_IVARS (class))
5694 chainon (CLASS_IVARS (class), field_decl
);
5696 CLASS_IVARS (class) = field_decl
;
5702 is_ivar (decl_chain
, ident
)
5706 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5707 if (DECL_NAME (decl_chain
) == ident
)
5712 /* True if the ivar is private and we are not in its implementation. */
5718 if (TREE_PRIVATE (decl
)
5719 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5721 error ("instance variable `%s' is declared private",
5722 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5729 /* We have an instance variable reference;, check to see if it is public. */
5732 is_public (expr
, identifier
)
5736 tree basetype
= TREE_TYPE (expr
);
5737 enum tree_code code
= TREE_CODE (basetype
);
5740 if (code
== RECORD_TYPE
)
5742 if (TREE_STATIC_TEMPLATE (basetype
))
5744 if (!lookup_interface (TYPE_NAME (basetype
)))
5746 error ("cannot find interface declaration for `%s'",
5747 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5751 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5753 if (TREE_PUBLIC (decl
))
5756 /* Important difference between the Stepstone translator:
5757 all instance variables should be public within the context
5758 of the implementation. */
5759 if (objc_implementation_context
5760 && (((TREE_CODE (objc_implementation_context
)
5761 == CLASS_IMPLEMENTATION_TYPE
)
5762 || (TREE_CODE (objc_implementation_context
)
5763 == CATEGORY_IMPLEMENTATION_TYPE
))
5764 && (CLASS_NAME (objc_implementation_context
)
5765 == TYPE_NAME (basetype
))))
5766 return ! is_private (decl
);
5768 error ("instance variable `%s' is declared %s",
5769 IDENTIFIER_POINTER (identifier
),
5770 TREE_PRIVATE (decl
) ? "private" : "protected");
5775 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5777 TREE_TYPE (expr
) = uprivate_record
;
5778 warning ("static access to object of type `id'");
5785 /* Implement @defs (<classname>) within struct bodies. */
5788 get_class_ivars (interface
)
5791 /* Make sure we copy the leaf ivars in case @defs is used in a local
5792 context. Otherwise finish_struct will overwrite the layout info
5793 using temporary storage. */
5794 return build_ivar_chain (interface
, 1);
5797 /* Make sure all entries in CHAIN are also in LIST. */
5800 check_methods (chain
, list
, mtype
)
5809 if (!lookup_method (list
, chain
))
5813 if (TREE_CODE (objc_implementation_context
)
5814 == CLASS_IMPLEMENTATION_TYPE
)
5815 warning ("incomplete implementation of class `%s'",
5816 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5817 else if (TREE_CODE (objc_implementation_context
)
5818 == CATEGORY_IMPLEMENTATION_TYPE
)
5819 warning ("incomplete implementation of category `%s'",
5820 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5824 warning ("method definition for `%c%s' not found",
5825 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5828 chain
= TREE_CHAIN (chain
);
5834 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5837 conforms_to_protocol (class, protocol
)
5841 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5843 tree p
= CLASS_PROTOCOL_LIST (class);
5844 while (p
&& TREE_VALUE (p
) != protocol
)
5849 tree super
= (CLASS_SUPER_NAME (class)
5850 ? lookup_interface (CLASS_SUPER_NAME (class))
5852 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5861 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5862 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5865 check_methods_accessible (chain
, context
, mtype
)
5872 tree base_context
= context
;
5876 context
= base_context
;
5880 list
= CLASS_CLS_METHODS (context
);
5882 list
= CLASS_NST_METHODS (context
);
5884 if (lookup_method (list
, chain
))
5887 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5888 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5889 context
= (CLASS_SUPER_NAME (context
)
5890 ? lookup_interface (CLASS_SUPER_NAME (context
))
5893 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5894 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5895 context
= (CLASS_NAME (context
)
5896 ? lookup_interface (CLASS_NAME (context
))
5902 if (context
== NULL_TREE
)
5906 if (TREE_CODE (objc_implementation_context
)
5907 == CLASS_IMPLEMENTATION_TYPE
)
5908 warning ("incomplete implementation of class `%s'",
5910 (CLASS_NAME (objc_implementation_context
)));
5911 else if (TREE_CODE (objc_implementation_context
)
5912 == CATEGORY_IMPLEMENTATION_TYPE
)
5913 warning ("incomplete implementation of category `%s'",
5915 (CLASS_SUPER_NAME (objc_implementation_context
)));
5918 warning ("method definition for `%c%s' not found",
5919 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5922 chain
= TREE_CHAIN (chain
); /* next method... */
5927 /* Check whether the current interface (accessible via
5928 'objc_implementation_context') actually implements protocol P, along
5929 with any protocols that P inherits. */
5932 check_protocol (p
, type
, name
)
5937 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5941 /* Ensure that all protocols have bodies! */
5942 if (flag_warn_protocol
)
5944 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5945 CLASS_CLS_METHODS (objc_implementation_context
),
5947 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5948 CLASS_NST_METHODS (objc_implementation_context
),
5953 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5954 objc_implementation_context
,
5956 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5957 objc_implementation_context
,
5962 warning ("%s `%s' does not fully implement the `%s' protocol",
5963 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5966 /* Check protocols recursively. */
5967 if (PROTOCOL_LIST (p
))
5969 tree subs
= PROTOCOL_LIST (p
);
5971 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5974 tree sub
= TREE_VALUE (subs
);
5976 /* If the superclass does not conform to the protocols
5977 inherited by P, then we must! */
5978 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5979 check_protocol (sub
, type
, name
);
5980 subs
= TREE_CHAIN (subs
);
5985 /* Check whether the current interface (accessible via
5986 'objc_implementation_context') actually implements the protocols listed
5990 check_protocols (proto_list
, type
, name
)
5995 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5997 tree p
= TREE_VALUE (proto_list
);
5999 check_protocol (p
, type
, name
);
6003 /* Make sure that the class CLASS_NAME is defined
6004 CODE says which kind of thing CLASS_NAME ought to be.
6005 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6006 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6009 start_class (code
, class_name
, super_name
, protocol_list
)
6010 enum tree_code code
;
6017 if (objc_implementation_context
)
6019 warning ("`@end' missing in implementation context");
6020 finish_class (objc_implementation_context
);
6021 objc_ivar_chain
= NULL_TREE
;
6022 objc_implementation_context
= NULL_TREE
;
6025 class = make_node (code
);
6026 TYPE_BINFO (class) = make_tree_vec (5);
6028 CLASS_NAME (class) = class_name
;
6029 CLASS_SUPER_NAME (class) = super_name
;
6030 CLASS_CLS_METHODS (class) = NULL_TREE
;
6032 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6034 error ("`%s' redeclared as different kind of symbol",
6035 IDENTIFIER_POINTER (class_name
));
6036 error_with_decl (decl
, "previous declaration of `%s'");
6039 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6044 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6045 if (TREE_VALUE (chain
) == class_name
)
6047 error ("reimplementation of class `%s'",
6048 IDENTIFIER_POINTER (class_name
));
6049 return error_mark_node
;
6051 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6052 implemented_classes
);
6055 /* Pre-build the following entities - for speed/convenience. */
6057 self_id
= get_identifier ("self");
6059 ucmd_id
= get_identifier ("_cmd");
6062 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6063 if (!objc_super_template
)
6064 objc_super_template
= build_super_template ();
6066 /* Reset for multiple classes per file. */
6069 objc_implementation_context
= class;
6071 /* Lookup the interface for this implementation. */
6073 if (!(implementation_template
= lookup_interface (class_name
)))
6075 warning ("cannot find interface declaration for `%s'",
6076 IDENTIFIER_POINTER (class_name
));
6077 add_class (implementation_template
= objc_implementation_context
);
6080 /* If a super class has been specified in the implementation,
6081 insure it conforms to the one specified in the interface. */
6084 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6086 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6087 const char *const name
=
6088 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6089 error ("conflicting super class name `%s'",
6090 IDENTIFIER_POINTER (super_name
));
6091 error ("previous declaration of `%s'", name
);
6094 else if (! super_name
)
6096 CLASS_SUPER_NAME (objc_implementation_context
)
6097 = CLASS_SUPER_NAME (implementation_template
);
6101 else if (code
== CLASS_INTERFACE_TYPE
)
6103 if (lookup_interface (class_name
))
6104 warning ("duplicate interface declaration for class `%s'",
6105 IDENTIFIER_POINTER (class_name
));
6110 CLASS_PROTOCOL_LIST (class)
6111 = lookup_and_install_protocols (protocol_list
);
6114 else if (code
== CATEGORY_INTERFACE_TYPE
)
6116 tree class_category_is_assoc_with
;
6118 /* For a category, class_name is really the name of the class that
6119 the following set of methods will be associated with. We must
6120 find the interface so that can derive the objects template. */
6122 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6124 error ("cannot find interface declaration for `%s'",
6125 IDENTIFIER_POINTER (class_name
));
6126 exit (FATAL_EXIT_CODE
);
6129 add_category (class_category_is_assoc_with
, class);
6132 CLASS_PROTOCOL_LIST (class)
6133 = lookup_and_install_protocols (protocol_list
);
6136 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6138 /* Pre-build the following entities for speed/convenience. */
6140 self_id
= get_identifier ("self");
6142 ucmd_id
= get_identifier ("_cmd");
6145 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6146 if (!objc_super_template
)
6147 objc_super_template
= build_super_template ();
6149 /* Reset for multiple classes per file. */
6152 objc_implementation_context
= class;
6154 /* For a category, class_name is really the name of the class that
6155 the following set of methods will be associated with. We must
6156 find the interface so that can derive the objects template. */
6158 if (!(implementation_template
= lookup_interface (class_name
)))
6160 error ("cannot find interface declaration for `%s'",
6161 IDENTIFIER_POINTER (class_name
));
6162 exit (FATAL_EXIT_CODE
);
6169 continue_class (class)
6172 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6173 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6175 struct imp_entry
*imp_entry
;
6178 /* Check consistency of the instance variables. */
6180 if (CLASS_IVARS (class))
6181 check_ivars (implementation_template
, class);
6183 /* code generation */
6185 ivar_context
= build_private_template (implementation_template
);
6187 if (!objc_class_template
)
6188 build_class_template ();
6190 imp_entry
= (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
));
6192 imp_entry
->next
= imp_list
;
6193 imp_entry
->imp_context
= class;
6194 imp_entry
->imp_template
= implementation_template
;
6196 synth_forward_declarations ();
6197 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6198 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6200 /* Append to front and increment count. */
6201 imp_list
= imp_entry
;
6202 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6207 return ivar_context
;
6210 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6212 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6214 if (!TYPE_FIELDS (record
))
6216 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6217 CLASS_STATIC_TEMPLATE (class) = record
;
6219 /* Mark this record as a class template for static typing. */
6220 TREE_STATIC_TEMPLATE (record
) = 1;
6227 return error_mark_node
;
6230 /* This is called once we see the "@end" in an interface/implementation. */
6233 finish_class (class)
6236 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6238 /* All code generation is done in finish_objc. */
6240 if (implementation_template
!= objc_implementation_context
)
6242 /* Ensure that all method listed in the interface contain bodies. */
6243 check_methods (CLASS_CLS_METHODS (implementation_template
),
6244 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6245 check_methods (CLASS_NST_METHODS (implementation_template
),
6246 CLASS_NST_METHODS (objc_implementation_context
), '-');
6248 if (CLASS_PROTOCOL_LIST (implementation_template
))
6249 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6251 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6255 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6257 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6259 /* Find the category interface from the class it is associated with. */
6262 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6264 category
= CLASS_CATEGORY_LIST (category
);
6269 /* Ensure all method listed in the interface contain bodies. */
6270 check_methods (CLASS_CLS_METHODS (category
),
6271 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6272 check_methods (CLASS_NST_METHODS (category
),
6273 CLASS_NST_METHODS (objc_implementation_context
), '-');
6275 if (CLASS_PROTOCOL_LIST (category
))
6276 check_protocols (CLASS_PROTOCOL_LIST (category
),
6278 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6282 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6285 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6286 char *string
= (char *) alloca (strlen (class_name
) + 3);
6288 /* extern struct objc_object *_<my_name>; */
6290 sprintf (string
, "_%s", class_name
);
6292 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6293 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6294 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6300 add_protocol (protocol
)
6303 /* Put protocol on list in reverse order. */
6304 TREE_CHAIN (protocol
) = protocol_chain
;
6305 protocol_chain
= protocol
;
6306 return protocol_chain
;
6310 lookup_protocol (ident
)
6315 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6317 if (ident
== PROTOCOL_NAME (chain
))
6324 /* This function forward declares the protocols named by NAMES. If
6325 they are already declared or defined, the function has no effect. */
6328 objc_declare_protocols (names
)
6333 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6335 tree name
= TREE_VALUE (list
);
6337 if (lookup_protocol (name
) == NULL_TREE
)
6339 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6341 TYPE_BINFO (protocol
) = make_tree_vec (2);
6342 PROTOCOL_NAME (protocol
) = name
;
6343 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6344 add_protocol (protocol
);
6345 PROTOCOL_DEFINED (protocol
) = 0;
6346 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6352 start_protocol (code
, name
, list
)
6353 enum tree_code code
;
6359 /* This is as good a place as any. Need to invoke
6360 push_tag_toplevel. */
6361 if (!objc_protocol_template
)
6362 objc_protocol_template
= build_protocol_template ();
6364 protocol
= lookup_protocol (name
);
6368 protocol
= make_node (code
);
6369 TYPE_BINFO (protocol
) = make_tree_vec (2);
6371 PROTOCOL_NAME (protocol
) = name
;
6372 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6373 add_protocol (protocol
);
6374 PROTOCOL_DEFINED (protocol
) = 1;
6375 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6377 check_protocol_recursively (protocol
, list
);
6379 else if (! PROTOCOL_DEFINED (protocol
))
6381 PROTOCOL_DEFINED (protocol
) = 1;
6382 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6384 check_protocol_recursively (protocol
, list
);
6388 warning ("duplicate declaration for protocol `%s'",
6389 IDENTIFIER_POINTER (name
));
6395 finish_protocol (protocol
)
6396 tree protocol ATTRIBUTE_UNUSED
;
6401 /* "Encode" a data type into a string, which grows in util_obstack.
6402 ??? What is the FORMAT? Someone please document this! */
6405 encode_type_qualifiers (declspecs
)
6410 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6412 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6413 obstack_1grow (&util_obstack
, 'r');
6414 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6415 obstack_1grow (&util_obstack
, 'n');
6416 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6417 obstack_1grow (&util_obstack
, 'N');
6418 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6419 obstack_1grow (&util_obstack
, 'o');
6420 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6421 obstack_1grow (&util_obstack
, 'O');
6422 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6423 obstack_1grow (&util_obstack
, 'R');
6424 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6425 obstack_1grow (&util_obstack
, 'V');
6429 /* Encode a pointer type. */
6432 encode_pointer (type
, curtype
, format
)
6437 tree pointer_to
= TREE_TYPE (type
);
6439 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6441 if (TYPE_NAME (pointer_to
)
6442 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6444 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6446 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6448 obstack_1grow (&util_obstack
, '@');
6451 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6453 if (generating_instance_variables
)
6455 obstack_1grow (&util_obstack
, '@');
6456 obstack_1grow (&util_obstack
, '"');
6457 obstack_grow (&util_obstack
, name
, strlen (name
));
6458 obstack_1grow (&util_obstack
, '"');
6463 obstack_1grow (&util_obstack
, '@');
6467 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6469 obstack_1grow (&util_obstack
, '#');
6472 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6474 obstack_1grow (&util_obstack
, ':');
6479 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6480 && TYPE_MODE (pointer_to
) == QImode
)
6482 obstack_1grow (&util_obstack
, '*');
6486 /* We have a type that does not get special treatment. */
6488 /* NeXT extension */
6489 obstack_1grow (&util_obstack
, '^');
6490 encode_type (pointer_to
, curtype
, format
);
6494 encode_array (type
, curtype
, format
)
6499 tree an_int_cst
= TYPE_SIZE (type
);
6500 tree array_of
= TREE_TYPE (type
);
6503 /* An incomplete array is treated like a pointer. */
6504 if (an_int_cst
== NULL
)
6506 encode_pointer (type
, curtype
, format
);
6510 sprintf (buffer
, "[%ld",
6511 (long) (TREE_INT_CST_LOW (an_int_cst
)
6512 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6514 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6515 encode_type (array_of
, curtype
, format
);
6516 obstack_1grow (&util_obstack
, ']');
6521 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6528 /* The RECORD_TYPE may in fact be a typedef! For purposes
6529 of encoding, we need the real underlying enchilada. */
6530 if (TYPE_MAIN_VARIANT (type
))
6531 type
= TYPE_MAIN_VARIANT (type
);
6533 if (obstack_object_size (&util_obstack
) > 0
6534 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6536 tree name
= TYPE_NAME (type
);
6538 /* we have a reference; this is a NeXT extension. */
6540 if (obstack_object_size (&util_obstack
) - curtype
== 1
6541 && format
== OBJC_ENCODE_INLINE_DEFS
)
6543 /* Output format of struct for first level only. */
6544 tree fields
= TYPE_FIELDS (type
);
6546 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6548 obstack_1grow (&util_obstack
, left
);
6549 obstack_grow (&util_obstack
,
6550 IDENTIFIER_POINTER (name
),
6551 strlen (IDENTIFIER_POINTER (name
)));
6552 obstack_1grow (&util_obstack
, '=');
6556 obstack_1grow (&util_obstack
, left
);
6557 obstack_grow (&util_obstack
, "?=", 2);
6560 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6561 encode_field_decl (fields
, curtype
, format
);
6563 obstack_1grow (&util_obstack
, right
);
6566 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6568 obstack_1grow (&util_obstack
, left
);
6569 obstack_grow (&util_obstack
,
6570 IDENTIFIER_POINTER (name
),
6571 strlen (IDENTIFIER_POINTER (name
)));
6572 obstack_1grow (&util_obstack
, right
);
6577 /* We have an untagged structure or a typedef. */
6578 obstack_1grow (&util_obstack
, left
);
6579 obstack_1grow (&util_obstack
, '?');
6580 obstack_1grow (&util_obstack
, right
);
6586 tree name
= TYPE_NAME (type
);
6587 tree fields
= TYPE_FIELDS (type
);
6589 if (format
== OBJC_ENCODE_INLINE_DEFS
6590 || generating_instance_variables
)
6592 obstack_1grow (&util_obstack
, left
);
6593 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6594 obstack_grow (&util_obstack
,
6595 IDENTIFIER_POINTER (name
),
6596 strlen (IDENTIFIER_POINTER (name
)));
6598 obstack_1grow (&util_obstack
, '?');
6600 obstack_1grow (&util_obstack
, '=');
6602 for (; fields
; fields
= TREE_CHAIN (fields
))
6604 if (generating_instance_variables
)
6606 tree fname
= DECL_NAME (fields
);
6608 obstack_1grow (&util_obstack
, '"');
6609 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6611 obstack_grow (&util_obstack
,
6612 IDENTIFIER_POINTER (fname
),
6613 strlen (IDENTIFIER_POINTER (fname
)));
6616 obstack_1grow (&util_obstack
, '"');
6619 encode_field_decl (fields
, curtype
, format
);
6622 obstack_1grow (&util_obstack
, right
);
6627 obstack_1grow (&util_obstack
, left
);
6628 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6629 obstack_grow (&util_obstack
,
6630 IDENTIFIER_POINTER (name
),
6631 strlen (IDENTIFIER_POINTER (name
)));
6633 /* We have an untagged structure or a typedef. */
6634 obstack_1grow (&util_obstack
, '?');
6636 obstack_1grow (&util_obstack
, right
);
6642 encode_aggregate (type
, curtype
, format
)
6647 enum tree_code code
= TREE_CODE (type
);
6653 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6658 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6663 obstack_1grow (&util_obstack
, 'i');
6671 /* Support bitfields. The current version of Objective-C does not support
6672 them. The string will consist of one or more "b:n"'s where n is an
6673 integer describing the width of the bitfield. Currently, classes in
6674 the kit implement a method "-(char *)describeBitfieldStruct:" that
6675 simulates this. If they do not implement this method, the archiver
6676 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6677 according to the GNU compiler. After looking at the "kit", it appears
6678 that all classes currently rely on this default behavior, rather than
6679 hand generating this string (which is tedious). */
6682 encode_bitfield (width
)
6686 sprintf (buffer
, "b%d", width
);
6687 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6690 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6693 encode_type (type
, curtype
, format
)
6698 enum tree_code code
= TREE_CODE (type
);
6700 if (code
== INTEGER_TYPE
)
6702 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6704 /* Unsigned integer types. */
6706 if (TYPE_MODE (type
) == QImode
)
6707 obstack_1grow (&util_obstack
, 'C');
6708 else if (TYPE_MODE (type
) == HImode
)
6709 obstack_1grow (&util_obstack
, 'S');
6710 else if (TYPE_MODE (type
) == SImode
)
6712 if (type
== long_unsigned_type_node
)
6713 obstack_1grow (&util_obstack
, 'L');
6715 obstack_1grow (&util_obstack
, 'I');
6717 else if (TYPE_MODE (type
) == DImode
)
6718 obstack_1grow (&util_obstack
, 'Q');
6722 /* Signed integer types. */
6724 if (TYPE_MODE (type
) == QImode
)
6725 obstack_1grow (&util_obstack
, 'c');
6726 else if (TYPE_MODE (type
) == HImode
)
6727 obstack_1grow (&util_obstack
, 's');
6728 else if (TYPE_MODE (type
) == SImode
)
6730 if (type
== long_integer_type_node
)
6731 obstack_1grow (&util_obstack
, 'l');
6733 obstack_1grow (&util_obstack
, 'i');
6736 else if (TYPE_MODE (type
) == DImode
)
6737 obstack_1grow (&util_obstack
, 'q');
6741 else if (code
== REAL_TYPE
)
6743 /* Floating point types. */
6745 if (TYPE_MODE (type
) == SFmode
)
6746 obstack_1grow (&util_obstack
, 'f');
6747 else if (TYPE_MODE (type
) == DFmode
6748 || TYPE_MODE (type
) == TFmode
)
6749 obstack_1grow (&util_obstack
, 'd');
6752 else if (code
== VOID_TYPE
)
6753 obstack_1grow (&util_obstack
, 'v');
6755 else if (code
== ARRAY_TYPE
)
6756 encode_array (type
, curtype
, format
);
6758 else if (code
== POINTER_TYPE
)
6759 encode_pointer (type
, curtype
, format
);
6761 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6762 encode_aggregate (type
, curtype
, format
);
6764 else if (code
== FUNCTION_TYPE
) /* '?' */
6765 obstack_1grow (&util_obstack
, '?');
6769 encode_complete_bitfield (int position
, tree type
, int size
)
6771 enum tree_code code
= TREE_CODE (type
);
6773 char charType
= '?';
6775 if (code
== INTEGER_TYPE
)
6777 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6779 /* Unsigned integer types. */
6781 if (TYPE_MODE (type
) == QImode
)
6783 else if (TYPE_MODE (type
) == HImode
)
6785 else if (TYPE_MODE (type
) == SImode
)
6787 if (type
== long_unsigned_type_node
)
6792 else if (TYPE_MODE (type
) == DImode
)
6797 /* Signed integer types. */
6799 if (TYPE_MODE (type
) == QImode
)
6801 else if (TYPE_MODE (type
) == HImode
)
6803 else if (TYPE_MODE (type
) == SImode
)
6805 if (type
== long_integer_type_node
)
6811 else if (TYPE_MODE (type
) == DImode
)
6819 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6820 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6824 encode_field_decl (field_decl
, curtype
, format
)
6831 type
= TREE_TYPE (field_decl
);
6833 /* If this field is obviously a bitfield, or is a bitfield that has been
6834 clobbered to look like a ordinary integer mode, go ahead and generate
6835 the bitfield typing information. */
6836 if (flag_next_runtime
)
6838 if (DECL_BIT_FIELD (field_decl
))
6839 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6841 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6845 if (DECL_BIT_FIELD (field_decl
))
6846 encode_complete_bitfield (int_bit_position (field_decl
),
6847 DECL_BIT_FIELD_TYPE (field_decl
),
6848 tree_low_cst (DECL_SIZE (field_decl
), 1));
6850 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6855 expr_last (complex_expr
)
6861 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6862 complex_expr
= next
;
6864 return complex_expr
;
6867 /* Transform a method definition into a function definition as follows:
6868 - synthesize the first two arguments, "self" and "_cmd". */
6871 start_method_def (method
)
6876 /* Required to implement _msgSuper. */
6877 objc_method_context
= method
;
6878 UOBJC_SUPER_decl
= NULL_TREE
;
6880 /* Must be called BEFORE start_function. */
6883 /* Generate prototype declarations for arguments..."new-style". */
6885 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6886 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6888 /* Really a `struct objc_class *'. However, we allow people to
6889 assign to self, which changes its type midstream. */
6890 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6892 push_parm_decl (build_tree_list
6893 (build_tree_list (decl_specs
,
6894 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6897 decl_specs
= build_tree_list (NULL_TREE
,
6898 xref_tag (RECORD_TYPE
,
6899 get_identifier (TAG_SELECTOR
)));
6900 push_parm_decl (build_tree_list
6901 (build_tree_list (decl_specs
,
6902 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6905 /* Generate argument declarations if a keyword_decl. */
6906 if (METHOD_SEL_ARGS (method
))
6908 tree arglist
= METHOD_SEL_ARGS (method
);
6911 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6912 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6916 tree last_expr
= expr_last (arg_decl
);
6918 /* Unite the abstract decl with its name. */
6919 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6920 push_parm_decl (build_tree_list
6921 (build_tree_list (arg_spec
, arg_decl
),
6924 /* Unhook: restore the abstract declarator. */
6925 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6929 push_parm_decl (build_tree_list
6930 (build_tree_list (arg_spec
,
6931 KEYWORD_ARG_NAME (arglist
)),
6934 arglist
= TREE_CHAIN (arglist
);
6939 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6940 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6942 /* We have a variable length selector - in "prototype" format. */
6943 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6946 /* This must be done prior to calling pushdecl. pushdecl is
6947 going to change our chain on us. */
6948 tree nextkey
= TREE_CHAIN (akey
);
6956 warn_with_method (message
, mtype
, method
)
6957 const char *message
;
6961 if (count_error (1) == 0)
6964 report_error_function (DECL_SOURCE_FILE (method
));
6966 /* Add a readable method name to the warning. */
6967 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6968 DECL_SOURCE_LINE (method
),
6971 gen_method_decl (method
, errbuf
));
6974 /* Return 1 if METHOD is consistent with PROTO. */
6977 comp_method_with_proto (method
, proto
)
6980 /* Create a function template node at most once. */
6981 if (!function1_template
)
6982 function1_template
= make_node (FUNCTION_TYPE
);
6984 /* Install argument types - normally set by build_function_type. */
6985 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6987 /* install return type */
6988 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6990 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6993 /* Return 1 if PROTO1 is consistent with PROTO2. */
6996 comp_proto_with_proto (proto0
, proto1
)
6997 tree proto0
, proto1
;
6999 /* Create a couple of function_template nodes at most once. */
7000 if (!function1_template
)
7001 function1_template
= make_node (FUNCTION_TYPE
);
7002 if (!function2_template
)
7003 function2_template
= make_node (FUNCTION_TYPE
);
7005 /* Install argument types; normally set by build_function_type. */
7006 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7007 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7009 /* Install return type. */
7010 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
7011 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
7013 return comptypes (function1_template
, function2_template
);
7016 /* - Generate an identifier for the function. the format is "_n_cls",
7017 where 1 <= n <= nMethods, and cls is the name the implementation we
7019 - Install the return type from the method declaration.
7020 - If we have a prototype, check for type consistency. */
7023 really_start_method (method
, parmlist
)
7024 tree method
, parmlist
;
7026 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7027 tree method_decl
, method_id
;
7028 const char *sel_name
, *class_name
, *cat_name
;
7031 /* Synth the storage class & assemble the return type. */
7032 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7033 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7034 decl_specs
= chainon (sc_spec
, ret_spec
);
7036 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7037 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7038 cat_name
= ((TREE_CODE (objc_implementation_context
)
7039 == CLASS_IMPLEMENTATION_TYPE
)
7041 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7044 /* Make sure this is big enough for any plausible method label. */
7045 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7046 + (cat_name
? strlen (cat_name
) : 0));
7048 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7049 class_name
, cat_name
, sel_name
, method_slot
);
7051 method_id
= get_identifier (buf
);
7053 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7055 /* Check the declarator portion of the return type for the method. */
7056 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7058 /* Unite the complex decl (specified in the abstract decl) with the
7059 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7060 tree save_expr
= expr_last (ret_decl
);
7062 TREE_OPERAND (save_expr
, 0) = method_decl
;
7063 method_decl
= ret_decl
;
7065 /* Fool the parser into thinking it is starting a function. */
7066 start_function (decl_specs
, method_decl
, NULL_TREE
);
7068 /* Unhook: this has the effect of restoring the abstract declarator. */
7069 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7074 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7076 /* Fool the parser into thinking it is starting a function. */
7077 start_function (decl_specs
, method_decl
, NULL_TREE
);
7079 /* Unhook: this has the effect of restoring the abstract declarator. */
7080 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7083 METHOD_DEFINITION (method
) = current_function_decl
;
7085 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7087 if (implementation_template
!= objc_implementation_context
)
7091 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7092 proto
= lookup_instance_method_static (implementation_template
,
7093 METHOD_SEL_NAME (method
));
7095 proto
= lookup_class_method_static (implementation_template
,
7096 METHOD_SEL_NAME (method
));
7098 if (proto
&& ! comp_method_with_proto (method
, proto
))
7100 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7102 warn_with_method ("conflicting types for", type
, method
);
7103 warn_with_method ("previous declaration of", type
, proto
);
7108 /* The following routine is always called...this "architecture" is to
7109 accommodate "old-style" variable length selectors.
7111 - a:a b:b // prototype ; id c; id d; // old-style. */
7114 continue_method_def ()
7118 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7119 /* We have a `, ...' immediately following the selector. */
7120 parmlist
= get_parm_info (0);
7122 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7124 /* Set self_decl from the first argument...this global is used by
7125 build_ivar_reference calling build_indirect_ref. */
7126 self_decl
= TREE_PURPOSE (parmlist
);
7129 really_start_method (objc_method_context
, parmlist
);
7130 store_parm_decls ();
7133 /* Called by the parser, from the `pushlevel' production. */
7138 if (!UOBJC_SUPER_decl
)
7140 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7141 build_tree_list (NULL_TREE
,
7142 objc_super_template
),
7145 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7147 /* This prevents `unused variable' warnings when compiling with -Wall. */
7148 TREE_USED (UOBJC_SUPER_decl
) = 1;
7149 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7153 /* _n_Method (id self, SEL sel, ...)
7155 struct objc_super _S;
7156 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7160 get_super_receiver ()
7162 if (objc_method_context
)
7164 tree super_expr
, super_expr_list
;
7166 /* Set receiver to self. */
7167 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7168 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7169 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7171 /* Set class to begin searching. */
7172 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7173 get_identifier ("class"));
7175 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7177 /* [_cls, __cls]Super are "pre-built" in
7178 synth_forward_declarations. */
7180 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7181 ((TREE_CODE (objc_method_context
)
7182 == INSTANCE_METHOD_DECL
)
7184 : uucls_super_ref
));
7188 /* We have a category. */
7190 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7193 /* Barf if super used in a category of Object. */
7196 error ("no super class declared in interface for `%s'",
7197 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7198 return error_mark_node
;
7201 if (flag_next_runtime
)
7203 super_class
= get_class_reference (super_name
);
7204 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7206 = build_component_ref (build_indirect_ref (super_class
, "->"),
7207 get_identifier ("isa"));
7211 add_class_reference (super_name
);
7212 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7213 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7214 assemble_external (super_class
);
7216 = build_function_call
7220 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7221 IDENTIFIER_POINTER (super_name
))));
7224 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7225 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7228 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7230 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7231 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7233 return build_compound_expr (super_expr_list
);
7237 error ("[super ...] must appear in a method context");
7238 return error_mark_node
;
7243 encode_method_def (func_decl
)
7248 HOST_WIDE_INT max_parm_end
= 0;
7253 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7254 obstack_object_size (&util_obstack
),
7255 OBJC_ENCODE_INLINE_DEFS
);
7258 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7259 parms
= TREE_CHAIN (parms
))
7261 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7262 + int_size_in_bytes (TREE_TYPE (parms
)));
7264 if (! offset_is_register
&& parm_end
> max_parm_end
)
7265 max_parm_end
= parm_end
;
7268 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7270 sprintf (buffer
, "%d", stack_size
);
7271 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7273 /* Argument types. */
7274 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7275 parms
= TREE_CHAIN (parms
))
7278 encode_type (TREE_TYPE (parms
),
7279 obstack_object_size (&util_obstack
),
7280 OBJC_ENCODE_INLINE_DEFS
);
7282 /* Compute offset. */
7283 sprintf (buffer
, "%d", forwarding_offset (parms
));
7285 /* Indicate register. */
7286 if (offset_is_register
)
7287 obstack_1grow (&util_obstack
, '+');
7289 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7292 /* Null terminate string. */
7293 obstack_1grow (&util_obstack
, 0);
7294 result
= get_identifier (obstack_finish (&util_obstack
));
7295 obstack_free (&util_obstack
, util_firstobj
);
7300 objc_expand_function_end ()
7302 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7306 finish_method_def ()
7308 lang_expand_function_end
= objc_expand_function_end
;
7309 finish_function (0);
7310 lang_expand_function_end
= NULL
;
7312 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7313 since the optimizer may find "may be used before set" errors. */
7314 objc_method_context
= NULL_TREE
;
7319 lang_report_error_function (decl
)
7322 if (objc_method_context
)
7324 fprintf (stderr
, "In method `%s'\n",
7325 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7335 is_complex_decl (type
)
7338 return (TREE_CODE (type
) == ARRAY_TYPE
7339 || TREE_CODE (type
) == FUNCTION_TYPE
7340 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7344 /* Code to convert a decl node into text for a declaration in C. */
7346 static char tmpbuf
[256];
7349 adorn_decl (decl
, str
)
7353 enum tree_code code
= TREE_CODE (decl
);
7355 if (code
== ARRAY_REF
)
7357 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7359 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7360 sprintf (str
+ strlen (str
), "[%ld]",
7361 (long) TREE_INT_CST_LOW (an_int_cst
));
7366 else if (code
== ARRAY_TYPE
)
7368 tree an_int_cst
= TYPE_SIZE (decl
);
7369 tree array_of
= TREE_TYPE (decl
);
7371 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7372 sprintf (str
+ strlen (str
), "[%ld]",
7373 (long) (TREE_INT_CST_LOW (an_int_cst
)
7374 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7379 else if (code
== CALL_EXPR
)
7381 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7386 gen_declaration_1 (chain
, str
);
7387 chain
= TREE_CHAIN (chain
);
7394 else if (code
== FUNCTION_TYPE
)
7396 tree chain
= TYPE_ARG_TYPES (decl
);
7399 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7401 gen_declaration_1 (TREE_VALUE (chain
), str
);
7402 chain
= TREE_CHAIN (chain
);
7403 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7409 else if (code
== INDIRECT_REF
)
7411 strcpy (tmpbuf
, "*");
7412 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7416 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7418 chain
= TREE_CHAIN (chain
))
7420 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7422 strcat (tmpbuf
, " ");
7423 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7427 strcat (tmpbuf
, " ");
7429 strcat (tmpbuf
, str
);
7430 strcpy (str
, tmpbuf
);
7433 else if (code
== POINTER_TYPE
)
7435 strcpy (tmpbuf
, "*");
7436 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7438 if (TREE_READONLY (decl
))
7439 strcat (tmpbuf
, " const");
7440 if (TYPE_VOLATILE (decl
))
7441 strcat (tmpbuf
, " volatile");
7443 strcat (tmpbuf
, " ");
7445 strcat (tmpbuf
, str
);
7446 strcpy (str
, tmpbuf
);
7451 gen_declarator (decl
, buf
, name
)
7458 enum tree_code code
= TREE_CODE (decl
);
7468 op
= TREE_OPERAND (decl
, 0);
7470 /* We have a pointer to a function or array...(*)(), (*)[] */
7471 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7472 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7475 str
= gen_declarator (op
, buf
, name
);
7479 strcpy (tmpbuf
, "(");
7480 strcat (tmpbuf
, str
);
7481 strcat (tmpbuf
, ")");
7482 strcpy (str
, tmpbuf
);
7485 adorn_decl (decl
, str
);
7494 /* This clause is done iteratively rather than recursively. */
7497 op
= (is_complex_decl (TREE_TYPE (decl
))
7498 ? TREE_TYPE (decl
) : NULL_TREE
);
7500 adorn_decl (decl
, str
);
7502 /* We have a pointer to a function or array...(*)(), (*)[] */
7503 if (code
== POINTER_TYPE
7504 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7505 || TREE_CODE (op
) == ARRAY_TYPE
))
7507 strcpy (tmpbuf
, "(");
7508 strcat (tmpbuf
, str
);
7509 strcat (tmpbuf
, ")");
7510 strcpy (str
, tmpbuf
);
7513 decl
= (is_complex_decl (TREE_TYPE (decl
))
7514 ? TREE_TYPE (decl
) : NULL_TREE
);
7517 while (decl
&& (code
= TREE_CODE (decl
)))
7522 case IDENTIFIER_NODE
:
7523 /* Will only happen if we are processing a "raw" expr-decl. */
7524 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7535 /* We have an abstract declarator or a _DECL node. */
7543 gen_declspecs (declspecs
, buf
, raw
)
7552 for (chain
= nreverse (copy_list (declspecs
));
7553 chain
; chain
= TREE_CHAIN (chain
))
7555 tree aspec
= TREE_VALUE (chain
);
7557 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7558 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7559 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7561 if (TYPE_NAME (aspec
))
7563 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7565 if (! TREE_STATIC_TEMPLATE (aspec
))
7566 strcat (buf
, "struct ");
7567 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7572 tree chain
= protocol_list
;
7579 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7580 chain
= TREE_CHAIN (chain
);
7589 strcat (buf
, "untagged struct");
7592 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7594 if (TYPE_NAME (aspec
))
7596 if (! TREE_STATIC_TEMPLATE (aspec
))
7597 strcat (buf
, "union ");
7598 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7601 strcat (buf
, "untagged union");
7604 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7606 if (TYPE_NAME (aspec
))
7608 if (! TREE_STATIC_TEMPLATE (aspec
))
7609 strcat (buf
, "enum ");
7610 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7613 strcat (buf
, "untagged enum");
7616 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7617 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7619 else if (IS_ID (aspec
))
7621 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7626 tree chain
= protocol_list
;
7633 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7634 chain
= TREE_CHAIN (chain
);
7641 if (TREE_CHAIN (chain
))
7647 /* Type qualifiers. */
7648 if (TREE_READONLY (declspecs
))
7649 strcat (buf
, "const ");
7650 if (TYPE_VOLATILE (declspecs
))
7651 strcat (buf
, "volatile ");
7653 switch (TREE_CODE (declspecs
))
7655 /* Type specifiers. */
7658 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7660 /* Signed integer types. */
7662 if (declspecs
== short_integer_type_node
)
7663 strcat (buf
, "short int ");
7664 else if (declspecs
== integer_type_node
)
7665 strcat (buf
, "int ");
7666 else if (declspecs
== long_integer_type_node
)
7667 strcat (buf
, "long int ");
7668 else if (declspecs
== long_long_integer_type_node
)
7669 strcat (buf
, "long long int ");
7670 else if (declspecs
== signed_char_type_node
7671 || declspecs
== char_type_node
)
7672 strcat (buf
, "char ");
7674 /* Unsigned integer types. */
7676 else if (declspecs
== short_unsigned_type_node
)
7677 strcat (buf
, "unsigned short ");
7678 else if (declspecs
== unsigned_type_node
)
7679 strcat (buf
, "unsigned int ");
7680 else if (declspecs
== long_unsigned_type_node
)
7681 strcat (buf
, "unsigned long ");
7682 else if (declspecs
== long_long_unsigned_type_node
)
7683 strcat (buf
, "unsigned long long ");
7684 else if (declspecs
== unsigned_char_type_node
)
7685 strcat (buf
, "unsigned char ");
7689 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7691 if (declspecs
== float_type_node
)
7692 strcat (buf
, "float ");
7693 else if (declspecs
== double_type_node
)
7694 strcat (buf
, "double ");
7695 else if (declspecs
== long_double_type_node
)
7696 strcat (buf
, "long double ");
7700 if (TYPE_NAME (declspecs
)
7701 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7703 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7705 if (! TREE_STATIC_TEMPLATE (declspecs
))
7706 strcat (buf
, "struct ");
7707 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7711 tree chain
= protocol_list
;
7718 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7719 chain
= TREE_CHAIN (chain
);
7728 strcat (buf
, "untagged struct");
7734 if (TYPE_NAME (declspecs
)
7735 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7737 strcat (buf
, "union ");
7738 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7743 strcat (buf
, "untagged union ");
7747 if (TYPE_NAME (declspecs
)
7748 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7750 strcat (buf
, "enum ");
7751 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7756 strcat (buf
, "untagged enum ");
7760 strcat (buf
, "void ");
7765 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7770 tree chain
= protocol_list
;
7777 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7778 chain
= TREE_CHAIN (chain
);
7794 /* Given a tree node, produce a printable description of it in the given
7795 buffer, overwriting the buffer. */
7798 gen_declaration (atype_or_adecl
, buf
)
7799 tree atype_or_adecl
;
7803 gen_declaration_1 (atype_or_adecl
, buf
);
7807 /* Given a tree node, append a printable description to the end of the
7811 gen_declaration_1 (atype_or_adecl
, buf
)
7812 tree atype_or_adecl
;
7817 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7819 tree declspecs
; /* "identifier_node", "record_type" */
7820 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7822 /* We have a "raw", abstract declarator (typename). */
7823 declarator
= TREE_VALUE (atype_or_adecl
);
7824 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7826 gen_declspecs (declspecs
, buf
, 1);
7830 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7837 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7838 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7840 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7841 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7842 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7843 atype
= TREE_TYPE (atype_or_adecl
);
7845 /* Assume we have a *_type node. */
7846 atype
= atype_or_adecl
;
7848 if (is_complex_decl (atype
))
7852 /* Get the declaration specifier; it is at the end of the list. */
7853 declarator
= chain
= atype
;
7855 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7856 while (is_complex_decl (chain
));
7863 declarator
= NULL_TREE
;
7866 gen_declspecs (declspecs
, buf
, 0);
7868 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7869 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7870 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7872 const char *const decl_name
=
7873 (DECL_NAME (atype_or_adecl
)
7874 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7879 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7882 else if (decl_name
[0])
7885 strcat (buf
, decl_name
);
7888 else if (declarator
)
7891 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7896 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7898 /* Given a method tree, put a printable description into the given
7899 buffer (overwriting) and return a pointer to the buffer. */
7902 gen_method_decl (method
, buf
)
7909 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7912 gen_declaration_1 (TREE_TYPE (method
), buf
);
7916 chain
= METHOD_SEL_ARGS (method
);
7919 /* We have a chain of keyword_decls. */
7922 if (KEYWORD_KEY_NAME (chain
))
7923 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7926 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7929 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7933 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7934 if ((chain
= TREE_CHAIN (chain
)))
7939 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7940 strcat (buf
, ", ...");
7941 else if (METHOD_ADD_ARGS (method
))
7943 /* We have a tree list node as generate by get_parm_info. */
7944 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7946 /* Know we have a chain of parm_decls. */
7950 gen_declaration_1 (chain
, buf
);
7951 chain
= TREE_CHAIN (chain
);
7957 /* We have a unary selector. */
7958 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7966 dump_interface (fp
, chain
)
7970 char *buf
= (char *)xmalloc (256);
7971 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7972 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7973 tree nst_methods
= CLASS_NST_METHODS (chain
);
7974 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7976 fprintf (fp
, "\n@interface %s", my_name
);
7978 if (CLASS_SUPER_NAME (chain
))
7980 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7981 fprintf (fp
, " : %s\n", super_name
);
7988 fprintf (fp
, "{\n");
7991 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7992 ivar_decls
= TREE_CHAIN (ivar_decls
);
7995 fprintf (fp
, "}\n");
8000 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8001 nst_methods
= TREE_CHAIN (nst_methods
);
8006 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8007 cls_methods
= TREE_CHAIN (cls_methods
);
8009 fprintf (fp
, "\n@end");
8012 /* Demangle function for Objective-C */
8014 objc_demangle (mangled
)
8015 const char *mangled
;
8017 char *demangled
, *cp
;
8019 if (mangled
[0] == '_' &&
8020 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8023 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8024 if (mangled
[1] == 'i')
8025 *cp
++ = '-'; /* for instance method */
8027 *cp
++ = '+'; /* for class method */
8028 *cp
++ = '['; /* opening left brace */
8029 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8030 while (*cp
&& *cp
== '_')
8031 cp
++; /* skip any initial underbars in class name */
8032 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8035 free(demangled
); /* not mangled name */
8038 if (cp
[1] == '_') /* easy case: no category name */
8040 *cp
++ = ' '; /* replace two '_' with one ' ' */
8041 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8045 *cp
++ = '('; /* less easy case: category name */
8046 cp
= strchr(cp
, '_');
8049 free(demangled
); /* not mangled name */
8053 *cp
++ = ' '; /* overwriting 1st char of method name... */
8054 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8056 while (*cp
&& *cp
== '_')
8057 cp
++; /* skip any initial underbars in method name */
8060 *cp
= ':'; /* replace remaining '_' with ':' */
8061 *cp
++ = ']'; /* closing right brace */
8062 *cp
++ = 0; /* string terminator */
8066 return mangled
; /* not an objc mangled name */
8070 objc_printable_name (decl
, kind
)
8072 int kind ATTRIBUTE_UNUSED
;
8074 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8080 /* Add the special tree codes of Objective C to the tables. */
8082 gcc_obstack_init (&util_obstack
);
8083 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8085 memcpy (tree_code_type
+ (int) LAST_BASE_TREE_CODE
,
8086 objc_tree_code_type
,
8087 (int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
);
8088 memcpy (tree_code_length
+ (int) LAST_BASE_TREE_CODE
,
8089 objc_tree_code_length
,
8090 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
) * sizeof (int)));
8091 memcpy (tree_code_name
+ (int) LAST_BASE_TREE_CODE
,
8092 objc_tree_code_name
,
8093 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
) * sizeof (char *)));
8095 errbuf
= (char *)xmalloc (BUFSIZE
);
8097 synth_module_prologue ();
8103 struct imp_entry
*impent
;
8105 /* The internally generated initializers appear to have missing braces.
8106 Don't warn about this. */
8107 int save_warn_missing_braces
= warn_missing_braces
;
8108 warn_missing_braces
= 0;
8110 /* A missing @end may not be detected by the parser. */
8111 if (objc_implementation_context
)
8113 warning ("`@end' missing in implementation context");
8114 finish_class (objc_implementation_context
);
8115 objc_ivar_chain
= NULL_TREE
;
8116 objc_implementation_context
= NULL_TREE
;
8119 generate_forward_declaration_to_string_table ();
8121 #ifdef OBJC_PROLOGUE
8125 /* Process the static instances here because initialization of objc_symtab
8127 if (objc_static_instances
)
8128 generate_static_references ();
8130 if (imp_list
|| class_names_chain
8131 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8132 generate_objc_symtab_decl ();
8134 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8136 objc_implementation_context
= impent
->imp_context
;
8137 implementation_template
= impent
->imp_template
;
8139 UOBJC_CLASS_decl
= impent
->class_decl
;
8140 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8142 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8144 /* all of the following reference the string pool... */
8145 generate_ivar_lists ();
8146 generate_dispatch_tables ();
8147 generate_shared_structures ();
8151 generate_dispatch_tables ();
8152 generate_category (objc_implementation_context
);
8156 /* If we are using an array of selectors, we must always
8157 finish up the array decl even if no selectors were used. */
8158 if (! flag_next_runtime
|| sel_ref_chain
)
8159 build_selector_translation_table ();
8162 generate_protocols ();
8164 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8165 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8167 /* Arrange for Objc data structures to be initialized at run time. */
8168 rtx init_sym
= build_module_descriptor ();
8169 if (init_sym
&& targetm
.have_ctors_dtors
)
8170 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8173 /* Dump the class references. This forces the appropriate classes
8174 to be linked into the executable image, preserving unix archive
8175 semantics. This can be removed when we move to a more dynamically
8176 linked environment. */
8178 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8180 handle_class_ref (chain
);
8181 if (TREE_PURPOSE (chain
))
8182 generate_classref_translation_entry (chain
);
8185 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8186 handle_impent (impent
);
8188 /* Dump the string table last. */
8190 generate_strings ();
8192 if (flag_gen_declaration
)
8194 add_class (objc_implementation_context
);
8195 dump_interface (gen_declaration_file
, objc_implementation_context
);
8203 /* Run through the selector hash tables and print a warning for any
8204 selector which has multiple methods. */
8206 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8207 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8210 tree meth
= hsh
->key
;
8211 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8215 warning ("potential selector conflict for method `%s'",
8216 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8217 warn_with_method ("found", type
, meth
);
8218 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8219 warn_with_method ("found", type
, loop
->value
);
8222 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8223 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8226 tree meth
= hsh
->key
;
8227 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8231 warning ("potential selector conflict for method `%s'",
8232 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8233 warn_with_method ("found", type
, meth
);
8234 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8235 warn_with_method ("found", type
, loop
->value
);
8239 warn_missing_braces
= save_warn_missing_braces
;
8242 /* Subroutines of finish_objc. */
8245 generate_classref_translation_entry (chain
)
8248 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8251 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8253 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8254 expr
= build_c_cast (type
, expr
); /* cast! */
8256 name
= DECL_NAME (TREE_PURPOSE (chain
));
8258 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8260 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8261 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8263 /* The decl that is returned from start_decl is the one that we
8264 forward declared in build_class_reference. */
8265 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8266 DECL_CONTEXT (decl
) = NULL_TREE
;
8267 finish_decl (decl
, expr
, NULL_TREE
);
8272 handle_class_ref (chain
)
8275 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8276 char *string
= (char *) alloca (strlen (name
) + 30);
8280 sprintf (string
, "%sobjc_class_name_%s",
8281 (flag_next_runtime
? "." : "__"), name
);
8283 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8284 if (flag_next_runtime
)
8286 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8291 /* Make a decl for this name, so we can use its address in a tree. */
8292 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8293 DECL_EXTERNAL (decl
) = 1;
8294 TREE_PUBLIC (decl
) = 1;
8297 rest_of_decl_compilation (decl
, 0, 0, 0);
8299 /* Make a decl for the address. */
8300 sprintf (string
, "%sobjc_class_ref_%s",
8301 (flag_next_runtime
? "." : "__"), name
);
8302 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8303 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8304 DECL_INITIAL (decl
) = exp
;
8305 TREE_STATIC (decl
) = 1;
8308 rest_of_decl_compilation (decl
, 0, 0, 0);
8312 handle_impent (impent
)
8313 struct imp_entry
*impent
;
8317 objc_implementation_context
= impent
->imp_context
;
8318 implementation_template
= impent
->imp_template
;
8320 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8322 const char *const class_name
=
8323 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8325 string
= (char *) alloca (strlen (class_name
) + 30);
8327 sprintf (string
, "*%sobjc_class_name_%s",
8328 (flag_next_runtime
? "." : "__"), class_name
);
8330 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8332 const char *const class_name
=
8333 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8334 const char *const class_super_name
=
8335 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8337 string
= (char *) alloca (strlen (class_name
)
8338 + strlen (class_super_name
) + 30);
8340 /* Do the same for categories. Even though no references to
8341 these symbols are generated automatically by the compiler, it
8342 gives you a handle to pull them into an archive by hand. */
8343 sprintf (string
, "*%sobjc_category_name_%s_%s",
8344 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8349 #ifdef ASM_DECLARE_CLASS_REFERENCE
8350 if (flag_next_runtime
)
8352 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8357 /* (Should this be a routine in varasm.c?) */
8358 readonly_data_section ();
8359 assemble_global (string
);
8360 assemble_align (UNITS_PER_WORD
);
8361 assemble_label (string
);
8362 assemble_zeros (UNITS_PER_WORD
);
8366 ggc_mark_imp_list (arg
)
8369 struct imp_entry
*impent
;
8371 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8373 ggc_mark_tree (impent
->imp_context
);
8374 ggc_mark_tree (impent
->imp_template
);
8375 ggc_mark_tree (impent
->class_decl
);
8376 ggc_mark_tree (impent
->meta_decl
);
8381 ggc_mark_hash_table (arg
)
8384 hash
*hash_table
= *(hash
**)arg
;
8389 if (hash_table
== NULL
)
8391 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8392 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8394 ggc_mark_tree (hst
->key
);
8395 for (list
= hst
->list
; list
; list
= list
->next
)
8396 ggc_mark_tree (list
->value
);
8400 /* Add GC roots for variables local to this file. */
8402 objc_act_parse_init ()
8404 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8405 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8406 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8407 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8410 /* Look up ID as an instance variable. */
8412 lookup_objc_ivar (id
)
8417 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8418 /* we have a message to super */
8419 return get_super_receiver ();
8420 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8422 if (is_private (decl
))
8423 return error_mark_node
;
8425 return build_ivar_reference (id
);