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
472 /* Each front end provides its own. */
473 const struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
475 static varray_type deferred_fns
;
477 /* Post-switch processing. */
481 c_common_post_options ();
484 /* Some platforms pass small structures through registers versus through
485 an invisible pointer. Determine at what size structure is the
486 transition point between the two possibilities. */
489 generate_struct_by_value_array ()
492 tree field_decl
, field_decl_chain
;
494 int aggregate_in_mem
[32];
497 /* Presumably no platform passes 32 byte structures in a register. */
498 for (i
= 1; i
< 32; i
++)
502 /* Create an unnamed struct that has `i' character components */
503 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
505 strcpy (buffer
, "c1");
506 field_decl
= create_builtin_decl (FIELD_DECL
,
509 field_decl_chain
= field_decl
;
511 for (j
= 1; j
< i
; j
++)
513 sprintf (buffer
, "c%d", j
+ 1);
514 field_decl
= create_builtin_decl (FIELD_DECL
,
517 chainon (field_decl_chain
, field_decl
);
519 finish_struct (type
, field_decl_chain
, NULL_TREE
);
521 aggregate_in_mem
[i
] = aggregate_value_p (type
);
522 if (!aggregate_in_mem
[i
])
526 /* We found some structures that are returned in registers instead of memory
527 so output the necessary data. */
530 for (i
= 31; i
>= 0; i
--)
531 if (!aggregate_in_mem
[i
])
533 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
535 /* The first member of the structure is always 0 because we don't handle
536 structures with 0 members */
537 printf ("static int struct_forward_array[] = {\n 0");
539 for (j
= 1; j
<= i
; j
++)
540 printf (", %d", aggregate_in_mem
[j
]);
550 c_common_init_options (clk_objective_c
);
555 const char *filename
;
557 c_init_decl_processing ();
559 filename
= c_common_init (filename
);
563 /* Force the line number back to 0; check_newline will have
564 raised it to 1, which will make the builtin functions appear
565 not to be built in. */
568 /* If gen_declaration desired, open the output file. */
569 if (flag_gen_declaration
)
571 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
572 gen_declaration_file
= fopen (dumpname
, "w");
573 if (gen_declaration_file
== 0)
574 fatal_io_error ("can't open %s", dumpname
);
578 if (flag_next_runtime
)
580 TAG_GETCLASS
= "objc_getClass";
581 TAG_GETMETACLASS
= "objc_getMetaClass";
582 TAG_MSGSEND
= "objc_msgSend";
583 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
584 TAG_EXECCLASS
= "__objc_execClass";
588 TAG_GETCLASS
= "objc_get_class";
589 TAG_GETMETACLASS
= "objc_get_meta_class";
590 TAG_MSGSEND
= "objc_msg_lookup";
591 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
592 TAG_EXECCLASS
= "__objc_exec_class";
593 flag_typed_selectors
= 1;
596 objc_ellipsis_node
= make_node (ERROR_MARK
);
600 if (print_struct_values
)
601 generate_struct_by_value_array ();
603 objc_act_parse_init ();
605 VARRAY_TREE_INIT (deferred_fns
, 32, "deferred_fns");
606 ggc_add_tree_varray_root (&deferred_fns
, 1);
611 /* Register a function tree, so that its optimization and conversion
612 to RTL is only done at the end of the compilation. */
618 VARRAY_PUSH_TREE (deferred_fns
, fn
);
628 for (i
= 0; i
< VARRAY_ACTIVE_SIZE (deferred_fns
); i
++)
629 /* Don't output the same function twice. We may run into such
630 situations when an extern inline function is later given a
631 non-extern-inline definition. */
632 if (! TREE_ASM_WRITTEN (VARRAY_TREE (deferred_fns
, i
)))
633 c_expand_deferred_function (VARRAY_TREE (deferred_fns
, i
));
634 VARRAY_FREE (deferred_fns
);
636 finish_objc (); /* Objective-C finalization */
638 if (gen_declaration_file
)
639 fclose (gen_declaration_file
);
643 objc_decode_option (argc
, argv
)
647 const char *p
= argv
[0];
649 if (!strcmp (p
, "-gen-decls"))
650 flag_gen_declaration
= 1;
651 else if (!strcmp (p
, "-Wselector"))
653 else if (!strcmp (p
, "-Wno-selector"))
655 else if (!strcmp (p
, "-Wprotocol"))
656 flag_warn_protocol
= 1;
657 else if (!strcmp (p
, "-Wno-protocol"))
658 flag_warn_protocol
= 0;
659 else if (!strcmp (p
, "-fgnu-runtime"))
660 flag_next_runtime
= 0;
661 else if (!strcmp (p
, "-fno-next-runtime"))
662 flag_next_runtime
= 0;
663 else if (!strcmp (p
, "-fno-gnu-runtime"))
664 flag_next_runtime
= 1;
665 else if (!strcmp (p
, "-fnext-runtime"))
666 flag_next_runtime
= 1;
667 else if (!strcmp (p
, "-print-objc-runtime-info"))
668 print_struct_values
= 1;
669 #define CSTSTRCLASS "-fconstant-string-class="
670 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
671 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
672 error ("no class name specified as argument to -fconstant-string-class");
673 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
677 return c_decode_option (argc
, argv
);
684 define_decl (declarator
, declspecs
)
688 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
689 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
693 /* Return 1 if LHS and RHS are compatible types for assignment or
694 various other operations. Return 0 if they are incompatible, and
695 return -1 if we choose to not decide. When the operation is
696 REFLEXIVE, check for compatibility in either direction.
698 For statically typed objects, an assignment of the form `a' = `b'
702 `a' and `b' are the same class type, or
703 `a' and `b' are of class types A and B such that B is a descendant of A. */
706 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
710 return objc_comptypes (lhs
, rhs
, reflexive
);
714 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
722 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
724 p
= TREE_VALUE (rproto
);
726 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
728 if ((fnd
= lookup_method (class_meth
729 ? PROTOCOL_CLS_METHODS (p
)
730 : PROTOCOL_NST_METHODS (p
), sel_name
)))
732 else if (PROTOCOL_LIST (p
))
733 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
734 sel_name
, class_meth
);
738 ; /* An identifier...if we could not find a protocol. */
749 lookup_protocol_in_reflist (rproto_list
, lproto
)
755 /* Make sure the protocol is supported by the object on the rhs. */
756 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
759 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
761 p
= TREE_VALUE (rproto
);
763 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
768 else if (PROTOCOL_LIST (p
))
769 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
778 ; /* An identifier...if we could not find a protocol. */
784 /* Return 1 if LHS and RHS are compatible types for assignment
785 or various other operations. Return 0 if they are incompatible,
786 and return -1 if we choose to not decide. When the operation
787 is REFLEXIVE, check for compatibility in either direction. */
790 objc_comptypes (lhs
, rhs
, reflexive
)
795 /* New clause for protocols. */
797 if (TREE_CODE (lhs
) == POINTER_TYPE
798 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
799 && TREE_CODE (rhs
) == POINTER_TYPE
800 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
802 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
803 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
807 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
808 tree rproto
, rproto_list
;
813 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
815 /* Make sure the protocol is supported by the object
817 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
819 p
= TREE_VALUE (lproto
);
820 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
823 warning ("object does not conform to the `%s' protocol",
824 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
827 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
829 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
832 /* Make sure the protocol is supported by the object
834 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
836 p
= TREE_VALUE (lproto
);
838 rinter
= lookup_interface (rname
);
840 while (rinter
&& !rproto
)
844 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
845 /* If the underlying ObjC class does not have
846 protocols attached to it, perhaps there are
847 "one-off" protocols attached to the rhs?
848 E.g., 'id<MyProt> foo;'. */
850 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
851 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
853 /* Check for protocols adopted by categories. */
854 cat
= CLASS_CATEGORY_LIST (rinter
);
855 while (cat
&& !rproto
)
857 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
858 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
860 cat
= CLASS_CATEGORY_LIST (cat
);
863 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
867 warning ("class `%s' does not implement the `%s' protocol",
868 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
869 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
873 /* May change...based on whether there was any mismatch */
876 else if (rhs_is_proto
)
877 /* Lhs is not a protocol...warn if it is statically typed */
878 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
881 /* Defer to comptypes. */
885 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
886 ; /* Fall thru. This is the case we have been handling all along */
888 /* Defer to comptypes. */
891 /* `id' = `<class> *', `<class> *' = `id' */
893 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
894 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
897 /* `id' = `Class', `Class' = `id' */
899 else if ((TYPE_NAME (lhs
) == objc_object_id
900 && TYPE_NAME (rhs
) == objc_class_id
)
901 || (TYPE_NAME (lhs
) == objc_class_id
902 && TYPE_NAME (rhs
) == objc_object_id
))
905 /* `<class> *' = `<class> *' */
907 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
909 tree lname
= TYPE_NAME (lhs
);
910 tree rname
= TYPE_NAME (rhs
);
916 /* If the left hand side is a super class of the right hand side,
918 for (inter
= lookup_interface (rname
); inter
;
919 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
920 if (lname
== CLASS_SUPER_NAME (inter
))
923 /* Allow the reverse when reflexive. */
925 for (inter
= lookup_interface (lname
); inter
;
926 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
927 if (rname
== CLASS_SUPER_NAME (inter
))
933 /* Defer to comptypes. */
937 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
940 objc_check_decl (decl
)
943 tree type
= TREE_TYPE (decl
);
945 if (TREE_CODE (type
) == RECORD_TYPE
946 && TREE_STATIC_TEMPLATE (type
)
947 && type
!= constant_string_type
)
948 error_with_decl (decl
, "`%s' cannot be statically allocated");
952 maybe_objc_check_decl (decl
)
955 objc_check_decl (decl
);
958 /* Implement static typing. At this point, we know we have an interface. */
961 get_static_reference (interface
, protocols
)
965 tree type
= xref_tag (RECORD_TYPE
, interface
);
969 tree t
, m
= TYPE_MAIN_VARIANT (type
);
971 t
= copy_node (type
);
972 TYPE_BINFO (t
) = make_tree_vec (2);
974 /* Add this type to the chain of variants of TYPE. */
975 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
976 TYPE_NEXT_VARIANT (m
) = t
;
978 /* Look up protocols and install in lang specific list. Note
979 that the protocol list can have a different lifetime than T! */
980 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
982 /* This forces a new pointer type to be created later
983 (in build_pointer_type)...so that the new template
984 we just created will actually be used...what a hack! */
985 if (TYPE_POINTER_TO (t
))
986 TYPE_POINTER_TO (t
) = NULL_TREE
;
995 get_object_reference (protocols
)
998 tree type_decl
= lookup_name (objc_id_id
);
1001 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1003 type
= TREE_TYPE (type_decl
);
1004 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1005 warning ("Unexpected type for `id' (%s)",
1006 gen_declaration (type
, errbuf
));
1010 error ("Undefined type `id', please import <objc/objc.h>");
1011 return error_mark_node
;
1014 /* This clause creates a new pointer type that is qualified with
1015 the protocol specification...this info is used later to do more
1016 elaborate type checking. */
1020 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1022 t
= copy_node (type
);
1023 TYPE_BINFO (t
) = make_tree_vec (2);
1025 /* Add this type to the chain of variants of TYPE. */
1026 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1027 TYPE_NEXT_VARIANT (m
) = t
;
1029 /* Look up protocols...and install in lang specific list */
1030 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1032 /* This forces a new pointer type to be created later
1033 (in build_pointer_type)...so that the new template
1034 we just created will actually be used...what a hack! */
1035 if (TYPE_POINTER_TO (t
))
1036 TYPE_POINTER_TO (t
) = NULL_TREE
;
1043 /* Check for circular dependencies in protocols. The arguments are
1044 PROTO, the protocol to check, and LIST, a list of protocol it
1048 check_protocol_recursively (proto
, list
)
1054 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1056 tree pp
= TREE_VALUE (p
);
1058 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1059 pp
= lookup_protocol (pp
);
1062 fatal_error ("protocol `%s' has circular dependency",
1063 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1065 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1070 lookup_and_install_protocols (protocols
)
1075 tree return_value
= protocols
;
1077 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1079 tree ident
= TREE_VALUE (proto
);
1080 tree p
= lookup_protocol (ident
);
1084 error ("Cannot find protocol declaration for `%s'",
1085 IDENTIFIER_POINTER (ident
));
1087 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1089 return_value
= TREE_CHAIN (proto
);
1093 /* Replace identifier with actual protocol node. */
1094 TREE_VALUE (proto
) = p
;
1099 return return_value
;
1102 /* Create and push a decl for a built-in external variable or field NAME.
1104 TYPE is its data type. */
1107 create_builtin_decl (code
, type
, name
)
1108 enum tree_code code
;
1112 tree decl
= build_decl (code
, get_identifier (name
), type
);
1114 if (code
== VAR_DECL
)
1116 TREE_STATIC (decl
) = 1;
1117 make_decl_rtl (decl
, 0);
1121 DECL_ARTIFICIAL (decl
) = 1;
1125 /* Find the decl for the constant string class. */
1128 setup_string_decl ()
1130 if (!string_class_decl
)
1132 if (!constant_string_global_id
)
1133 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1134 string_class_decl
= lookup_name (constant_string_global_id
);
1138 /* Purpose: "play" parser, creating/installing representations
1139 of the declarations that are required by Objective-C.
1143 type_spec--------->sc_spec
1144 (tree_list) (tree_list)
1147 identifier_node identifier_node */
1150 synth_module_prologue ()
1155 /* Defined in `objc.h' */
1156 objc_object_id
= get_identifier (TAG_OBJECT
);
1158 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1160 id_type
= build_pointer_type (objc_object_reference
);
1162 objc_id_id
= get_identifier (TYPE_ID
);
1163 objc_class_id
= get_identifier (TAG_CLASS
);
1165 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1166 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1167 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1169 /* Declare type of selector-objects that represent an operation name. */
1171 /* `struct objc_selector *' */
1173 = build_pointer_type (xref_tag (RECORD_TYPE
,
1174 get_identifier (TAG_SELECTOR
)));
1176 /* Forward declare type, or else the prototype for msgSendSuper will
1179 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1180 get_identifier (TAG_SUPER
)));
1183 /* id objc_msgSend (id, SEL, ...); */
1186 = build_function_type (id_type
,
1187 tree_cons (NULL_TREE
, id_type
,
1188 tree_cons (NULL_TREE
, selector_type
,
1191 if (! flag_next_runtime
)
1193 umsg_decl
= build_decl (FUNCTION_DECL
,
1194 get_identifier (TAG_MSGSEND
), temp_type
);
1195 DECL_EXTERNAL (umsg_decl
) = 1;
1196 TREE_PUBLIC (umsg_decl
) = 1;
1197 DECL_INLINE (umsg_decl
) = 1;
1198 DECL_ARTIFICIAL (umsg_decl
) = 1;
1200 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1201 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1203 make_decl_rtl (umsg_decl
, NULL
);
1204 pushdecl (umsg_decl
);
1207 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1209 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1212 = build_function_type (id_type
,
1213 tree_cons (NULL_TREE
, super_p
,
1214 tree_cons (NULL_TREE
, selector_type
,
1217 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1218 temp_type
, 0, NOT_BUILT_IN
, 0);
1220 /* id objc_getClass (const char *); */
1222 temp_type
= build_function_type (id_type
,
1223 tree_cons (NULL_TREE
,
1224 const_string_type_node
,
1225 tree_cons (NULL_TREE
, void_type_node
,
1229 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1231 /* id objc_getMetaClass (const char *); */
1233 objc_get_meta_class_decl
1234 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1236 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1238 if (! flag_next_runtime
)
1240 if (flag_typed_selectors
)
1242 /* Suppress outputting debug symbols, because
1243 dbxout_init hasn'r been called yet. */
1244 enum debug_info_type save_write_symbols
= write_symbols
;
1245 struct gcc_debug_hooks
*save_hooks
= debug_hooks
;
1246 write_symbols
= NO_DEBUG
;
1247 debug_hooks
= &do_nothing_debug_hooks
;
1249 build_selector_template ();
1250 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1252 write_symbols
= save_write_symbols
;
1253 debug_hooks
= save_hooks
;
1256 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1258 layout_type (temp_type
);
1259 UOBJC_SELECTOR_TABLE_decl
1260 = create_builtin_decl (VAR_DECL
, temp_type
,
1261 "_OBJC_SELECTOR_TABLE");
1263 /* Avoid warning when not sending messages. */
1264 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1267 generate_forward_declaration_to_string_table ();
1269 /* Forward declare constant_string_id and constant_string_type. */
1270 if (!constant_string_class_name
)
1271 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1273 constant_string_id
= get_identifier (constant_string_class_name
);
1274 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1277 /* Custom build_string which sets TREE_TYPE! */
1280 my_build_string (len
, str
)
1285 tree a_string
= build_string (len
, str
);
1287 /* Some code from combine_strings, which is local to c-parse.y. */
1288 if (TREE_TYPE (a_string
) == int_array_type_node
)
1291 TREE_TYPE (a_string
)
1292 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1293 build_index_type (build_int_2 (len
- 1, 0)));
1295 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1296 TREE_STATIC (a_string
) = 1;
1301 /* Given a chain of STRING_CST's, build a static instance of
1302 NXConstantString which points at the concatenation of those strings.
1303 We place the string object in the __string_objects section of the
1304 __OBJC segment. The Objective-C runtime will initialize the isa
1305 pointers of the string objects to point at the NXConstantString
1309 build_objc_string_object (strings
)
1312 tree string
, initlist
, constructor
;
1315 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1317 error ("Cannot find interface declaration for `%s'",
1318 IDENTIFIER_POINTER (constant_string_id
));
1319 return error_mark_node
;
1322 add_class_reference (constant_string_id
);
1324 string
= combine_strings (strings
);
1325 TREE_SET_CODE (string
, STRING_CST
);
1326 length
= TREE_STRING_LENGTH (string
) - 1;
1328 /* & ((NXConstantString) {0, string, length}) */
1330 if (flag_next_runtime
)
1332 /* For the NeXT runtime, we can generate a literal reference
1333 to the string class, don't need to run a constructor. */
1334 setup_string_decl ();
1335 if (string_class_decl
== NULL_TREE
)
1337 error ("Cannot find reference tag for class `%s'",
1338 IDENTIFIER_POINTER (constant_string_id
));
1339 return error_mark_node
;
1341 initlist
= build_tree_list
1343 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1347 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1351 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1353 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1354 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1356 if (!flag_next_runtime
)
1359 = objc_add_static_instance (constructor
, constant_string_type
);
1362 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1365 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1368 objc_add_static_instance (constructor
, class_decl
)
1369 tree constructor
, class_decl
;
1371 static int num_static_inst
;
1375 /* Find the list of static instances for the CLASS_DECL. Create one if
1377 for (chain
= &objc_static_instances
;
1378 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1379 chain
= &TREE_CHAIN (*chain
));
1382 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1383 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1386 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1387 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1388 DECL_COMMON (decl
) = 1;
1389 TREE_STATIC (decl
) = 1;
1390 DECL_ARTIFICIAL (decl
) = 1;
1391 DECL_INITIAL (decl
) = constructor
;
1393 /* We may be writing something else just now.
1394 Postpone till end of input. */
1395 DECL_DEFER_OUTPUT (decl
) = 1;
1396 pushdecl_top_level (decl
);
1397 rest_of_decl_compilation (decl
, 0, 1, 0);
1399 /* Add the DECL to the head of this CLASS' list. */
1400 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1405 /* Build a static constant CONSTRUCTOR
1406 with type TYPE and elements ELTS. */
1409 build_constructor (type
, elts
)
1412 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1414 TREE_CONSTANT (constructor
) = 1;
1415 TREE_STATIC (constructor
) = 1;
1416 TREE_READONLY (constructor
) = 1;
1421 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1423 /* Predefine the following data type:
1431 void *defs[cls_def_cnt + cat_def_cnt];
1435 build_objc_symtab_template ()
1437 tree field_decl
, field_decl_chain
, index
;
1439 objc_symtab_template
1440 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1442 /* long sel_ref_cnt; */
1444 field_decl
= create_builtin_decl (FIELD_DECL
,
1445 long_integer_type_node
,
1447 field_decl_chain
= field_decl
;
1451 field_decl
= create_builtin_decl (FIELD_DECL
,
1452 build_pointer_type (selector_type
),
1454 chainon (field_decl_chain
, field_decl
);
1456 /* short cls_def_cnt; */
1458 field_decl
= create_builtin_decl (FIELD_DECL
,
1459 short_integer_type_node
,
1461 chainon (field_decl_chain
, field_decl
);
1463 /* short cat_def_cnt; */
1465 field_decl
= create_builtin_decl (FIELD_DECL
,
1466 short_integer_type_node
,
1468 chainon (field_decl_chain
, field_decl
);
1470 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1472 if (!flag_next_runtime
)
1473 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1475 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1476 imp_count
== 0 && cat_count
== 0
1478 field_decl
= create_builtin_decl (FIELD_DECL
,
1479 build_array_type (ptr_type_node
, index
),
1481 chainon (field_decl_chain
, field_decl
);
1483 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1486 /* Create the initial value for the `defs' field of _objc_symtab.
1487 This is a CONSTRUCTOR. */
1490 init_def_list (type
)
1493 tree expr
, initlist
= NULL_TREE
;
1494 struct imp_entry
*impent
;
1497 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1499 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1501 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1502 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1507 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1509 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1511 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1512 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1516 if (!flag_next_runtime
)
1518 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1521 if (static_instances_decl
)
1522 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1524 expr
= build_int_2 (0, 0);
1526 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1529 return build_constructor (type
, nreverse (initlist
));
1532 /* Construct the initial value for all of _objc_symtab. */
1535 init_objc_symtab (type
)
1540 /* sel_ref_cnt = { ..., 5, ... } */
1542 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1544 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1546 if (flag_next_runtime
|| ! sel_ref_chain
)
1547 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1549 initlist
= tree_cons (NULL_TREE
,
1550 build_unary_op (ADDR_EXPR
,
1551 UOBJC_SELECTOR_TABLE_decl
, 1),
1554 /* cls_def_cnt = { ..., 5, ... } */
1556 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1558 /* cat_def_cnt = { ..., 5, ... } */
1560 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1562 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1564 if (imp_count
|| cat_count
|| static_instances_decl
)
1567 tree field
= TYPE_FIELDS (type
);
1568 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1570 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1574 return build_constructor (type
, nreverse (initlist
));
1577 /* Push forward-declarations of all the categories
1578 so that init_def_list can use them in a CONSTRUCTOR. */
1581 forward_declare_categories ()
1583 struct imp_entry
*impent
;
1584 tree sav
= objc_implementation_context
;
1586 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1588 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1590 /* Set an invisible arg to synth_id_with_class_suffix. */
1591 objc_implementation_context
= impent
->imp_context
;
1593 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1594 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1597 objc_implementation_context
= sav
;
1600 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1601 and initialized appropriately. */
1604 generate_objc_symtab_decl ()
1608 if (!objc_category_template
)
1609 build_category_template ();
1611 /* forward declare categories */
1613 forward_declare_categories ();
1615 if (!objc_symtab_template
)
1616 build_objc_symtab_template ();
1618 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1620 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1621 tree_cons (NULL_TREE
,
1622 objc_symtab_template
, sc_spec
),
1626 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1627 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1628 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1629 finish_decl (UOBJC_SYMBOLS_decl
,
1630 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1635 init_module_descriptor (type
)
1638 tree initlist
, expr
;
1640 /* version = { 1, ... } */
1642 expr
= build_int_2 (OBJC_VERSION
, 0);
1643 initlist
= build_tree_list (NULL_TREE
, expr
);
1645 /* size = { ..., sizeof (struct objc_module), ... } */
1647 expr
= size_in_bytes (objc_module_template
);
1648 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1650 /* name = { ..., "foo.m", ... } */
1652 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1653 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1655 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1657 if (UOBJC_SYMBOLS_decl
)
1658 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1660 expr
= build_int_2 (0, 0);
1661 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1663 return build_constructor (type
, nreverse (initlist
));
1666 /* Write out the data structures to describe Objective C classes defined.
1667 If appropriate, compile and output a setup function to initialize them.
1668 Return a symbol_ref to the function to call to initialize the Objective C
1669 data structures for this file (and perhaps for other files also).
1671 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1674 build_module_descriptor ()
1676 tree decl_specs
, field_decl
, field_decl_chain
;
1678 objc_module_template
1679 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1683 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1684 field_decl
= get_identifier ("version");
1686 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1687 field_decl_chain
= field_decl
;
1691 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1692 field_decl
= get_identifier ("size");
1694 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1695 chainon (field_decl_chain
, field_decl
);
1699 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1700 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1702 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1703 chainon (field_decl_chain
, field_decl
);
1705 /* struct objc_symtab *symtab; */
1707 decl_specs
= get_identifier (UTAG_SYMTAB
);
1708 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1709 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1711 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1712 chainon (field_decl_chain
, field_decl
);
1714 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1716 /* Create an instance of "objc_module". */
1718 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1719 build_tree_list (NULL_TREE
,
1720 ridpointers
[(int) RID_STATIC
]));
1722 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1723 decl_specs
, 1, NULL_TREE
);
1725 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1726 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1727 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1729 finish_decl (UOBJC_MODULES_decl
,
1730 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1733 /* Mark the decl to avoid "defined but not used" warning. */
1734 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1736 /* Generate a constructor call for the module descriptor.
1737 This code was generated by reading the grammar rules
1738 of c-parse.in; Therefore, it may not be the most efficient
1739 way of generating the requisite code. */
1741 if (flag_next_runtime
)
1745 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1746 tree init_function_name
, init_function_decl
;
1748 /* Declare void __objc_execClass (void *); */
1750 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1751 execclass_decl
= build_decl (FUNCTION_DECL
,
1752 get_identifier (TAG_EXECCLASS
),
1753 build_function_type (void_type_node
,
1754 tree_cons (NULL_TREE
, ptr_type_node
,
1755 void_list_node_1
)));
1756 DECL_EXTERNAL (execclass_decl
) = 1;
1757 DECL_ARTIFICIAL (execclass_decl
) = 1;
1758 TREE_PUBLIC (execclass_decl
) = 1;
1759 pushdecl (execclass_decl
);
1760 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1761 assemble_external (execclass_decl
);
1763 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1765 init_function_name
= get_file_function_name ('I');
1766 start_function (void_list_node_1
,
1767 build_nt (CALL_EXPR
, init_function_name
,
1768 tree_cons (NULL_TREE
, NULL_TREE
,
1772 store_parm_decls ();
1774 init_function_decl
= current_function_decl
;
1775 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1776 TREE_USED (init_function_decl
) = 1;
1777 current_function_cannot_inline
1778 = "static constructors and destructors cannot be inlined";
1781 = build_tree_list (NULL_TREE
,
1782 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1783 decelerator
= build_function_call (execclass_decl
, parms
);
1785 c_expand_expr_stmt (decelerator
);
1787 finish_function (0);
1789 return XEXP (DECL_RTL (init_function_decl
), 0);
1793 /* extern const char _OBJC_STRINGS[]; */
1796 generate_forward_declaration_to_string_table ()
1798 tree sc_spec
, decl_specs
, expr_decl
;
1800 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1801 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1804 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1806 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1809 /* Return the DECL of the string IDENT in the SECTION. */
1812 get_objc_string_decl (ident
, section
)
1814 enum string_section section
;
1818 if (section
== class_names
)
1819 chain
= class_names_chain
;
1820 else if (section
== meth_var_names
)
1821 chain
= meth_var_names_chain
;
1822 else if (section
== meth_var_types
)
1823 chain
= meth_var_types_chain
;
1827 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1828 if (TREE_VALUE (chain
) == ident
)
1829 return (TREE_PURPOSE (chain
));
1835 /* Output references to all statically allocated objects. Return the DECL
1836 for the array built. */
1839 generate_static_references ()
1841 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1842 tree class_name
, class, decl
, initlist
;
1843 tree cl_chain
, in_chain
, type
;
1844 int num_inst
, num_class
;
1847 if (flag_next_runtime
)
1850 for (cl_chain
= objc_static_instances
, num_class
= 0;
1851 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1853 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1854 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1856 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1857 ident
= get_identifier (buf
);
1859 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1860 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1861 build_tree_list (NULL_TREE
,
1862 ridpointers
[(int) RID_STATIC
]));
1863 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1864 DECL_CONTEXT (decl
) = 0;
1865 DECL_ARTIFICIAL (decl
) = 1;
1867 /* Output {class_name, ...}. */
1868 class = TREE_VALUE (cl_chain
);
1869 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1870 initlist
= build_tree_list (NULL_TREE
,
1871 build_unary_op (ADDR_EXPR
, class_name
, 1));
1873 /* Output {..., instance, ...}. */
1874 for (in_chain
= TREE_PURPOSE (cl_chain
);
1875 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1877 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1878 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1881 /* Output {..., NULL}. */
1882 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1884 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1885 finish_decl (decl
, expr
, NULL_TREE
);
1886 TREE_USED (decl
) = 1;
1888 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1889 decl
= build_decl (VAR_DECL
, ident
, type
);
1890 TREE_USED (decl
) = 1;
1891 TREE_STATIC (decl
) = 1;
1893 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1896 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1897 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1898 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1899 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1900 build_tree_list (NULL_TREE
,
1901 ridpointers
[(int) RID_STATIC
]));
1902 static_instances_decl
1903 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1904 TREE_USED (static_instances_decl
) = 1;
1905 DECL_CONTEXT (static_instances_decl
) = 0;
1906 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1907 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1909 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1912 /* Output all strings. */
1917 tree sc_spec
, decl_specs
, expr_decl
;
1918 tree chain
, string_expr
;
1921 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1923 string
= TREE_VALUE (chain
);
1924 decl
= TREE_PURPOSE (chain
);
1926 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1927 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1928 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1929 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1930 DECL_CONTEXT (decl
) = NULL_TREE
;
1931 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1932 IDENTIFIER_POINTER (string
));
1933 finish_decl (decl
, string_expr
, NULL_TREE
);
1936 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1938 string
= TREE_VALUE (chain
);
1939 decl
= TREE_PURPOSE (chain
);
1941 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1942 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1943 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1944 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1945 DECL_CONTEXT (decl
) = NULL_TREE
;
1946 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1947 IDENTIFIER_POINTER (string
));
1948 finish_decl (decl
, string_expr
, NULL_TREE
);
1951 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1953 string
= TREE_VALUE (chain
);
1954 decl
= TREE_PURPOSE (chain
);
1956 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1957 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1958 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1959 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1960 DECL_CONTEXT (decl
) = NULL_TREE
;
1961 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1962 IDENTIFIER_POINTER (string
));
1963 finish_decl (decl
, string_expr
, NULL_TREE
);
1968 build_selector_reference_decl ()
1974 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1976 ident
= get_identifier (buf
);
1978 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1979 DECL_EXTERNAL (decl
) = 1;
1980 TREE_PUBLIC (decl
) = 1;
1981 TREE_USED (decl
) = 1;
1982 TREE_READONLY (decl
) = 1;
1983 DECL_ARTIFICIAL (decl
) = 1;
1984 DECL_CONTEXT (decl
) = 0;
1986 make_decl_rtl (decl
, 0);
1987 pushdecl_top_level (decl
);
1992 /* Just a handy wrapper for add_objc_string. */
1995 build_selector (ident
)
1998 tree expr
= add_objc_string (ident
, meth_var_names
);
1999 if (flag_typed_selectors
)
2002 return build_c_cast (selector_type
, expr
); /* cast! */
2006 build_selector_translation_table ()
2008 tree sc_spec
, decl_specs
;
2009 tree chain
, initlist
= NULL_TREE
;
2011 tree decl
= NULL_TREE
, var_decl
, name
;
2013 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2017 expr
= build_selector (TREE_VALUE (chain
));
2019 if (flag_next_runtime
)
2021 name
= DECL_NAME (TREE_PURPOSE (chain
));
2023 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2025 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2026 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2030 /* The `decl' that is returned from start_decl is the one that we
2031 forward declared in `build_selector_reference' */
2032 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2035 /* add one for the '\0' character */
2036 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2038 if (flag_next_runtime
)
2039 finish_decl (decl
, expr
, NULL_TREE
);
2042 if (flag_typed_selectors
)
2044 tree eltlist
= NULL_TREE
;
2045 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2046 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2047 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2048 expr
= build_constructor (objc_selector_template
,
2049 nreverse (eltlist
));
2051 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2056 if (! flag_next_runtime
)
2058 /* Cause the variable and its initial value to be actually output. */
2059 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2060 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2061 /* NULL terminate the list and fix the decl for output. */
2062 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2063 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2064 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2065 nreverse (initlist
));
2066 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2067 current_function_decl
= NULL_TREE
;
2072 get_proto_encoding (proto
)
2080 if (! METHOD_ENCODING (proto
))
2082 tmp_decl
= build_tmp_function_decl ();
2083 hack_method_prototype (proto
, tmp_decl
);
2084 encoding
= encode_method_prototype (proto
, tmp_decl
);
2085 METHOD_ENCODING (proto
) = encoding
;
2088 encoding
= METHOD_ENCODING (proto
);
2090 return add_objc_string (encoding
, meth_var_types
);
2093 return build_int_2 (0, 0);
2096 /* sel_ref_chain is a list whose "value" fields will be instances of
2097 identifier_node that represent the selector. */
2100 build_typed_selector_reference (ident
, proto
)
2103 tree
*chain
= &sel_ref_chain
;
2109 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2110 goto return_at_index
;
2113 chain
= &TREE_CHAIN (*chain
);
2116 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2119 expr
= build_unary_op (ADDR_EXPR
,
2120 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2121 build_int_2 (index
, 0)),
2123 return build_c_cast (selector_type
, expr
);
2127 build_selector_reference (ident
)
2130 tree
*chain
= &sel_ref_chain
;
2136 if (TREE_VALUE (*chain
) == ident
)
2137 return (flag_next_runtime
2138 ? TREE_PURPOSE (*chain
)
2139 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2140 build_int_2 (index
, 0)));
2143 chain
= &TREE_CHAIN (*chain
);
2146 expr
= build_selector_reference_decl ();
2148 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2150 return (flag_next_runtime
2152 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2153 build_int_2 (index
, 0)));
2157 build_class_reference_decl ()
2163 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2165 ident
= get_identifier (buf
);
2167 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2168 DECL_EXTERNAL (decl
) = 1;
2169 TREE_PUBLIC (decl
) = 1;
2170 TREE_USED (decl
) = 1;
2171 TREE_READONLY (decl
) = 1;
2172 DECL_CONTEXT (decl
) = 0;
2173 DECL_ARTIFICIAL (decl
) = 1;
2175 make_decl_rtl (decl
, 0);
2176 pushdecl_top_level (decl
);
2181 /* Create a class reference, but don't create a variable to reference
2185 add_class_reference (ident
)
2190 if ((chain
= cls_ref_chain
))
2195 if (ident
== TREE_VALUE (chain
))
2199 chain
= TREE_CHAIN (chain
);
2203 /* Append to the end of the list */
2204 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2207 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2210 /* Get a class reference, creating it if necessary. Also create the
2211 reference variable. */
2214 get_class_reference (ident
)
2217 if (flag_next_runtime
)
2222 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2223 if (TREE_VALUE (*chain
) == ident
)
2225 if (! TREE_PURPOSE (*chain
))
2226 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2228 return TREE_PURPOSE (*chain
);
2231 decl
= build_class_reference_decl ();
2232 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2239 add_class_reference (ident
);
2241 params
= build_tree_list (NULL_TREE
,
2242 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2243 IDENTIFIER_POINTER (ident
)));
2245 assemble_external (objc_get_class_decl
);
2246 return build_function_call (objc_get_class_decl
, params
);
2250 /* For each string section we have a chain which maps identifier nodes
2251 to decls for the strings. */
2254 add_objc_string (ident
, section
)
2256 enum string_section section
;
2260 if (section
== class_names
)
2261 chain
= &class_names_chain
;
2262 else if (section
== meth_var_names
)
2263 chain
= &meth_var_names_chain
;
2264 else if (section
== meth_var_types
)
2265 chain
= &meth_var_types_chain
;
2271 if (TREE_VALUE (*chain
) == ident
)
2272 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2274 chain
= &TREE_CHAIN (*chain
);
2277 decl
= build_objc_string_decl (section
);
2279 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2281 return build_unary_op (ADDR_EXPR
, decl
, 1);
2285 build_objc_string_decl (section
)
2286 enum string_section section
;
2290 static int class_names_idx
= 0;
2291 static int meth_var_names_idx
= 0;
2292 static int meth_var_types_idx
= 0;
2294 if (section
== class_names
)
2295 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2296 else if (section
== meth_var_names
)
2297 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2298 else if (section
== meth_var_types
)
2299 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2301 ident
= get_identifier (buf
);
2303 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2304 DECL_EXTERNAL (decl
) = 1;
2305 TREE_PUBLIC (decl
) = 1;
2306 TREE_USED (decl
) = 1;
2307 TREE_READONLY (decl
) = 1;
2308 TREE_CONSTANT (decl
) = 1;
2309 DECL_CONTEXT (decl
) = 0;
2310 DECL_ARTIFICIAL (decl
) = 1;
2312 make_decl_rtl (decl
, 0);
2313 pushdecl_top_level (decl
);
2320 objc_declare_alias (alias_ident
, class_ident
)
2324 if (is_class_name (class_ident
) != class_ident
)
2325 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2326 else if (is_class_name (alias_ident
))
2327 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2329 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2333 objc_declare_class (ident_list
)
2338 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2340 tree ident
= TREE_VALUE (list
);
2343 if ((decl
= lookup_name (ident
)))
2345 error ("`%s' redeclared as different kind of symbol",
2346 IDENTIFIER_POINTER (ident
));
2347 error_with_decl (decl
, "previous declaration of `%s'");
2350 if (! is_class_name (ident
))
2352 tree record
= xref_tag (RECORD_TYPE
, ident
);
2353 TREE_STATIC_TEMPLATE (record
) = 1;
2354 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2360 is_class_name (ident
)
2365 if (lookup_interface (ident
))
2368 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2370 if (ident
== TREE_VALUE (chain
))
2374 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2376 if (ident
== TREE_VALUE (chain
))
2377 return TREE_PURPOSE (chain
);
2384 lookup_interface (ident
)
2389 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2391 if (ident
== CLASS_NAME (chain
))
2398 objc_copy_list (list
, head
)
2402 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2406 tail
= copy_node (list
);
2408 /* The following statement fixes a bug when inheriting instance
2409 variables that are declared to be bitfields. finish_struct
2410 expects to find the width of the bitfield in DECL_INITIAL. */
2411 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2412 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2414 newlist
= chainon (newlist
, tail
);
2415 list
= TREE_CHAIN (list
);
2422 /* Used by: build_private_template, get_class_ivars, and
2423 continue_class. COPY is 1 when called from @defs. In this case
2424 copy all fields. Otherwise don't copy leaf ivars since we rely on
2425 them being side-effected exactly once by finish_struct. */
2428 build_ivar_chain (interface
, copy
)
2432 tree my_name
, super_name
, ivar_chain
;
2434 my_name
= CLASS_NAME (interface
);
2435 super_name
= CLASS_SUPER_NAME (interface
);
2437 /* Possibly copy leaf ivars. */
2439 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2441 ivar_chain
= CLASS_IVARS (interface
);
2446 tree super_interface
= lookup_interface (super_name
);
2448 if (!super_interface
)
2450 /* fatal did not work with 2 args...should fix */
2451 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2452 IDENTIFIER_POINTER (super_name
),
2453 IDENTIFIER_POINTER (my_name
));
2454 exit (FATAL_EXIT_CODE
);
2457 if (super_interface
== interface
)
2458 fatal_error ("Circular inheritance in interface declaration for `%s'",
2459 IDENTIFIER_POINTER (super_name
));
2461 interface
= super_interface
;
2462 my_name
= CLASS_NAME (interface
);
2463 super_name
= CLASS_SUPER_NAME (interface
);
2465 op1
= CLASS_IVARS (interface
);
2468 tree head
, tail
= objc_copy_list (op1
, &head
);
2470 /* Prepend super class ivars...make a copy of the list, we
2471 do not want to alter the original. */
2472 TREE_CHAIN (tail
) = ivar_chain
;
2479 /* struct <classname> {
2480 struct objc_class *isa;
2485 build_private_template (class)
2490 if (CLASS_STATIC_TEMPLATE (class))
2492 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2493 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2497 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2499 ivar_context
= build_ivar_chain (class, 0);
2501 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2503 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2505 /* mark this record as class template - for class type checking */
2506 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2510 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2512 build1 (INDIRECT_REF
, NULL_TREE
,
2515 return ivar_context
;
2518 /* Begin code generation for protocols... */
2520 /* struct objc_protocol {
2521 char *protocol_name;
2522 struct objc_protocol **protocol_list;
2523 struct objc_method_desc *instance_methods;
2524 struct objc_method_desc *class_methods;
2528 build_protocol_template ()
2530 tree decl_specs
, field_decl
, field_decl_chain
;
2533 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2535 /* struct objc_class *isa; */
2537 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2538 get_identifier (UTAG_CLASS
)));
2539 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2541 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2542 field_decl_chain
= field_decl
;
2544 /* char *protocol_name; */
2546 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2548 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2550 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2551 chainon (field_decl_chain
, field_decl
);
2553 /* struct objc_protocol **protocol_list; */
2555 decl_specs
= build_tree_list (NULL_TREE
, template);
2557 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2558 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2560 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2561 chainon (field_decl_chain
, field_decl
);
2563 /* struct objc_method_list *instance_methods; */
2566 = build_tree_list (NULL_TREE
,
2567 xref_tag (RECORD_TYPE
,
2568 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2570 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2572 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2573 chainon (field_decl_chain
, field_decl
);
2575 /* struct objc_method_list *class_methods; */
2578 = build_tree_list (NULL_TREE
,
2579 xref_tag (RECORD_TYPE
,
2580 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2582 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2584 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2585 chainon (field_decl_chain
, field_decl
);
2587 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2591 build_descriptor_table_initializer (type
, entries
)
2595 tree initlist
= NULL_TREE
;
2599 tree eltlist
= NULL_TREE
;
2602 = tree_cons (NULL_TREE
,
2603 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2605 = tree_cons (NULL_TREE
,
2606 add_objc_string (METHOD_ENCODING (entries
),
2611 = tree_cons (NULL_TREE
,
2612 build_constructor (type
, nreverse (eltlist
)), initlist
);
2614 entries
= TREE_CHAIN (entries
);
2618 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2621 /* struct objc_method_prototype_list {
2623 struct objc_method_prototype {
2630 build_method_prototype_list_template (list_type
, size
)
2634 tree objc_ivar_list_record
;
2635 tree decl_specs
, field_decl
, field_decl_chain
;
2637 /* Generate an unnamed struct definition. */
2639 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2641 /* int method_count; */
2643 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2644 field_decl
= get_identifier ("method_count");
2647 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2648 field_decl_chain
= field_decl
;
2650 /* struct objc_method method_list[]; */
2652 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2653 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2654 build_int_2 (size
, 0));
2657 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2658 chainon (field_decl_chain
, field_decl
);
2660 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2662 return objc_ivar_list_record
;
2666 build_method_prototype_template ()
2669 tree decl_specs
, field_decl
, field_decl_chain
;
2672 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2674 /* struct objc_selector *_cmd; */
2675 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2676 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2677 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2680 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2681 field_decl_chain
= field_decl
;
2683 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2685 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2687 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2688 chainon (field_decl_chain
, field_decl
);
2690 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2692 return proto_record
;
2695 /* True if last call to forwarding_offset yielded a register offset. */
2696 static int offset_is_register
;
2699 forwarding_offset (parm
)
2702 int offset_in_bytes
;
2704 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2706 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2708 /* ??? Here we assume that the parm address is indexed
2709 off the frame pointer or arg pointer.
2710 If that is not true, we produce meaningless results,
2711 but do not crash. */
2712 if (GET_CODE (addr
) == PLUS
2713 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2714 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2716 offset_in_bytes
= 0;
2718 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2719 offset_is_register
= 0;
2721 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2723 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2724 offset_in_bytes
= apply_args_register_offset (regno
);
2725 offset_is_register
= 1;
2730 /* This is the case where the parm is passed as an int or double
2731 and it is converted to a char, short or float and stored back
2732 in the parmlist. In this case, describe the parm
2733 with the variable's declared type, and adjust the address
2734 if the least significant bytes (which we are using) are not
2736 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2737 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2738 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2740 return offset_in_bytes
;
2744 encode_method_prototype (method_decl
, func_decl
)
2751 HOST_WIDE_INT max_parm_end
= 0;
2755 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2756 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2759 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2760 obstack_object_size (&util_obstack
),
2761 OBJC_ENCODE_INLINE_DEFS
);
2764 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2765 parms
= TREE_CHAIN (parms
))
2767 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2768 + int_size_in_bytes (TREE_TYPE (parms
)));
2770 if (!offset_is_register
&& max_parm_end
< parm_end
)
2771 max_parm_end
= parm_end
;
2774 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2776 sprintf (buf
, "%d", stack_size
);
2777 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2779 user_args
= METHOD_SEL_ARGS (method_decl
);
2781 /* Argument types. */
2782 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2783 parms
= TREE_CHAIN (parms
), i
++)
2785 /* Process argument qualifiers for user supplied arguments. */
2788 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2789 user_args
= TREE_CHAIN (user_args
);
2793 encode_type (TREE_TYPE (parms
),
2794 obstack_object_size (&util_obstack
),
2795 OBJC_ENCODE_INLINE_DEFS
);
2797 /* Compute offset. */
2798 sprintf (buf
, "%d", forwarding_offset (parms
));
2800 /* Indicate register. */
2801 if (offset_is_register
)
2802 obstack_1grow (&util_obstack
, '+');
2804 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2807 obstack_1grow (&util_obstack
, '\0');
2808 result
= get_identifier (obstack_finish (&util_obstack
));
2809 obstack_free (&util_obstack
, util_firstobj
);
2814 generate_descriptor_table (type
, name
, size
, list
, proto
)
2821 tree sc_spec
, decl_specs
, decl
, initlist
;
2823 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2824 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2826 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2827 decl_specs
, 1, NULL_TREE
);
2828 DECL_CONTEXT (decl
) = NULL_TREE
;
2830 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2831 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2833 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2840 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2843 tree initlist
, chain
, method_list_template
;
2844 tree cast
, variable_length_type
;
2847 if (!objc_method_prototype_template
)
2849 objc_method_prototype_template
= build_method_prototype_template ();
2852 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2853 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2855 variable_length_type
= groktypename (cast
);
2857 chain
= PROTOCOL_CLS_METHODS (protocol
);
2860 size
= list_length (chain
);
2862 method_list_template
2863 = build_method_prototype_list_template (objc_method_prototype_template
,
2867 = build_descriptor_table_initializer (objc_method_prototype_template
,
2870 UOBJC_CLASS_METHODS_decl
2871 = generate_descriptor_table (method_list_template
,
2872 "_OBJC_PROTOCOL_CLASS_METHODS",
2873 size
, initlist
, protocol
);
2874 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2877 UOBJC_CLASS_METHODS_decl
= 0;
2879 chain
= PROTOCOL_NST_METHODS (protocol
);
2882 size
= list_length (chain
);
2884 method_list_template
2885 = build_method_prototype_list_template (objc_method_prototype_template
,
2888 = build_descriptor_table_initializer (objc_method_prototype_template
,
2891 UOBJC_INSTANCE_METHODS_decl
2892 = generate_descriptor_table (method_list_template
,
2893 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2894 size
, initlist
, protocol
);
2895 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2898 UOBJC_INSTANCE_METHODS_decl
= 0;
2901 /* Generate a temporary FUNCTION_DECL node to be used in
2902 hack_method_prototype below. */
2905 build_tmp_function_decl ()
2907 tree decl_specs
, expr_decl
, parms
;
2911 /* struct objc_object *objc_xxx (id, SEL, ...); */
2913 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2914 push_parm_decl (build_tree_list
2915 (build_tree_list (decl_specs
,
2916 build1 (INDIRECT_REF
, NULL_TREE
,
2920 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2921 get_identifier (TAG_SELECTOR
)));
2922 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2924 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2926 parms
= get_parm_info (0);
2929 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2930 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2931 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2932 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2934 return define_decl (expr_decl
, decl_specs
);
2937 /* Generate the prototypes for protocol methods. This is used to
2938 generate method encodings for these.
2940 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2941 a decl node to be used. This is also where the return value is
2945 hack_method_prototype (nst_methods
, tmp_decl
)
2952 /* Hack to avoid problem with static typing of self arg. */
2953 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2954 start_method_def (nst_methods
);
2955 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2957 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2958 parms
= get_parm_info (0); /* we have a `, ...' */
2960 parms
= get_parm_info (1); /* place a `void_at_end' */
2962 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2964 /* Usually called from store_parm_decls -> init_function_start. */
2966 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2967 current_function_decl
= tmp_decl
;
2970 /* Code taken from start_function. */
2971 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2972 /* Promote the value to int before returning it. */
2973 if (TREE_CODE (restype
) == INTEGER_TYPE
2974 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2975 restype
= integer_type_node
;
2976 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2979 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2980 DECL_CONTEXT (parm
) = tmp_decl
;
2982 init_function_start (tmp_decl
, "objc-act", 0);
2984 /* Typically called from expand_function_start for function definitions. */
2985 assign_parms (tmp_decl
);
2987 /* install return type */
2988 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2993 generate_protocol_references (plist
)
2998 /* Forward declare protocols referenced. */
2999 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3001 tree proto
= TREE_VALUE (lproto
);
3003 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3004 && PROTOCOL_NAME (proto
))
3006 if (! PROTOCOL_FORWARD_DECL (proto
))
3007 build_protocol_reference (proto
);
3009 if (PROTOCOL_LIST (proto
))
3010 generate_protocol_references (PROTOCOL_LIST (proto
));
3016 generate_protocols ()
3018 tree p
, tmp_decl
, encoding
;
3019 tree sc_spec
, decl_specs
, decl
;
3020 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3023 tmp_decl
= build_tmp_function_decl ();
3025 if (! objc_protocol_template
)
3026 objc_protocol_template
= build_protocol_template ();
3028 /* If a protocol was directly referenced, pull in indirect references. */
3029 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3030 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3031 generate_protocol_references (PROTOCOL_LIST (p
));
3033 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3035 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3036 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3038 /* If protocol wasn't referenced, don't generate any code. */
3039 if (! PROTOCOL_FORWARD_DECL (p
))
3042 /* Make sure we link in the Protocol class. */
3043 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3047 if (! METHOD_ENCODING (nst_methods
))
3049 hack_method_prototype (nst_methods
, tmp_decl
);
3050 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3051 METHOD_ENCODING (nst_methods
) = encoding
;
3053 nst_methods
= TREE_CHAIN (nst_methods
);
3058 if (! METHOD_ENCODING (cls_methods
))
3060 hack_method_prototype (cls_methods
, tmp_decl
);
3061 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3062 METHOD_ENCODING (cls_methods
) = encoding
;
3065 cls_methods
= TREE_CHAIN (cls_methods
);
3067 generate_method_descriptors (p
);
3069 if (PROTOCOL_LIST (p
))
3070 refs_decl
= generate_protocol_list (p
);
3074 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3076 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3078 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3080 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3081 decl_specs
, 1, NULL_TREE
);
3083 DECL_CONTEXT (decl
) = NULL_TREE
;
3085 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3091 (build_tree_list (build_tree_list (NULL_TREE
,
3092 objc_protocol_template
),
3093 build1 (INDIRECT_REF
, NULL_TREE
,
3094 build1 (INDIRECT_REF
, NULL_TREE
,
3097 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3098 TREE_TYPE (refs_expr
) = cast_type2
;
3101 refs_expr
= build_int_2 (0, 0);
3103 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3104 by generate_method_descriptors, which is called above. */
3105 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3106 protocol_name_expr
, refs_expr
,
3107 UOBJC_INSTANCE_METHODS_decl
,
3108 UOBJC_CLASS_METHODS_decl
);
3109 finish_decl (decl
, initlist
, NULL_TREE
);
3111 /* Mark the decl as used to avoid "defined but not used" warning. */
3112 TREE_USED (decl
) = 1;
3117 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3118 instance_methods
, class_methods
)
3122 tree instance_methods
;
3125 tree initlist
= NULL_TREE
, expr
;
3128 cast_type
= groktypename
3130 (build_tree_list (NULL_TREE
,
3131 xref_tag (RECORD_TYPE
,
3132 get_identifier (UTAG_CLASS
))),
3133 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3135 /* Filling the "isa" in with one allows the runtime system to
3136 detect that the version change...should remove before final release. */
3138 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3139 TREE_TYPE (expr
) = cast_type
;
3140 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3141 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3142 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3144 if (!instance_methods
)
3145 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3148 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3149 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3153 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3156 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3157 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3160 return build_constructor (type
, nreverse (initlist
));
3163 /* struct objc_category {
3164 char *category_name;
3166 struct objc_method_list *instance_methods;
3167 struct objc_method_list *class_methods;
3168 struct objc_protocol_list *protocols;
3172 build_category_template ()
3174 tree decl_specs
, field_decl
, field_decl_chain
;
3176 objc_category_template
= start_struct (RECORD_TYPE
,
3177 get_identifier (UTAG_CATEGORY
));
3178 /* char *category_name; */
3180 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3182 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3184 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3185 field_decl_chain
= field_decl
;
3187 /* char *class_name; */
3189 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3190 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3192 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3193 chainon (field_decl_chain
, field_decl
);
3195 /* struct objc_method_list *instance_methods; */
3197 decl_specs
= build_tree_list (NULL_TREE
,
3198 xref_tag (RECORD_TYPE
,
3199 get_identifier (UTAG_METHOD_LIST
)));
3201 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3203 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3204 chainon (field_decl_chain
, field_decl
);
3206 /* struct objc_method_list *class_methods; */
3208 decl_specs
= build_tree_list (NULL_TREE
,
3209 xref_tag (RECORD_TYPE
,
3210 get_identifier (UTAG_METHOD_LIST
)));
3212 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3214 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3215 chainon (field_decl_chain
, field_decl
);
3217 /* struct objc_protocol **protocol_list; */
3219 decl_specs
= build_tree_list (NULL_TREE
,
3220 xref_tag (RECORD_TYPE
,
3221 get_identifier (UTAG_PROTOCOL
)));
3223 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3224 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3226 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3227 chainon (field_decl_chain
, field_decl
);
3229 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3232 /* struct objc_selector {
3238 build_selector_template ()
3241 tree decl_specs
, field_decl
, field_decl_chain
;
3243 objc_selector_template
3244 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3248 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3249 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3251 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3252 field_decl_chain
= field_decl
;
3254 /* char *sel_type; */
3256 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3257 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3259 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3260 chainon (field_decl_chain
, field_decl
);
3262 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3265 /* struct objc_class {
3266 struct objc_class *isa;
3267 struct objc_class *super_class;
3272 struct objc_ivar_list *ivars;
3273 struct objc_method_list *methods;
3274 if (flag_next_runtime)
3275 struct objc_cache *cache;
3277 struct sarray *dtable;
3278 struct objc_class *subclass_list;
3279 struct objc_class *sibling_class;
3281 struct objc_protocol_list *protocols;
3282 void *gc_object_type;
3286 build_class_template ()
3288 tree decl_specs
, field_decl
, field_decl_chain
;
3291 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3293 /* struct objc_class *isa; */
3295 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3296 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3298 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3299 field_decl_chain
= field_decl
;
3301 /* struct objc_class *super_class; */
3303 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3305 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3307 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3308 chainon (field_decl_chain
, field_decl
);
3312 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3313 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
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_LONG
]);
3321 field_decl
= get_identifier ("version");
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 ("info");
3331 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3332 chainon (field_decl_chain
, field_decl
);
3334 /* long instance_size; */
3336 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3337 field_decl
= get_identifier ("instance_size");
3339 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3340 chainon (field_decl_chain
, field_decl
);
3342 /* struct objc_ivar_list *ivars; */
3344 decl_specs
= build_tree_list (NULL_TREE
,
3345 xref_tag (RECORD_TYPE
,
3346 get_identifier (UTAG_IVAR_LIST
)));
3347 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3349 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3350 chainon (field_decl_chain
, field_decl
);
3352 /* struct objc_method_list *methods; */
3354 decl_specs
= build_tree_list (NULL_TREE
,
3355 xref_tag (RECORD_TYPE
,
3356 get_identifier (UTAG_METHOD_LIST
)));
3357 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3359 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3360 chainon (field_decl_chain
, field_decl
);
3362 if (flag_next_runtime
)
3364 /* struct objc_cache *cache; */
3366 decl_specs
= build_tree_list (NULL_TREE
,
3367 xref_tag (RECORD_TYPE
,
3368 get_identifier ("objc_cache")));
3369 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3370 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3371 decl_specs
, NULL_TREE
);
3372 chainon (field_decl_chain
, field_decl
);
3376 /* struct sarray *dtable; */
3378 decl_specs
= build_tree_list (NULL_TREE
,
3379 xref_tag (RECORD_TYPE
,
3380 get_identifier ("sarray")));
3381 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3382 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3383 decl_specs
, NULL_TREE
);
3384 chainon (field_decl_chain
, field_decl
);
3386 /* struct objc_class *subclass_list; */
3388 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3390 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3391 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3392 decl_specs
, NULL_TREE
);
3393 chainon (field_decl_chain
, field_decl
);
3395 /* struct objc_class *sibling_class; */
3397 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3399 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3400 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3401 decl_specs
, NULL_TREE
);
3402 chainon (field_decl_chain
, field_decl
);
3405 /* struct objc_protocol **protocol_list; */
3407 decl_specs
= build_tree_list (NULL_TREE
,
3408 xref_tag (RECORD_TYPE
,
3409 get_identifier (UTAG_PROTOCOL
)));
3411 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3413 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3414 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3415 decl_specs
, NULL_TREE
);
3416 chainon (field_decl_chain
, field_decl
);
3420 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3421 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3423 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3424 chainon (field_decl_chain
, field_decl
);
3426 /* void *gc_object_type; */
3428 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3429 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3431 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3432 chainon (field_decl_chain
, field_decl
);
3434 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3437 /* Generate appropriate forward declarations for an implementation. */
3440 synth_forward_declarations ()
3442 tree sc_spec
, decl_specs
, an_id
;
3444 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3446 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3448 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3449 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3450 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3451 TREE_USED (UOBJC_CLASS_decl
) = 1;
3452 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3454 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3456 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3457 objc_implementation_context
);
3459 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3460 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3461 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3463 /* Pre-build the following entities - for speed/convenience. */
3465 an_id
= get_identifier ("super_class");
3466 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3467 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3471 error_with_ivar (message
, decl
, rawdecl
)
3472 const char *message
;
3478 report_error_function (DECL_SOURCE_FILE (decl
));
3480 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3481 DECL_SOURCE_LINE (decl
),
3483 message
, gen_declaration (rawdecl
, errbuf
));
3487 #define USERTYPE(t) \
3488 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3489 || TREE_CODE (t) == ENUMERAL_TYPE)
3492 check_ivars (inter
, imp
)
3496 tree intdecls
= CLASS_IVARS (inter
);
3497 tree impdecls
= CLASS_IVARS (imp
);
3498 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3499 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3505 if (intdecls
== 0 && impdecls
== 0)
3507 if (intdecls
== 0 || impdecls
== 0)
3509 error ("inconsistent instance variable specification");
3513 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3515 if (!comptypes (t1
, t2
))
3517 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3519 error_with_ivar ("conflicting instance variable type",
3520 impdecls
, rawimpdecls
);
3521 error_with_ivar ("previous declaration of",
3522 intdecls
, rawintdecls
);
3524 else /* both the type and the name don't match */
3526 error ("inconsistent instance variable specification");
3531 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3533 error_with_ivar ("conflicting instance variable name",
3534 impdecls
, rawimpdecls
);
3535 error_with_ivar ("previous declaration of",
3536 intdecls
, rawintdecls
);
3539 intdecls
= TREE_CHAIN (intdecls
);
3540 impdecls
= TREE_CHAIN (impdecls
);
3541 rawintdecls
= TREE_CHAIN (rawintdecls
);
3542 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3546 /* Set super_type to the data type node for struct objc_super *,
3547 first defining struct objc_super itself.
3548 This needs to be done just once per compilation. */
3551 build_super_template ()
3553 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3555 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3557 /* struct objc_object *self; */
3559 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3560 field_decl
= get_identifier ("self");
3561 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3562 field_decl
= grokfield (input_filename
, lineno
,
3563 field_decl
, decl_specs
, NULL_TREE
);
3564 field_decl_chain
= field_decl
;
3566 /* struct objc_class *class; */
3568 decl_specs
= get_identifier (UTAG_CLASS
);
3569 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3570 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3572 field_decl
= grokfield (input_filename
, lineno
,
3573 field_decl
, decl_specs
, NULL_TREE
);
3574 chainon (field_decl_chain
, field_decl
);
3576 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3578 /* `struct objc_super *' */
3579 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3581 build1 (INDIRECT_REF
,
3582 NULL_TREE
, NULL_TREE
)));
3586 /* struct objc_ivar {
3593 build_ivar_template ()
3595 tree objc_ivar_id
, objc_ivar_record
;
3596 tree decl_specs
, field_decl
, field_decl_chain
;
3598 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3599 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3601 /* char *ivar_name; */
3603 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3604 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3606 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3607 decl_specs
, NULL_TREE
);
3608 field_decl_chain
= field_decl
;
3610 /* char *ivar_type; */
3612 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3613 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3615 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3616 decl_specs
, NULL_TREE
);
3617 chainon (field_decl_chain
, field_decl
);
3619 /* int ivar_offset; */
3621 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3622 field_decl
= get_identifier ("ivar_offset");
3624 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3625 decl_specs
, NULL_TREE
);
3626 chainon (field_decl_chain
, field_decl
);
3628 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3630 return objc_ivar_record
;
3635 struct objc_ivar ivar_list[ivar_count];
3639 build_ivar_list_template (list_type
, size
)
3643 tree objc_ivar_list_record
;
3644 tree decl_specs
, field_decl
, field_decl_chain
;
3646 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3648 /* int ivar_count; */
3650 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3651 field_decl
= get_identifier ("ivar_count");
3653 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3654 decl_specs
, NULL_TREE
);
3655 field_decl_chain
= field_decl
;
3657 /* struct objc_ivar ivar_list[]; */
3659 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3660 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3661 build_int_2 (size
, 0));
3663 field_decl
= grokfield (input_filename
, lineno
,
3664 field_decl
, decl_specs
, NULL_TREE
);
3665 chainon (field_decl_chain
, field_decl
);
3667 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3669 return objc_ivar_list_record
;
3675 struct objc_method method_list[method_count];
3679 build_method_list_template (list_type
, size
)
3683 tree objc_ivar_list_record
;
3684 tree decl_specs
, field_decl
, field_decl_chain
;
3686 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3688 /* int method_next; */
3693 xref_tag (RECORD_TYPE
,
3694 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3696 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3697 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3698 decl_specs
, NULL_TREE
);
3699 field_decl_chain
= field_decl
;
3701 /* int method_count; */
3703 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3704 field_decl
= get_identifier ("method_count");
3706 field_decl
= grokfield (input_filename
, lineno
,
3707 field_decl
, decl_specs
, NULL_TREE
);
3708 chainon (field_decl_chain
, field_decl
);
3710 /* struct objc_method method_list[]; */
3712 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3713 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3714 build_int_2 (size
, 0));
3716 field_decl
= grokfield (input_filename
, lineno
,
3717 field_decl
, decl_specs
, NULL_TREE
);
3718 chainon (field_decl_chain
, field_decl
);
3720 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3722 return objc_ivar_list_record
;
3726 build_ivar_list_initializer (type
, field_decl
)
3730 tree initlist
= NULL_TREE
;
3734 tree ivar
= NULL_TREE
;
3737 if (DECL_NAME (field_decl
))
3738 ivar
= tree_cons (NULL_TREE
,
3739 add_objc_string (DECL_NAME (field_decl
),
3743 /* Unnamed bit-field ivar (yuck). */
3744 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3747 encode_field_decl (field_decl
,
3748 obstack_object_size (&util_obstack
),
3749 OBJC_ENCODE_DONT_INLINE_DEFS
);
3751 /* Null terminate string. */
3752 obstack_1grow (&util_obstack
, 0);
3756 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3759 obstack_free (&util_obstack
, util_firstobj
);
3762 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3763 initlist
= tree_cons (NULL_TREE
,
3764 build_constructor (type
, nreverse (ivar
)),
3767 field_decl
= TREE_CHAIN (field_decl
);
3771 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3775 generate_ivars_list (type
, name
, size
, list
)
3781 tree sc_spec
, decl_specs
, decl
, initlist
;
3783 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3784 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3786 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3787 decl_specs
, 1, NULL_TREE
);
3789 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3790 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3793 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3800 generate_ivar_lists ()
3802 tree initlist
, ivar_list_template
, chain
;
3803 tree cast
, variable_length_type
;
3806 generating_instance_variables
= 1;
3808 if (!objc_ivar_template
)
3809 objc_ivar_template
= build_ivar_template ();
3813 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3814 get_identifier (UTAG_IVAR_LIST
))),
3816 variable_length_type
= groktypename (cast
);
3818 /* Only generate class variables for the root of the inheritance
3819 hierarchy since these will be the same for every class. */
3821 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3822 && (chain
= TYPE_FIELDS (objc_class_template
)))
3824 size
= list_length (chain
);
3826 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3827 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3829 UOBJC_CLASS_VARIABLES_decl
3830 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3832 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3835 UOBJC_CLASS_VARIABLES_decl
= 0;
3837 chain
= CLASS_IVARS (implementation_template
);
3840 size
= list_length (chain
);
3841 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3842 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3844 UOBJC_INSTANCE_VARIABLES_decl
3845 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3847 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3850 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3852 generating_instance_variables
= 0;
3856 build_dispatch_table_initializer (type
, entries
)
3860 tree initlist
= NULL_TREE
;
3864 tree elemlist
= NULL_TREE
;
3866 elemlist
= tree_cons (NULL_TREE
,
3867 build_selector (METHOD_SEL_NAME (entries
)),
3870 elemlist
= tree_cons (NULL_TREE
,
3871 add_objc_string (METHOD_ENCODING (entries
),
3875 elemlist
= tree_cons (NULL_TREE
,
3876 build_unary_op (ADDR_EXPR
,
3877 METHOD_DEFINITION (entries
), 1),
3880 initlist
= tree_cons (NULL_TREE
,
3881 build_constructor (type
, nreverse (elemlist
)),
3884 entries
= TREE_CHAIN (entries
);
3888 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3891 /* To accomplish method prototyping without generating all kinds of
3892 inane warnings, the definition of the dispatch table entries were
3895 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3897 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3900 build_method_template ()
3903 tree decl_specs
, field_decl
, field_decl_chain
;
3905 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3907 /* struct objc_selector *_cmd; */
3908 decl_specs
= tree_cons (NULL_TREE
,
3909 xref_tag (RECORD_TYPE
,
3910 get_identifier (TAG_SELECTOR
)),
3912 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3914 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3915 decl_specs
, NULL_TREE
);
3916 field_decl_chain
= field_decl
;
3918 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3919 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3920 get_identifier ("method_types"));
3921 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3922 decl_specs
, NULL_TREE
);
3923 chainon (field_decl_chain
, field_decl
);
3927 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3928 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3929 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3930 decl_specs
, NULL_TREE
);
3931 chainon (field_decl_chain
, field_decl
);
3933 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3940 generate_dispatch_table (type
, name
, size
, list
)
3946 tree sc_spec
, decl_specs
, decl
, initlist
;
3948 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3949 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3951 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3952 decl_specs
, 1, NULL_TREE
);
3954 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3955 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3956 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3959 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3966 generate_dispatch_tables ()
3968 tree initlist
, chain
, method_list_template
;
3969 tree cast
, variable_length_type
;
3972 if (!objc_method_template
)
3973 objc_method_template
= build_method_template ();
3977 (build_tree_list (NULL_TREE
,
3978 xref_tag (RECORD_TYPE
,
3979 get_identifier (UTAG_METHOD_LIST
))),
3982 variable_length_type
= groktypename (cast
);
3984 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3987 size
= list_length (chain
);
3989 method_list_template
3990 = build_method_list_template (objc_method_template
, size
);
3992 = build_dispatch_table_initializer (objc_method_template
, chain
);
3994 UOBJC_CLASS_METHODS_decl
3995 = generate_dispatch_table (method_list_template
,
3996 ((TREE_CODE (objc_implementation_context
)
3997 == CLASS_IMPLEMENTATION_TYPE
)
3998 ? "_OBJC_CLASS_METHODS"
3999 : "_OBJC_CATEGORY_CLASS_METHODS"),
4001 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4004 UOBJC_CLASS_METHODS_decl
= 0;
4006 chain
= CLASS_NST_METHODS (objc_implementation_context
);
4009 size
= list_length (chain
);
4011 method_list_template
4012 = build_method_list_template (objc_method_template
, size
);
4014 = build_dispatch_table_initializer (objc_method_template
, chain
);
4016 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4017 UOBJC_INSTANCE_METHODS_decl
4018 = generate_dispatch_table (method_list_template
,
4019 "_OBJC_INSTANCE_METHODS",
4022 /* We have a category. */
4023 UOBJC_INSTANCE_METHODS_decl
4024 = generate_dispatch_table (method_list_template
,
4025 "_OBJC_CATEGORY_INSTANCE_METHODS",
4027 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4030 UOBJC_INSTANCE_METHODS_decl
= 0;
4034 generate_protocol_list (i_or_p
)
4037 tree initlist
, decl_specs
, sc_spec
;
4038 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4042 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4043 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4044 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4045 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4046 plist
= PROTOCOL_LIST (i_or_p
);
4050 cast_type
= groktypename
4052 (build_tree_list (NULL_TREE
,
4053 xref_tag (RECORD_TYPE
,
4054 get_identifier (UTAG_PROTOCOL
))),
4055 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4058 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4059 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4060 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4063 /* Build initializer. */
4064 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4066 e
= build_int_2 (size
, 0);
4067 TREE_TYPE (e
) = cast_type
;
4068 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4070 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4072 tree pval
= TREE_VALUE (lproto
);
4074 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4075 && PROTOCOL_FORWARD_DECL (pval
))
4077 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4078 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4082 /* static struct objc_protocol *refs[n]; */
4084 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4085 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4086 get_identifier (UTAG_PROTOCOL
)),
4089 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4090 expr_decl
= build_nt (ARRAY_REF
,
4091 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4093 build_int_2 (size
+ 2, 0));
4094 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4095 expr_decl
= build_nt (ARRAY_REF
,
4096 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4098 build_int_2 (size
+ 2, 0));
4099 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4101 = build_nt (ARRAY_REF
,
4102 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4104 build_int_2 (size
+ 2, 0));
4108 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4110 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4111 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4113 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4114 nreverse (initlist
)),
4121 build_category_initializer (type
, cat_name
, class_name
,
4122 instance_methods
, class_methods
, protocol_list
)
4126 tree instance_methods
;
4130 tree initlist
= NULL_TREE
, expr
;
4132 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4133 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4135 if (!instance_methods
)
4136 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4139 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4140 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4143 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4146 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4147 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4150 /* protocol_list = */
4152 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4155 tree cast_type2
= groktypename
4157 (build_tree_list (NULL_TREE
,
4158 xref_tag (RECORD_TYPE
,
4159 get_identifier (UTAG_PROTOCOL
))),
4160 build1 (INDIRECT_REF
, NULL_TREE
,
4161 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4163 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4164 TREE_TYPE (expr
) = cast_type2
;
4165 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4168 return build_constructor (type
, nreverse (initlist
));
4171 /* struct objc_class {
4172 struct objc_class *isa;
4173 struct objc_class *super_class;
4178 struct objc_ivar_list *ivars;
4179 struct objc_method_list *methods;
4180 if (flag_next_runtime)
4181 struct objc_cache *cache;
4183 struct sarray *dtable;
4184 struct objc_class *subclass_list;
4185 struct objc_class *sibling_class;
4187 struct objc_protocol_list *protocols;
4188 void *gc_object_type;
4192 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4193 dispatch_table
, ivar_list
, protocol_list
)
4200 tree dispatch_table
;
4204 tree initlist
= NULL_TREE
, expr
;
4207 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4210 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4213 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4216 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4219 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4221 /* instance_size = */
4222 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4224 /* objc_ivar_list = */
4226 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4229 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4230 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4233 /* objc_method_list = */
4234 if (!dispatch_table
)
4235 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4238 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4239 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4242 if (flag_next_runtime
)
4243 /* method_cache = */
4244 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4248 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4250 /* subclass_list = */
4251 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4253 /* sibling_class = */
4254 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4257 /* protocol_list = */
4258 if (! protocol_list
)
4259 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4265 (build_tree_list (NULL_TREE
,
4266 xref_tag (RECORD_TYPE
,
4267 get_identifier (UTAG_PROTOCOL
))),
4268 build1 (INDIRECT_REF
, NULL_TREE
,
4269 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4271 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4272 TREE_TYPE (expr
) = cast_type2
;
4273 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4276 /* gc_object_type = NULL */
4277 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4279 return build_constructor (type
, nreverse (initlist
));
4282 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4285 generate_category (cat
)
4288 tree sc_spec
, decl_specs
, decl
;
4289 tree initlist
, cat_name_expr
, class_name_expr
;
4290 tree protocol_decl
, category
;
4292 add_class_reference (CLASS_NAME (cat
));
4293 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4295 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4297 category
= CLASS_CATEGORY_LIST (implementation_template
);
4299 /* find the category interface from the class it is associated with */
4302 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4304 category
= CLASS_CATEGORY_LIST (category
);
4307 if (category
&& CLASS_PROTOCOL_LIST (category
))
4309 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4310 protocol_decl
= generate_protocol_list (category
);
4315 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4316 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4318 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4319 objc_implementation_context
),
4320 decl_specs
, 1, NULL_TREE
);
4322 initlist
= build_category_initializer (TREE_TYPE (decl
),
4323 cat_name_expr
, class_name_expr
,
4324 UOBJC_INSTANCE_METHODS_decl
,
4325 UOBJC_CLASS_METHODS_decl
,
4328 TREE_USED (decl
) = 1;
4329 finish_decl (decl
, initlist
, NULL_TREE
);
4332 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4333 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4336 generate_shared_structures ()
4338 tree sc_spec
, decl_specs
, decl
;
4339 tree name_expr
, super_expr
, root_expr
;
4340 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4341 tree cast_type
, initlist
, protocol_decl
;
4343 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4346 add_class_reference (my_super_id
);
4348 /* Compute "my_root_id" - this is required for code generation.
4349 the "isa" for all meta class structures points to the root of
4350 the inheritance hierarchy (e.g. "__Object")... */
4351 my_root_id
= my_super_id
;
4354 tree my_root_int
= lookup_interface (my_root_id
);
4356 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4357 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4364 /* No super class. */
4365 my_root_id
= CLASS_NAME (implementation_template
);
4368 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4369 objc_class_template
),
4370 build1 (INDIRECT_REF
,
4371 NULL_TREE
, NULL_TREE
)));
4373 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4376 /* Install class `isa' and `super' pointers at runtime. */
4379 super_expr
= add_objc_string (my_super_id
, class_names
);
4380 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4383 super_expr
= build_int_2 (0, 0);
4385 root_expr
= add_objc_string (my_root_id
, class_names
);
4386 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4388 if (CLASS_PROTOCOL_LIST (implementation_template
))
4390 generate_protocol_references
4391 (CLASS_PROTOCOL_LIST (implementation_template
));
4392 protocol_decl
= generate_protocol_list (implementation_template
);
4397 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4399 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4400 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4402 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4406 = build_shared_structure_initializer
4408 root_expr
, super_expr
, name_expr
,
4409 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4411 UOBJC_CLASS_METHODS_decl
,
4412 UOBJC_CLASS_VARIABLES_decl
,
4415 finish_decl (decl
, initlist
, NULL_TREE
);
4417 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4419 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4423 = build_shared_structure_initializer
4425 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4426 super_expr
, name_expr
,
4427 convert (integer_type_node
,
4428 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4429 (implementation_template
))),
4431 UOBJC_INSTANCE_METHODS_decl
,
4432 UOBJC_INSTANCE_VARIABLES_decl
,
4435 finish_decl (decl
, initlist
, NULL_TREE
);
4439 synth_id_with_class_suffix (preamble
, ctxt
)
4440 const char *preamble
;
4444 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4445 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4447 const char *const class_name
4448 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4449 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4450 sprintf (string
, "%s_%s", preamble
,
4451 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4453 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4454 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4456 /* We have a category. */
4457 const char *const class_name
4458 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4459 const char *const class_super_name
4460 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4461 string
= (char *) alloca (strlen (preamble
)
4462 + strlen (class_name
)
4463 + strlen (class_super_name
)
4465 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4467 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4469 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4471 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4472 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4477 return get_identifier (string
);
4481 is_objc_type_qualifier (node
)
4484 return (TREE_CODE (node
) == IDENTIFIER_NODE
4485 && (node
== ridpointers
[(int) RID_CONST
]
4486 || node
== ridpointers
[(int) RID_VOLATILE
]
4487 || node
== ridpointers
[(int) RID_IN
]
4488 || node
== ridpointers
[(int) RID_OUT
]
4489 || node
== ridpointers
[(int) RID_INOUT
]
4490 || node
== ridpointers
[(int) RID_BYCOPY
]
4491 || node
== ridpointers
[(int) RID_BYREF
]
4492 || node
== ridpointers
[(int) RID_ONEWAY
]));
4495 /* If type is empty or only type qualifiers are present, add default
4496 type of id (otherwise grokdeclarator will default to int). */
4499 adjust_type_for_id_default (type
)
4502 tree declspecs
, chain
;
4505 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4506 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4508 declspecs
= TREE_PURPOSE (type
);
4510 /* Determine if a typespec is present. */
4511 for (chain
= declspecs
;
4513 chain
= TREE_CHAIN (chain
))
4515 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4519 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4521 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4526 selector ':' '(' typename ')' identifier
4529 Transform an Objective-C keyword argument into
4530 the C equivalent parameter declarator.
4532 In: key_name, an "identifier_node" (optional).
4533 arg_type, a "tree_list" (optional).
4534 arg_name, an "identifier_node".
4536 Note: It would be really nice to strongly type the preceding
4537 arguments in the function prototype; however, then I
4538 could not use the "accessor" macros defined in "tree.h".
4540 Out: an instance of "keyword_decl". */
4543 build_keyword_decl (key_name
, arg_type
, arg_name
)
4550 /* If no type is specified, default to "id". */
4551 arg_type
= adjust_type_for_id_default (arg_type
);
4553 keyword_decl
= make_node (KEYWORD_DECL
);
4555 TREE_TYPE (keyword_decl
) = arg_type
;
4556 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4557 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4559 return keyword_decl
;
4562 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4565 build_keyword_selector (selector
)
4569 tree key_chain
, key_name
;
4572 /* Scan the selector to see how much space we'll need. */
4573 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4575 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4576 key_name
= KEYWORD_KEY_NAME (key_chain
);
4577 else if (TREE_CODE (selector
) == TREE_LIST
)
4578 key_name
= TREE_PURPOSE (key_chain
);
4583 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4585 /* Just a ':' arg. */
4589 buf
= (char *) alloca (len
+ 1);
4590 /* Start the buffer out as an empty string. */
4593 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4595 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4596 key_name
= KEYWORD_KEY_NAME (key_chain
);
4597 else if (TREE_CODE (selector
) == TREE_LIST
)
4598 key_name
= TREE_PURPOSE (key_chain
);
4603 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4607 return get_identifier (buf
);
4610 /* Used for declarations and definitions. */
4613 build_method_decl (code
, ret_type
, selector
, add_args
)
4614 enum tree_code code
;
4621 /* If no type is specified, default to "id". */
4622 ret_type
= adjust_type_for_id_default (ret_type
);
4624 method_decl
= make_node (code
);
4625 TREE_TYPE (method_decl
) = ret_type
;
4627 /* If we have a keyword selector, create an identifier_node that
4628 represents the full selector name (`:' included)... */
4629 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4631 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4632 METHOD_SEL_ARGS (method_decl
) = selector
;
4633 METHOD_ADD_ARGS (method_decl
) = add_args
;
4637 METHOD_SEL_NAME (method_decl
) = selector
;
4638 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4639 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4645 #define METHOD_DEF 0
4646 #define METHOD_REF 1
4648 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4649 an argument list for method METH. CONTEXT is either METHOD_DEF or
4650 METHOD_REF, saying whether we are trying to define a method or call
4651 one. SUPERFLAG says this is for a send to super; this makes a
4652 difference for the NeXT calling sequence in which the lookup and
4653 the method call are done together. */
4656 get_arg_type_list (meth
, context
, superflag
)
4663 /* Receiver type. */
4664 if (flag_next_runtime
&& superflag
)
4665 arglist
= build_tree_list (NULL_TREE
, super_type
);
4666 else if (context
== METHOD_DEF
)
4667 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4669 arglist
= build_tree_list (NULL_TREE
, id_type
);
4671 /* Selector type - will eventually change to `int'. */
4672 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4674 /* Build a list of argument types. */
4675 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4677 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4678 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4681 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4682 /* We have a `, ...' immediately following the selector,
4683 finalize the arglist...simulate get_parm_info (0). */
4685 else if (METHOD_ADD_ARGS (meth
))
4687 /* we have a variable length selector */
4688 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4689 chainon (arglist
, add_arg_list
);
4692 /* finalize the arglist...simulate get_parm_info (1) */
4693 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4699 check_duplicates (hsh
)
4702 tree meth
= NULL_TREE
;
4710 /* We have two methods with the same name and different types. */
4712 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4714 warning ("multiple declarations for method `%s'",
4715 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4717 warn_with_method ("using", type
, meth
);
4718 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4719 warn_with_method ("also found", type
, loop
->value
);
4725 /* If RECEIVER is a class reference, return the identifier node for
4726 the referenced class. RECEIVER is created by get_class_reference,
4727 so we check the exact form created depending on which runtimes are
4731 receiver_is_class_object (receiver
)
4734 tree chain
, exp
, arg
;
4736 /* The receiver is 'self' in the context of a class method. */
4737 if (objc_method_context
4738 && receiver
== self_decl
4739 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4741 return CLASS_NAME (objc_implementation_context
);
4744 if (flag_next_runtime
)
4746 /* The receiver is a variable created by
4747 build_class_reference_decl. */
4748 if (TREE_CODE (receiver
) == VAR_DECL
4749 && TREE_TYPE (receiver
) == objc_class_type
)
4750 /* Look up the identifier. */
4751 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4752 if (TREE_PURPOSE (chain
) == receiver
)
4753 return TREE_VALUE (chain
);
4757 /* The receiver is a function call that returns an id. Check if
4758 it is a call to objc_getClass, if so, pick up the class name. */
4759 if (TREE_CODE (receiver
) == CALL_EXPR
4760 && (exp
= TREE_OPERAND (receiver
, 0))
4761 && TREE_CODE (exp
) == ADDR_EXPR
4762 && (exp
= TREE_OPERAND (exp
, 0))
4763 && TREE_CODE (exp
) == FUNCTION_DECL
4764 && exp
== objc_get_class_decl
4765 /* We have a call to objc_getClass! */
4766 && (arg
= TREE_OPERAND (receiver
, 1))
4767 && TREE_CODE (arg
) == TREE_LIST
4768 && (arg
= TREE_VALUE (arg
)))
4771 if (TREE_CODE (arg
) == ADDR_EXPR
4772 && (arg
= TREE_OPERAND (arg
, 0))
4773 && TREE_CODE (arg
) == STRING_CST
)
4774 /* Finally, we have the class name. */
4775 return get_identifier (TREE_STRING_POINTER (arg
));
4781 /* If we are currently building a message expr, this holds
4782 the identifier of the selector of the message. This is
4783 used when printing warnings about argument mismatches. */
4785 static tree building_objc_message_expr
= 0;
4788 maybe_building_objc_message_expr ()
4790 return building_objc_message_expr
;
4793 /* Construct an expression for sending a message.
4794 MESS has the object to send to in TREE_PURPOSE
4795 and the argument list (including selector) in TREE_VALUE.
4797 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4798 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4801 build_message_expr (mess
)
4804 tree receiver
= TREE_PURPOSE (mess
);
4806 tree args
= TREE_VALUE (mess
);
4807 tree method_params
= NULL_TREE
;
4809 if (TREE_CODE (receiver
) == ERROR_MARK
)
4810 return error_mark_node
;
4812 /* Obtain the full selector name. */
4813 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4814 /* A unary selector. */
4816 else if (TREE_CODE (args
) == TREE_LIST
)
4817 sel_name
= build_keyword_selector (args
);
4821 /* Build the parameter list to give to the method. */
4822 if (TREE_CODE (args
) == TREE_LIST
)
4824 tree chain
= args
, prev
= NULL_TREE
;
4826 /* We have a keyword selector--check for comma expressions. */
4829 tree element
= TREE_VALUE (chain
);
4831 /* We have a comma expression, must collapse... */
4832 if (TREE_CODE (element
) == TREE_LIST
)
4835 TREE_CHAIN (prev
) = element
;
4840 chain
= TREE_CHAIN (chain
);
4842 method_params
= args
;
4845 return finish_message_expr (receiver
, sel_name
, method_params
);
4848 /* The 'finish_message_expr' routine is called from within
4849 'build_message_expr' for non-template functions. In the case of
4850 C++ template functions, it is called from 'build_expr_from_tree'
4851 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4854 finish_message_expr (receiver
, sel_name
, method_params
)
4855 tree receiver
, sel_name
, method_params
;
4857 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4858 tree selector
, self_object
, retval
;
4859 int statically_typed
= 0, statically_allocated
= 0;
4861 /* Determine receiver type. */
4862 tree rtype
= TREE_TYPE (receiver
);
4863 int super
= IS_SUPER (rtype
);
4867 if (TREE_STATIC_TEMPLATE (rtype
))
4868 statically_allocated
= 1;
4869 else if (TREE_CODE (rtype
) == POINTER_TYPE
4870 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4871 statically_typed
= 1;
4872 else if ((flag_next_runtime
4874 && (class_ident
= receiver_is_class_object (receiver
)))))
4876 else if (! IS_ID (rtype
)
4877 /* Allow any type that matches objc_class_type. */
4878 && ! comptypes (rtype
, objc_class_type
))
4880 warning ("invalid receiver type `%s'",
4881 gen_declaration (rtype
, errbuf
));
4883 if (statically_allocated
)
4884 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4886 /* Don't evaluate the receiver twice. */
4887 receiver
= save_expr (receiver
);
4888 self_object
= receiver
;
4891 /* If sending to `super', use current self as the object. */
4892 self_object
= self_decl
;
4894 /* Determine operation return type. */
4900 if (CLASS_SUPER_NAME (implementation_template
))
4903 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4905 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4906 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4908 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4910 if (iface
&& !method_prototype
)
4911 warning ("`%s' does not respond to `%s'",
4912 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4913 IDENTIFIER_POINTER (sel_name
));
4917 error ("no super class declared in interface for `%s'",
4918 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4919 return error_mark_node
;
4923 else if (statically_allocated
)
4925 tree ctype
= TREE_TYPE (rtype
);
4926 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4929 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4931 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4933 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4936 if (!method_prototype
)
4937 warning ("`%s' does not respond to `%s'",
4938 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4939 IDENTIFIER_POINTER (sel_name
));
4941 else if (statically_typed
)
4943 tree ctype
= TREE_TYPE (rtype
);
4945 /* `self' is now statically_typed. All methods should be visible
4946 within the context of the implementation. */
4947 if (objc_implementation_context
4948 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4951 = lookup_instance_method_static (implementation_template
,
4954 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4956 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4959 if (! method_prototype
4960 && implementation_template
!= objc_implementation_context
)
4961 /* The method is not published in the interface. Check
4964 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4971 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4972 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4974 if (! method_prototype
)
4976 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4979 = lookup_method_in_protocol_list (protocol_list
,
4984 if (!method_prototype
)
4985 warning ("`%s' does not respond to `%s'",
4986 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4987 IDENTIFIER_POINTER (sel_name
));
4989 else if (class_ident
)
4991 if (objc_implementation_context
4992 && CLASS_NAME (objc_implementation_context
) == class_ident
)
4995 = lookup_class_method_static (implementation_template
, sel_name
);
4997 if (!method_prototype
4998 && implementation_template
!= objc_implementation_context
)
4999 /* The method is not published in the interface. Check
5002 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
5009 if ((iface
= lookup_interface (class_ident
)))
5010 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5013 if (!method_prototype
)
5015 warning ("cannot find class (factory) method.");
5016 warning ("return type for `%s' defaults to id",
5017 IDENTIFIER_POINTER (sel_name
));
5020 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5022 /* An anonymous object that has been qualified with a protocol. */
5024 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5026 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5029 if (!method_prototype
)
5033 warning ("method `%s' not implemented by protocol.",
5034 IDENTIFIER_POINTER (sel_name
));
5036 /* Try and find the method signature in the global pools. */
5038 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5039 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5041 if (!(method_prototype
= check_duplicates (hsh
)))
5042 warning ("return type defaults to id");
5049 /* We think we have an instance...loophole: extern id Object; */
5050 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5053 /* For various loopholes */
5054 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5056 method_prototype
= check_duplicates (hsh
);
5057 if (!method_prototype
)
5059 warning ("cannot find method.");
5060 warning ("return type for `%s' defaults to id",
5061 IDENTIFIER_POINTER (sel_name
));
5065 /* Save the selector name for printing error messages. */
5066 building_objc_message_expr
= sel_name
;
5068 /* Build the parameters list for looking up the method.
5069 These are the object itself and the selector. */
5071 if (flag_typed_selectors
)
5072 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5074 selector
= build_selector_reference (sel_name
);
5076 retval
= build_objc_method_call (super
, method_prototype
,
5077 receiver
, self_object
,
5078 selector
, method_params
);
5080 building_objc_message_expr
= 0;
5085 /* Build a tree expression to send OBJECT the operation SELECTOR,
5086 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5087 assuming the method has prototype METHOD_PROTOTYPE.
5088 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5089 Use METHOD_PARAMS as list of args to pass to the method.
5090 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5093 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5094 selector
, method_params
)
5096 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5098 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5099 tree rcv_p
= (super_flag
5100 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5101 get_identifier (TAG_SUPER
)))
5104 if (flag_next_runtime
)
5106 if (! method_prototype
)
5108 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5109 tree_cons (NULL_TREE
, selector
,
5111 assemble_external (sender
);
5112 return build_function_call (sender
, method_params
);
5116 /* This is a real kludge, but it is used only for the Next.
5117 Clobber the data type of SENDER temporarily to accept
5118 all the arguments for this operation, and to return
5119 whatever this operation returns. */
5120 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5121 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5123 /* Save the proper contents of SENDER's data type. */
5124 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5125 savret
= TREE_TYPE (TREE_TYPE (sender
));
5127 /* Install this method's argument types. */
5128 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5130 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5132 /* Install this method's return type. */
5133 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5135 /* Call SENDER with all the parameters. This will do type
5136 checking using the arg types for this method. */
5137 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5138 tree_cons (NULL_TREE
, selector
,
5140 assemble_external (sender
);
5141 retval
= build_function_call (sender
, method_params
);
5143 /* Restore SENDER's return/argument types. */
5144 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5145 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5151 /* This is the portable way.
5152 First call the lookup function to get a pointer to the method,
5153 then cast the pointer, then call it with the method arguments. */
5156 /* Avoid trouble since we may evaluate each of these twice. */
5157 object
= save_expr (object
);
5158 selector
= save_expr (selector
);
5160 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5162 assemble_external (sender
);
5164 = build_function_call (sender
,
5165 tree_cons (NULL_TREE
, lookup_object
,
5166 tree_cons (NULL_TREE
, selector
,
5169 /* If we have a method prototype, construct the data type this
5170 method needs, and cast what we got from SENDER into a pointer
5172 if (method_prototype
)
5174 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5176 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5177 tree fake_function_type
= build_function_type (valtype
, arglist
);
5178 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5182 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5184 /* Pass the object to the method. */
5185 assemble_external (method
);
5186 return build_function_call (method
,
5187 tree_cons (NULL_TREE
, object
,
5188 tree_cons (NULL_TREE
, selector
,
5194 build_protocol_reference (p
)
5197 tree decl
, ident
, ptype
;
5199 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5201 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5203 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5204 objc_protocol_template
),
5207 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5208 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5211 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5212 DECL_EXTERNAL (decl
) = 1;
5213 TREE_PUBLIC (decl
) = 1;
5214 TREE_USED (decl
) = 1;
5215 DECL_ARTIFICIAL (decl
) = 1;
5217 make_decl_rtl (decl
, 0);
5218 pushdecl_top_level (decl
);
5221 PROTOCOL_FORWARD_DECL (p
) = decl
;
5225 build_protocol_expr (protoname
)
5229 tree p
= lookup_protocol (protoname
);
5233 error ("Cannot find protocol declaration for `%s'",
5234 IDENTIFIER_POINTER (protoname
));
5235 return error_mark_node
;
5238 if (!PROTOCOL_FORWARD_DECL (p
))
5239 build_protocol_reference (p
);
5241 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5243 TREE_TYPE (expr
) = protocol_type
;
5249 build_selector_expr (selnamelist
)
5254 /* Obtain the full selector name. */
5255 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5256 /* A unary selector. */
5257 selname
= selnamelist
;
5258 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5259 selname
= build_keyword_selector (selnamelist
);
5263 if (flag_typed_selectors
)
5264 return build_typed_selector_reference (selname
, 0);
5266 return build_selector_reference (selname
);
5270 build_encode_expr (type
)
5276 encode_type (type
, obstack_object_size (&util_obstack
),
5277 OBJC_ENCODE_INLINE_DEFS
);
5278 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5279 string
= obstack_finish (&util_obstack
);
5281 /* Synthesize a string that represents the encoded struct/union. */
5282 result
= my_build_string (strlen (string
) + 1, string
);
5283 obstack_free (&util_obstack
, util_firstobj
);
5288 build_ivar_reference (id
)
5291 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5293 /* Historically, a class method that produced objects (factory
5294 method) would assign `self' to the instance that it
5295 allocated. This would effectively turn the class method into
5296 an instance method. Following this assignment, the instance
5297 variables could be accessed. That practice, while safe,
5298 violates the simple rule that a class method should not refer
5299 to an instance variable. It's better to catch the cases
5300 where this is done unknowingly than to support the above
5302 warning ("instance variable `%s' accessed in class method",
5303 IDENTIFIER_POINTER (id
));
5304 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5307 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5309 \f/* Make the hash value positive. */
5310 #define HASHFUNCTION(key) ((size_t) key & 0x7fffffff)
5315 nst_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5316 cls_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5319 /* WARNING!!!! hash_enter is called with a method, and will peek
5320 inside to find its selector! But hash_lookup is given a selector
5321 directly, and looks for the selector that's inside the found
5322 entry's key (method) for comparison. */
5325 hash_enter (hashlist
, method
)
5329 static hash hash_alloc_list
= 0;
5330 static int hash_alloc_index
= 0;
5332 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5334 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5336 hash_alloc_index
= 0;
5337 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5338 * HASH_ALLOC_LIST_SIZE
);
5340 obj
= &hash_alloc_list
[hash_alloc_index
++];
5342 obj
->next
= hashlist
[slot
];
5345 hashlist
[slot
] = obj
; /* append to front */
5349 hash_lookup (hashlist
, sel_name
)
5355 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5359 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5362 target
= target
->next
;
5368 hash_add_attr (entry
, value
)
5372 static attr attr_alloc_list
= 0;
5373 static int attr_alloc_index
= 0;
5376 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5378 attr_alloc_index
= 0;
5379 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5380 * ATTR_ALLOC_LIST_SIZE
);
5382 obj
= &attr_alloc_list
[attr_alloc_index
++];
5383 obj
->next
= entry
->list
;
5386 entry
->list
= obj
; /* append to front */
5390 lookup_method (mchain
, method
)
5396 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5399 key
= METHOD_SEL_NAME (method
);
5403 if (METHOD_SEL_NAME (mchain
) == key
)
5405 mchain
= TREE_CHAIN (mchain
);
5411 lookup_instance_method_static (interface
, ident
)
5415 tree inter
= interface
;
5416 tree chain
= CLASS_NST_METHODS (inter
);
5417 tree meth
= NULL_TREE
;
5421 if ((meth
= lookup_method (chain
, ident
)))
5424 if (CLASS_CATEGORY_LIST (inter
))
5426 tree category
= CLASS_CATEGORY_LIST (inter
);
5427 chain
= CLASS_NST_METHODS (category
);
5431 if ((meth
= lookup_method (chain
, ident
)))
5434 /* Check for instance methods in protocols in categories. */
5435 if (CLASS_PROTOCOL_LIST (category
))
5437 if ((meth
= (lookup_method_in_protocol_list
5438 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5442 if ((category
= CLASS_CATEGORY_LIST (category
)))
5443 chain
= CLASS_NST_METHODS (category
);
5448 if (CLASS_PROTOCOL_LIST (inter
))
5450 if ((meth
= (lookup_method_in_protocol_list
5451 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5455 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5456 chain
= CLASS_NST_METHODS (inter
);
5464 lookup_class_method_static (interface
, ident
)
5468 tree inter
= interface
;
5469 tree chain
= CLASS_CLS_METHODS (inter
);
5470 tree meth
= NULL_TREE
;
5471 tree root_inter
= NULL_TREE
;
5475 if ((meth
= lookup_method (chain
, ident
)))
5478 if (CLASS_CATEGORY_LIST (inter
))
5480 tree category
= CLASS_CATEGORY_LIST (inter
);
5481 chain
= CLASS_CLS_METHODS (category
);
5485 if ((meth
= lookup_method (chain
, ident
)))
5488 /* Check for class methods in protocols in categories. */
5489 if (CLASS_PROTOCOL_LIST (category
))
5491 if ((meth
= (lookup_method_in_protocol_list
5492 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5496 if ((category
= CLASS_CATEGORY_LIST (category
)))
5497 chain
= CLASS_CLS_METHODS (category
);
5502 /* Check for class methods in protocols. */
5503 if (CLASS_PROTOCOL_LIST (inter
))
5505 if ((meth
= (lookup_method_in_protocol_list
5506 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5511 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5512 chain
= CLASS_CLS_METHODS (inter
);
5516 /* If no class (factory) method was found, check if an _instance_
5517 method of the same name exists in the root class. This is what
5518 the Objective-C runtime will do. */
5519 return lookup_instance_method_static (root_inter
, ident
);
5523 add_class_method (class, method
)
5530 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5532 /* put method on list in reverse order */
5533 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5534 CLASS_CLS_METHODS (class) = method
;
5538 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5539 error ("duplicate definition of class method `%s'.",
5540 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5543 /* Check types; if different, complain. */
5544 if (!comp_proto_with_proto (method
, mth
))
5545 error ("duplicate declaration of class method `%s'.",
5546 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5550 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5552 /* Install on a global chain. */
5553 hash_enter (cls_method_hash_list
, method
);
5557 /* Check types; if different, add to a list. */
5558 if (!comp_proto_with_proto (method
, hsh
->key
))
5559 hash_add_attr (hsh
, method
);
5565 add_instance_method (class, method
)
5572 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5574 /* Put method on list in reverse order. */
5575 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5576 CLASS_NST_METHODS (class) = method
;
5580 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5581 error ("duplicate definition of instance method `%s'.",
5582 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5585 /* Check types; if different, complain. */
5586 if (!comp_proto_with_proto (method
, mth
))
5587 error ("duplicate declaration of instance method `%s'.",
5588 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5592 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5594 /* Install on a global chain. */
5595 hash_enter (nst_method_hash_list
, method
);
5599 /* Check types; if different, add to a list. */
5600 if (!comp_proto_with_proto (method
, hsh
->key
))
5601 hash_add_attr (hsh
, method
);
5610 /* Put interfaces on list in reverse order. */
5611 TREE_CHAIN (class) = interface_chain
;
5612 interface_chain
= class;
5613 return interface_chain
;
5617 add_category (class, category
)
5621 /* Put categories on list in reverse order. */
5622 tree cat
= CLASS_CATEGORY_LIST (class);
5626 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5627 warning ("duplicate interface declaration for category `%s(%s)'",
5628 IDENTIFIER_POINTER (CLASS_NAME (class)),
5629 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5630 cat
= CLASS_CATEGORY_LIST (cat
);
5633 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5634 CLASS_CATEGORY_LIST (class) = category
;
5637 /* Called after parsing each instance variable declaration. Necessary to
5638 preserve typedefs and implement public/private...
5640 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5643 add_instance_variable (class, public, declarator
, declspecs
, width
)
5650 tree field_decl
, raw_decl
;
5652 raw_decl
= build_tree_list (declspecs
, declarator
);
5654 if (CLASS_RAW_IVARS (class))
5655 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5657 CLASS_RAW_IVARS (class) = raw_decl
;
5659 field_decl
= grokfield (input_filename
, lineno
,
5660 declarator
, declspecs
, width
);
5662 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5666 TREE_PUBLIC (field_decl
) = 0;
5667 TREE_PRIVATE (field_decl
) = 0;
5668 TREE_PROTECTED (field_decl
) = 1;
5672 TREE_PUBLIC (field_decl
) = 1;
5673 TREE_PRIVATE (field_decl
) = 0;
5674 TREE_PROTECTED (field_decl
) = 0;
5678 TREE_PUBLIC (field_decl
) = 0;
5679 TREE_PRIVATE (field_decl
) = 1;
5680 TREE_PROTECTED (field_decl
) = 0;
5685 if (CLASS_IVARS (class))
5686 chainon (CLASS_IVARS (class), field_decl
);
5688 CLASS_IVARS (class) = field_decl
;
5694 is_ivar (decl_chain
, ident
)
5698 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5699 if (DECL_NAME (decl_chain
) == ident
)
5704 /* True if the ivar is private and we are not in its implementation. */
5710 if (TREE_PRIVATE (decl
)
5711 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5713 error ("instance variable `%s' is declared private",
5714 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5721 /* We have an instance variable reference;, check to see if it is public. */
5724 is_public (expr
, identifier
)
5728 tree basetype
= TREE_TYPE (expr
);
5729 enum tree_code code
= TREE_CODE (basetype
);
5732 if (code
== RECORD_TYPE
)
5734 if (TREE_STATIC_TEMPLATE (basetype
))
5736 if (!lookup_interface (TYPE_NAME (basetype
)))
5738 error ("Cannot find interface declaration for `%s'",
5739 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5743 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5745 if (TREE_PUBLIC (decl
))
5748 /* Important difference between the Stepstone translator:
5749 all instance variables should be public within the context
5750 of the implementation. */
5751 if (objc_implementation_context
5752 && (((TREE_CODE (objc_implementation_context
)
5753 == CLASS_IMPLEMENTATION_TYPE
)
5754 || (TREE_CODE (objc_implementation_context
)
5755 == CATEGORY_IMPLEMENTATION_TYPE
))
5756 && (CLASS_NAME (objc_implementation_context
)
5757 == TYPE_NAME (basetype
))))
5758 return ! is_private (decl
);
5760 error ("instance variable `%s' is declared %s",
5761 IDENTIFIER_POINTER (identifier
),
5762 TREE_PRIVATE (decl
) ? "private" : "protected");
5767 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5769 TREE_TYPE (expr
) = uprivate_record
;
5770 warning ("static access to object of type `id'");
5777 /* Implement @defs (<classname>) within struct bodies. */
5780 get_class_ivars (interface
)
5783 /* Make sure we copy the leaf ivars in case @defs is used in a local
5784 context. Otherwise finish_struct will overwrite the layout info
5785 using temporary storage. */
5786 return build_ivar_chain (interface
, 1);
5789 /* Make sure all entries in CHAIN are also in LIST. */
5792 check_methods (chain
, list
, mtype
)
5801 if (!lookup_method (list
, chain
))
5805 if (TREE_CODE (objc_implementation_context
)
5806 == CLASS_IMPLEMENTATION_TYPE
)
5807 warning ("incomplete implementation of class `%s'",
5808 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5809 else if (TREE_CODE (objc_implementation_context
)
5810 == CATEGORY_IMPLEMENTATION_TYPE
)
5811 warning ("incomplete implementation of category `%s'",
5812 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5816 warning ("method definition for `%c%s' not found",
5817 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5820 chain
= TREE_CHAIN (chain
);
5826 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5829 conforms_to_protocol (class, protocol
)
5833 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5835 tree p
= CLASS_PROTOCOL_LIST (class);
5836 while (p
&& TREE_VALUE (p
) != protocol
)
5841 tree super
= (CLASS_SUPER_NAME (class)
5842 ? lookup_interface (CLASS_SUPER_NAME (class))
5844 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5853 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5854 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5857 check_methods_accessible (chain
, context
, mtype
)
5864 tree base_context
= context
;
5868 context
= base_context
;
5872 list
= CLASS_CLS_METHODS (context
);
5874 list
= CLASS_NST_METHODS (context
);
5876 if (lookup_method (list
, chain
))
5879 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5880 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5881 context
= (CLASS_SUPER_NAME (context
)
5882 ? lookup_interface (CLASS_SUPER_NAME (context
))
5885 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5886 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5887 context
= (CLASS_NAME (context
)
5888 ? lookup_interface (CLASS_NAME (context
))
5894 if (context
== NULL_TREE
)
5898 if (TREE_CODE (objc_implementation_context
)
5899 == CLASS_IMPLEMENTATION_TYPE
)
5900 warning ("incomplete implementation of class `%s'",
5902 (CLASS_NAME (objc_implementation_context
)));
5903 else if (TREE_CODE (objc_implementation_context
)
5904 == CATEGORY_IMPLEMENTATION_TYPE
)
5905 warning ("incomplete implementation of category `%s'",
5907 (CLASS_SUPER_NAME (objc_implementation_context
)));
5910 warning ("method definition for `%c%s' not found",
5911 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5914 chain
= TREE_CHAIN (chain
); /* next method... */
5919 /* Check whether the current interface (accessible via
5920 'objc_implementation_context') actually implements protocol P, along
5921 with any protocols that P inherits. */
5924 check_protocol (p
, type
, name
)
5929 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5933 /* Ensure that all protocols have bodies! */
5934 if (flag_warn_protocol
)
5936 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5937 CLASS_CLS_METHODS (objc_implementation_context
),
5939 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5940 CLASS_NST_METHODS (objc_implementation_context
),
5945 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5946 objc_implementation_context
,
5948 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5949 objc_implementation_context
,
5954 warning ("%s `%s' does not fully implement the `%s' protocol",
5955 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5958 /* Check protocols recursively. */
5959 if (PROTOCOL_LIST (p
))
5961 tree subs
= PROTOCOL_LIST (p
);
5963 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5966 tree sub
= TREE_VALUE (subs
);
5968 /* If the superclass does not conform to the protocols
5969 inherited by P, then we must! */
5970 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5971 check_protocol (sub
, type
, name
);
5972 subs
= TREE_CHAIN (subs
);
5977 /* Check whether the current interface (accessible via
5978 'objc_implementation_context') actually implements the protocols listed
5982 check_protocols (proto_list
, type
, name
)
5987 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5989 tree p
= TREE_VALUE (proto_list
);
5991 check_protocol (p
, type
, name
);
5995 /* Make sure that the class CLASS_NAME is defined
5996 CODE says which kind of thing CLASS_NAME ought to be.
5997 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5998 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6001 start_class (code
, class_name
, super_name
, protocol_list
)
6002 enum tree_code code
;
6009 if (objc_implementation_context
)
6011 warning ("`@end' missing in implementation context");
6012 finish_class (objc_implementation_context
);
6013 objc_ivar_chain
= NULL_TREE
;
6014 objc_implementation_context
= NULL_TREE
;
6017 class = make_node (code
);
6018 TYPE_BINFO (class) = make_tree_vec (5);
6020 CLASS_NAME (class) = class_name
;
6021 CLASS_SUPER_NAME (class) = super_name
;
6022 CLASS_CLS_METHODS (class) = NULL_TREE
;
6024 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6026 error ("`%s' redeclared as different kind of symbol",
6027 IDENTIFIER_POINTER (class_name
));
6028 error_with_decl (decl
, "previous declaration of `%s'");
6031 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6036 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6037 if (TREE_VALUE (chain
) == class_name
)
6039 error ("reimplementation of class `%s'",
6040 IDENTIFIER_POINTER (class_name
));
6041 return error_mark_node
;
6043 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6044 implemented_classes
);
6047 /* Pre-build the following entities - for speed/convenience. */
6049 self_id
= get_identifier ("self");
6051 ucmd_id
= get_identifier ("_cmd");
6054 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6055 if (!objc_super_template
)
6056 objc_super_template
= build_super_template ();
6058 /* Reset for multiple classes per file. */
6061 objc_implementation_context
= class;
6063 /* Lookup the interface for this implementation. */
6065 if (!(implementation_template
= lookup_interface (class_name
)))
6067 warning ("Cannot find interface declaration for `%s'",
6068 IDENTIFIER_POINTER (class_name
));
6069 add_class (implementation_template
= objc_implementation_context
);
6072 /* If a super class has been specified in the implementation,
6073 insure it conforms to the one specified in the interface. */
6076 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6078 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6079 const char *const name
=
6080 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6081 error ("conflicting super class name `%s'",
6082 IDENTIFIER_POINTER (super_name
));
6083 error ("previous declaration of `%s'", name
);
6086 else if (! super_name
)
6088 CLASS_SUPER_NAME (objc_implementation_context
)
6089 = CLASS_SUPER_NAME (implementation_template
);
6093 else if (code
== CLASS_INTERFACE_TYPE
)
6095 if (lookup_interface (class_name
))
6096 warning ("duplicate interface declaration for class `%s'",
6097 IDENTIFIER_POINTER (class_name
));
6102 CLASS_PROTOCOL_LIST (class)
6103 = lookup_and_install_protocols (protocol_list
);
6106 else if (code
== CATEGORY_INTERFACE_TYPE
)
6108 tree class_category_is_assoc_with
;
6110 /* For a category, class_name is really the name of the class that
6111 the following set of methods will be associated with. We must
6112 find the interface so that can derive the objects template. */
6114 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6116 error ("Cannot find interface declaration for `%s'",
6117 IDENTIFIER_POINTER (class_name
));
6118 exit (FATAL_EXIT_CODE
);
6121 add_category (class_category_is_assoc_with
, class);
6124 CLASS_PROTOCOL_LIST (class)
6125 = lookup_and_install_protocols (protocol_list
);
6128 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6130 /* Pre-build the following entities for speed/convenience. */
6132 self_id
= get_identifier ("self");
6134 ucmd_id
= get_identifier ("_cmd");
6137 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6138 if (!objc_super_template
)
6139 objc_super_template
= build_super_template ();
6141 /* Reset for multiple classes per file. */
6144 objc_implementation_context
= class;
6146 /* For a category, class_name is really the name of the class that
6147 the following set of methods will be associated with. We must
6148 find the interface so that can derive the objects template. */
6150 if (!(implementation_template
= lookup_interface (class_name
)))
6152 error ("Cannot find interface declaration for `%s'",
6153 IDENTIFIER_POINTER (class_name
));
6154 exit (FATAL_EXIT_CODE
);
6161 continue_class (class)
6164 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6165 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6167 struct imp_entry
*imp_entry
;
6170 /* Check consistency of the instance variables. */
6172 if (CLASS_IVARS (class))
6173 check_ivars (implementation_template
, class);
6175 /* code generation */
6177 ivar_context
= build_private_template (implementation_template
);
6179 if (!objc_class_template
)
6180 build_class_template ();
6182 imp_entry
= (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
));
6184 imp_entry
->next
= imp_list
;
6185 imp_entry
->imp_context
= class;
6186 imp_entry
->imp_template
= implementation_template
;
6188 synth_forward_declarations ();
6189 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6190 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6192 /* Append to front and increment count. */
6193 imp_list
= imp_entry
;
6194 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6199 return ivar_context
;
6202 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6204 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6206 if (!TYPE_FIELDS (record
))
6208 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6209 CLASS_STATIC_TEMPLATE (class) = record
;
6211 /* Mark this record as a class template for static typing. */
6212 TREE_STATIC_TEMPLATE (record
) = 1;
6219 return error_mark_node
;
6222 /* This is called once we see the "@end" in an interface/implementation. */
6225 finish_class (class)
6228 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6230 /* All code generation is done in finish_objc. */
6232 if (implementation_template
!= objc_implementation_context
)
6234 /* Ensure that all method listed in the interface contain bodies. */
6235 check_methods (CLASS_CLS_METHODS (implementation_template
),
6236 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6237 check_methods (CLASS_NST_METHODS (implementation_template
),
6238 CLASS_NST_METHODS (objc_implementation_context
), '-');
6240 if (CLASS_PROTOCOL_LIST (implementation_template
))
6241 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6243 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6247 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6249 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6251 /* Find the category interface from the class it is associated with. */
6254 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6256 category
= CLASS_CATEGORY_LIST (category
);
6261 /* Ensure all method listed in the interface contain bodies. */
6262 check_methods (CLASS_CLS_METHODS (category
),
6263 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6264 check_methods (CLASS_NST_METHODS (category
),
6265 CLASS_NST_METHODS (objc_implementation_context
), '-');
6267 if (CLASS_PROTOCOL_LIST (category
))
6268 check_protocols (CLASS_PROTOCOL_LIST (category
),
6270 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6274 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6277 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6278 char *string
= (char *) alloca (strlen (class_name
) + 3);
6280 /* extern struct objc_object *_<my_name>; */
6282 sprintf (string
, "_%s", class_name
);
6284 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6285 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6286 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6292 add_protocol (protocol
)
6295 /* Put protocol on list in reverse order. */
6296 TREE_CHAIN (protocol
) = protocol_chain
;
6297 protocol_chain
= protocol
;
6298 return protocol_chain
;
6302 lookup_protocol (ident
)
6307 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6309 if (ident
== PROTOCOL_NAME (chain
))
6316 /* This function forward declares the protocols named by NAMES. If
6317 they are already declared or defined, the function has no effect. */
6320 objc_declare_protocols (names
)
6325 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6327 tree name
= TREE_VALUE (list
);
6329 if (lookup_protocol (name
) == NULL_TREE
)
6331 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6333 TYPE_BINFO (protocol
) = make_tree_vec (2);
6334 PROTOCOL_NAME (protocol
) = name
;
6335 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6336 add_protocol (protocol
);
6337 PROTOCOL_DEFINED (protocol
) = 0;
6338 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6344 start_protocol (code
, name
, list
)
6345 enum tree_code code
;
6351 /* This is as good a place as any. Need to invoke
6352 push_tag_toplevel. */
6353 if (!objc_protocol_template
)
6354 objc_protocol_template
= build_protocol_template ();
6356 protocol
= lookup_protocol (name
);
6360 protocol
= make_node (code
);
6361 TYPE_BINFO (protocol
) = make_tree_vec (2);
6363 PROTOCOL_NAME (protocol
) = name
;
6364 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6365 add_protocol (protocol
);
6366 PROTOCOL_DEFINED (protocol
) = 1;
6367 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6369 check_protocol_recursively (protocol
, list
);
6371 else if (! PROTOCOL_DEFINED (protocol
))
6373 PROTOCOL_DEFINED (protocol
) = 1;
6374 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6376 check_protocol_recursively (protocol
, list
);
6380 warning ("duplicate declaration for protocol `%s'",
6381 IDENTIFIER_POINTER (name
));
6387 finish_protocol (protocol
)
6388 tree protocol ATTRIBUTE_UNUSED
;
6393 /* "Encode" a data type into a string, which grows in util_obstack.
6394 ??? What is the FORMAT? Someone please document this! */
6397 encode_type_qualifiers (declspecs
)
6402 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6404 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6405 obstack_1grow (&util_obstack
, 'r');
6406 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6407 obstack_1grow (&util_obstack
, 'n');
6408 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6409 obstack_1grow (&util_obstack
, 'N');
6410 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6411 obstack_1grow (&util_obstack
, 'o');
6412 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6413 obstack_1grow (&util_obstack
, 'O');
6414 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6415 obstack_1grow (&util_obstack
, 'R');
6416 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6417 obstack_1grow (&util_obstack
, 'V');
6421 /* Encode a pointer type. */
6424 encode_pointer (type
, curtype
, format
)
6429 tree pointer_to
= TREE_TYPE (type
);
6431 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6433 if (TYPE_NAME (pointer_to
)
6434 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6436 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6438 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6440 obstack_1grow (&util_obstack
, '@');
6443 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6445 if (generating_instance_variables
)
6447 obstack_1grow (&util_obstack
, '@');
6448 obstack_1grow (&util_obstack
, '"');
6449 obstack_grow (&util_obstack
, name
, strlen (name
));
6450 obstack_1grow (&util_obstack
, '"');
6455 obstack_1grow (&util_obstack
, '@');
6459 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6461 obstack_1grow (&util_obstack
, '#');
6464 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6466 obstack_1grow (&util_obstack
, ':');
6471 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6472 && TYPE_MODE (pointer_to
) == QImode
)
6474 obstack_1grow (&util_obstack
, '*');
6478 /* We have a type that does not get special treatment. */
6480 /* NeXT extension */
6481 obstack_1grow (&util_obstack
, '^');
6482 encode_type (pointer_to
, curtype
, format
);
6486 encode_array (type
, curtype
, format
)
6491 tree an_int_cst
= TYPE_SIZE (type
);
6492 tree array_of
= TREE_TYPE (type
);
6495 /* An incomplete array is treated like a pointer. */
6496 if (an_int_cst
== NULL
)
6498 encode_pointer (type
, curtype
, format
);
6502 sprintf (buffer
, "[%ld",
6503 (long) (TREE_INT_CST_LOW (an_int_cst
)
6504 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6506 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6507 encode_type (array_of
, curtype
, format
);
6508 obstack_1grow (&util_obstack
, ']');
6513 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6520 /* The RECORD_TYPE may in fact be a typedef! For purposes
6521 of encoding, we need the real underlying enchilada. */
6522 if (TYPE_MAIN_VARIANT (type
))
6523 type
= TYPE_MAIN_VARIANT (type
);
6525 if (obstack_object_size (&util_obstack
) > 0
6526 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6528 tree name
= TYPE_NAME (type
);
6530 /* we have a reference; this is a NeXT extension. */
6532 if (obstack_object_size (&util_obstack
) - curtype
== 1
6533 && format
== OBJC_ENCODE_INLINE_DEFS
)
6535 /* Output format of struct for first level only. */
6536 tree fields
= TYPE_FIELDS (type
);
6538 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6540 obstack_1grow (&util_obstack
, left
);
6541 obstack_grow (&util_obstack
,
6542 IDENTIFIER_POINTER (name
),
6543 strlen (IDENTIFIER_POINTER (name
)));
6544 obstack_1grow (&util_obstack
, '=');
6548 obstack_1grow (&util_obstack
, left
);
6549 obstack_grow (&util_obstack
, "?=", 2);
6552 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6553 encode_field_decl (fields
, curtype
, format
);
6555 obstack_1grow (&util_obstack
, right
);
6558 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6560 obstack_1grow (&util_obstack
, left
);
6561 obstack_grow (&util_obstack
,
6562 IDENTIFIER_POINTER (name
),
6563 strlen (IDENTIFIER_POINTER (name
)));
6564 obstack_1grow (&util_obstack
, right
);
6569 /* We have an untagged structure or a typedef. */
6570 obstack_1grow (&util_obstack
, left
);
6571 obstack_1grow (&util_obstack
, '?');
6572 obstack_1grow (&util_obstack
, right
);
6578 tree name
= TYPE_NAME (type
);
6579 tree fields
= TYPE_FIELDS (type
);
6581 if (format
== OBJC_ENCODE_INLINE_DEFS
6582 || generating_instance_variables
)
6584 obstack_1grow (&util_obstack
, left
);
6585 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6586 obstack_grow (&util_obstack
,
6587 IDENTIFIER_POINTER (name
),
6588 strlen (IDENTIFIER_POINTER (name
)));
6590 obstack_1grow (&util_obstack
, '?');
6592 obstack_1grow (&util_obstack
, '=');
6594 for (; fields
; fields
= TREE_CHAIN (fields
))
6596 if (generating_instance_variables
)
6598 tree fname
= DECL_NAME (fields
);
6600 obstack_1grow (&util_obstack
, '"');
6601 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6603 obstack_grow (&util_obstack
,
6604 IDENTIFIER_POINTER (fname
),
6605 strlen (IDENTIFIER_POINTER (fname
)));
6608 obstack_1grow (&util_obstack
, '"');
6611 encode_field_decl (fields
, curtype
, format
);
6614 obstack_1grow (&util_obstack
, right
);
6619 obstack_1grow (&util_obstack
, left
);
6620 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6621 obstack_grow (&util_obstack
,
6622 IDENTIFIER_POINTER (name
),
6623 strlen (IDENTIFIER_POINTER (name
)));
6625 /* We have an untagged structure or a typedef. */
6626 obstack_1grow (&util_obstack
, '?');
6628 obstack_1grow (&util_obstack
, right
);
6634 encode_aggregate (type
, curtype
, format
)
6639 enum tree_code code
= TREE_CODE (type
);
6645 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6650 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6655 obstack_1grow (&util_obstack
, 'i');
6663 /* Support bitfields. The current version of Objective-C does not support
6664 them. The string will consist of one or more "b:n"'s where n is an
6665 integer describing the width of the bitfield. Currently, classes in
6666 the kit implement a method "-(char *)describeBitfieldStruct:" that
6667 simulates this. If they do not implement this method, the archiver
6668 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6669 according to the GNU compiler. After looking at the "kit", it appears
6670 that all classes currently rely on this default behavior, rather than
6671 hand generating this string (which is tedious). */
6674 encode_bitfield (width
)
6678 sprintf (buffer
, "b%d", width
);
6679 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6682 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6685 encode_type (type
, curtype
, format
)
6690 enum tree_code code
= TREE_CODE (type
);
6692 if (code
== INTEGER_TYPE
)
6694 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6696 /* Unsigned integer types. */
6698 if (TYPE_MODE (type
) == QImode
)
6699 obstack_1grow (&util_obstack
, 'C');
6700 else if (TYPE_MODE (type
) == HImode
)
6701 obstack_1grow (&util_obstack
, 'S');
6702 else if (TYPE_MODE (type
) == SImode
)
6704 if (type
== long_unsigned_type_node
)
6705 obstack_1grow (&util_obstack
, 'L');
6707 obstack_1grow (&util_obstack
, 'I');
6709 else if (TYPE_MODE (type
) == DImode
)
6710 obstack_1grow (&util_obstack
, 'Q');
6714 /* Signed integer types. */
6716 if (TYPE_MODE (type
) == QImode
)
6717 obstack_1grow (&util_obstack
, 'c');
6718 else if (TYPE_MODE (type
) == HImode
)
6719 obstack_1grow (&util_obstack
, 's');
6720 else if (TYPE_MODE (type
) == SImode
)
6722 if (type
== long_integer_type_node
)
6723 obstack_1grow (&util_obstack
, 'l');
6725 obstack_1grow (&util_obstack
, 'i');
6728 else if (TYPE_MODE (type
) == DImode
)
6729 obstack_1grow (&util_obstack
, 'q');
6733 else if (code
== REAL_TYPE
)
6735 /* Floating point types. */
6737 if (TYPE_MODE (type
) == SFmode
)
6738 obstack_1grow (&util_obstack
, 'f');
6739 else if (TYPE_MODE (type
) == DFmode
6740 || TYPE_MODE (type
) == TFmode
)
6741 obstack_1grow (&util_obstack
, 'd');
6744 else if (code
== VOID_TYPE
)
6745 obstack_1grow (&util_obstack
, 'v');
6747 else if (code
== ARRAY_TYPE
)
6748 encode_array (type
, curtype
, format
);
6750 else if (code
== POINTER_TYPE
)
6751 encode_pointer (type
, curtype
, format
);
6753 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6754 encode_aggregate (type
, curtype
, format
);
6756 else if (code
== FUNCTION_TYPE
) /* '?' */
6757 obstack_1grow (&util_obstack
, '?');
6761 encode_complete_bitfield (int position
, tree type
, int size
)
6763 enum tree_code code
= TREE_CODE (type
);
6765 char charType
= '?';
6767 if (code
== INTEGER_TYPE
)
6769 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6771 /* Unsigned integer types. */
6773 if (TYPE_MODE (type
) == QImode
)
6775 else if (TYPE_MODE (type
) == HImode
)
6777 else if (TYPE_MODE (type
) == SImode
)
6779 if (type
== long_unsigned_type_node
)
6784 else if (TYPE_MODE (type
) == DImode
)
6789 /* Signed integer types. */
6791 if (TYPE_MODE (type
) == QImode
)
6793 else if (TYPE_MODE (type
) == HImode
)
6795 else if (TYPE_MODE (type
) == SImode
)
6797 if (type
== long_integer_type_node
)
6803 else if (TYPE_MODE (type
) == DImode
)
6811 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6812 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6816 encode_field_decl (field_decl
, curtype
, format
)
6823 type
= TREE_TYPE (field_decl
);
6825 /* If this field is obviously a bitfield, or is a bitfield that has been
6826 clobbered to look like a ordinary integer mode, go ahead and generate
6827 the bitfield typing information. */
6828 if (flag_next_runtime
)
6830 if (DECL_BIT_FIELD (field_decl
))
6831 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6833 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6837 if (DECL_BIT_FIELD (field_decl
))
6838 encode_complete_bitfield (int_bit_position (field_decl
),
6839 DECL_BIT_FIELD_TYPE (field_decl
),
6840 tree_low_cst (DECL_SIZE (field_decl
), 1));
6842 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6847 expr_last (complex_expr
)
6853 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6854 complex_expr
= next
;
6856 return complex_expr
;
6859 /* Transform a method definition into a function definition as follows:
6860 - synthesize the first two arguments, "self" and "_cmd". */
6863 start_method_def (method
)
6868 /* Required to implement _msgSuper. */
6869 objc_method_context
= method
;
6870 UOBJC_SUPER_decl
= NULL_TREE
;
6872 /* Must be called BEFORE start_function. */
6875 /* Generate prototype declarations for arguments..."new-style". */
6877 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6878 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6880 /* Really a `struct objc_class *'. However, we allow people to
6881 assign to self, which changes its type midstream. */
6882 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6884 push_parm_decl (build_tree_list
6885 (build_tree_list (decl_specs
,
6886 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6889 decl_specs
= build_tree_list (NULL_TREE
,
6890 xref_tag (RECORD_TYPE
,
6891 get_identifier (TAG_SELECTOR
)));
6892 push_parm_decl (build_tree_list
6893 (build_tree_list (decl_specs
,
6894 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6897 /* Generate argument declarations if a keyword_decl. */
6898 if (METHOD_SEL_ARGS (method
))
6900 tree arglist
= METHOD_SEL_ARGS (method
);
6903 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6904 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6908 tree last_expr
= expr_last (arg_decl
);
6910 /* Unite the abstract decl with its name. */
6911 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6912 push_parm_decl (build_tree_list
6913 (build_tree_list (arg_spec
, arg_decl
),
6916 /* Unhook: restore the abstract declarator. */
6917 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6921 push_parm_decl (build_tree_list
6922 (build_tree_list (arg_spec
,
6923 KEYWORD_ARG_NAME (arglist
)),
6926 arglist
= TREE_CHAIN (arglist
);
6931 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6932 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6934 /* We have a variable length selector - in "prototype" format. */
6935 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6938 /* This must be done prior to calling pushdecl. pushdecl is
6939 going to change our chain on us. */
6940 tree nextkey
= TREE_CHAIN (akey
);
6948 warn_with_method (message
, mtype
, method
)
6949 const char *message
;
6953 if (count_error (1) == 0)
6956 report_error_function (DECL_SOURCE_FILE (method
));
6958 /* Add a readable method name to the warning. */
6959 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6960 DECL_SOURCE_LINE (method
),
6963 gen_method_decl (method
, errbuf
));
6966 /* Return 1 if METHOD is consistent with PROTO. */
6969 comp_method_with_proto (method
, proto
)
6972 /* Create a function template node at most once. */
6973 if (!function1_template
)
6974 function1_template
= make_node (FUNCTION_TYPE
);
6976 /* Install argument types - normally set by build_function_type. */
6977 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6979 /* install return type */
6980 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6982 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6985 /* Return 1 if PROTO1 is consistent with PROTO2. */
6988 comp_proto_with_proto (proto0
, proto1
)
6989 tree proto0
, proto1
;
6991 /* Create a couple of function_template nodes at most once. */
6992 if (!function1_template
)
6993 function1_template
= make_node (FUNCTION_TYPE
);
6994 if (!function2_template
)
6995 function2_template
= make_node (FUNCTION_TYPE
);
6997 /* Install argument types; normally set by build_function_type. */
6998 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
6999 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7001 /* Install return type. */
7002 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
7003 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
7005 return comptypes (function1_template
, function2_template
);
7008 /* - Generate an identifier for the function. the format is "_n_cls",
7009 where 1 <= n <= nMethods, and cls is the name the implementation we
7011 - Install the return type from the method declaration.
7012 - If we have a prototype, check for type consistency. */
7015 really_start_method (method
, parmlist
)
7016 tree method
, parmlist
;
7018 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7019 tree method_decl
, method_id
;
7020 const char *sel_name
, *class_name
, *cat_name
;
7023 /* Synth the storage class & assemble the return type. */
7024 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7025 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7026 decl_specs
= chainon (sc_spec
, ret_spec
);
7028 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7029 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7030 cat_name
= ((TREE_CODE (objc_implementation_context
)
7031 == CLASS_IMPLEMENTATION_TYPE
)
7033 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7036 /* Make sure this is big enough for any plausible method label. */
7037 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7038 + (cat_name
? strlen (cat_name
) : 0));
7040 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7041 class_name
, cat_name
, sel_name
, method_slot
);
7043 method_id
= get_identifier (buf
);
7045 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7047 /* Check the declarator portion of the return type for the method. */
7048 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7050 /* Unite the complex decl (specified in the abstract decl) with the
7051 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7052 tree save_expr
= expr_last (ret_decl
);
7054 TREE_OPERAND (save_expr
, 0) = method_decl
;
7055 method_decl
= ret_decl
;
7057 /* Fool the parser into thinking it is starting a function. */
7058 start_function (decl_specs
, method_decl
, NULL_TREE
);
7060 /* Unhook: this has the effect of restoring the abstract declarator. */
7061 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7066 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7068 /* Fool the parser into thinking it is starting a function. */
7069 start_function (decl_specs
, method_decl
, NULL_TREE
);
7071 /* Unhook: this has the effect of restoring the abstract declarator. */
7072 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7075 METHOD_DEFINITION (method
) = current_function_decl
;
7077 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7079 if (implementation_template
!= objc_implementation_context
)
7083 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7084 proto
= lookup_instance_method_static (implementation_template
,
7085 METHOD_SEL_NAME (method
));
7087 proto
= lookup_class_method_static (implementation_template
,
7088 METHOD_SEL_NAME (method
));
7090 if (proto
&& ! comp_method_with_proto (method
, proto
))
7092 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7094 warn_with_method ("conflicting types for", type
, method
);
7095 warn_with_method ("previous declaration of", type
, proto
);
7100 /* The following routine is always called...this "architecture" is to
7101 accommodate "old-style" variable length selectors.
7103 - a:a b:b // prototype ; id c; id d; // old-style. */
7106 continue_method_def ()
7110 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7111 /* We have a `, ...' immediately following the selector. */
7112 parmlist
= get_parm_info (0);
7114 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7116 /* Set self_decl from the first argument...this global is used by
7117 build_ivar_reference calling build_indirect_ref. */
7118 self_decl
= TREE_PURPOSE (parmlist
);
7121 really_start_method (objc_method_context
, parmlist
);
7122 store_parm_decls ();
7125 /* Called by the parser, from the `pushlevel' production. */
7130 if (!UOBJC_SUPER_decl
)
7132 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7133 build_tree_list (NULL_TREE
,
7134 objc_super_template
),
7137 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7139 /* This prevents `unused variable' warnings when compiling with -Wall. */
7140 TREE_USED (UOBJC_SUPER_decl
) = 1;
7141 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7145 /* _n_Method (id self, SEL sel, ...)
7147 struct objc_super _S;
7148 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7152 get_super_receiver ()
7154 if (objc_method_context
)
7156 tree super_expr
, super_expr_list
;
7158 /* Set receiver to self. */
7159 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7160 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7161 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7163 /* Set class to begin searching. */
7164 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7165 get_identifier ("class"));
7167 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7169 /* [_cls, __cls]Super are "pre-built" in
7170 synth_forward_declarations. */
7172 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7173 ((TREE_CODE (objc_method_context
)
7174 == INSTANCE_METHOD_DECL
)
7176 : uucls_super_ref
));
7180 /* We have a category. */
7182 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7185 /* Barf if super used in a category of Object. */
7188 error ("no super class declared in interface for `%s'",
7189 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7190 return error_mark_node
;
7193 if (flag_next_runtime
)
7195 super_class
= get_class_reference (super_name
);
7196 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7198 = build_component_ref (build_indirect_ref (super_class
, "->"),
7199 get_identifier ("isa"));
7203 add_class_reference (super_name
);
7204 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7205 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7206 assemble_external (super_class
);
7208 = build_function_call
7212 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7213 IDENTIFIER_POINTER (super_name
))));
7216 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7217 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7220 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7222 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7223 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7225 return build_compound_expr (super_expr_list
);
7229 error ("[super ...] must appear in a method context");
7230 return error_mark_node
;
7235 encode_method_def (func_decl
)
7240 HOST_WIDE_INT max_parm_end
= 0;
7245 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7246 obstack_object_size (&util_obstack
),
7247 OBJC_ENCODE_INLINE_DEFS
);
7250 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7251 parms
= TREE_CHAIN (parms
))
7253 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7254 + int_size_in_bytes (TREE_TYPE (parms
)));
7256 if (! offset_is_register
&& parm_end
> max_parm_end
)
7257 max_parm_end
= parm_end
;
7260 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7262 sprintf (buffer
, "%d", stack_size
);
7263 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7265 /* Argument types. */
7266 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7267 parms
= TREE_CHAIN (parms
))
7270 encode_type (TREE_TYPE (parms
),
7271 obstack_object_size (&util_obstack
),
7272 OBJC_ENCODE_INLINE_DEFS
);
7274 /* Compute offset. */
7275 sprintf (buffer
, "%d", forwarding_offset (parms
));
7277 /* Indicate register. */
7278 if (offset_is_register
)
7279 obstack_1grow (&util_obstack
, '+');
7281 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7284 /* Null terminate string. */
7285 obstack_1grow (&util_obstack
, 0);
7286 result
= get_identifier (obstack_finish (&util_obstack
));
7287 obstack_free (&util_obstack
, util_firstobj
);
7292 objc_expand_function_end ()
7294 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7298 finish_method_def ()
7300 lang_expand_function_end
= objc_expand_function_end
;
7301 finish_function (0);
7302 lang_expand_function_end
= NULL
;
7304 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7305 since the optimizer may find "may be used before set" errors. */
7306 objc_method_context
= NULL_TREE
;
7311 lang_report_error_function (decl
)
7314 if (objc_method_context
)
7316 fprintf (stderr
, "In method `%s'\n",
7317 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7327 is_complex_decl (type
)
7330 return (TREE_CODE (type
) == ARRAY_TYPE
7331 || TREE_CODE (type
) == FUNCTION_TYPE
7332 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7336 /* Code to convert a decl node into text for a declaration in C. */
7338 static char tmpbuf
[256];
7341 adorn_decl (decl
, str
)
7345 enum tree_code code
= TREE_CODE (decl
);
7347 if (code
== ARRAY_REF
)
7349 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7351 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7352 sprintf (str
+ strlen (str
), "[%ld]",
7353 (long) TREE_INT_CST_LOW (an_int_cst
));
7358 else if (code
== ARRAY_TYPE
)
7360 tree an_int_cst
= TYPE_SIZE (decl
);
7361 tree array_of
= TREE_TYPE (decl
);
7363 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7364 sprintf (str
+ strlen (str
), "[%ld]",
7365 (long) (TREE_INT_CST_LOW (an_int_cst
)
7366 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7371 else if (code
== CALL_EXPR
)
7373 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7378 gen_declaration_1 (chain
, str
);
7379 chain
= TREE_CHAIN (chain
);
7386 else if (code
== FUNCTION_TYPE
)
7388 tree chain
= TYPE_ARG_TYPES (decl
);
7391 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7393 gen_declaration_1 (TREE_VALUE (chain
), str
);
7394 chain
= TREE_CHAIN (chain
);
7395 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7401 else if (code
== INDIRECT_REF
)
7403 strcpy (tmpbuf
, "*");
7404 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7408 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7410 chain
= TREE_CHAIN (chain
))
7412 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7414 strcat (tmpbuf
, " ");
7415 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7419 strcat (tmpbuf
, " ");
7421 strcat (tmpbuf
, str
);
7422 strcpy (str
, tmpbuf
);
7425 else if (code
== POINTER_TYPE
)
7427 strcpy (tmpbuf
, "*");
7428 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7430 if (TREE_READONLY (decl
))
7431 strcat (tmpbuf
, " const");
7432 if (TYPE_VOLATILE (decl
))
7433 strcat (tmpbuf
, " volatile");
7435 strcat (tmpbuf
, " ");
7437 strcat (tmpbuf
, str
);
7438 strcpy (str
, tmpbuf
);
7443 gen_declarator (decl
, buf
, name
)
7450 enum tree_code code
= TREE_CODE (decl
);
7460 op
= TREE_OPERAND (decl
, 0);
7462 /* We have a pointer to a function or array...(*)(), (*)[] */
7463 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7464 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7467 str
= gen_declarator (op
, buf
, name
);
7471 strcpy (tmpbuf
, "(");
7472 strcat (tmpbuf
, str
);
7473 strcat (tmpbuf
, ")");
7474 strcpy (str
, tmpbuf
);
7477 adorn_decl (decl
, str
);
7486 /* This clause is done iteratively rather than recursively. */
7489 op
= (is_complex_decl (TREE_TYPE (decl
))
7490 ? TREE_TYPE (decl
) : NULL_TREE
);
7492 adorn_decl (decl
, str
);
7494 /* We have a pointer to a function or array...(*)(), (*)[] */
7495 if (code
== POINTER_TYPE
7496 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7497 || TREE_CODE (op
) == ARRAY_TYPE
))
7499 strcpy (tmpbuf
, "(");
7500 strcat (tmpbuf
, str
);
7501 strcat (tmpbuf
, ")");
7502 strcpy (str
, tmpbuf
);
7505 decl
= (is_complex_decl (TREE_TYPE (decl
))
7506 ? TREE_TYPE (decl
) : NULL_TREE
);
7509 while (decl
&& (code
= TREE_CODE (decl
)))
7514 case IDENTIFIER_NODE
:
7515 /* Will only happen if we are processing a "raw" expr-decl. */
7516 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7527 /* We have an abstract declarator or a _DECL node. */
7535 gen_declspecs (declspecs
, buf
, raw
)
7544 for (chain
= nreverse (copy_list (declspecs
));
7545 chain
; chain
= TREE_CHAIN (chain
))
7547 tree aspec
= TREE_VALUE (chain
);
7549 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7550 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7551 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7553 if (TYPE_NAME (aspec
))
7555 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7557 if (! TREE_STATIC_TEMPLATE (aspec
))
7558 strcat (buf
, "struct ");
7559 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7564 tree chain
= protocol_list
;
7571 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7572 chain
= TREE_CHAIN (chain
);
7581 strcat (buf
, "untagged struct");
7584 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7586 if (TYPE_NAME (aspec
))
7588 if (! TREE_STATIC_TEMPLATE (aspec
))
7589 strcat (buf
, "union ");
7590 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7593 strcat (buf
, "untagged union");
7596 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7598 if (TYPE_NAME (aspec
))
7600 if (! TREE_STATIC_TEMPLATE (aspec
))
7601 strcat (buf
, "enum ");
7602 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7605 strcat (buf
, "untagged enum");
7608 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7609 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7611 else if (IS_ID (aspec
))
7613 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7618 tree chain
= protocol_list
;
7625 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7626 chain
= TREE_CHAIN (chain
);
7633 if (TREE_CHAIN (chain
))
7639 /* Type qualifiers. */
7640 if (TREE_READONLY (declspecs
))
7641 strcat (buf
, "const ");
7642 if (TYPE_VOLATILE (declspecs
))
7643 strcat (buf
, "volatile ");
7645 switch (TREE_CODE (declspecs
))
7647 /* Type specifiers. */
7650 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7652 /* Signed integer types. */
7654 if (declspecs
== short_integer_type_node
)
7655 strcat (buf
, "short int ");
7656 else if (declspecs
== integer_type_node
)
7657 strcat (buf
, "int ");
7658 else if (declspecs
== long_integer_type_node
)
7659 strcat (buf
, "long int ");
7660 else if (declspecs
== long_long_integer_type_node
)
7661 strcat (buf
, "long long int ");
7662 else if (declspecs
== signed_char_type_node
7663 || declspecs
== char_type_node
)
7664 strcat (buf
, "char ");
7666 /* Unsigned integer types. */
7668 else if (declspecs
== short_unsigned_type_node
)
7669 strcat (buf
, "unsigned short ");
7670 else if (declspecs
== unsigned_type_node
)
7671 strcat (buf
, "unsigned int ");
7672 else if (declspecs
== long_unsigned_type_node
)
7673 strcat (buf
, "unsigned long ");
7674 else if (declspecs
== long_long_unsigned_type_node
)
7675 strcat (buf
, "unsigned long long ");
7676 else if (declspecs
== unsigned_char_type_node
)
7677 strcat (buf
, "unsigned char ");
7681 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7683 if (declspecs
== float_type_node
)
7684 strcat (buf
, "float ");
7685 else if (declspecs
== double_type_node
)
7686 strcat (buf
, "double ");
7687 else if (declspecs
== long_double_type_node
)
7688 strcat (buf
, "long double ");
7692 if (TYPE_NAME (declspecs
)
7693 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7695 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7697 if (! TREE_STATIC_TEMPLATE (declspecs
))
7698 strcat (buf
, "struct ");
7699 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7703 tree chain
= protocol_list
;
7710 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7711 chain
= TREE_CHAIN (chain
);
7720 strcat (buf
, "untagged struct");
7726 if (TYPE_NAME (declspecs
)
7727 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7729 strcat (buf
, "union ");
7730 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7735 strcat (buf
, "untagged union ");
7739 if (TYPE_NAME (declspecs
)
7740 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7742 strcat (buf
, "enum ");
7743 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7748 strcat (buf
, "untagged enum ");
7752 strcat (buf
, "void ");
7757 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7762 tree chain
= protocol_list
;
7769 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7770 chain
= TREE_CHAIN (chain
);
7786 /* Given a tree node, produce a printable description of it in the given
7787 buffer, overwriting the buffer. */
7790 gen_declaration (atype_or_adecl
, buf
)
7791 tree atype_or_adecl
;
7795 gen_declaration_1 (atype_or_adecl
, buf
);
7799 /* Given a tree node, append a printable description to the end of the
7803 gen_declaration_1 (atype_or_adecl
, buf
)
7804 tree atype_or_adecl
;
7809 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7811 tree declspecs
; /* "identifier_node", "record_type" */
7812 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7814 /* We have a "raw", abstract declarator (typename). */
7815 declarator
= TREE_VALUE (atype_or_adecl
);
7816 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7818 gen_declspecs (declspecs
, buf
, 1);
7822 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7829 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7830 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7832 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7833 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7834 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7835 atype
= TREE_TYPE (atype_or_adecl
);
7837 /* Assume we have a *_type node. */
7838 atype
= atype_or_adecl
;
7840 if (is_complex_decl (atype
))
7844 /* Get the declaration specifier; it is at the end of the list. */
7845 declarator
= chain
= atype
;
7847 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7848 while (is_complex_decl (chain
));
7855 declarator
= NULL_TREE
;
7858 gen_declspecs (declspecs
, buf
, 0);
7860 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7861 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7862 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7864 const char *const decl_name
=
7865 (DECL_NAME (atype_or_adecl
)
7866 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7871 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7874 else if (decl_name
[0])
7877 strcat (buf
, decl_name
);
7880 else if (declarator
)
7883 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7888 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7890 /* Given a method tree, put a printable description into the given
7891 buffer (overwriting) and return a pointer to the buffer. */
7894 gen_method_decl (method
, buf
)
7901 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7904 gen_declaration_1 (TREE_TYPE (method
), buf
);
7908 chain
= METHOD_SEL_ARGS (method
);
7911 /* We have a chain of keyword_decls. */
7914 if (KEYWORD_KEY_NAME (chain
))
7915 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7918 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7921 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7925 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7926 if ((chain
= TREE_CHAIN (chain
)))
7931 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7932 strcat (buf
, ", ...");
7933 else if (METHOD_ADD_ARGS (method
))
7935 /* We have a tree list node as generate by get_parm_info. */
7936 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7938 /* Know we have a chain of parm_decls. */
7942 gen_declaration_1 (chain
, buf
);
7943 chain
= TREE_CHAIN (chain
);
7949 /* We have a unary selector. */
7950 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7958 dump_interface (fp
, chain
)
7962 char *buf
= (char *)xmalloc (256);
7963 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7964 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7965 tree nst_methods
= CLASS_NST_METHODS (chain
);
7966 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7968 fprintf (fp
, "\n@interface %s", my_name
);
7970 if (CLASS_SUPER_NAME (chain
))
7972 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7973 fprintf (fp
, " : %s\n", super_name
);
7980 fprintf (fp
, "{\n");
7983 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7984 ivar_decls
= TREE_CHAIN (ivar_decls
);
7987 fprintf (fp
, "}\n");
7992 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7993 nst_methods
= TREE_CHAIN (nst_methods
);
7998 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7999 cls_methods
= TREE_CHAIN (cls_methods
);
8001 fprintf (fp
, "\n@end");
8004 /* Demangle function for Objective-C */
8006 objc_demangle (mangled
)
8007 const char *mangled
;
8009 char *demangled
, *cp
;
8011 if (mangled
[0] == '_' &&
8012 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8015 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8016 if (mangled
[1] == 'i')
8017 *cp
++ = '-'; /* for instance method */
8019 *cp
++ = '+'; /* for class method */
8020 *cp
++ = '['; /* opening left brace */
8021 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8022 while (*cp
&& *cp
== '_')
8023 cp
++; /* skip any initial underbars in class name */
8024 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8027 free(demangled
); /* not mangled name */
8030 if (cp
[1] == '_') /* easy case: no category name */
8032 *cp
++ = ' '; /* replace two '_' with one ' ' */
8033 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8037 *cp
++ = '('; /* less easy case: category name */
8038 cp
= strchr(cp
, '_');
8041 free(demangled
); /* not mangled name */
8045 *cp
++ = ' '; /* overwriting 1st char of method name... */
8046 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8048 while (*cp
&& *cp
== '_')
8049 cp
++; /* skip any initial underbars in method name */
8052 *cp
= ':'; /* replace remaining '_' with ':' */
8053 *cp
++ = ']'; /* closing right brace */
8054 *cp
++ = 0; /* string terminator */
8058 return mangled
; /* not an objc mangled name */
8062 objc_printable_name (decl
, kind
)
8064 int kind ATTRIBUTE_UNUSED
;
8066 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8072 /* Add the special tree codes of Objective C to the tables. */
8074 gcc_obstack_init (&util_obstack
);
8075 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8077 memcpy (tree_code_type
+ (int) LAST_BASE_TREE_CODE
,
8078 objc_tree_code_type
,
8079 (int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
);
8080 memcpy (tree_code_length
+ (int) LAST_BASE_TREE_CODE
,
8081 objc_tree_code_length
,
8082 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
) * sizeof (int)));
8083 memcpy (tree_code_name
+ (int) LAST_BASE_TREE_CODE
,
8084 objc_tree_code_name
,
8085 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
) * sizeof (char *)));
8087 errbuf
= (char *)xmalloc (BUFSIZE
);
8089 synth_module_prologue ();
8091 /* Change the default error function */
8092 save_lang_status
= &push_c_function_context
;
8093 restore_lang_status
= &pop_c_function_context
;
8094 mark_lang_status
= &mark_c_function_context
;
8095 decl_printable_name
= objc_printable_name
;
8096 lang_expand_expr
= c_expand_expr
;
8097 lang_expand_decl_stmt
= c_expand_decl_stmt
;
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
);