1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC 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 GCC 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 GCC; 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':
44 #include "coretypes.h"
53 #include "langhooks.h"
64 #include "diagnostic.h"
66 #include "tree-iterator.h"
69 /* This is the default way of generating a method name. */
70 /* I am not sure it is really correct.
71 Perhaps there's a danger that it will make name conflicts
72 if method names contain underscores. -- rms. */
73 #ifndef OBJC_GEN_METHOD_LABEL
74 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
77 sprintf ((BUF), "_%s_%s_%s_%s", \
78 ((IS_INST) ? "i" : "c"), \
80 ((CAT_NAME)? (CAT_NAME) : ""), \
82 for (temp = (BUF); *temp; temp++) \
83 if (*temp == ':') *temp = '_'; \
87 /* These need specifying. */
88 #ifndef OBJC_FORWARDING_STACK_OFFSET
89 #define OBJC_FORWARDING_STACK_OFFSET 0
92 #ifndef OBJC_FORWARDING_MIN_OFFSET
93 #define OBJC_FORWARDING_MIN_OFFSET 0
96 /* Set up for use of obstacks. */
100 /* This obstack is used to accumulate the encoding of a data type. */
101 static struct obstack util_obstack;
103 /* This points to the beginning of obstack contents, so we can free
104 the whole contents. */
107 /* The version identifies which language generation and runtime
108 the module (file) was compiled for, and is recorded in the
109 module descriptor. */
111 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
112 #define PROTOCOL_VERSION 2
114 /* (Decide if these can ever be validly changed.) */
115 #define OBJC_ENCODE_INLINE_DEFS 0
116 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
118 /*** Private Interface (procedures) ***/
120 /* Used by compile_file. */
122 static void init_objc (void);
123 static void finish_objc (void);
125 /* Code generation. */
127 static void synth_module_prologue (void);
128 static tree objc_build_constructor (tree, tree);
129 static rtx build_module_descriptor (void);
130 static tree init_module_descriptor (tree);
131 static tree build_objc_method_call (int, tree, tree, tree, tree);
132 static void generate_strings (void);
133 static tree get_proto_encoding (tree);
134 static void build_selector_translation_table (void);
136 static tree objc_add_static_instance (tree, tree);
138 static void build_objc_exception_stuff (void);
139 static void build_next_objc_exception_stuff (void);
141 static tree build_ivar_template (void);
142 static tree build_method_template (void);
143 static tree build_private_template (tree);
144 static void build_class_template (void);
145 static void build_selector_template (void);
146 static void build_category_template (void);
147 static tree lookup_method_in_hash_lists (tree, int);
148 static void build_super_template (void);
149 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
150 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
151 static void synth_forward_declarations (void);
152 static int ivar_list_length (tree);
153 static tree get_class_ivars (tree, int);
154 static void generate_ivar_lists (void);
155 static void generate_dispatch_tables (void);
156 static void generate_shared_structures (void);
157 static tree generate_protocol_list (tree);
158 static void build_protocol_reference (tree);
160 static tree build_keyword_selector (tree);
161 static tree synth_id_with_class_suffix (const char *, tree);
163 static void generate_static_references (void);
164 static int check_methods_accessible (tree, tree, int);
165 static void encode_aggregate_within (tree, int, int, int, int);
166 static const char *objc_demangle (const char *);
167 static void objc_expand_function_end (void);
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash *nst_method_hash_list = 0;
172 hash *cls_method_hash_list = 0;
174 static size_t hash_func (tree);
175 static void hash_init (void);
176 static void hash_enter (hash *, tree);
177 static hash hash_lookup (hash *, tree);
178 static void hash_add_attr (hash, tree);
179 static tree lookup_method (tree, tree);
180 static tree lookup_method_static (tree, tree, int);
181 static void add_method_to_hash_list (hash *, tree);
182 static tree add_class (tree);
183 static void add_category (tree, tree);
184 static inline tree lookup_category (tree, tree);
188 class_names, /* class, category, protocol, module names */
189 meth_var_names, /* method and variable names */
190 meth_var_types /* method and variable type descriptors */
193 static tree add_objc_string (tree, enum string_section);
194 static tree get_objc_string_decl (tree, enum string_section);
195 static tree build_objc_string_decl (enum string_section);
196 static tree build_selector_reference_decl (void);
198 /* Protocol additions. */
200 static tree add_protocol (tree);
201 static tree lookup_protocol (tree);
202 static void check_protocol_recursively (tree, tree);
203 static tree lookup_and_install_protocols (tree);
207 static void encode_type_qualifiers (tree);
208 static void encode_pointer (tree, int, int);
209 static void encode_array (tree, int, int);
210 static void encode_aggregate (tree, int, int);
211 static void encode_next_bitfield (int);
212 static void encode_gnu_bitfield (int, tree, int);
213 static void encode_type (tree, int, int);
214 static void encode_field_decl (tree, int, int);
216 static void really_start_method (tree, tree);
217 static int comp_method_with_proto (tree, tree);
218 static int objc_types_are_equivalent (tree, tree);
219 static int comp_proto_with_proto (tree, tree);
220 static tree get_arg_type_list (tree, int, int);
221 static tree objc_expr_last (tree);
222 static void synth_self_and_ucmd_args (void);
224 /* Utilities for debugging and error diagnostics. */
226 static void warn_with_method (const char *, int, tree);
227 static void error_with_ivar (const char *, tree, tree);
228 static char *gen_method_decl (tree, char *);
229 static char *gen_declaration (tree, char *);
230 static void gen_declaration_1 (tree, char *);
231 static char *gen_declarator (tree, char *, const char *);
232 static int is_complex_decl (tree);
233 static void adorn_decl (tree, char *);
234 static void dump_interface (FILE *, tree);
236 /* Everything else. */
238 static tree define_decl (tree, tree);
239 static tree lookup_method_in_protocol_list (tree, tree, int);
240 static tree lookup_protocol_in_reflist (tree, tree);
241 static tree create_builtin_decl (enum tree_code, tree, const char *);
242 static void setup_string_decl (void);
243 static int check_string_class_template (void);
244 static tree my_build_string (int, const char *);
245 static void build_objc_symtab_template (void);
246 static tree init_def_list (tree);
247 static tree init_objc_symtab (tree);
248 static tree build_metadata_decl (const char *, tree);
249 static void forward_declare_categories (void);
250 static void generate_objc_symtab_decl (void);
251 static tree build_selector (tree);
252 static tree build_typed_selector_reference (tree, tree);
253 static tree build_selector_reference (tree);
254 static tree build_class_reference_decl (void);
255 static void add_class_reference (tree);
256 static tree build_protocol_template (void);
257 static tree build_descriptor_table_initializer (tree, tree);
258 static tree build_method_prototype_list_template (tree, int);
259 static tree build_method_prototype_template (void);
260 static tree objc_method_parm_type (tree);
261 static int objc_encoded_type_size (tree);
262 static tree encode_method_prototype (tree);
263 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
264 static void generate_method_descriptors (tree);
265 static void generate_protocol_references (tree);
266 static void generate_protocols (void);
267 static void check_ivars (tree, tree);
268 static tree build_ivar_list_template (tree, int);
269 static tree build_method_list_template (tree, int);
270 static tree build_ivar_list_initializer (tree, tree);
271 static tree generate_ivars_list (tree, const char *, int, tree);
272 static tree build_dispatch_table_initializer (tree, tree);
273 static tree generate_dispatch_table (tree, const char *, int, tree);
274 static tree build_shared_structure_initializer (tree, tree, tree, tree,
275 tree, int, tree, tree, tree);
276 static void generate_category (tree);
277 static int is_objc_type_qualifier (tree);
278 static tree adjust_type_for_id_default (tree);
279 static tree check_duplicates (hash, int, int);
280 static tree receiver_is_class_object (tree, int, int);
281 static int check_methods (tree, tree, int);
282 static int conforms_to_protocol (tree, tree);
283 static void check_protocol (tree, const char *, const char *);
284 static void check_protocols (tree, const char *, const char *);
285 static void gen_declspecs (tree, char *, int);
286 static void generate_classref_translation_entry (tree);
287 static void handle_class_ref (tree);
288 static void generate_struct_by_value_array (void)
290 static void mark_referenced_methods (void);
291 static void generate_objc_image_info (void);
293 /*** Private Interface (data) ***/
295 /* Reserved tag definitions. */
298 #define TAG_OBJECT "objc_object"
299 #define TAG_CLASS "objc_class"
300 #define TAG_SUPER "objc_super"
301 #define TAG_SELECTOR "objc_selector"
303 #define UTAG_CLASS "_objc_class"
304 #define UTAG_IVAR "_objc_ivar"
305 #define UTAG_IVAR_LIST "_objc_ivar_list"
306 #define UTAG_METHOD "_objc_method"
307 #define UTAG_METHOD_LIST "_objc_method_list"
308 #define UTAG_CATEGORY "_objc_category"
309 #define UTAG_MODULE "_objc_module"
310 #define UTAG_SYMTAB "_objc_symtab"
311 #define UTAG_SUPER "_objc_super"
312 #define UTAG_SELECTOR "_objc_selector"
314 #define UTAG_PROTOCOL "_objc_protocol"
315 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
316 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
318 /* Note that the string object global name is only needed for the
320 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
322 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
324 static const char *TAG_GETCLASS;
325 static const char *TAG_GETMETACLASS;
326 static const char *TAG_MSGSEND;
327 static const char *TAG_MSGSENDSUPER;
328 /* The NeXT Objective-C messenger may have two extra entry points, for use
329 when returning a structure. */
330 static const char *TAG_MSGSEND_STRET;
331 static const char *TAG_MSGSENDSUPER_STRET;
332 static const char *TAG_EXECCLASS;
333 static const char *default_constant_string_class_name;
335 /* Runtime metadata flags. */
336 #define CLS_FACTORY 0x0001L
337 #define CLS_META 0x0002L
339 #define OBJC_MODIFIER_STATIC 0x00000001
340 #define OBJC_MODIFIER_FINAL 0x00000002
341 #define OBJC_MODIFIER_PUBLIC 0x00000004
342 #define OBJC_MODIFIER_PRIVATE 0x00000008
343 #define OBJC_MODIFIER_PROTECTED 0x00000010
344 #define OBJC_MODIFIER_NATIVE 0x00000020
345 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
346 #define OBJC_MODIFIER_ABSTRACT 0x00000080
347 #define OBJC_MODIFIER_VOLATILE 0x00000100
348 #define OBJC_MODIFIER_TRANSIENT 0x00000200
349 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
351 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
352 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
353 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
354 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
355 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
356 #define TAG_EXCEPTIONMATCH "objc_exception_match"
357 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
358 #define TAG_SYNCENTER "objc_sync_enter"
359 #define TAG_SYNCEXIT "objc_sync_exit"
360 #define TAG_SETJMP "_setjmp"
361 #define TAG_RETURN_STRUCT "objc_return_struct"
363 #define UTAG_EXCDATA "_objc_exception_data"
365 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
366 tree objc_global_trees[OCTI_MAX];
368 static void handle_impent (struct imp_entry *);
370 struct imp_entry *imp_list = 0;
371 int imp_count = 0; /* `@implementation' */
372 int cat_count = 0; /* `@category' */
374 /* Use to generate method labels. */
375 static int method_slot = 0;
379 static char *errbuf; /* Buffer for error diagnostics */
381 /* Data imported from tree.c. */
383 extern enum debug_info_type write_symbols;
385 /* Data imported from toplev.c. */
387 extern const char *dump_base_name;
389 static int flag_typed_selectors;
391 FILE *gen_declaration_file;
393 /* Tells "encode_pointer/encode_aggregate" whether we are generating
394 type descriptors for instance variables (as opposed to methods).
395 Type descriptors for instance variables contain more information
396 than methods (for static typing and embedded structures). */
398 static int generating_instance_variables = 0;
400 /* Some platforms pass small structures through registers versus
401 through an invisible pointer. Determine at what size structure is
402 the transition point between the two possibilities. */
405 generate_struct_by_value_array (void)
408 tree field_decl, field_decl_chain;
410 int aggregate_in_mem[32];
413 /* Presumably no platform passes 32 byte structures in a register. */
414 for (i = 1; i < 32; i++)
418 /* Create an unnamed struct that has `i' character components */
419 type = start_struct (RECORD_TYPE, NULL_TREE);
421 strcpy (buffer, "c1");
422 field_decl = create_builtin_decl (FIELD_DECL,
425 field_decl_chain = field_decl;
427 for (j = 1; j < i; j++)
429 sprintf (buffer, "c%d", j + 1);
430 field_decl = create_builtin_decl (FIELD_DECL,
433 chainon (field_decl_chain, field_decl);
435 finish_struct (type, field_decl_chain, NULL_TREE);
437 aggregate_in_mem[i] = aggregate_value_p (type, 0);
438 if (!aggregate_in_mem[i])
442 /* We found some structures that are returned in registers instead of memory
443 so output the necessary data. */
446 for (i = 31; i >= 0; i--)
447 if (!aggregate_in_mem[i])
449 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
451 /* The first member of the structure is always 0 because we don't handle
452 structures with 0 members */
453 printf ("static int struct_forward_array[] = {\n 0");
455 for (j = 1; j <= i; j++)
456 printf (", %d", aggregate_in_mem[j]);
466 if (c_objc_common_init () == false)
469 /* Force the line number back to 0; check_newline will have
470 raised it to 1, which will make the builtin functions appear
471 not to be built in. */
474 /* If gen_declaration desired, open the output file. */
475 if (flag_gen_declaration)
477 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
478 gen_declaration_file = fopen (dumpname, "w");
479 if (gen_declaration_file == 0)
480 fatal_error ("can't open %s: %m", dumpname);
484 if (flag_next_runtime)
486 TAG_GETCLASS = "objc_getClass";
487 TAG_GETMETACLASS = "objc_getMetaClass";
488 TAG_MSGSEND = "objc_msgSend";
489 TAG_MSGSENDSUPER = "objc_msgSendSuper";
490 TAG_MSGSEND_STRET = "objc_msgSend_stret";
491 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
492 TAG_EXECCLASS = "__objc_execClass";
493 default_constant_string_class_name = "NSConstantString";
497 TAG_GETCLASS = "objc_get_class";
498 TAG_GETMETACLASS = "objc_get_meta_class";
499 TAG_MSGSEND = "objc_msg_lookup";
500 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
501 /* GNU runtime does not provide special functions to support
502 structure-returning methods. */
503 TAG_EXECCLASS = "__objc_exec_class";
504 default_constant_string_class_name = "NXConstantString";
505 flag_typed_selectors = 1;
508 objc_ellipsis_node = make_node (ERROR_MARK);
512 if (print_struct_values)
513 generate_struct_by_value_array ();
521 mark_referenced_methods ();
522 c_objc_common_finish_file ();
524 /* Finalize Objective-C runtime data. No need to generate tables
525 and code if only checking syntax. */
526 if (!flag_syntax_only)
529 if (gen_declaration_file)
530 fclose (gen_declaration_file);
534 define_decl (tree declarator, tree declspecs)
536 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
537 finish_decl (decl, NULL_TREE, NULL_TREE);
541 /* Return the first occurrence of a method declaration corresponding
542 to sel_name in rproto_list. Search rproto_list recursively.
543 If is_class is 0, search for instance methods, otherwise for class
546 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
552 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
554 p = TREE_VALUE (rproto);
556 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
558 if ((fnd = lookup_method (is_class
559 ? PROTOCOL_CLS_METHODS (p)
560 : PROTOCOL_NST_METHODS (p), sel_name)))
562 else if (PROTOCOL_LIST (p))
563 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
568 ; /* An identifier...if we could not find a protocol. */
579 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
583 /* Make sure the protocol is supported by the object on the rhs. */
584 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
587 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
589 p = TREE_VALUE (rproto);
591 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
596 else if (PROTOCOL_LIST (p))
597 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
606 ; /* An identifier...if we could not find a protocol. */
612 /* Return true if TYPE is 'id'. */
615 objc_is_object_id (tree type)
617 return OBJC_TYPE_NAME (type) == objc_object_id;
621 objc_is_class_id (tree type)
623 return OBJC_TYPE_NAME (type) == objc_class_id;
626 /* Return 1 if LHS and RHS are compatible types for assignment or
627 various other operations. Return 0 if they are incompatible, and
628 return -1 if we choose to not decide (because the types are really
629 just C types, not ObjC specific ones). When the operation is
630 REFLEXIVE (typically comparisons), check for compatibility in
631 either direction; when it's not (typically assignments), don't.
633 This function is called in two cases: when both lhs and rhs are
634 pointers to records (in which case we check protocols too), and
635 when both lhs and rhs are records (in which case we check class
638 Warnings about classes/protocols not implementing a protocol are
639 emitted here (multiple of those warnings might be emitted for a
640 single line!); generic warnings about incompatible assignments and
641 lacks of casts in comparisons are/must be emitted by the caller if
646 objc_comptypes (tree lhs, tree rhs, int reflexive)
648 /* New clause for protocols. */
650 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
651 manage the ObjC ones, and leave the rest to the C code. */
652 if (TREE_CODE (lhs) == POINTER_TYPE
653 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
654 && TREE_CODE (rhs) == POINTER_TYPE
655 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
657 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
658 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
662 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
663 tree rproto, rproto_list;
666 /* <Protocol> = <Protocol> */
669 rproto_list = TYPE_PROTOCOL_LIST (rhs);
673 /* An assignment between objects of type 'id
674 <Protocol>'; make sure the protocol on the lhs is
675 supported by the object on the rhs. */
676 for (lproto = lproto_list; lproto;
677 lproto = TREE_CHAIN (lproto))
679 p = TREE_VALUE (lproto);
680 rproto = lookup_protocol_in_reflist (rproto_list, p);
684 ("object does not conform to the `%s' protocol",
685 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
691 /* Obscure case - a comparison between two objects
692 of type 'id <Protocol>'. Check that either the
693 protocol on the lhs is supported by the object on
694 the rhs, or viceversa. */
696 /* Check if the protocol on the lhs is supported by the
697 object on the rhs. */
698 for (lproto = lproto_list; lproto;
699 lproto = TREE_CHAIN (lproto))
701 p = TREE_VALUE (lproto);
702 rproto = lookup_protocol_in_reflist (rproto_list, p);
706 /* Check failed - check if the protocol on the rhs
707 is supported by the object on the lhs. */
708 for (rproto = rproto_list; rproto;
709 rproto = TREE_CHAIN (rproto))
711 p = TREE_VALUE (rproto);
712 lproto = lookup_protocol_in_reflist (lproto_list,
717 /* This check failed too: incompatible */
727 /* <Protocol> = <class> * */
728 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
730 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
733 /* Make sure the protocol is supported by the object on
735 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
737 p = TREE_VALUE (lproto);
739 rinter = lookup_interface (rname);
741 while (rinter && !rproto)
745 rproto_list = CLASS_PROTOCOL_LIST (rinter);
746 rproto = lookup_protocol_in_reflist (rproto_list, p);
747 /* If the underlying ObjC class does not have
748 the protocol we're looking for, check for "one-off"
749 protocols (e.g., `NSObject<MyProt> *foo;') attached
753 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
754 rproto = lookup_protocol_in_reflist (rproto_list, p);
757 /* Check for protocols adopted by categories. */
758 cat = CLASS_CATEGORY_LIST (rinter);
759 while (cat && !rproto)
761 rproto_list = CLASS_PROTOCOL_LIST (cat);
762 rproto = lookup_protocol_in_reflist (rproto_list, p);
763 cat = CLASS_CATEGORY_LIST (cat);
766 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
770 warning ("class `%s' does not implement the `%s' protocol",
771 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
772 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
776 /* <Protocol> = id */
777 else if (objc_is_object_id (TREE_TYPE (rhs)))
781 /* <Protocol> = Class */
782 else if (objc_is_class_id (TREE_TYPE (rhs)))
786 /* <Protocol> = ?? : let comptypes decide. */
789 else if (rhs_is_proto)
791 /* <class> * = <Protocol> */
792 if (TYPED_OBJECT (TREE_TYPE (lhs)))
796 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
798 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
800 /* Make sure the protocol is supported by the object on
802 for (rproto = rproto_list; rproto;
803 rproto = TREE_CHAIN (rproto))
805 tree p = TREE_VALUE (rproto);
807 rinter = lookup_interface (rname);
809 while (rinter && !lproto)
813 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
814 lproto = lookup_protocol_in_reflist (lproto_list, p);
815 /* If the underlying ObjC class does not
816 have the protocol we're looking for,
817 check for "one-off" protocols (e.g.,
818 `NSObject<MyProt> *foo;') attached to the
822 lproto_list = TYPE_PROTOCOL_LIST
824 lproto = lookup_protocol_in_reflist
828 /* Check for protocols adopted by categories. */
829 cat = CLASS_CATEGORY_LIST (rinter);
830 while (cat && !lproto)
832 lproto_list = CLASS_PROTOCOL_LIST (cat);
833 lproto = lookup_protocol_in_reflist (lproto_list,
835 cat = CLASS_CATEGORY_LIST (cat);
838 rinter = lookup_interface (CLASS_SUPER_NAME
843 warning ("class `%s' does not implement the `%s' protocol",
844 IDENTIFIER_POINTER (OBJC_TYPE_NAME
846 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
853 /* id = <Protocol> */
854 else if (objc_is_object_id (TREE_TYPE (lhs)))
858 /* Class = <Protocol> */
859 else if (objc_is_class_id (TREE_TYPE (lhs)))
863 /* ??? = <Protocol> : let comptypes decide */
871 /* Attention: we shouldn't defer to comptypes here. One bad
872 side effect would be that we might loose the REFLEXIVE
875 lhs = TREE_TYPE (lhs);
876 rhs = TREE_TYPE (rhs);
880 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
882 /* Nothing to do with ObjC - let immediately comptypes take
883 responsibility for checking. */
887 /* `id' = `<class> *' `<class> *' = `id': always allow it.
889 'Object *o = [[Object alloc] init]; falls
890 in the case <class> * = `id'.
892 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
893 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
896 /* `id' = `Class', `Class' = `id' */
898 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
899 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
902 /* `Class' != `<class> *' && `<class> *' != `Class'! */
903 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
904 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
907 /* `<class> *' = `<class> *' */
909 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
911 tree lname = OBJC_TYPE_NAME (lhs);
912 tree rname = OBJC_TYPE_NAME (rhs);
918 /* If the left hand side is a super class of the right hand side,
920 for (inter = lookup_interface (rname); inter;
921 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
922 if (lname == CLASS_SUPER_NAME (inter))
925 /* Allow the reverse when reflexive. */
927 for (inter = lookup_interface (lname); inter;
928 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
929 if (rname == CLASS_SUPER_NAME (inter))
935 /* Not an ObjC type - let comptypes do the check. */
939 /* Called from finish_decl. */
942 objc_check_decl (tree decl)
944 tree type = TREE_TYPE (decl);
946 if (TREE_CODE (type) != RECORD_TYPE)
948 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
949 error ("statically allocated instance of Objective-C class `%s'",
950 IDENTIFIER_POINTER (type));
953 /* Implement static typing. At this point, we know we have an interface. */
956 get_static_reference (tree interface, tree protocols)
958 tree type = xref_tag (RECORD_TYPE, interface);
962 tree t, m = TYPE_MAIN_VARIANT (type);
964 t = copy_node (type);
966 /* Add this type to the chain of variants of TYPE. */
967 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
968 TYPE_NEXT_VARIANT (m) = t;
970 /* Look up protocols and install in lang specific list. Note
971 that the protocol list can have a different lifetime than T! */
972 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
974 /* This forces a new pointer type to be created later
975 (in build_pointer_type)...so that the new template
976 we just created will actually be used...what a hack! */
977 if (TYPE_POINTER_TO (t))
978 TYPE_POINTER_TO (t) = NULL_TREE;
986 /* Return a declaration corresponding to a protocol list qualified 'id'. */
988 get_protocol_reference (tree protocols)
990 tree type_decl = lookup_name (objc_id_id);
993 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
995 type = TREE_TYPE (type_decl);
996 if (TYPE_MAIN_VARIANT (type) != objc_id_type)
997 warning ("unexpected type for `id' (%s)",
998 gen_declaration (type, errbuf));
1002 error ("undefined type `id', please import <objc/objc.h>");
1003 return error_mark_node;
1006 /* This clause creates a new pointer type that is qualified with
1007 the protocol specification...this info is used later to do more
1008 elaborate type checking. */
1012 tree t, m = TYPE_MAIN_VARIANT (type);
1014 t = copy_node (type);
1016 /* Add this type to the chain of variants of TYPE. */
1017 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1018 TYPE_NEXT_VARIANT (m) = t;
1020 /* Look up protocols...and install in lang specific list */
1021 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1023 /* This forces a new pointer type to be created later
1024 (in build_pointer_type)...so that the new template
1025 we just created will actually be used...what a hack! */
1026 if (TYPE_POINTER_TO (t))
1027 TYPE_POINTER_TO (t) = NULL_TREE;
1034 /* Check for circular dependencies in protocols. The arguments are
1035 PROTO, the protocol to check, and LIST, a list of protocol it
1039 check_protocol_recursively (tree proto, tree list)
1043 for (p = list; p; p = TREE_CHAIN (p))
1045 tree pp = TREE_VALUE (p);
1047 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1048 pp = lookup_protocol (pp);
1051 fatal_error ("protocol `%s' has circular dependency",
1052 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1054 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1058 /* Look up PROTOCOLS, and return a list of those that are found.
1059 If none are found, return NULL. */
1062 lookup_and_install_protocols (tree protocols)
1065 tree return_value = NULL_TREE;
1067 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1069 tree ident = TREE_VALUE (proto);
1070 tree p = lookup_protocol (ident);
1073 error ("cannot find protocol declaration for `%s'",
1074 IDENTIFIER_POINTER (ident));
1076 return_value = chainon (return_value,
1077 build_tree_list (NULL_TREE, p));
1080 return return_value;
1083 /* Create and push a decl for a built-in external variable or field NAME.
1085 TYPE is its data type. */
1088 create_builtin_decl (enum tree_code code, tree type, const char *name)
1090 tree decl = build_decl (code, get_identifier (name), type);
1092 if (code == VAR_DECL)
1094 TREE_STATIC (decl) = 1;
1095 make_decl_rtl (decl, 0);
1097 DECL_ARTIFICIAL (decl) = 1;
1103 /* Find the decl for the constant string class. */
1106 setup_string_decl (void)
1108 if (!string_class_decl)
1110 if (!constant_string_global_id)
1114 /* %s in format will provide room for terminating null */
1115 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1116 + strlen (constant_string_class_name);
1117 name = xmalloc (length);
1118 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1119 constant_string_class_name);
1120 constant_string_global_id = get_identifier (name);
1122 string_class_decl = lookup_name (constant_string_global_id);
1126 /* Purpose: "play" parser, creating/installing representations
1127 of the declarations that are required by Objective-C.
1131 type_spec--------->sc_spec
1132 (tree_list) (tree_list)
1135 identifier_node identifier_node */
1138 synth_module_prologue (void)
1142 /* Defined in `objc.h' */
1143 objc_object_id = get_identifier (TAG_OBJECT);
1145 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1147 objc_id_type = build_pointer_type (objc_object_reference);
1149 objc_id_id = get_identifier (TYPE_ID);
1150 objc_class_id = get_identifier (TAG_CLASS);
1152 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1153 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1154 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1155 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, temp_type));
1157 /* Declare type of selector-objects that represent an operation name. */
1159 if (flag_next_runtime)
1160 /* `struct objc_selector *' */
1162 = build_pointer_type (xref_tag (RECORD_TYPE,
1163 get_identifier (TAG_SELECTOR)));
1165 /* `const struct objc_selector *' */
1167 = build_pointer_type
1168 (build_qualified_type (xref_tag (RECORD_TYPE,
1169 get_identifier (TAG_SELECTOR)),
1172 /* Declare receiver type used for dispatching messages to 'super'. */
1174 /* `struct objc_super *' */
1175 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1176 get_identifier (TAG_SUPER)));
1178 if (flag_next_runtime)
1180 /* NB: In order to call one of the ..._stret (struct-returning)
1181 functions, the function *MUST* first be cast to a signature that
1182 corresponds to the actual ObjC method being invoked. This is
1183 what is done by the build_objc_method_call() routine below. */
1185 /* id objc_msgSend (id, SEL, ...); */
1186 /* id objc_msgSendNonNil (id, SEL, ...); */
1187 /* id objc_msgSend_stret (id, SEL, ...); */
1188 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1190 = build_function_type (objc_id_type,
1191 tree_cons (NULL_TREE, objc_id_type,
1192 tree_cons (NULL_TREE,
1195 umsg_decl = builtin_function (TAG_MSGSEND,
1196 temp_type, 0, NOT_BUILT_IN,
1198 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1199 temp_type, 0, NOT_BUILT_IN,
1201 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1202 temp_type, 0, NOT_BUILT_IN,
1204 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1205 temp_type, 0, NOT_BUILT_IN,
1208 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1209 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1211 = build_function_type (objc_id_type,
1212 tree_cons (NULL_TREE, objc_super_type,
1213 tree_cons (NULL_TREE,
1216 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1217 temp_type, 0, NOT_BUILT_IN,
1219 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1220 temp_type, 0, NOT_BUILT_IN, 0,
1225 /* GNU runtime messenger entry points. */
1227 /* typedef id (*IMP)(id, SEL, ...); */
1229 = build_pointer_type
1230 (build_function_type (objc_id_type,
1231 tree_cons (NULL_TREE, objc_id_type,
1232 tree_cons (NULL_TREE,
1236 /* IMP objc_msg_lookup (id, SEL); */
1238 = build_function_type (IMP_type,
1239 tree_cons (NULL_TREE, objc_id_type,
1240 tree_cons (NULL_TREE,
1243 umsg_decl = builtin_function (TAG_MSGSEND,
1244 temp_type, 0, NOT_BUILT_IN,
1247 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1249 = build_function_type (IMP_type,
1250 tree_cons (NULL_TREE, objc_super_type,
1251 tree_cons (NULL_TREE,
1254 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1255 temp_type, 0, NOT_BUILT_IN,
1259 /* id objc_getClass (const char *); */
1261 temp_type = build_function_type (objc_id_type,
1262 tree_cons (NULL_TREE,
1263 const_string_type_node,
1267 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1270 /* id objc_getMetaClass (const char *); */
1272 objc_get_meta_class_decl
1273 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1275 build_super_template ();
1276 build_objc_exception_stuff ();
1277 if (flag_next_runtime)
1278 build_next_objc_exception_stuff ();
1280 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1282 if (! flag_next_runtime)
1284 if (flag_typed_selectors)
1286 /* Suppress outputting debug symbols, because
1287 dbxout_init hasn'r been called yet. */
1288 enum debug_info_type save_write_symbols = write_symbols;
1289 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1290 write_symbols = NO_DEBUG;
1291 debug_hooks = &do_nothing_debug_hooks;
1293 build_selector_template ();
1294 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1296 write_symbols = save_write_symbols;
1297 debug_hooks = save_hooks;
1300 temp_type = build_array_type (objc_selector_type, NULL_TREE);
1302 layout_type (temp_type);
1303 UOBJC_SELECTOR_TABLE_decl
1304 = create_builtin_decl (VAR_DECL, temp_type,
1305 "_OBJC_SELECTOR_TABLE");
1307 /* Avoid warning when not sending messages. */
1308 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1311 /* Forward declare constant_string_id and constant_string_type. */
1312 if (!constant_string_class_name)
1313 constant_string_class_name = default_constant_string_class_name;
1315 constant_string_id = get_identifier (constant_string_class_name);
1316 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1318 /* Pre-build the following entities - for speed/convenience. */
1319 self_id = get_identifier ("self");
1320 ucmd_id = get_identifier ("_cmd");
1322 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1323 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1327 /* Ensure that the ivar list for NSConstantString/NXConstantString
1328 (or whatever was specified via `-fconstant-string-class')
1329 contains fields at least as large as the following three, so that
1330 the runtime can stomp on them with confidence:
1332 struct STRING_OBJECT_CLASS_NAME
1336 unsigned int length;
1340 check_string_class_template (void)
1342 tree field_decl = TYPE_FIELDS (constant_string_type);
1344 #define AT_LEAST_AS_LARGE_AS(F, T) \
1345 (F && TREE_CODE (F) == FIELD_DECL \
1346 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1347 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1349 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1352 field_decl = TREE_CHAIN (field_decl);
1353 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1356 field_decl = TREE_CHAIN (field_decl);
1357 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1359 #undef AT_LEAST_AS_LARGE_AS
1362 /* Avoid calling `check_string_class_template ()' more than once. */
1363 static GTY(()) int string_layout_checked;
1365 /* Custom build_string which sets TREE_TYPE! */
1368 my_build_string (int len, const char *str)
1370 return fix_string_type (build_string (len, str));
1373 /* Given a chain of STRING_CST's, build a static instance of
1374 NXConstantString which points at the concatenation of those
1375 strings. We place the string object in the __string_objects
1376 section of the __OBJC segment. The Objective-C runtime will
1377 initialize the isa pointers of the string objects to point at the
1378 NXConstantString class object. */
1381 build_objc_string_object (tree string)
1383 tree initlist, constructor, constant_string_class;
1387 string = fix_string_type (string);
1389 constant_string_class = lookup_interface (constant_string_id);
1390 if (!constant_string_class
1391 || !(constant_string_type
1392 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1394 error ("cannot find interface declaration for `%s'",
1395 IDENTIFIER_POINTER (constant_string_id));
1396 return error_mark_node;
1399 /* Call to 'combine_strings' has been moved above. */
1400 TREE_SET_CODE (string, STRING_CST);
1401 length = TREE_STRING_LENGTH (string) - 1;
1403 if (!string_layout_checked)
1405 /* The NSConstantString/NXConstantString ivar layout is now
1407 if (!check_string_class_template ())
1409 error ("interface `%s' does not have valid constant string layout",
1410 IDENTIFIER_POINTER (constant_string_id));
1411 return error_mark_node;
1413 add_class_reference (constant_string_id);
1415 fields = TYPE_FIELDS (constant_string_type);
1417 /* & ((NXConstantString) { NULL, string, length }) */
1419 if (flag_next_runtime)
1421 /* For the NeXT runtime, we can generate a literal reference
1422 to the string class, don't need to run a constructor. */
1423 setup_string_decl ();
1424 if (string_class_decl == NULL_TREE)
1426 error ("cannot find reference tag for class `%s'",
1427 IDENTIFIER_POINTER (constant_string_id));
1428 return error_mark_node;
1430 initlist = build_tree_list
1432 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1436 initlist = build_tree_list (fields, build_int_2 (0, 0));
1439 fields = TREE_CHAIN (fields);
1442 = tree_cons (fields, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1445 fields = TREE_CHAIN (fields);
1447 initlist = tree_cons (fields, build_int_2 (length, 0), initlist);
1448 constructor = objc_build_constructor (constant_string_type,
1449 nreverse (initlist));
1451 if (!flag_next_runtime)
1454 = objc_add_static_instance (constructor, constant_string_type);
1457 return (build_unary_op (ADDR_EXPR, constructor, 1));
1460 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1462 static GTY(()) int num_static_inst;
1465 objc_add_static_instance (tree constructor, tree class_decl)
1470 /* Find the list of static instances for the CLASS_DECL. Create one if
1472 for (chain = &objc_static_instances;
1473 *chain && TREE_VALUE (*chain) != class_decl;
1474 chain = &TREE_CHAIN (*chain));
1477 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1478 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1481 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1482 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1483 DECL_COMMON (decl) = 1;
1484 TREE_STATIC (decl) = 1;
1485 DECL_ARTIFICIAL (decl) = 1;
1486 DECL_INITIAL (decl) = constructor;
1488 /* We may be writing something else just now.
1489 Postpone till end of input. */
1490 DECL_DEFER_OUTPUT (decl) = 1;
1491 pushdecl_top_level (decl);
1492 rest_of_decl_compilation (decl, 0, 1, 0);
1494 /* Add the DECL to the head of this CLASS' list. */
1495 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1500 /* Build a static constant CONSTRUCTOR
1501 with type TYPE and elements ELTS. */
1504 objc_build_constructor (tree type, tree elts)
1506 tree constructor, f, e;
1508 /* ??? Most of the places that we build constructors, we don't fill in
1509 the type of integers properly. Convert them all en masse. */
1510 if (TREE_CODE (type) == ARRAY_TYPE)
1512 f = TREE_TYPE (type);
1513 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1514 for (e = elts; e ; e = TREE_CHAIN (e))
1515 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1519 f = TYPE_FIELDS (type);
1520 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1521 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1522 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1523 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1526 constructor = build_constructor (type, elts);
1527 TREE_CONSTANT (constructor) = 1;
1528 TREE_STATIC (constructor) = 1;
1529 TREE_READONLY (constructor) = 1;
1532 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1533 build_unary_op (wasn't true in 2.7.2.1 days) */
1534 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1539 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1541 /* Predefine the following data type:
1549 void *defs[cls_def_cnt + cat_def_cnt];
1553 build_objc_symtab_template (void)
1555 tree field_decl, field_decl_chain;
1557 objc_symtab_template
1558 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1560 /* long sel_ref_cnt; */
1562 field_decl = create_builtin_decl (FIELD_DECL,
1563 long_integer_type_node,
1565 field_decl_chain = field_decl;
1569 field_decl = create_builtin_decl (FIELD_DECL,
1570 build_pointer_type (objc_selector_type),
1572 chainon (field_decl_chain, field_decl);
1574 /* short cls_def_cnt; */
1576 field_decl = create_builtin_decl (FIELD_DECL,
1577 short_integer_type_node,
1579 chainon (field_decl_chain, field_decl);
1581 /* short cat_def_cnt; */
1583 field_decl = create_builtin_decl (FIELD_DECL,
1584 short_integer_type_node,
1586 chainon (field_decl_chain, field_decl);
1588 if (imp_count || cat_count || !flag_next_runtime)
1590 /* void *defs[imp_count + cat_count (+ 1)]; */
1591 /* NB: The index is one less than the size of the array. */
1592 int index = imp_count + cat_count
1593 + (flag_next_runtime? -1: 0);
1594 field_decl = create_builtin_decl
1598 build_index_type (build_int_2 (index, 0))),
1600 chainon (field_decl_chain, field_decl);
1603 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1606 /* Create the initial value for the `defs' field of _objc_symtab.
1607 This is a CONSTRUCTOR. */
1610 init_def_list (tree type)
1612 tree expr, initlist = NULL_TREE;
1613 struct imp_entry *impent;
1616 for (impent = imp_list; impent; impent = impent->next)
1618 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1620 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1621 initlist = tree_cons (NULL_TREE, expr, initlist);
1626 for (impent = imp_list; impent; impent = impent->next)
1628 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1630 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1631 initlist = tree_cons (NULL_TREE, expr, initlist);
1635 if (!flag_next_runtime)
1637 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1640 if (static_instances_decl)
1641 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1643 expr = build_int_2 (0, 0);
1645 initlist = tree_cons (NULL_TREE, expr, initlist);
1648 return objc_build_constructor (type, nreverse (initlist));
1651 /* Construct the initial value for all of _objc_symtab. */
1654 init_objc_symtab (tree type)
1658 /* sel_ref_cnt = { ..., 5, ... } */
1660 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1662 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1664 if (flag_next_runtime || ! sel_ref_chain)
1665 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1667 initlist = tree_cons (NULL_TREE,
1668 build_unary_op (ADDR_EXPR,
1669 UOBJC_SELECTOR_TABLE_decl, 1),
1672 /* cls_def_cnt = { ..., 5, ... } */
1674 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1676 /* cat_def_cnt = { ..., 5, ... } */
1678 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1680 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1682 if (imp_count || cat_count || !flag_next_runtime)
1685 tree field = TYPE_FIELDS (type);
1686 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1688 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1692 return objc_build_constructor (type, nreverse (initlist));
1695 /* Generate forward declarations for metadata such as
1696 'OBJC_CLASS_...'. */
1699 build_metadata_decl (const char *name, tree type)
1701 tree decl, decl_specs;
1702 /* extern struct TYPE NAME_<name>; */
1703 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1704 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1705 decl = define_decl (synth_id_with_class_suffix
1707 objc_implementation_context),
1709 TREE_USED (decl) = 1;
1710 DECL_ARTIFICIAL (decl) = 1;
1711 TREE_PUBLIC (decl) = 0;
1715 /* Push forward-declarations of all the categories so that
1716 init_def_list can use them in a CONSTRUCTOR. */
1719 forward_declare_categories (void)
1721 struct imp_entry *impent;
1722 tree sav = objc_implementation_context;
1724 for (impent = imp_list; impent; impent = impent->next)
1726 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1728 /* Set an invisible arg to synth_id_with_class_suffix. */
1729 objc_implementation_context = impent->imp_context;
1730 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1731 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1732 objc_category_template);
1735 objc_implementation_context = sav;
1738 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1739 and initialized appropriately. */
1742 generate_objc_symtab_decl (void)
1746 if (!objc_category_template)
1747 build_category_template ();
1749 /* forward declare categories */
1751 forward_declare_categories ();
1753 if (!objc_symtab_template)
1754 build_objc_symtab_template ();
1756 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1758 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1759 tree_cons (NULL_TREE,
1760 objc_symtab_template, sc_spec),
1764 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1765 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1766 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1767 finish_decl (UOBJC_SYMBOLS_decl,
1768 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1773 init_module_descriptor (tree type)
1775 tree initlist, expr;
1777 /* version = { 1, ... } */
1779 expr = build_int_2 (OBJC_VERSION, 0);
1780 initlist = build_tree_list (NULL_TREE, expr);
1782 /* size = { ..., sizeof (struct objc_module), ... } */
1784 expr = size_in_bytes (objc_module_template);
1785 initlist = tree_cons (NULL_TREE, expr, initlist);
1787 /* name = { ..., "foo.m", ... } */
1789 expr = add_objc_string (get_identifier (input_filename), class_names);
1790 initlist = tree_cons (NULL_TREE, expr, initlist);
1792 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1794 if (UOBJC_SYMBOLS_decl)
1795 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1797 expr = build_int_2 (0, 0);
1798 initlist = tree_cons (NULL_TREE, expr, initlist);
1800 return objc_build_constructor (type, nreverse (initlist));
1803 /* Write out the data structures to describe Objective C classes defined.
1804 If appropriate, compile and output a setup function to initialize them.
1805 Return a symbol_ref to the function to call to initialize the Objective C
1806 data structures for this file (and perhaps for other files also).
1808 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1811 build_module_descriptor (void)
1813 tree decl_specs, field_decl, field_decl_chain;
1815 objc_module_template
1816 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1820 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1821 field_decl = get_identifier ("version");
1822 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1823 field_decl_chain = field_decl;
1827 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1828 field_decl = get_identifier ("size");
1829 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1830 chainon (field_decl_chain, field_decl);
1834 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1835 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1836 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1837 chainon (field_decl_chain, field_decl);
1839 /* struct objc_symtab *symtab; */
1841 decl_specs = get_identifier (UTAG_SYMTAB);
1842 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1843 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1844 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1845 chainon (field_decl_chain, field_decl);
1847 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1849 /* Create an instance of "objc_module". */
1851 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1852 build_tree_list (NULL_TREE,
1853 ridpointers[(int) RID_STATIC]));
1855 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1856 decl_specs, 1, NULL_TREE);
1858 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1859 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1860 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1862 finish_decl (UOBJC_MODULES_decl,
1863 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1866 /* Mark the decl to avoid "defined but not used" warning. */
1867 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1869 /* Generate a constructor call for the module descriptor.
1870 This code was generated by reading the grammar rules
1871 of c-parse.in; Therefore, it may not be the most efficient
1872 way of generating the requisite code. */
1874 if (flag_next_runtime)
1878 tree parms, execclass_decl, decelerator, void_list_node_1;
1879 tree init_function_name, init_function_decl, compound;
1881 /* Declare void __objc_execClass (void *); */
1883 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1884 execclass_decl = build_decl (FUNCTION_DECL,
1885 get_identifier (TAG_EXECCLASS),
1886 build_function_type (void_type_node,
1887 tree_cons (NULL_TREE, ptr_type_node,
1890 DECL_EXTERNAL (execclass_decl) = 1;
1891 DECL_ARTIFICIAL (execclass_decl) = 1;
1892 TREE_PUBLIC (execclass_decl) = 1;
1893 pushdecl (execclass_decl);
1894 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1895 assemble_external (execclass_decl);
1897 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1899 init_function_name = get_file_function_name ('I');
1900 start_function (void_list_node_1,
1901 build_nt (CALL_EXPR, init_function_name,
1902 tree_cons (NULL_TREE, NULL_TREE,
1906 store_parm_decls ();
1907 compound = c_begin_compound_stmt (true);
1909 init_function_decl = current_function_decl;
1910 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1911 TREE_USED (init_function_decl) = 1;
1912 /* Don't let this one be deferred. */
1913 DECL_INLINE (init_function_decl) = 0;
1914 DECL_UNINLINABLE (init_function_decl) = 1;
1917 = build_tree_list (NULL_TREE,
1918 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1919 decelerator = build_function_call (execclass_decl, parms);
1921 add_stmt (decelerator);
1922 add_stmt (c_end_compound_stmt (compound, true));
1926 return XEXP (DECL_RTL (init_function_decl), 0);
1930 /* Return the DECL of the string IDENT in the SECTION. */
1933 get_objc_string_decl (tree ident, enum string_section section)
1937 if (section == class_names)
1938 chain = class_names_chain;
1939 else if (section == meth_var_names)
1940 chain = meth_var_names_chain;
1941 else if (section == meth_var_types)
1942 chain = meth_var_types_chain;
1946 for (; chain != 0; chain = TREE_CHAIN (chain))
1947 if (TREE_VALUE (chain) == ident)
1948 return (TREE_PURPOSE (chain));
1954 /* Output references to all statically allocated objects. Return the DECL
1955 for the array built. */
1958 generate_static_references (void)
1960 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1961 tree class_name, class, decl, initlist;
1962 tree cl_chain, in_chain, type;
1963 int num_inst, num_class;
1966 if (flag_next_runtime)
1969 for (cl_chain = objc_static_instances, num_class = 0;
1970 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1972 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1973 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1975 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1976 ident = get_identifier (buf);
1978 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
1979 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1980 build_tree_list (NULL_TREE,
1981 ridpointers[(int) RID_STATIC]));
1982 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1983 DECL_CONTEXT (decl) = 0;
1984 DECL_ARTIFICIAL (decl) = 1;
1986 /* Output {class_name, ...}. */
1987 class = TREE_VALUE (cl_chain);
1988 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
1989 initlist = build_tree_list (NULL_TREE,
1990 build_unary_op (ADDR_EXPR, class_name, 1));
1992 /* Output {..., instance, ...}. */
1993 for (in_chain = TREE_PURPOSE (cl_chain);
1994 in_chain; in_chain = TREE_CHAIN (in_chain))
1996 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1997 initlist = tree_cons (NULL_TREE, expr, initlist);
2000 /* Output {..., NULL}. */
2001 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2003 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2004 finish_decl (decl, expr, NULL_TREE);
2005 TREE_USED (decl) = 1;
2007 type = build_array_type (build_pointer_type (void_type_node), 0);
2008 decl = build_decl (VAR_DECL, ident, type);
2009 TREE_USED (decl) = 1;
2010 TREE_STATIC (decl) = 1;
2012 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2015 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2016 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2017 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
2018 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2019 build_tree_list (NULL_TREE,
2020 ridpointers[(int) RID_STATIC]));
2021 static_instances_decl
2022 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2023 TREE_USED (static_instances_decl) = 1;
2024 DECL_CONTEXT (static_instances_decl) = 0;
2025 DECL_ARTIFICIAL (static_instances_decl) = 1;
2026 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2028 finish_decl (static_instances_decl, expr, NULL_TREE);
2031 /* Output all strings. */
2034 generate_strings (void)
2036 tree sc_spec, decl_specs, expr_decl;
2037 tree chain, string_expr;
2040 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2042 string = TREE_VALUE (chain);
2043 decl = TREE_PURPOSE (chain);
2045 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2046 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2047 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2048 NULL_TREE, NULL_TREE);
2049 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2050 DECL_CONTEXT (decl) = NULL_TREE;
2051 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2052 IDENTIFIER_POINTER (string));
2053 finish_decl (decl, string_expr, NULL_TREE);
2056 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2058 string = TREE_VALUE (chain);
2059 decl = TREE_PURPOSE (chain);
2061 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2062 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2063 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2064 NULL_TREE, NULL_TREE);
2065 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2066 DECL_CONTEXT (decl) = NULL_TREE;
2067 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2068 IDENTIFIER_POINTER (string));
2069 finish_decl (decl, string_expr, NULL_TREE);
2072 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2074 string = TREE_VALUE (chain);
2075 decl = TREE_PURPOSE (chain);
2077 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2078 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2079 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2080 NULL_TREE, NULL_TREE);
2081 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2082 DECL_CONTEXT (decl) = NULL_TREE;
2083 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2084 IDENTIFIER_POINTER (string));
2085 finish_decl (decl, string_expr, NULL_TREE);
2089 static GTY(()) int selector_reference_idx;
2092 build_selector_reference_decl (void)
2097 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2099 ident = get_identifier (buf);
2101 decl = build_decl (VAR_DECL, ident, objc_selector_type);
2102 DECL_EXTERNAL (decl) = 1;
2103 TREE_PUBLIC (decl) = 0;
2104 TREE_USED (decl) = 1;
2105 DECL_ARTIFICIAL (decl) = 1;
2106 DECL_CONTEXT (decl) = 0;
2108 make_decl_rtl (decl, 0);
2109 pushdecl_top_level (decl);
2114 /* Just a handy wrapper for add_objc_string. */
2117 build_selector (tree ident)
2119 tree expr = add_objc_string (ident, meth_var_names);
2120 if (flag_typed_selectors)
2123 return build_c_cast (objc_selector_type, expr); /* cast! */
2127 build_selector_translation_table (void)
2129 tree sc_spec, decl_specs;
2130 tree chain, initlist = NULL_TREE;
2132 tree decl = NULL_TREE, var_decl, name;
2134 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2138 if (warn_selector && objc_implementation_context)
2142 for (method_chain = meth_var_names_chain;
2144 method_chain = TREE_CHAIN (method_chain))
2146 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2154 /* Adjust line number for warning message. */
2155 int save_lineno = input_line;
2156 if (flag_next_runtime && TREE_PURPOSE (chain))
2157 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2158 warning ("creating selector for non existant method %s",
2159 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2160 input_line = save_lineno;
2164 expr = build_selector (TREE_VALUE (chain));
2166 if (flag_next_runtime)
2168 name = DECL_NAME (TREE_PURPOSE (chain));
2170 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2172 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2173 decl_specs = tree_cons (NULL_TREE, objc_selector_type, sc_spec);
2177 /* The `decl' that is returned from start_decl is the one that we
2178 forward declared in `build_selector_reference' */
2179 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2182 /* add one for the '\0' character */
2183 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2185 if (flag_next_runtime)
2186 finish_decl (decl, expr, NULL_TREE);
2189 if (flag_typed_selectors)
2191 tree eltlist = NULL_TREE;
2192 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2193 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2194 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2195 expr = objc_build_constructor (objc_selector_template,
2196 nreverse (eltlist));
2198 initlist = tree_cons (NULL_TREE, expr, initlist);
2203 if (! flag_next_runtime)
2205 /* Cause the variable and its initial value to be actually output. */
2206 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2207 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2208 /* NULL terminate the list and fix the decl for output. */
2209 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2210 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2211 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2212 nreverse (initlist));
2213 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2214 current_function_decl = NULL_TREE;
2219 get_proto_encoding (tree proto)
2224 if (! METHOD_ENCODING (proto))
2226 encoding = encode_method_prototype (proto);
2227 METHOD_ENCODING (proto) = encoding;
2230 encoding = METHOD_ENCODING (proto);
2232 return add_objc_string (encoding, meth_var_types);
2235 return build_int_2 (0, 0);
2238 /* sel_ref_chain is a list whose "value" fields will be instances of
2239 identifier_node that represent the selector. */
2242 build_typed_selector_reference (tree ident, tree prototype)
2244 tree *chain = &sel_ref_chain;
2250 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2251 goto return_at_index;
2254 chain = &TREE_CHAIN (*chain);
2257 *chain = tree_cons (prototype, ident, NULL_TREE);
2260 expr = build_unary_op (ADDR_EXPR,
2261 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2262 build_int_2 (index, 0)),
2264 return build_c_cast (objc_selector_type, expr);
2268 build_selector_reference (tree ident)
2270 tree *chain = &sel_ref_chain;
2276 if (TREE_VALUE (*chain) == ident)
2277 return (flag_next_runtime
2278 ? TREE_PURPOSE (*chain)
2279 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2280 build_int_2 (index, 0)));
2283 chain = &TREE_CHAIN (*chain);
2286 expr = build_selector_reference_decl ();
2288 *chain = tree_cons (expr, ident, NULL_TREE);
2290 return (flag_next_runtime
2292 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2293 build_int_2 (index, 0)));
2296 static GTY(()) int class_reference_idx;
2299 build_class_reference_decl (void)
2304 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2306 ident = get_identifier (buf);
2308 decl = build_decl (VAR_DECL, ident, objc_class_type);
2309 DECL_EXTERNAL (decl) = 1;
2310 TREE_PUBLIC (decl) = 0;
2311 TREE_USED (decl) = 1;
2312 DECL_CONTEXT (decl) = 0;
2313 DECL_ARTIFICIAL (decl) = 1;
2315 make_decl_rtl (decl, 0);
2316 pushdecl_top_level (decl);
2321 /* Create a class reference, but don't create a variable to reference
2325 add_class_reference (tree ident)
2329 if ((chain = cls_ref_chain))
2334 if (ident == TREE_VALUE (chain))
2338 chain = TREE_CHAIN (chain);
2342 /* Append to the end of the list */
2343 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2346 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2349 /* Get a class reference, creating it if necessary. Also create the
2350 reference variable. */
2353 get_class_reference (tree ident)
2358 if (processing_template_decl)
2359 /* Must wait until template instantiation time. */
2360 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2361 if (TREE_CODE (ident) == TYPE_DECL)
2362 ident = DECL_NAME (ident);
2366 if (!(ident = is_class_name (ident)))
2368 error ("`%s' is not an Objective-C class name or alias",
2369 IDENTIFIER_POINTER (orig_ident));
2370 return error_mark_node;
2373 if (flag_next_runtime && !flag_zero_link)
2378 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2379 if (TREE_VALUE (*chain) == ident)
2381 if (! TREE_PURPOSE (*chain))
2382 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2384 return TREE_PURPOSE (*chain);
2387 decl = build_class_reference_decl ();
2388 *chain = tree_cons (decl, ident, NULL_TREE);
2395 add_class_reference (ident);
2397 params = build_tree_list (NULL_TREE,
2398 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2399 IDENTIFIER_POINTER (ident)));
2401 assemble_external (objc_get_class_decl);
2402 return build_function_call (objc_get_class_decl, params);
2406 /* For each string section we have a chain which maps identifier nodes
2407 to decls for the strings. */
2410 add_objc_string (tree ident, enum string_section section)
2414 if (section == class_names)
2415 chain = &class_names_chain;
2416 else if (section == meth_var_names)
2417 chain = &meth_var_names_chain;
2418 else if (section == meth_var_types)
2419 chain = &meth_var_types_chain;
2425 if (TREE_VALUE (*chain) == ident)
2426 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2428 chain = &TREE_CHAIN (*chain);
2431 decl = build_objc_string_decl (section);
2433 *chain = tree_cons (decl, ident, NULL_TREE);
2435 return build_unary_op (ADDR_EXPR, decl, 1);
2438 static GTY(()) int class_names_idx;
2439 static GTY(()) int meth_var_names_idx;
2440 static GTY(()) int meth_var_types_idx;
2443 build_objc_string_decl (enum string_section section)
2448 if (section == class_names)
2449 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2450 else if (section == meth_var_names)
2451 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2452 else if (section == meth_var_types)
2453 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2455 ident = get_identifier (buf);
2457 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2458 DECL_EXTERNAL (decl) = 1;
2459 TREE_PUBLIC (decl) = 0;
2460 TREE_USED (decl) = 1;
2461 TREE_CONSTANT (decl) = 1;
2462 DECL_CONTEXT (decl) = 0;
2463 DECL_ARTIFICIAL (decl) = 1;
2465 make_decl_rtl (decl, 0);
2466 pushdecl_top_level (decl);
2473 objc_declare_alias (tree alias_ident, tree class_ident)
2475 tree underlying_class;
2478 if (current_namespace != global_namespace) {
2479 error ("Objective-C declarations may only appear in global scope");
2481 #endif /* OBJCPLUS */
2483 if (!(underlying_class = is_class_name (class_ident)))
2484 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2485 else if (is_class_name (alias_ident))
2486 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2488 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2492 objc_declare_class (tree ident_list)
2496 if (current_namespace != global_namespace) {
2497 error ("Objective-C declarations may only appear in global scope");
2499 #endif /* OBJCPLUS */
2501 for (list = ident_list; list; list = TREE_CHAIN (list))
2503 tree ident = TREE_VALUE (list);
2505 if (! is_class_name (ident))
2507 tree record = lookup_name (ident);
2509 if (record && ! TREE_STATIC_TEMPLATE (record))
2511 error ("`%s' redeclared as different kind of symbol",
2512 IDENTIFIER_POINTER (ident));
2513 error ("%Jprevious declaration of '%D'",
2517 record = xref_tag (RECORD_TYPE, ident);
2518 TREE_STATIC_TEMPLATE (record) = 1;
2519 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2525 is_class_name (tree ident)
2529 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2530 && identifier_global_value (ident))
2531 ident = identifier_global_value (ident);
2532 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2533 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2536 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2537 ident = TYPE_NAME (ident);
2538 if (ident && TREE_CODE (ident) == TYPE_DECL)
2539 ident = DECL_NAME (ident);
2541 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2544 if (lookup_interface (ident))
2547 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2549 if (ident == TREE_VALUE (chain))
2553 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2555 if (ident == TREE_VALUE (chain))
2556 return TREE_PURPOSE (chain);
2562 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2563 class instance. This is needed by other parts of the compiler to
2564 handle ObjC types gracefully. */
2567 objc_is_object_ptr (tree type)
2569 type = TYPE_MAIN_VARIANT (type);
2570 if (!type || TREE_CODE (type) != POINTER_TYPE)
2572 /* NB: This function may be called before the ObjC front-end has
2573 been initialized, in which case OBJC_ID_TYPE will be NULL. */
2574 if (objc_id_type && type && TYPE_P (type)
2576 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2578 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2582 lookup_interface (tree ident)
2587 if (ident && TREE_CODE (ident) == TYPE_DECL)
2588 ident = DECL_NAME (ident);
2590 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2592 if (ident == CLASS_NAME (chain))
2598 /* Implement @defs (<classname>) within struct bodies. */
2601 get_class_ivars_from_name (tree class_name)
2603 tree interface = lookup_interface (class_name);
2604 tree field, fields = NULL_TREE;
2608 tree raw_ivar = get_class_ivars (interface, 1);
2610 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2611 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2613 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2614 TREE_PURPOSE (raw_ivar),
2615 TREE_VALUE (TREE_VALUE (raw_ivar)));
2617 finish_member_declaration (field);
2619 fields = chainon (fields, field);
2624 error ("cannot find interface declaration for `%s'",
2625 IDENTIFIER_POINTER (class_name));
2630 /* Used by: build_private_template, continue_class,
2631 and for @defs constructs. */
2634 get_class_ivars (tree interface, int raw)
2636 tree my_name, super_name, ivar_chain;
2638 my_name = CLASS_NAME (interface);
2639 super_name = CLASS_SUPER_NAME (interface);
2641 ivar_chain = CLASS_RAW_IVARS (interface);
2644 ivar_chain = CLASS_IVARS (interface);
2645 /* Save off a pristine copy of the leaf ivars (i.e, those not
2646 inherited from a super class). */
2647 if (!CLASS_OWN_IVARS (interface))
2648 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2654 tree super_interface = lookup_interface (super_name);
2656 if (!super_interface)
2658 /* fatal did not work with 2 args...should fix */
2659 error ("cannot find interface declaration for `%s', superclass of `%s'",
2660 IDENTIFIER_POINTER (super_name),
2661 IDENTIFIER_POINTER (my_name));
2662 exit (FATAL_EXIT_CODE);
2665 if (super_interface == interface)
2666 fatal_error ("circular inheritance in interface declaration for `%s'",
2667 IDENTIFIER_POINTER (super_name));
2669 interface = super_interface;
2670 my_name = CLASS_NAME (interface);
2671 super_name = CLASS_SUPER_NAME (interface);
2673 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2676 tree head = copy_list (op1);
2678 /* Prepend super class ivars...make a copy of the list, we
2679 do not want to alter the original. */
2680 chainon (head, ivar_chain);
2689 objc_create_temporary_var (tree type)
2693 decl = build_decl (VAR_DECL, NULL_TREE, type);
2694 TREE_USED (decl) = 1;
2695 DECL_ARTIFICIAL (decl) = 1;
2696 DECL_IGNORED_P (decl) = 1;
2697 DECL_CONTEXT (decl) = current_function_decl;
2702 /* Exception handling constructs. We begin by having the parser do most
2703 of the work and passing us blocks. What we do next depends on whether
2704 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2705 We abstract all of this in a handful of appropriately named routines. */
2707 /* Stack of open try blocks. */
2709 struct objc_try_context
2711 struct objc_try_context *outer;
2713 /* Statements (or statement lists) as processed by the parser. */
2717 /* Some file position locations. */
2718 location_t try_locus;
2719 location_t end_try_locus;
2720 location_t end_catch_locus;
2721 location_t finally_locus;
2722 location_t end_finally_locus;
2724 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2725 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2728 /* The CATCH_EXPR of an open @catch clause. */
2731 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2737 static struct objc_try_context *cur_try_context;
2739 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2740 that represents TYPE. For Objective-C, this is just the class name. */
2741 /* ??? Isn't there a class object or some such? Is it easy to get? */
2744 objc_eh_runtime_type (tree type)
2746 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2749 /* Initialize exception handling. */
2752 objc_init_exceptions (void)
2754 static bool done = false;
2760 if (!flag_objc_exceptions)
2761 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2762 "exception syntax");
2764 if (!flag_objc_sjlj_exceptions)
2766 c_eh_initialized_p = true;
2767 eh_personality_libfunc
2768 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2769 ? "__gnu_objc_personality_sj0"
2770 : "__gnu_objc_personality_v0");
2771 using_eh_for_cleanups ();
2772 lang_eh_runtime_type = objc_eh_runtime_type;
2776 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2777 we'll arrange for it to be initialized (and associated with a binding)
2781 objc_build_exc_ptr (void)
2783 if (flag_objc_sjlj_exceptions)
2785 tree var = cur_try_context->caught_decl;
2788 var = objc_create_temporary_var (objc_id_type);
2789 cur_try_context->caught_decl = var;
2794 return build (EXC_PTR_EXPR, objc_id_type);
2797 /* Build "objc_exception_try_exit(&_stack)". */
2800 next_sjlj_build_try_exit (void)
2803 t = build_fold_addr_expr (cur_try_context->stack_decl);
2804 t = tree_cons (NULL, t, NULL);
2805 t = build_function_call (objc_exception_try_exit_decl, t);
2810 objc_exception_try_enter (&_stack);
2811 if (_setjmp(&_stack.buf))
2815 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2816 empty, ready for the caller to fill them in. */
2819 next_sjlj_build_enter_and_setjmp (void)
2821 tree t, enter, sj, cond;
2823 t = build_fold_addr_expr (cur_try_context->stack_decl);
2824 t = tree_cons (NULL, t, NULL);
2825 enter = build_function_call (objc_exception_try_enter_decl, t);
2827 t = build_component_ref (cur_try_context->stack_decl,
2828 get_identifier ("buf"));
2829 t = build_fold_addr_expr (t);
2830 t = convert (ptr_type_node, t);
2831 t = tree_cons (NULL, t, NULL);
2832 sj = build_function_call (objc_setjmp_decl, t);
2834 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2835 cond = lang_hooks.truthvalue_conversion (cond);
2837 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2841 DECL = objc_exception_extract(&_stack);
2845 next_sjlj_build_exc_extract (tree decl)
2849 t = build_fold_addr_expr (cur_try_context->stack_decl);
2850 t = tree_cons (NULL, t, NULL);
2851 t = build_function_call (objc_exception_extract_decl, t);
2852 t = convert (TREE_TYPE (decl), t);
2853 t = build (MODIFY_EXPR, void_type_node, decl, t);
2859 if (objc_exception_match(obj_get_class(TYPE), _caught)
2866 objc_exception_try_exit(&_stack);
2868 from the sequence of CATCH_EXPRs in the current try context. */
2871 next_sjlj_build_catch_list (void)
2873 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
2875 tree *last = &catch_seq;
2876 bool saw_id = false;
2878 for (; !tsi_end_p (i); tsi_next (&i))
2880 tree stmt = tsi_stmt (i);
2881 tree type = CATCH_TYPES (stmt);
2882 tree body = CATCH_BODY (stmt);
2894 if (type == error_mark_node)
2895 cond = error_mark_node;
2898 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
2899 t = get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
2900 args = tree_cons (NULL, t, args);
2901 t = build_function_call (objc_exception_match_decl, args);
2902 cond = lang_hooks.truthvalue_conversion (t);
2904 t = build (COND_EXPR, void_type_node, cond, body, NULL);
2905 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
2908 last = &COND_EXPR_ELSE (t);
2914 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
2915 cur_try_context->caught_decl);
2916 annotate_with_locus (t, cur_try_context->end_catch_locus);
2917 append_to_statement_list (t, last);
2919 t = next_sjlj_build_try_exit ();
2920 annotate_with_locus (t, cur_try_context->end_catch_locus);
2921 append_to_statement_list (t, last);
2927 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
2928 exception handling. We aim to build:
2931 struct _objc_exception_data _stack;
2932 id volatile _rethrow = 0;
2935 objc_exception_try_enter (&_stack);
2936 if (_setjmp(&_stack.buf))
2938 id _caught = objc_exception_extract(&_stack);
2939 objc_exception_try_enter (&_stack);
2940 if (_setjmp(&_stack.buf))
2941 _rethrow = objc_exception_extract(&_stack);
2951 objc_exception_try_exit(&_stack);
2954 objc_exception_throw(_rethrow);
2958 If CATCH-LIST is empty, we can omit all of the block containing
2959 "_caught" except for the setting of _rethrow. Note the use of
2960 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
2961 but handles goto and other exits from the block. */
2964 next_sjlj_build_try_catch_finally (void)
2966 tree rethrow_decl, stack_decl, t;
2967 tree catch_seq, try_fin, bind;
2969 /* Create the declarations involved. */
2970 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
2971 stack_decl = objc_create_temporary_var (t);
2972 cur_try_context->stack_decl = stack_decl;
2974 rethrow_decl = objc_create_temporary_var (objc_id_type);
2975 cur_try_context->rethrow_decl = rethrow_decl;
2976 TREE_THIS_VOLATILE (rethrow_decl) = 1;
2977 TREE_CHAIN (rethrow_decl) = stack_decl;
2979 /* Build the outermost varible binding level. */
2980 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
2981 annotate_with_locus (bind, cur_try_context->try_locus);
2982 TREE_SIDE_EFFECTS (bind) = 1;
2984 /* Initialize rethrow_decl. */
2985 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
2986 convert (objc_id_type, null_pointer_node));
2987 annotate_with_locus (t, cur_try_context->try_locus);
2988 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
2990 /* Build the outermost TRY_FINALLY_EXPR. */
2991 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
2992 annotate_with_locus (try_fin, cur_try_context->try_locus);
2993 TREE_SIDE_EFFECTS (try_fin) = 1;
2994 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
2996 /* Create the complete catch sequence. */
2997 if (cur_try_context->catch_list)
2999 tree caught_decl = objc_build_exc_ptr ();
3000 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3002 t = next_sjlj_build_exc_extract (caught_decl);
3003 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3005 t = next_sjlj_build_enter_and_setjmp ();
3006 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3007 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3008 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3011 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3012 annotate_with_locus (catch_seq, cur_try_context->end_try_locus);
3014 /* Build the main register-and-try if statement. */
3015 t = next_sjlj_build_enter_and_setjmp ();
3016 annotate_with_locus (t, cur_try_context->try_locus);
3017 COND_EXPR_THEN (t) = catch_seq;
3018 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3019 TREE_OPERAND (try_fin, 0) = t;
3021 /* Build the complete FINALLY statement list. */
3022 t = next_sjlj_build_try_exit ();
3023 t = build_stmt (COND_EXPR,
3024 lang_hooks.truthvalue_conversion (rethrow_decl),
3026 annotate_with_locus (t, cur_try_context->finally_locus);
3027 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3029 append_to_statement_list (cur_try_context->finally_body,
3030 &TREE_OPERAND (try_fin, 1));
3032 t = tree_cons (NULL, rethrow_decl, NULL);
3033 t = build_function_call (objc_exception_throw_decl, t);
3034 t = build_stmt (COND_EXPR,
3035 lang_hooks.truthvalue_conversion (rethrow_decl),
3037 annotate_with_locus (t, cur_try_context->end_finally_locus);
3038 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3043 /* Called just after parsing the @try and its associated BODY. We now
3044 must prepare for the tricky bits -- handling the catches and finally. */
3047 objc_begin_try_stmt (location_t try_locus, tree body)
3049 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3050 c->outer = cur_try_context;
3052 c->try_locus = try_locus;
3053 c->end_try_locus = input_location;
3054 cur_try_context = c;
3056 objc_init_exceptions ();
3059 /* Called just after parsing "@catch (parm)". Open a binding level,
3060 enter PARM into the binding level, and initialize it. Leave the
3061 binding level open while the body of the compound statement is parsed. */
3064 objc_begin_catch_clause (tree parm)
3066 tree compound, decl, type, t;
3068 /* Begin a new scope that the entire catch clause will live in. */
3069 compound = c_begin_compound_stmt (1);
3071 /* Turn the raw declarator/declspecs into a decl in the current scope. */
3072 decl = define_decl (TREE_VALUE (TREE_PURPOSE (parm)),
3073 TREE_PURPOSE (TREE_PURPOSE (parm)));
3075 /* Since a decl is required here by syntax, don't warn if its unused. */
3076 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3077 be what the previous objc implementation did. */
3078 TREE_USED (decl) = 1;
3080 /* Verify that the type of the catch is valid. It must be a pointer
3081 to an Objective-C class, or "id" (which is catch-all). */
3082 type = TREE_TYPE (decl);
3083 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3085 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3087 error ("@catch parameter is not a known Objective-C class type");
3088 type = error_mark_node;
3090 else if (cur_try_context->catch_list)
3092 /* Examine previous @catch clauses and see if we've already
3093 caught the type in question. */
3094 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3095 for (; !tsi_end_p (i); tsi_next (&i))
3097 tree stmt = tsi_stmt (i);
3098 t = CATCH_TYPES (stmt);
3099 if (t == error_mark_node)
3101 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3103 warning ("exception of type %<%T%> will be caught",
3105 warning ("%H by earlier handler for %<%T%>",
3106 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_id_type));
3112 /* Record the data for the catch in the try context so that we can
3113 finalize it later. */
3114 t = build_stmt (CATCH_EXPR, type, compound);
3115 cur_try_context->current_catch = t;
3117 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3118 t = objc_build_exc_ptr ();
3119 t = convert (TREE_TYPE (decl), t);
3120 t = build (MODIFY_EXPR, void_type_node, decl, t);
3124 /* Called just after parsing the closing brace of a @catch clause. Close
3125 the open binding level, and record a CATCH_EXPR for it. */
3128 objc_finish_catch_clause (void)
3130 tree c = cur_try_context->current_catch;
3131 cur_try_context->current_catch = NULL;
3132 cur_try_context->end_catch_locus = input_location;
3134 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3135 append_to_statement_list (c, &cur_try_context->catch_list);
3138 /* Called after parsing a @finally clause and its associated BODY.
3139 Record the body for later placement. */
3142 objc_build_finally_clause (location_t finally_locus, tree body)
3144 cur_try_context->finally_body = body;
3145 cur_try_context->finally_locus = finally_locus;
3146 cur_try_context->end_finally_locus = input_location;
3149 /* Called to finalize a @try construct. */
3152 objc_finish_try_stmt (void)
3154 struct objc_try_context *c = cur_try_context;
3157 if (c->catch_list == NULL && c->finally_body == NULL)
3158 error ("`@try' without `@catch' or `@finally'");
3160 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3161 if (flag_objc_sjlj_exceptions)
3163 if (!cur_try_context->finally_body)
3165 cur_try_context->finally_locus = input_location;
3166 cur_try_context->end_finally_locus = input_location;
3168 stmt = next_sjlj_build_try_catch_finally ();
3172 /* Otherwise, nest the CATCH inside a FINALLY. */
3176 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3177 annotate_with_locus (stmt, cur_try_context->try_locus);
3179 if (c->finally_body)
3181 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3182 annotate_with_locus (stmt, cur_try_context->try_locus);
3187 cur_try_context = c->outer;
3192 objc_build_throw_stmt (tree throw_expr)
3196 if (throw_expr == NULL)
3198 /* If we're not inside a @catch block, there is no "current
3199 exception" to be rethrown. */
3200 if (cur_try_context == NULL
3201 || cur_try_context->current_catch == NULL)
3203 error ("%<@throw%> (rethrow) used outside of a @catch block");
3207 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3208 value that we get from the runtime. */
3209 throw_expr = objc_build_exc_ptr ();
3212 /* A throw is just a call to the runtime throw function with the
3213 object as a parameter. */
3214 func_params = tree_cons (NULL, throw_expr, NULL);
3215 add_stmt (build_function_call (objc_exception_throw_decl, func_params));
3217 objc_init_exceptions ();
3221 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3225 /* First lock the mutex. */
3226 mutex = save_expr (mutex);
3227 args = tree_cons (NULL, mutex, NULL);
3228 call = build_function_call (objc_sync_enter_decl, args);
3229 annotate_with_locus (call, start_locus);
3232 /* Build the mutex unlock. */
3233 args = tree_cons (NULL, mutex, NULL);
3234 call = build_function_call (objc_sync_exit_decl, args);
3235 annotate_with_locus (call, input_location);
3237 /* Put the that and the body in a TRY_FINALLY. */
3238 objc_begin_try_stmt (start_locus, body);
3239 objc_build_finally_clause (input_location, call);
3240 objc_finish_try_stmt ();
3244 /* Predefine the following data type:
3246 struct _objc_exception_data
3252 /* The following yuckiness should prevent users from having to #include
3253 <setjmp.h> in their code... */
3255 #ifdef TARGET_POWERPC
3256 /* snarfed from /usr/include/ppc/setjmp.h */
3257 #define _JBLEN (26 + 36 + 129 + 1)
3259 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3264 build_next_objc_exception_stuff (void)
3266 tree field_decl, field_decl_chain, index, temp_type;
3268 /* Suppress outputting debug symbols, because
3269 dbxout_init hasn't been called yet. */
3270 enum debug_info_type save_write_symbols = write_symbols;
3271 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3273 write_symbols = NO_DEBUG;
3274 debug_hooks = &do_nothing_debug_hooks;
3276 objc_exception_data_template
3277 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3279 /* int buf[_JBLEN]; */
3281 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3282 field_decl = create_builtin_decl (FIELD_DECL,
3283 build_array_type (integer_type_node, index),
3285 field_decl_chain = field_decl;
3287 /* void *pointers[4]; */
3289 index = build_index_type (build_int_2 (4 - 1, 0));
3290 field_decl = create_builtin_decl (FIELD_DECL,
3291 build_array_type (ptr_type_node, index),
3293 chainon (field_decl_chain, field_decl);
3295 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3297 /* int _setjmp(...); */
3298 /* If the user includes <setjmp.h>, this shall be superseded by
3299 'int _setjmp(jmp_buf);' */
3300 temp_type = build_function_type (integer_type_node, NULL_TREE);
3302 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3304 /* id objc_exception_extract(struct _objc_exception_data *); */
3306 = build_function_type (objc_id_type,
3307 tree_cons (NULL_TREE,
3308 build_pointer_type (objc_exception_data_template),
3310 objc_exception_extract_decl
3311 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3312 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3313 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3315 = build_function_type (void_type_node,
3316 tree_cons (NULL_TREE,
3317 build_pointer_type (objc_exception_data_template),
3319 objc_exception_try_enter_decl
3320 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3321 objc_exception_try_exit_decl
3322 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3324 /* int objc_exception_match(id, id); */
3326 = build_function_type (integer_type_node,
3327 tree_cons (NULL_TREE, objc_id_type,
3328 tree_cons (NULL_TREE, objc_id_type,
3330 objc_exception_match_decl
3331 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3333 write_symbols = save_write_symbols;
3334 debug_hooks = save_hooks;
3338 build_objc_exception_stuff (void)
3340 tree noreturn_list, nothrow_list, temp_type;
3342 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3343 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3345 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3346 /* void objc_sync_enter(id); */
3347 /* void objc_sync_exit(id); */
3348 temp_type = build_function_type (void_type_node,
3349 tree_cons (NULL_TREE, objc_id_type,
3351 objc_exception_throw_decl
3352 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3354 objc_sync_enter_decl
3355 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3356 NULL, nothrow_list);
3358 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3359 NULL, nothrow_list);
3363 /* struct <classname> {
3364 struct objc_class *isa;
3369 build_private_template (tree class)
3373 if (CLASS_STATIC_TEMPLATE (class))
3375 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3376 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3380 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3381 ivar_context = get_class_ivars (class, 0);
3383 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3385 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3387 /* mark this record as class template - for class type checking */
3388 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3392 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3394 build1 (INDIRECT_REF, NULL_TREE,
3397 return ivar_context;
3400 /* Begin code generation for protocols... */
3402 /* struct objc_protocol {
3403 char *protocol_name;
3404 struct objc_protocol **protocol_list;
3405 struct objc_method_desc *instance_methods;
3406 struct objc_method_desc *class_methods;
3410 build_protocol_template (void)
3412 tree decl_specs, field_decl, field_decl_chain;
3415 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3417 /* struct objc_class *isa; */
3419 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3420 get_identifier (UTAG_CLASS)));
3421 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3422 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3423 field_decl_chain = field_decl;
3425 /* char *protocol_name; */
3427 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3429 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3430 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3431 chainon (field_decl_chain, field_decl);
3433 /* struct objc_protocol **protocol_list; */
3435 decl_specs = build_tree_list (NULL_TREE, template);
3437 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3438 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3439 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3440 chainon (field_decl_chain, field_decl);
3442 /* struct objc_method_list *instance_methods; */
3445 = build_tree_list (NULL_TREE,
3446 xref_tag (RECORD_TYPE,
3447 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3449 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3450 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3451 chainon (field_decl_chain, field_decl);
3453 /* struct objc_method_list *class_methods; */
3456 = build_tree_list (NULL_TREE,
3457 xref_tag (RECORD_TYPE,
3458 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3460 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3461 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3462 chainon (field_decl_chain, field_decl);
3464 return finish_struct (template, field_decl_chain, NULL_TREE);
3468 build_descriptor_table_initializer (tree type, tree entries)
3470 tree initlist = NULL_TREE;
3474 tree eltlist = NULL_TREE;
3477 = tree_cons (NULL_TREE,
3478 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3480 = tree_cons (NULL_TREE,
3481 add_objc_string (METHOD_ENCODING (entries),
3486 = tree_cons (NULL_TREE,
3487 objc_build_constructor (type, nreverse (eltlist)),
3490 entries = TREE_CHAIN (entries);
3494 return objc_build_constructor (build_array_type (type, 0),
3495 nreverse (initlist));
3498 /* struct objc_method_prototype_list {
3500 struct objc_method_prototype {
3507 build_method_prototype_list_template (tree list_type, int size)
3509 tree objc_ivar_list_record;
3510 tree decl_specs, field_decl, field_decl_chain;
3512 /* Generate an unnamed struct definition. */
3514 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3516 /* int method_count; */
3518 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3519 field_decl = get_identifier ("method_count");
3520 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3521 field_decl_chain = field_decl;
3523 /* struct objc_method method_list[]; */
3525 decl_specs = build_tree_list (NULL_TREE, list_type);
3526 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3527 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
3528 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3529 chainon (field_decl_chain, field_decl);
3531 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3533 return objc_ivar_list_record;
3537 build_method_prototype_template (void)
3540 tree decl_specs, field_decl, field_decl_chain;
3543 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3545 /* struct objc_selector *_cmd; */
3546 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3547 get_identifier (TAG_SELECTOR)), NULL_TREE);
3548 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3549 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3550 field_decl_chain = field_decl;
3552 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3554 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3555 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3556 chainon (field_decl_chain, field_decl);
3558 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3560 return proto_record;
3564 objc_method_parm_type (tree type)
3566 type = groktypename (TREE_TYPE (type));
3567 if (TREE_CODE (type) == TYPE_DECL)
3568 type = TREE_TYPE (type);
3569 return TYPE_MAIN_VARIANT (type);
3573 objc_encoded_type_size (tree type)
3575 int sz = int_size_in_bytes (type);
3577 /* Make all integer and enum types at least as large
3579 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3580 || TREE_CODE (type) == BOOLEAN_TYPE
3581 || TREE_CODE (type) == ENUMERAL_TYPE))
3582 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3583 /* Treat arrays as pointers, since that's how they're
3585 else if (TREE_CODE (type) == ARRAY_TYPE)
3586 sz = int_size_in_bytes (ptr_type_node);
3591 encode_method_prototype (tree method_decl)
3598 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3599 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3601 /* Encode return type. */
3602 encode_type (objc_method_parm_type (method_decl),
3603 obstack_object_size (&util_obstack),
3604 OBJC_ENCODE_INLINE_DEFS);
3607 /* The first two arguments (self and _cmd) are pointers; account for
3609 i = int_size_in_bytes (ptr_type_node);
3610 parm_offset = 2 * i;
3611 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3612 parms = TREE_CHAIN (parms))
3614 tree type = objc_method_parm_type (parms);
3615 int sz = objc_encoded_type_size (type);
3617 /* If a type size is not known, bail out. */
3620 error ("%Jtype '%D' does not have a known size",
3622 /* Pretend that the encoding succeeded; the compilation will
3623 fail nevertheless. */
3624 goto finish_encoding;
3629 sprintf (buf, "%d@0:%d", parm_offset, i);
3630 obstack_grow (&util_obstack, buf, strlen (buf));
3632 /* Argument types. */
3633 parm_offset = 2 * i;
3634 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3635 parms = TREE_CHAIN (parms))
3637 tree type = objc_method_parm_type (parms);
3639 /* Process argument qualifiers for user supplied arguments. */
3640 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3643 encode_type (type, obstack_object_size (&util_obstack),
3644 OBJC_ENCODE_INLINE_DEFS);
3646 /* Compute offset. */
3647 sprintf (buf, "%d", parm_offset);
3648 parm_offset += objc_encoded_type_size (type);
3650 obstack_grow (&util_obstack, buf, strlen (buf));
3654 obstack_1grow (&util_obstack, '\0');
3655 result = get_identifier (obstack_finish (&util_obstack));
3656 obstack_free (&util_obstack, util_firstobj);
3661 generate_descriptor_table (tree type, const char *name, int size, tree list,
3664 tree sc_spec, decl_specs, decl, initlist;
3666 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3667 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3669 decl = start_decl (synth_id_with_class_suffix (name, proto),
3670 decl_specs, 1, NULL_TREE);
3671 DECL_CONTEXT (decl) = NULL_TREE;
3673 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3674 initlist = tree_cons (NULL_TREE, list, initlist);
3676 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3683 generate_method_descriptors (tree protocol)
3685 tree initlist, chain, method_list_template;
3686 tree cast, variable_length_type;
3689 if (!objc_method_prototype_template)
3690 objc_method_prototype_template = build_method_prototype_template ();
3692 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3693 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3695 variable_length_type = groktypename (cast);
3697 chain = PROTOCOL_CLS_METHODS (protocol);
3700 size = list_length (chain);
3702 method_list_template
3703 = build_method_prototype_list_template (objc_method_prototype_template,
3707 = build_descriptor_table_initializer (objc_method_prototype_template,
3710 UOBJC_CLASS_METHODS_decl
3711 = generate_descriptor_table (method_list_template,
3712 "_OBJC_PROTOCOL_CLASS_METHODS",
3713 size, initlist, protocol);
3714 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3717 UOBJC_CLASS_METHODS_decl = 0;
3719 chain = PROTOCOL_NST_METHODS (protocol);
3722 size = list_length (chain);
3724 method_list_template
3725 = build_method_prototype_list_template (objc_method_prototype_template,
3728 = build_descriptor_table_initializer (objc_method_prototype_template,
3731 UOBJC_INSTANCE_METHODS_decl
3732 = generate_descriptor_table (method_list_template,
3733 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3734 size, initlist, protocol);
3735 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3738 UOBJC_INSTANCE_METHODS_decl = 0;
3742 generate_protocol_references (tree plist)
3746 /* Forward declare protocols referenced. */
3747 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3749 tree proto = TREE_VALUE (lproto);
3751 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3752 && PROTOCOL_NAME (proto))
3754 if (! PROTOCOL_FORWARD_DECL (proto))
3755 build_protocol_reference (proto);
3757 if (PROTOCOL_LIST (proto))
3758 generate_protocol_references (PROTOCOL_LIST (proto));
3763 /* For each protocol which was referenced either from a @protocol()
3764 expression, or because a class/category implements it (then a
3765 pointer to the protocol is stored in the struct describing the
3766 class/category), we create a statically allocated instance of the
3767 Protocol class. The code is written in such a way as to generate
3768 as few Protocol objects as possible; we generate a unique Protocol
3769 instance for each protocol, and we don't generate a Protocol
3770 instance if the protocol is never referenced (either from a
3771 @protocol() or from a class/category implementation). These
3772 statically allocated objects can be referred to via the static
3773 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3775 The statically allocated Protocol objects that we generate here
3776 need to be fixed up at runtime in order to be used: the 'isa'
3777 pointer of the objects need to be set up to point to the 'Protocol'
3778 class, as known at runtime.
3780 The NeXT runtime fixes up all protocols at program startup time,
3781 before main() is entered. It uses a low-level trick to look up all
3782 those symbols, then loops on them and fixes them up.
3784 The GNU runtime as well fixes up all protocols before user code
3785 from the module is executed; it requires pointers to those symbols
3786 to be put in the objc_symtab (which is then passed as argument to
3787 the function __objc_exec_class() which the compiler sets up to be
3788 executed automatically when the module is loaded); setup of those
3789 Protocol objects happen in two ways in the GNU runtime: all
3790 Protocol objects referred to by a class or category implementation
3791 are fixed up when the class/category is loaded; all Protocol
3792 objects referred to by a @protocol() expression are added by the
3793 compiler to the list of statically allocated instances to fixup
3794 (the same list holding the statically allocated constant string
3795 objects). Because, as explained above, the compiler generates as
3796 few Protocol objects as possible, some Protocol object might end up
3797 being referenced multiple times when compiled with the GNU runtime,
3798 and end up being fixed up multiple times at runtime inizialization.
3799 But that doesn't hurt, it's just a little inefficient. */
3802 generate_protocols (void)
3805 tree sc_spec, decl_specs, decl;
3806 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3809 if (! objc_protocol_template)
3810 objc_protocol_template = build_protocol_template ();
3812 /* If a protocol was directly referenced, pull in indirect references. */
3813 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3814 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3815 generate_protocol_references (PROTOCOL_LIST (p));
3817 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3819 tree nst_methods = PROTOCOL_NST_METHODS (p);
3820 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3822 /* If protocol wasn't referenced, don't generate any code. */
3823 if (! PROTOCOL_FORWARD_DECL (p))
3826 /* Make sure we link in the Protocol class. */
3827 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3831 if (! METHOD_ENCODING (nst_methods))
3833 encoding = encode_method_prototype (nst_methods);
3834 METHOD_ENCODING (nst_methods) = encoding;
3836 nst_methods = TREE_CHAIN (nst_methods);
3841 if (! METHOD_ENCODING (cls_methods))
3843 encoding = encode_method_prototype (cls_methods);
3844 METHOD_ENCODING (cls_methods) = encoding;
3847 cls_methods = TREE_CHAIN (cls_methods);
3849 generate_method_descriptors (p);
3851 if (PROTOCOL_LIST (p))
3852 refs_decl = generate_protocol_list (p);
3856 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3858 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3860 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3862 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3863 decl_specs, 1, NULL_TREE);
3865 DECL_CONTEXT (decl) = NULL_TREE;
3867 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3873 (build_tree_list (build_tree_list (NULL_TREE,
3874 objc_protocol_template),
3875 build1 (INDIRECT_REF, NULL_TREE,
3876 build1 (INDIRECT_REF, NULL_TREE,
3879 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3880 TREE_TYPE (refs_expr) = cast_type2;
3883 refs_expr = build_int_2 (0, 0);
3885 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3886 by generate_method_descriptors, which is called above. */
3887 initlist = build_protocol_initializer (TREE_TYPE (decl),
3888 protocol_name_expr, refs_expr,
3889 UOBJC_INSTANCE_METHODS_decl,
3890 UOBJC_CLASS_METHODS_decl);
3891 finish_decl (decl, initlist, NULL_TREE);
3893 /* Mark the decl as used to avoid "defined but not used" warning. */
3894 TREE_USED (decl) = 1;
3899 build_protocol_initializer (tree type, tree protocol_name,
3900 tree protocol_list, tree instance_methods,
3903 tree initlist = NULL_TREE, expr;
3906 cast_type = groktypename
3908 (build_tree_list (NULL_TREE,
3909 xref_tag (RECORD_TYPE,
3910 get_identifier (UTAG_CLASS))),
3911 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3913 /* Filling the "isa" in with one allows the runtime system to
3914 detect that the version change...should remove before final release. */
3916 expr = build_int_2 (PROTOCOL_VERSION, 0);
3917 TREE_TYPE (expr) = cast_type;
3918 initlist = tree_cons (NULL_TREE, expr, initlist);
3919 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3920 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3922 if (!instance_methods)
3923 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3926 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3927 initlist = tree_cons (NULL_TREE, expr, initlist);
3931 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3934 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3935 initlist = tree_cons (NULL_TREE, expr, initlist);
3938 return objc_build_constructor (type, nreverse (initlist));
3941 /* struct objc_category {
3942 char *category_name;
3944 struct objc_method_list *instance_methods;
3945 struct objc_method_list *class_methods;
3946 struct objc_protocol_list *protocols;
3950 build_category_template (void)
3952 tree decl_specs, field_decl, field_decl_chain;
3954 objc_category_template = start_struct (RECORD_TYPE,
3955 get_identifier (UTAG_CATEGORY));
3956 /* char *category_name; */
3958 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3960 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3961 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3962 field_decl_chain = field_decl;
3964 /* char *class_name; */
3966 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3967 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3968 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3969 chainon (field_decl_chain, field_decl);
3971 /* struct objc_method_list *instance_methods; */
3973 decl_specs = build_tree_list (NULL_TREE,
3974 xref_tag (RECORD_TYPE,
3975 get_identifier (UTAG_METHOD_LIST)));
3977 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3978 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3979 chainon (field_decl_chain, field_decl);
3981 /* struct objc_method_list *class_methods; */
3983 decl_specs = build_tree_list (NULL_TREE,
3984 xref_tag (RECORD_TYPE,
3985 get_identifier (UTAG_METHOD_LIST)));
3987 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3988 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3989 chainon (field_decl_chain, field_decl);
3991 /* struct objc_protocol **protocol_list; */
3993 decl_specs = build_tree_list (NULL_TREE,
3994 xref_tag (RECORD_TYPE,
3995 get_identifier (UTAG_PROTOCOL)));
3997 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3998 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3999 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4000 chainon (field_decl_chain, field_decl);
4002 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4005 /* struct objc_selector {
4011 build_selector_template (void)
4014 tree decl_specs, field_decl, field_decl_chain;
4016 objc_selector_template
4017 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4021 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4022 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4023 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4024 field_decl_chain = field_decl;
4026 /* char *sel_type; */
4028 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4029 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4030 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4031 chainon (field_decl_chain, field_decl);
4033 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4036 /* struct objc_class {
4037 struct objc_class *isa;
4038 struct objc_class *super_class;
4043 struct objc_ivar_list *ivars;
4044 struct objc_method_list *methods;
4045 if (flag_next_runtime)
4046 struct objc_cache *cache;
4048 struct sarray *dtable;
4049 struct objc_class *subclass_list;
4050 struct objc_class *sibling_class;
4052 struct objc_protocol_list *protocols;
4053 if (flag_next_runtime)
4055 void *gc_object_type;
4058 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4059 the NeXT/Apple runtime; still, the compiler must generate them to
4060 maintain backward binary compatibility (and to allow for future
4064 build_class_template (void)
4066 tree decl_specs, field_decl, field_decl_chain;
4069 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4071 /* struct objc_class *isa; */
4073 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4074 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4075 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4076 field_decl_chain = field_decl;
4078 /* struct objc_class *super_class; */
4080 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4082 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4083 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4084 chainon (field_decl_chain, field_decl);
4088 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4089 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4090 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4091 chainon (field_decl_chain, field_decl);
4095 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4096 field_decl = get_identifier ("version");
4097 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4098 chainon (field_decl_chain, field_decl);
4102 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4103 field_decl = get_identifier ("info");
4104 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4105 chainon (field_decl_chain, field_decl);
4107 /* long instance_size; */
4109 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4110 field_decl = get_identifier ("instance_size");
4111 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4112 chainon (field_decl_chain, field_decl);
4114 /* struct objc_ivar_list *ivars; */
4116 decl_specs = build_tree_list (NULL_TREE,
4117 xref_tag (RECORD_TYPE,
4118 get_identifier (UTAG_IVAR_LIST)));
4119 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4120 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4121 chainon (field_decl_chain, field_decl);
4123 /* struct objc_method_list *methods; */
4125 decl_specs = build_tree_list (NULL_TREE,
4126 xref_tag (RECORD_TYPE,
4127 get_identifier (UTAG_METHOD_LIST)));
4128 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4129 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4130 chainon (field_decl_chain, field_decl);
4132 if (flag_next_runtime)
4134 /* struct objc_cache *cache; */
4136 decl_specs = build_tree_list (NULL_TREE,
4137 xref_tag (RECORD_TYPE,
4138 get_identifier ("objc_cache")));
4139 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4140 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4141 chainon (field_decl_chain, field_decl);
4145 /* struct sarray *dtable; */
4147 decl_specs = build_tree_list (NULL_TREE,
4148 xref_tag (RECORD_TYPE,
4149 get_identifier ("sarray")));
4150 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4151 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4152 chainon (field_decl_chain, field_decl);
4154 /* struct objc_class *subclass_list; */
4156 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4158 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4159 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4160 chainon (field_decl_chain, field_decl);
4162 /* struct objc_class *sibling_class; */
4164 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4166 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4167 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4168 chainon (field_decl_chain, field_decl);
4171 /* struct objc_protocol **protocol_list; */
4173 decl_specs = build_tree_list (NULL_TREE,
4174 xref_tag (RECORD_TYPE,
4175 get_identifier (UTAG_PROTOCOL)));
4177 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4179 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4180 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4181 chainon (field_decl_chain, field_decl);
4183 if (flag_next_runtime)
4187 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4188 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4190 = grokfield (field_decl, decl_specs, NULL_TREE);
4191 chainon (field_decl_chain, field_decl);
4194 /* void *gc_object_type; */
4196 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4197 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4198 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4199 chainon (field_decl_chain, field_decl);
4201 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4204 /* Generate appropriate forward declarations for an implementation. */
4207 synth_forward_declarations (void)
4211 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4212 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4213 objc_class_template);
4215 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4216 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4217 objc_class_template);
4219 /* Pre-build the following entities - for speed/convenience. */
4221 an_id = get_identifier ("super_class");
4222 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4223 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4227 error_with_ivar (const char *message, tree decl, tree rawdecl)
4229 error ("%J%s `%s'", decl,
4230 message, gen_declaration (rawdecl, errbuf));
4235 check_ivars (tree inter, tree imp)
4237 tree intdecls = CLASS_IVARS (inter);
4238 tree impdecls = CLASS_IVARS (imp);
4239 tree rawintdecls = CLASS_RAW_IVARS (inter);
4240 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4247 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4248 intdecls = TREE_CHAIN (intdecls);
4250 if (intdecls == 0 && impdecls == 0)
4252 if (intdecls == 0 || impdecls == 0)
4254 error ("inconsistent instance variable specification");
4258 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4260 if (!comptypes (t1, t2)
4261 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4262 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4264 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4266 error_with_ivar ("conflicting instance variable type",
4267 impdecls, rawimpdecls);
4268 error_with_ivar ("previous declaration of",
4269 intdecls, rawintdecls);
4271 else /* both the type and the name don't match */
4273 error ("inconsistent instance variable specification");
4278 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4280 error_with_ivar ("conflicting instance variable name",
4281 impdecls, rawimpdecls);
4282 error_with_ivar ("previous declaration of",
4283 intdecls, rawintdecls);
4286 intdecls = TREE_CHAIN (intdecls);
4287 impdecls = TREE_CHAIN (impdecls);
4288 rawintdecls = TREE_CHAIN (rawintdecls);
4289 rawimpdecls = TREE_CHAIN (rawimpdecls);
4293 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4294 This needs to be done just once per compilation. */
4297 build_super_template (void)
4299 tree decl_specs, field_decl, field_decl_chain;
4301 /* Suppress outputting debug symbols, because
4302 dbxout_init hasn't been called yet. */
4303 enum debug_info_type save_write_symbols = write_symbols;
4304 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4306 write_symbols = NO_DEBUG;
4307 debug_hooks = &do_nothing_debug_hooks;
4309 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4311 /* struct objc_object *self; */
4313 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4314 field_decl = get_identifier ("self");
4315 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4316 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4317 field_decl_chain = field_decl;
4320 /* struct objc_class *super_class; */
4322 /* struct objc_class *class; */
4325 decl_specs = get_identifier (UTAG_CLASS);
4326 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4328 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4330 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4333 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4334 chainon (field_decl_chain, field_decl);
4336 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4338 write_symbols = save_write_symbols;
4339 debug_hooks = save_hooks;
4342 /* struct objc_ivar {
4349 build_ivar_template (void)
4351 tree objc_ivar_id, objc_ivar_record;
4352 tree decl_specs, field_decl, field_decl_chain;
4354 objc_ivar_id = get_identifier (UTAG_IVAR);
4355 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4357 /* char *ivar_name; */
4359 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4360 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4362 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4363 field_decl_chain = field_decl;
4365 /* char *ivar_type; */
4367 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4368 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4370 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4371 chainon (field_decl_chain, field_decl);
4373 /* int ivar_offset; */
4375 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4376 field_decl = get_identifier ("ivar_offset");
4378 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4379 chainon (field_decl_chain, field_decl);
4381 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4383 return objc_ivar_record;
4388 struct objc_ivar ivar_list[ivar_count];
4392 build_ivar_list_template (tree list_type, int size)
4394 tree objc_ivar_list_record;
4395 tree decl_specs, field_decl, field_decl_chain;
4397 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4399 /* int ivar_count; */
4401 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4402 field_decl = get_identifier ("ivar_count");
4404 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4405 field_decl_chain = field_decl;
4407 /* struct objc_ivar ivar_list[]; */
4409 decl_specs = build_tree_list (NULL_TREE, list_type);
4410 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4411 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
4413 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4414 chainon (field_decl_chain, field_decl);
4416 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4418 return objc_ivar_list_record;
4424 struct objc_method method_list[method_count];
4428 build_method_list_template (tree list_type, int size)
4430 tree objc_ivar_list_record;
4431 tree decl_specs, field_decl, field_decl_chain;
4433 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4435 /* int method_next; */
4440 xref_tag (RECORD_TYPE,
4441 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4443 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4444 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4445 field_decl_chain = field_decl;
4447 /* int method_count; */
4449 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4450 field_decl = get_identifier ("method_count");
4452 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4453 chainon (field_decl_chain, field_decl);
4455 /* struct objc_method method_list[]; */
4457 decl_specs = build_tree_list (NULL_TREE, list_type);
4458 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4459 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
4461 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4462 chainon (field_decl_chain, field_decl);
4464 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4466 return objc_ivar_list_record;
4470 build_ivar_list_initializer (tree type, tree field_decl)
4472 tree initlist = NULL_TREE;
4476 tree ivar = NULL_TREE;
4479 if (DECL_NAME (field_decl))
4480 ivar = tree_cons (NULL_TREE,
4481 add_objc_string (DECL_NAME (field_decl),
4485 /* Unnamed bit-field ivar (yuck). */
4486 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4489 encode_field_decl (field_decl,
4490 obstack_object_size (&util_obstack),
4491 OBJC_ENCODE_DONT_INLINE_DEFS);
4493 /* Null terminate string. */
4494 obstack_1grow (&util_obstack, 0);
4498 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4501 obstack_free (&util_obstack, util_firstobj);
4504 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4505 initlist = tree_cons (NULL_TREE,
4506 objc_build_constructor (type, nreverse (ivar)),
4509 field_decl = TREE_CHAIN (field_decl);
4510 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4514 return objc_build_constructor (build_array_type (type, 0),
4515 nreverse (initlist));
4519 generate_ivars_list (tree type, const char *name, int size, tree list)
4521 tree sc_spec, decl_specs, decl, initlist;
4523 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4524 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4526 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4527 decl_specs, 1, NULL_TREE);
4529 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4530 initlist = tree_cons (NULL_TREE, list, initlist);
4533 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4539 /* Count only the fields occurring in T. */
4541 ivar_list_length (tree t)
4545 for (; t; t = TREE_CHAIN (t))
4546 if (TREE_CODE (t) == FIELD_DECL)
4553 generate_ivar_lists (void)
4555 tree initlist, ivar_list_template, chain;
4556 tree cast, variable_length_type;
4559 generating_instance_variables = 1;
4561 if (!objc_ivar_template)
4562 objc_ivar_template = build_ivar_template ();
4566 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4567 get_identifier (UTAG_IVAR_LIST))),
4569 variable_length_type = groktypename (cast);
4571 /* Only generate class variables for the root of the inheritance
4572 hierarchy since these will be the same for every class. */
4574 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4575 && (chain = TYPE_FIELDS (objc_class_template)))
4577 size = ivar_list_length (chain);
4579 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4580 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4582 UOBJC_CLASS_VARIABLES_decl
4583 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4585 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4588 UOBJC_CLASS_VARIABLES_decl = 0;
4590 chain = CLASS_IVARS (implementation_template);
4593 size = ivar_list_length (chain);
4594 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4595 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4597 UOBJC_INSTANCE_VARIABLES_decl
4598 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4600 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4603 UOBJC_INSTANCE_VARIABLES_decl = 0;
4605 generating_instance_variables = 0;
4609 build_dispatch_table_initializer (tree type, tree entries)
4611 tree initlist = NULL_TREE;
4615 tree elemlist = NULL_TREE;
4617 elemlist = tree_cons (NULL_TREE,
4618 build_selector (METHOD_SEL_NAME (entries)),
4621 /* Generate the method encoding if we don't have one already. */
4622 if (! METHOD_ENCODING (entries))
4623 METHOD_ENCODING (entries) =
4624 encode_method_prototype (entries);
4626 elemlist = tree_cons (NULL_TREE,
4627 add_objc_string (METHOD_ENCODING (entries),
4631 elemlist = tree_cons (NULL_TREE,
4632 build_unary_op (ADDR_EXPR,
4633 METHOD_DEFINITION (entries), 1),
4636 initlist = tree_cons (NULL_TREE,
4637 objc_build_constructor (type, nreverse (elemlist)),
4640 entries = TREE_CHAIN (entries);
4644 return objc_build_constructor (build_array_type (type, 0),
4645 nreverse (initlist));
4648 /* To accomplish method prototyping without generating all kinds of
4649 inane warnings, the definition of the dispatch table entries were
4652 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4654 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4657 build_method_template (void)
4660 tree decl_specs, field_decl, field_decl_chain;
4662 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4664 /* struct objc_selector *_cmd; */
4665 decl_specs = tree_cons (NULL_TREE,
4666 xref_tag (RECORD_TYPE,
4667 get_identifier (TAG_SELECTOR)),
4669 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4671 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4672 field_decl_chain = field_decl;
4674 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4675 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4676 get_identifier ("method_types"));
4677 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4678 chainon (field_decl_chain, field_decl);
4682 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4683 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4684 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4685 chainon (field_decl_chain, field_decl);
4687 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4694 generate_dispatch_table (tree type, const char *name, int size, tree list)
4696 tree sc_spec, decl_specs, decl, initlist;
4698 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4699 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4701 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4702 decl_specs, 1, NULL_TREE);
4704 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4705 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4706 initlist = tree_cons (NULL_TREE, list, initlist);
4709 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4716 mark_referenced_methods (void)
4718 struct imp_entry *impent;
4721 for (impent = imp_list; impent; impent = impent->next)
4723 chain = CLASS_CLS_METHODS (impent->imp_context);
4726 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4727 chain = TREE_CHAIN (chain);
4730 chain = CLASS_NST_METHODS (impent->imp_context);
4733 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4734 chain = TREE_CHAIN (chain);
4740 generate_dispatch_tables (void)
4742 tree initlist, chain, method_list_template;
4743 tree cast, variable_length_type;
4746 if (!objc_method_template)
4747 objc_method_template = build_method_template ();
4751 (build_tree_list (NULL_TREE,
4752 xref_tag (RECORD_TYPE,
4753 get_identifier (UTAG_METHOD_LIST))),
4756 variable_length_type = groktypename (cast);
4758 chain = CLASS_CLS_METHODS (objc_implementation_context);
4761 size = list_length (chain);
4763 method_list_template
4764 = build_method_list_template (objc_method_template, size);
4766 = build_dispatch_table_initializer (objc_method_template, chain);
4768 UOBJC_CLASS_METHODS_decl
4769 = generate_dispatch_table (method_list_template,
4770 ((TREE_CODE (objc_implementation_context)
4771 == CLASS_IMPLEMENTATION_TYPE)
4772 ? "_OBJC_CLASS_METHODS"
4773 : "_OBJC_CATEGORY_CLASS_METHODS"),
4775 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4778 UOBJC_CLASS_METHODS_decl = 0;
4780 chain = CLASS_NST_METHODS (objc_implementation_context);
4783 size = list_length (chain);
4785 method_list_template
4786 = build_method_list_template (objc_method_template, size);
4788 = build_dispatch_table_initializer (objc_method_template, chain);
4790 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4791 UOBJC_INSTANCE_METHODS_decl
4792 = generate_dispatch_table (method_list_template,
4793 "_OBJC_INSTANCE_METHODS",
4796 /* We have a category. */
4797 UOBJC_INSTANCE_METHODS_decl
4798 = generate_dispatch_table (method_list_template,
4799 "_OBJC_CATEGORY_INSTANCE_METHODS",
4801 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4804 UOBJC_INSTANCE_METHODS_decl = 0;
4808 generate_protocol_list (tree i_or_p)
4810 tree initlist, decl_specs, sc_spec;
4811 tree refs_decl, expr_decl, lproto, e, plist;
4815 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4816 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4817 plist = CLASS_PROTOCOL_LIST (i_or_p);
4818 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4819 plist = PROTOCOL_LIST (i_or_p);
4823 cast_type = groktypename
4825 (build_tree_list (NULL_TREE,
4826 xref_tag (RECORD_TYPE,
4827 get_identifier (UTAG_PROTOCOL))),
4828 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4831 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4832 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4833 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4836 /* Build initializer. */
4837 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4839 e = build_int_2 (size, 0);
4840 TREE_TYPE (e) = cast_type;
4841 initlist = tree_cons (NULL_TREE, e, initlist);
4843 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4845 tree pval = TREE_VALUE (lproto);
4847 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4848 && PROTOCOL_FORWARD_DECL (pval))
4850 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4851 initlist = tree_cons (NULL_TREE, e, initlist);
4855 /* static struct objc_protocol *refs[n]; */
4857 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4858 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4859 get_identifier (UTAG_PROTOCOL)),
4862 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4863 expr_decl = build_nt (ARRAY_REF,
4864 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4866 build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
4867 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4868 expr_decl = build_nt (ARRAY_REF,
4869 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4871 build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
4872 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4874 = build_nt (ARRAY_REF,
4875 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4877 build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
4881 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4883 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4884 DECL_CONTEXT (refs_decl) = NULL_TREE;
4886 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4887 nreverse (initlist)),
4894 build_category_initializer (tree type, tree cat_name, tree class_name,
4895 tree instance_methods, tree class_methods,
4898 tree initlist = NULL_TREE, expr;
4900 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4901 initlist = tree_cons (NULL_TREE, class_name, initlist);
4903 if (!instance_methods)
4904 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4907 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4908 initlist = tree_cons (NULL_TREE, expr, initlist);
4911 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4914 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4915 initlist = tree_cons (NULL_TREE, expr, initlist);
4918 /* protocol_list = */
4920 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4923 tree cast_type2 = groktypename
4925 (build_tree_list (NULL_TREE,
4926 xref_tag (RECORD_TYPE,
4927 get_identifier (UTAG_PROTOCOL))),
4928 build1 (INDIRECT_REF, NULL_TREE,
4929 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4931 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4932 TREE_TYPE (expr) = cast_type2;
4933 initlist = tree_cons (NULL_TREE, expr, initlist);
4936 return objc_build_constructor (type, nreverse (initlist));
4939 /* struct objc_class {
4940 struct objc_class *isa;
4941 struct objc_class *super_class;
4946 struct objc_ivar_list *ivars;
4947 struct objc_method_list *methods;
4948 if (flag_next_runtime)
4949 struct objc_cache *cache;
4951 struct sarray *dtable;
4952 struct objc_class *subclass_list;
4953 struct objc_class *sibling_class;
4955 struct objc_protocol_list *protocols;
4956 if (flag_next_runtime)
4958 void *gc_object_type;
4962 build_shared_structure_initializer (tree type, tree isa, tree super,
4963 tree name, tree size, int status,
4964 tree dispatch_table, tree ivar_list,
4967 tree initlist = NULL_TREE, expr;
4970 initlist = tree_cons (NULL_TREE, isa, initlist);
4973 initlist = tree_cons (NULL_TREE, super, initlist);
4976 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4979 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4982 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4984 /* instance_size = */
4985 initlist = tree_cons (NULL_TREE, size, initlist);
4987 /* objc_ivar_list = */
4989 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4992 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4993 initlist = tree_cons (NULL_TREE, expr, initlist);
4996 /* objc_method_list = */
4997 if (!dispatch_table)
4998 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5001 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
5002 initlist = tree_cons (NULL_TREE, expr, initlist);
5005 if (flag_next_runtime)
5006 /* method_cache = */
5007 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5011 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5013 /* subclass_list = */
5014 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5016 /* sibling_class = */
5017 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5020 /* protocol_list = */
5021 if (! protocol_list)
5022 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5028 (build_tree_list (NULL_TREE,
5029 xref_tag (RECORD_TYPE,
5030 get_identifier (UTAG_PROTOCOL))),
5031 build1 (INDIRECT_REF, NULL_TREE,
5032 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5034 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5035 TREE_TYPE (expr) = cast_type2;
5036 initlist = tree_cons (NULL_TREE, expr, initlist);
5039 if (flag_next_runtime)
5041 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5043 /* gc_object_type = NULL */
5044 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5046 return objc_build_constructor (type, nreverse (initlist));
5049 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5052 lookup_category (tree class, tree cat_name)
5054 tree category = CLASS_CATEGORY_LIST (class);
5056 while (category && CLASS_SUPER_NAME (category) != cat_name)
5057 category = CLASS_CATEGORY_LIST (category);
5061 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5064 generate_category (tree cat)
5066 tree sc_spec, decl_specs, decl;
5067 tree initlist, cat_name_expr, class_name_expr;
5068 tree protocol_decl, category;
5070 add_class_reference (CLASS_NAME (cat));
5071 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5073 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5075 category = lookup_category (implementation_template,
5076 CLASS_SUPER_NAME (cat));
5078 if (category && CLASS_PROTOCOL_LIST (category))
5080 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5081 protocol_decl = generate_protocol_list (category);
5086 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5087 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5089 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5090 objc_implementation_context),
5091 decl_specs, 1, NULL_TREE);
5093 initlist = build_category_initializer (TREE_TYPE (decl),
5094 cat_name_expr, class_name_expr,
5095 UOBJC_INSTANCE_METHODS_decl,
5096 UOBJC_CLASS_METHODS_decl,
5099 finish_decl (decl, initlist, NULL_TREE);
5102 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5103 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5106 generate_shared_structures (void)
5108 tree sc_spec, decl_specs, decl;
5109 tree name_expr, super_expr, root_expr;
5110 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5111 tree cast_type, initlist, protocol_decl;
5113 my_super_id = CLASS_SUPER_NAME (implementation_template);
5116 add_class_reference (my_super_id);
5118 /* Compute "my_root_id" - this is required for code generation.
5119 the "isa" for all meta class structures points to the root of
5120 the inheritance hierarchy (e.g. "__Object")... */
5121 my_root_id = my_super_id;
5124 tree my_root_int = lookup_interface (my_root_id);
5126 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5127 my_root_id = CLASS_SUPER_NAME (my_root_int);
5134 /* No super class. */
5135 my_root_id = CLASS_NAME (implementation_template);
5138 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5139 objc_class_template),
5140 build1 (INDIRECT_REF,
5141 NULL_TREE, NULL_TREE)));
5143 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5146 /* Install class `isa' and `super' pointers at runtime. */
5149 super_expr = add_objc_string (my_super_id, class_names);
5150 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5153 super_expr = build_int_2 (0, 0);
5155 root_expr = add_objc_string (my_root_id, class_names);
5156 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5158 if (CLASS_PROTOCOL_LIST (implementation_template))
5160 generate_protocol_references
5161 (CLASS_PROTOCOL_LIST (implementation_template));
5162 protocol_decl = generate_protocol_list (implementation_template);
5167 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5169 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5170 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5172 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5176 = build_shared_structure_initializer
5178 root_expr, super_expr, name_expr,
5179 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5181 UOBJC_CLASS_METHODS_decl,
5182 UOBJC_CLASS_VARIABLES_decl,
5185 finish_decl (decl, initlist, NULL_TREE);
5187 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5189 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5193 = build_shared_structure_initializer
5195 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5196 super_expr, name_expr,
5197 convert (integer_type_node,
5198 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5199 (implementation_template))),
5201 UOBJC_INSTANCE_METHODS_decl,
5202 UOBJC_INSTANCE_VARIABLES_decl,
5205 finish_decl (decl, initlist, NULL_TREE);
5209 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5212 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5213 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5215 const char *const class_name
5216 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5217 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5218 sprintf (string, "%s_%s", preamble,
5219 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5221 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5222 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5224 /* We have a category. */
5225 const char *const class_name
5226 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5227 const char *const class_super_name
5228 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5229 string = (char *) alloca (strlen (preamble)
5230 + strlen (class_name)
5231 + strlen (class_super_name)
5233 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5235 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5237 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5239 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5240 sprintf (string, "%s_%s", preamble, protocol_name);
5245 return get_identifier (string);
5249 is_objc_type_qualifier (tree node)
5251 return (TREE_CODE (node) == IDENTIFIER_NODE
5252 && (node == ridpointers [(int) RID_CONST]
5253 || node == ridpointers [(int) RID_VOLATILE]
5254 || node == ridpointers [(int) RID_IN]
5255 || node == ridpointers [(int) RID_OUT]
5256 || node == ridpointers [(int) RID_INOUT]
5257 || node == ridpointers [(int) RID_BYCOPY]
5258 || node == ridpointers [(int) RID_BYREF]
5259 || node == ridpointers [(int) RID_ONEWAY]));
5262 /* If type is empty or only type qualifiers are present, add default
5263 type of id (otherwise grokdeclarator will default to int). */
5266 adjust_type_for_id_default (tree type)
5268 tree declspecs, chain;
5271 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5272 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5274 declspecs = TREE_PURPOSE (type);
5276 /* Determine if a typespec is present. */
5277 for (chain = declspecs;
5279 chain = TREE_CHAIN (chain))
5281 if (TYPED_OBJECT (TREE_VALUE (chain))
5282 && !(TREE_VALUE (type)
5283 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5284 error ("can not use an object as parameter to a method\n");
5285 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5289 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5291 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5296 selector ':' '(' typename ')' identifier
5299 Transform an Objective-C keyword argument into
5300 the C equivalent parameter declarator.
5302 In: key_name, an "identifier_node" (optional).
5303 arg_type, a "tree_list" (optional).
5304 arg_name, an "identifier_node".
5306 Note: It would be really nice to strongly type the preceding
5307 arguments in the function prototype; however, then I
5308 could not use the "accessor" macros defined in "tree.h".
5310 Out: an instance of "keyword_decl". */
5313 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5317 /* If no type is specified, default to "id". */
5318 arg_type = adjust_type_for_id_default (arg_type);
5320 keyword_decl = make_node (KEYWORD_DECL);
5322 TREE_TYPE (keyword_decl) = arg_type;
5323 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5324 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5326 return keyword_decl;
5329 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5332 build_keyword_selector (tree selector)
5335 tree key_chain, key_name;
5338 /* Scan the selector to see how much space we'll need. */
5339 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5341 if (TREE_CODE (selector) == KEYWORD_DECL)
5342 key_name = KEYWORD_KEY_NAME (key_chain);
5343 else if (TREE_CODE (selector) == TREE_LIST)
5344 key_name = TREE_PURPOSE (key_chain);
5349 len += IDENTIFIER_LENGTH (key_name) + 1;
5351 /* Just a ':' arg. */
5355 buf = (char *) alloca (len + 1);
5356 /* Start the buffer out as an empty string. */
5359 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5361 if (TREE_CODE (selector) == KEYWORD_DECL)
5362 key_name = KEYWORD_KEY_NAME (key_chain);
5363 else if (TREE_CODE (selector) == TREE_LIST)
5365 key_name = TREE_PURPOSE (key_chain);
5366 /* The keyword decl chain will later be used as a function argument
5367 chain. Unhook the selector itself so as to not confuse other
5368 parts of the compiler. */
5369 TREE_PURPOSE (key_chain) = NULL_TREE;
5375 strcat (buf, IDENTIFIER_POINTER (key_name));
5379 return get_identifier (buf);
5382 /* Used for declarations and definitions. */
5385 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5390 /* If no type is specified, default to "id". */
5391 ret_type = adjust_type_for_id_default (ret_type);
5393 method_decl = make_node (code);
5394 TREE_TYPE (method_decl) = ret_type;
5396 /* If we have a keyword selector, create an identifier_node that
5397 represents the full selector name (`:' included)... */
5398 if (TREE_CODE (selector) == KEYWORD_DECL)
5400 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5401 METHOD_SEL_ARGS (method_decl) = selector;
5402 METHOD_ADD_ARGS (method_decl) = add_args;
5406 METHOD_SEL_NAME (method_decl) = selector;
5407 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5408 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5414 #define METHOD_DEF 0
5415 #define METHOD_REF 1
5417 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5418 an argument list for method METH. CONTEXT is either METHOD_DEF or
5419 METHOD_REF, saying whether we are trying to define a method or call
5420 one. SUPERFLAG says this is for a send to super; this makes a
5421 difference for the NeXT calling sequence in which the lookup and
5422 the method call are done together. If METH is null, user-defined
5423 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5426 get_arg_type_list (tree meth, int context, int superflag)
5430 /* Receiver type. */
5431 if (flag_next_runtime && superflag)
5432 arglist = build_tree_list (NULL_TREE, objc_super_type);
5433 else if (context == METHOD_DEF)
5434 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5436 arglist = build_tree_list (NULL_TREE, objc_id_type);
5438 /* Selector type - will eventually change to `int'. */
5439 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5441 /* No actual method prototype given -- assume that remaining arguments
5446 /* Build a list of argument types. */
5447 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5449 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5450 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5453 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5454 /* We have a `, ...' immediately following the selector,
5455 finalize the arglist...simulate get_parm_info (true). */
5457 else if (METHOD_ADD_ARGS (meth))
5459 /* we have a variable length selector */
5460 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5461 chainon (arglist, add_arg_list);
5464 /* finalize the arglist...simulate get_parm_info (false) */
5465 chainon (arglist, void_list_node);
5471 check_duplicates (hash hsh, int methods, int is_class)
5473 tree meth = NULL_TREE;
5481 /* We have two or more methods with the same name but
5485 warning ("multiple %s named `%c%s' found",
5486 methods ? "methods" : "selectors",
5487 (is_class ? '+' : '-'),
5488 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5490 warn_with_method (methods ? "using" : "found",
5491 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5495 for (loop = hsh->list; loop; loop = loop->next)
5496 warn_with_method ("also found",
5497 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5506 /* If RECEIVER is a class reference, return the identifier node for
5507 the referenced class. RECEIVER is created by get_class_reference,
5508 so we check the exact form created depending on which runtimes are
5512 receiver_is_class_object (tree receiver, int self, int super)
5514 tree chain, exp, arg;
5516 /* The receiver is 'self' or 'super' in the context of a class method. */
5517 if (objc_method_context
5518 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5521 ? CLASS_SUPER_NAME (implementation_template)
5522 : CLASS_NAME (implementation_template));
5524 if (flag_next_runtime)
5526 /* The receiver is a variable created by
5527 build_class_reference_decl. */
5528 if (TREE_CODE (receiver) == VAR_DECL
5529 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5530 /* Look up the identifier. */
5531 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5532 if (TREE_PURPOSE (chain) == receiver)
5533 return TREE_VALUE (chain);
5536 /* The receiver is a function call that returns an id. Check if
5537 it is a call to objc_getClass, if so, pick up the class name. */
5538 if (TREE_CODE (receiver) == CALL_EXPR
5539 && (exp = TREE_OPERAND (receiver, 0))
5540 && TREE_CODE (exp) == ADDR_EXPR
5541 && (exp = TREE_OPERAND (exp, 0))
5542 && TREE_CODE (exp) == FUNCTION_DECL
5543 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5544 prototypes for objc_get_class(). Thankfully, they seem to share the
5545 same function type. */
5546 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5547 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5548 /* We have a call to objc_get_class/objc_getClass! */
5549 && (arg = TREE_OPERAND (receiver, 1))
5550 && TREE_CODE (arg) == TREE_LIST
5551 && (arg = TREE_VALUE (arg)))
5554 if (TREE_CODE (arg) == ADDR_EXPR
5555 && (arg = TREE_OPERAND (arg, 0))
5556 && TREE_CODE (arg) == STRING_CST)
5557 /* Finally, we have the class name. */
5558 return get_identifier (TREE_STRING_POINTER (arg));
5563 /* If we are currently building a message expr, this holds
5564 the identifier of the selector of the message. This is
5565 used when printing warnings about argument mismatches. */
5567 static tree current_objc_message_selector = 0;
5570 objc_message_selector (void)
5572 return current_objc_message_selector;
5575 /* Construct an expression for sending a message.
5576 MESS has the object to send to in TREE_PURPOSE
5577 and the argument list (including selector) in TREE_VALUE.
5579 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5580 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5583 build_message_expr (tree mess)
5585 tree receiver = TREE_PURPOSE (mess);
5587 tree args = TREE_VALUE (mess);
5588 tree method_params = NULL_TREE;
5590 if (TREE_CODE (receiver) == ERROR_MARK)
5591 return error_mark_node;
5593 /* Obtain the full selector name. */
5594 if (TREE_CODE (args) == IDENTIFIER_NODE)
5595 /* A unary selector. */
5597 else if (TREE_CODE (args) == TREE_LIST)
5598 sel_name = build_keyword_selector (args);
5602 /* Build the parameter list to give to the method. */
5603 if (TREE_CODE (args) == TREE_LIST)
5605 tree chain = args, prev = NULL_TREE;
5607 /* We have a keyword selector--check for comma expressions. */
5610 tree element = TREE_VALUE (chain);
5612 /* We have a comma expression, must collapse... */
5613 if (TREE_CODE (element) == TREE_LIST)
5616 TREE_CHAIN (prev) = element;
5621 chain = TREE_CHAIN (chain);
5623 method_params = args;
5627 if (processing_template_decl)
5628 /* Must wait until template instantiation time. */
5629 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5633 return finish_message_expr (receiver, sel_name, method_params);
5636 /* Look up method SEL_NAME that would be suitable for receiver
5637 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5638 nonzero), and report on any duplicates. */
5641 lookup_method_in_hash_lists (tree sel_name, int is_class)
5643 hash method_prototype = NULL;
5646 method_prototype = hash_lookup (nst_method_hash_list,
5649 if (!method_prototype)
5651 method_prototype = hash_lookup (cls_method_hash_list,
5656 return check_duplicates (method_prototype, 1, is_class);
5659 /* The 'finish_message_expr' routine is called from within
5660 'build_message_expr' for non-template functions. In the case of
5661 C++ template functions, it is called from 'build_expr_from_tree'
5662 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5665 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5667 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5668 tree selector, retval, class_tree;
5669 int self, super, have_cast;
5671 /* Extract the receiver of the message, as well as its type
5672 (where the latter may take the form of a cast or be inferred
5673 from the implementation context). */
5675 while (TREE_CODE (rtype) == COMPOUND_EXPR
5676 || TREE_CODE (rtype) == MODIFY_EXPR
5677 || TREE_CODE (rtype) == NOP_EXPR
5678 || TREE_CODE (rtype) == COMPONENT_REF)
5679 rtype = TREE_OPERAND (rtype, 0);
5680 self = (rtype == self_decl);
5681 super = (rtype == UOBJC_SUPER_decl);
5682 rtype = TREE_TYPE (receiver);
5683 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5684 || (TREE_CODE (receiver) == COMPOUND_EXPR
5685 && !IS_SUPER (rtype)));
5687 /* If the receiver is a class object, retrieve the corresponding
5688 @interface, if one exists. */
5689 class_tree = receiver_is_class_object (receiver, self, super);
5691 /* Now determine the receiver type (if an explicit cast has not been
5696 rtype = lookup_interface (class_tree);
5697 /* Handle `self' and `super'. */
5700 if (!CLASS_SUPER_NAME (implementation_template))
5702 error ("no super class declared in @interface for `%s'",
5703 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5704 return error_mark_node;
5706 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5709 rtype = lookup_interface (CLASS_NAME (implementation_template));
5712 /* If receiver is of type `id' or `Class' (or if the @interface for a
5713 class is not visible), we shall be satisfied with the existence of
5714 any instance or class method. */
5715 if (!rtype || IS_ID (rtype)
5716 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5719 rtype = xref_tag (RECORD_TYPE, class_tree);
5720 else if (IS_ID (rtype))
5722 rprotos = TYPE_PROTOCOL_LIST (rtype);
5726 class_tree = TYPE_NAME (rtype) = get_identifier ("Class");
5730 = lookup_method_in_protocol_list (rprotos, sel_name,
5731 class_tree != NULL_TREE);
5732 if (!method_prototype && !rprotos)
5734 = lookup_method_in_hash_lists (sel_name,
5735 class_tree != NULL_TREE);
5739 tree orig_rtype = rtype, saved_rtype;
5741 if (TREE_CODE (rtype) == POINTER_TYPE)
5742 rtype = TREE_TYPE (rtype);
5743 /* Traverse typedef aliases */
5744 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5745 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5746 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5747 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5748 saved_rtype = rtype;
5749 if (TYPED_OBJECT (rtype))
5751 rprotos = TYPE_PROTOCOL_LIST (rtype);
5752 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5754 /* If we could not find an @interface declaration, we must have
5755 only seen a @class declaration; so, we cannot say anything
5756 more intelligent about which methods the receiver will
5759 rtype = saved_rtype;
5760 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5761 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5763 /* We have a valid ObjC class name. Look up the method name
5764 in the published @interface for the class (and its
5767 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5769 /* If the method was not found in the @interface, it may still
5770 exist locally as part of the @implementation. */
5771 if (!method_prototype && objc_implementation_context
5772 && CLASS_NAME (objc_implementation_context)
5773 == OBJC_TYPE_NAME (rtype))
5777 ? CLASS_CLS_METHODS (objc_implementation_context)
5778 : CLASS_NST_METHODS (objc_implementation_context)),
5781 /* If we haven't found a candidate method by now, try looking for
5782 it in the protocol list. */
5783 if (!method_prototype && rprotos)
5785 = lookup_method_in_protocol_list (rprotos, sel_name,
5786 class_tree != NULL_TREE);
5790 warning ("invalid receiver type `%s'",
5791 gen_declaration (orig_rtype, errbuf));
5792 rtype = rprotos = NULL_TREE;
5796 if (!method_prototype)
5798 static bool warn_missing_methods = false;
5801 warning ("`%s' may not respond to `%c%s'",
5802 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5803 (class_tree ? '+' : '-'),
5804 IDENTIFIER_POINTER (sel_name));
5806 warning ("`%c%s' not implemented by protocol(s)",
5807 (class_tree ? '+' : '-'),
5808 IDENTIFIER_POINTER (sel_name));
5809 if (!warn_missing_methods)
5811 warning ("(Messages without a matching method signature");
5812 warning ("will be assumed to return `id' and accept");
5813 warning ("`...' as arguments.)");
5814 warn_missing_methods = true;
5818 /* Save the selector name for printing error messages. */
5819 current_objc_message_selector = sel_name;
5821 /* Build the parameters list for looking up the method.
5822 These are the object itself and the selector. */
5824 if (flag_typed_selectors)
5825 selector = build_typed_selector_reference (sel_name, method_prototype);
5827 selector = build_selector_reference (sel_name);
5829 retval = build_objc_method_call (super, method_prototype,
5831 selector, method_params);
5833 current_objc_message_selector = 0;
5838 /* Build a tree expression to send OBJECT the operation SELECTOR,
5839 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5840 assuming the method has prototype METHOD_PROTOTYPE.
5841 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5842 Use METHOD_PARAMS as list of args to pass to the method.
5843 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5846 build_objc_method_call (int super_flag, tree method_prototype,
5847 tree lookup_object, tree selector,
5850 tree sender = (super_flag ? umsg_super_decl :
5851 (!flag_next_runtime || flag_nil_receivers
5853 : umsg_nonnil_decl));
5854 tree rcv_p = (super_flag ? objc_super_type : objc_id_type);
5856 /* If a prototype for the method to be called exists, then cast
5857 the sender's return type and arguments to match that of the method.
5858 Otherwise, leave sender as is. */
5861 ? groktypename (TREE_TYPE (method_prototype))
5864 = build_pointer_type
5865 (build_function_type
5868 (method_prototype, METHOD_REF, super_flag)));
5871 lookup_object = build_c_cast (rcv_p, lookup_object);
5873 if (flag_next_runtime)
5875 /* If we are returning a struct in memory, and the address
5876 of that memory location is passed as a hidden first
5877 argument, then change which messenger entry point this
5878 expr will call. NB: Note that sender_cast remains
5879 unchanged (it already has a struct return type). */
5880 if (!targetm.calls.struct_value_rtx (0, 0)
5881 && (TREE_CODE (ret_type) == RECORD_TYPE
5882 || TREE_CODE (ret_type) == UNION_TYPE)
5883 && targetm.calls.return_in_memory (ret_type, 0))
5884 sender = (super_flag ? umsg_super_stret_decl :
5885 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5887 method_params = tree_cons (NULL_TREE, lookup_object,
5888 tree_cons (NULL_TREE, selector,
5890 method = build_fold_addr_expr (sender);
5894 /* This is the portable (GNU) way. */
5897 /* First, call the lookup function to get a pointer to the method,
5898 then cast the pointer, then call it with the method arguments.
5899 Use SAVE_EXPR to avoid evaluating the receiver twice. */
5900 lookup_object = save_expr (lookup_object);
5901 object = (super_flag ? self_decl : lookup_object);
5903 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5904 t = tree_cons (NULL_TREE, lookup_object, t);
5905 method = build_function_call (sender, t);
5907 /* Pass the object to the method. */
5908 method_params = tree_cons (NULL_TREE, object,
5909 tree_cons (NULL_TREE, selector,
5913 /* ??? Selector is not at this point something we can use inside
5914 the compiler itself. Set it to garbage for the nonce. */
5915 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5916 return build_function_call (t, method_params);
5920 build_protocol_reference (tree p)
5922 tree decl, ident, ptype;
5924 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5926 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5928 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5929 objc_protocol_template),
5932 if (identifier_global_value (ident))
5933 decl = identifier_global_value (ident); /* Set by pushdecl. */
5936 decl = build_decl (VAR_DECL, ident, ptype);
5937 DECL_EXTERNAL (decl) = 1;
5938 TREE_PUBLIC (decl) = 0;
5939 TREE_USED (decl) = 1;
5940 DECL_ARTIFICIAL (decl) = 1;
5942 make_decl_rtl (decl, 0);
5943 pushdecl_top_level (decl);
5946 PROTOCOL_FORWARD_DECL (p) = decl;
5949 /* This function is called by the parser when (and only when) a
5950 @protocol() expression is found, in order to compile it. */
5952 build_protocol_expr (tree protoname)
5955 tree p = lookup_protocol (protoname);
5959 error ("cannot find protocol declaration for `%s'",
5960 IDENTIFIER_POINTER (protoname));
5961 return error_mark_node;
5964 if (!PROTOCOL_FORWARD_DECL (p))
5965 build_protocol_reference (p);
5967 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5969 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5970 if we have it, rather than converting it here. */
5971 expr = convert (objc_protocol_type, expr);
5973 /* The @protocol() expression is being compiled into a pointer to a
5974 statically allocated instance of the Protocol class. To become
5975 usable at runtime, the 'isa' pointer of the instance need to be
5976 fixed up at runtime by the runtime library, to point to the
5977 actual 'Protocol' class. */
5979 /* For the GNU runtime, put the static Protocol instance in the list
5980 of statically allocated instances, so that we make sure that its
5981 'isa' pointer is fixed up at runtime by the GNU runtime library
5982 to point to the Protocol class (at runtime, when loading the
5983 module, the GNU runtime library loops on the statically allocated
5984 instances (as found in the defs field in objc_symtab) and fixups
5985 all the 'isa' pointers of those objects). */
5986 if (! flag_next_runtime)
5988 /* This type is a struct containing the fields of a Protocol
5989 object. (Cfr. objc_protocol_type instead is the type of a pointer
5990 to such a struct). */
5991 tree protocol_struct_type = xref_tag
5992 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5995 /* Look for the list of Protocol statically allocated instances
5996 to fixup at runtime. Create a new list to hold Protocol
5997 statically allocated instances, if the list is not found. At
5998 present there is only another list, holding NSConstantString
5999 static instances to be fixed up at runtime. */
6000 for (chain = &objc_static_instances;
6001 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6002 chain = &TREE_CHAIN (*chain));
6005 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6006 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6010 /* Add this statically allocated instance to the Protocol list. */
6011 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6012 PROTOCOL_FORWARD_DECL (p),
6013 TREE_PURPOSE (*chain));
6020 /* This function is called by the parser when a @selector() expression
6021 is found, in order to compile it. It is only called by the parser
6022 and only to compile a @selector(). */
6024 build_selector_expr (tree selnamelist)
6028 /* Obtain the full selector name. */
6029 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6030 /* A unary selector. */
6031 selname = selnamelist;
6032 else if (TREE_CODE (selnamelist) == TREE_LIST)
6033 selname = build_keyword_selector (selnamelist);
6037 /* If we are required to check @selector() expressions as they
6038 are found, check that the selector has been declared. */
6039 if (warn_undeclared_selector)
6041 /* Look the selector up in the list of all known class and
6042 instance methods (up to this line) to check that the selector
6046 /* First try with instance methods. */
6047 hsh = hash_lookup (nst_method_hash_list, selname);
6049 /* If not found, try with class methods. */
6052 hsh = hash_lookup (cls_method_hash_list, selname);
6055 /* If still not found, print out a warning. */
6058 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6063 if (flag_typed_selectors)
6064 return build_typed_selector_reference (selname, 0);
6066 return build_selector_reference (selname);
6070 build_encode_expr (tree type)
6075 encode_type (type, obstack_object_size (&util_obstack),
6076 OBJC_ENCODE_INLINE_DEFS);
6077 obstack_1grow (&util_obstack, 0); /* null terminate string */
6078 string = obstack_finish (&util_obstack);
6080 /* Synthesize a string that represents the encoded struct/union. */
6081 result = my_build_string (strlen (string) + 1, string);
6082 obstack_free (&util_obstack, util_firstobj);
6087 build_ivar_reference (tree id)
6089 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6091 /* Historically, a class method that produced objects (factory
6092 method) would assign `self' to the instance that it
6093 allocated. This would effectively turn the class method into
6094 an instance method. Following this assignment, the instance
6095 variables could be accessed. That practice, while safe,
6096 violates the simple rule that a class method should not refer
6097 to an instance variable. It's better to catch the cases
6098 where this is done unknowingly than to support the above
6100 warning ("instance variable `%s' accessed in class method",
6101 IDENTIFIER_POINTER (id));
6102 TREE_TYPE (self_decl) = objc_instance_type; /* cast */
6105 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6108 /* Compute a hash value for a given method SEL_NAME. */
6111 hash_func (tree sel_name)
6113 const unsigned char *s
6114 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6118 h = h * 67 + *s++ - 113;
6125 nst_method_hash_list
6126 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6127 cls_method_hash_list
6128 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6131 /* WARNING!!!! hash_enter is called with a method, and will peek
6132 inside to find its selector! But hash_lookup is given a selector
6133 directly, and looks for the selector that's inside the found
6134 entry's key (method) for comparison. */
6137 hash_enter (hash *hashlist, tree method)
6140 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6142 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6144 obj->next = hashlist[slot];
6147 hashlist[slot] = obj; /* append to front */
6151 hash_lookup (hash *hashlist, tree sel_name)
6155 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6159 if (sel_name == METHOD_SEL_NAME (target->key))
6162 target = target->next;
6168 hash_add_attr (hash entry, tree value)
6172 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6173 obj->next = entry->list;
6176 entry->list = obj; /* append to front */
6180 lookup_method (tree mchain, tree method)
6184 if (TREE_CODE (method) == IDENTIFIER_NODE)
6187 key = METHOD_SEL_NAME (method);
6191 if (METHOD_SEL_NAME (mchain) == key)
6194 mchain = TREE_CHAIN (mchain);
6200 lookup_method_static (tree interface, tree ident, int is_class)
6202 tree meth = NULL_TREE, root_inter = NULL_TREE;
6203 tree inter = interface;
6207 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6208 tree category = inter;
6210 /* First, look up the method in the class itself. */
6211 if ((meth = lookup_method (chain, ident)))
6214 /* Failing that, look for the method in each category of the class. */
6215 while ((category = CLASS_CATEGORY_LIST (category)))
6217 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6219 /* Check directly in each category. */
6220 if ((meth = lookup_method (chain, ident)))
6223 /* Failing that, check in each category's protocols. */
6224 if (CLASS_PROTOCOL_LIST (category))
6226 if ((meth = (lookup_method_in_protocol_list
6227 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6232 /* If not found in categories, check in protocols of the main class. */
6233 if (CLASS_PROTOCOL_LIST (inter))
6235 if ((meth = (lookup_method_in_protocol_list
6236 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6240 /* Failing that, climb up the inheritance hierarchy. */
6242 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6246 /* If no class (factory) method was found, check if an _instance_
6247 method of the same name exists in the root class. This is what
6248 the Objective-C runtime will do. If an instance method was not
6250 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6253 /* Add the method to the hash list if it doesn't contain an identical
6256 add_method_to_hash_list (hash *hash_list, tree method)
6260 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6262 /* Install on a global chain. */
6263 hash_enter (hash_list, method);
6267 /* Check types against those; if different, add to a list. */
6269 int already_there = comp_proto_with_proto (method, hsh->key);
6270 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6271 already_there |= comp_proto_with_proto (method, loop->value);
6273 hash_add_attr (hsh, method);
6278 objc_add_method (tree class, tree method, int is_class)
6282 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6284 /* put method on list in reverse order */
6287 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6288 CLASS_CLS_METHODS (class) = method;
6292 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6293 CLASS_NST_METHODS (class) = method;
6298 /* When processing an @interface for a class or category, give hard
6299 errors on methods with identical selectors but differing argument
6300 and/or return types. We do not do this for @implementations, because
6301 C/C++ will do it for us (i.e., there will be duplicate function
6302 definition errors). */
6303 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6304 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6305 && !comp_proto_with_proto (method, mth))
6306 error ("duplicate declaration of method `%c%s'",
6307 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6311 add_method_to_hash_list (cls_method_hash_list, method);
6314 add_method_to_hash_list (nst_method_hash_list, method);
6316 /* Instance methods in root classes (and categories thereof)
6317 may acts as class methods as a last resort. */
6318 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6319 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6320 class = lookup_interface (CLASS_NAME (class));
6322 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6323 && !CLASS_SUPER_NAME (class))
6324 add_method_to_hash_list (cls_method_hash_list, method);
6331 add_class (tree class)
6333 /* Put interfaces on list in reverse order. */
6334 TREE_CHAIN (class) = interface_chain;
6335 interface_chain = class;
6336 return interface_chain;
6340 add_category (tree class, tree category)
6342 /* Put categories on list in reverse order. */
6343 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6347 warning ("duplicate interface declaration for category `%s(%s)'",
6348 IDENTIFIER_POINTER (CLASS_NAME (class)),
6349 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6353 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6354 CLASS_CATEGORY_LIST (class) = category;
6358 /* Called after parsing each instance variable declaration. Necessary to
6359 preserve typedefs and implement public/private...
6361 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6364 add_instance_variable (tree class, int public, tree declarator,
6365 tree declspecs, tree width)
6367 tree field_decl = grokfield (declarator, declspecs, width);
6368 tree field_type = TREE_TYPE (field_decl);
6369 const char *ivar_name = DECL_NAME (field_decl)
6370 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6375 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6377 error ("illegal reference type specified for instance variable `%s'",
6379 /* Return class as is without adding this ivar. */
6384 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6385 || TYPE_SIZE (field_type) == error_mark_node
6386 /* 'type[0]' is allowed, but 'type[]' is not! */
6388 || (TYPE_SIZE (field_type) == bitsize_zero_node
6389 && !TREE_OPERAND (declarator, 1))
6393 error ("instance variable `%s' has unknown size", ivar_name);
6394 /* Return class as is without adding this ivar. */
6399 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6400 cannot be ivars; ditto for classes with vtables. */
6401 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6402 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6404 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6405 if(TYPE_POLYMORPHIC_P (field_type)) {
6406 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6407 error ("type `%s' has virtual member functions", type_name);
6408 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6409 type_name, ivar_name);
6410 /* Return class as is without adding this ivar. */
6413 /* user-defined constructors and destructors are not known to Obj-C and
6414 hence will not be called. This may or may not be a problem. */
6415 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6416 warning ("type `%s' has a user-defined constructor", type_name);
6417 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6418 warning ("type `%s' has a user-defined destructor", type_name);
6419 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6423 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6427 TREE_PUBLIC (field_decl) = 0;
6428 TREE_PRIVATE (field_decl) = 0;
6429 TREE_PROTECTED (field_decl) = 1;
6433 TREE_PUBLIC (field_decl) = 1;
6434 TREE_PRIVATE (field_decl) = 0;
6435 TREE_PROTECTED (field_decl) = 0;
6439 TREE_PUBLIC (field_decl) = 0;
6440 TREE_PRIVATE (field_decl) = 1;
6441 TREE_PROTECTED (field_decl) = 0;
6446 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6447 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6448 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6453 is_ivar (tree decl_chain, tree ident)
6455 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6456 if (DECL_NAME (decl_chain) == ident)
6461 /* True if the ivar is private and we are not in its implementation. */
6464 is_private (tree decl)
6466 return (TREE_PRIVATE (decl)
6467 && ! is_ivar (CLASS_IVARS (implementation_template),
6471 /* We have an instance variable reference;, check to see if it is public. */
6474 objc_is_public (tree expr, tree identifier)
6476 tree basetype = TREE_TYPE (expr);
6477 enum tree_code code = TREE_CODE (basetype);
6480 if (code == RECORD_TYPE)
6482 if (TREE_STATIC_TEMPLATE (basetype))
6484 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6486 error ("cannot find interface declaration for `%s'",
6487 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6491 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6493 if (TREE_PUBLIC (decl))
6496 /* Important difference between the Stepstone translator:
6497 all instance variables should be public within the context
6498 of the implementation. */
6499 if (objc_implementation_context
6500 && (((TREE_CODE (objc_implementation_context)
6501 == CLASS_IMPLEMENTATION_TYPE)
6502 || (TREE_CODE (objc_implementation_context)
6503 == CATEGORY_IMPLEMENTATION_TYPE))
6504 && (CLASS_NAME (objc_implementation_context)
6505 == OBJC_TYPE_NAME (basetype))))
6507 int private = is_private (decl);
6510 error ("instance variable `%s' is declared private",
6511 IDENTIFIER_POINTER (DECL_NAME (decl)));
6515 /* The 2.95.2 compiler sometimes allowed C functions to access
6516 non-@public ivars. We will let this slide for now... */
6517 if (!objc_method_context)
6519 warning ("instance variable `%s' is %s; "
6520 "this will be a hard error in the future",
6521 IDENTIFIER_POINTER (identifier),
6522 TREE_PRIVATE (decl) ? "@private" : "@protected");
6526 error ("instance variable `%s' is declared %s",
6527 IDENTIFIER_POINTER (identifier),
6528 TREE_PRIVATE (decl) ? "private" : "protected");
6533 else if (objc_implementation_context && (basetype == objc_object_reference))
6535 TREE_TYPE (expr) = uprivate_record;
6536 warning ("static access to object of type `id'");
6543 /* Make sure all entries in CHAIN are also in LIST. */
6546 check_methods (tree chain, tree list, int mtype)
6552 if (!lookup_method (list, chain))
6556 if (TREE_CODE (objc_implementation_context)
6557 == CLASS_IMPLEMENTATION_TYPE)
6558 warning ("incomplete implementation of class `%s'",
6559 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6560 else if (TREE_CODE (objc_implementation_context)
6561 == CATEGORY_IMPLEMENTATION_TYPE)
6562 warning ("incomplete implementation of category `%s'",
6563 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6567 warning ("method definition for `%c%s' not found",
6568 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6571 chain = TREE_CHAIN (chain);
6577 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6580 conforms_to_protocol (tree class, tree protocol)
6582 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6584 tree p = CLASS_PROTOCOL_LIST (class);
6585 while (p && TREE_VALUE (p) != protocol)
6590 tree super = (CLASS_SUPER_NAME (class)
6591 ? lookup_interface (CLASS_SUPER_NAME (class))
6593 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6602 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6603 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6606 check_methods_accessible (tree chain, tree context, int mtype)
6610 tree base_context = context;
6614 context = base_context;
6618 list = CLASS_CLS_METHODS (context);
6620 list = CLASS_NST_METHODS (context);
6622 if (lookup_method (list, chain))
6625 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6626 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6627 context = (CLASS_SUPER_NAME (context)
6628 ? lookup_interface (CLASS_SUPER_NAME (context))
6631 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6632 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6633 context = (CLASS_NAME (context)
6634 ? lookup_interface (CLASS_NAME (context))
6640 if (context == NULL_TREE)
6644 if (TREE_CODE (objc_implementation_context)
6645 == CLASS_IMPLEMENTATION_TYPE)
6646 warning ("incomplete implementation of class `%s'",
6648 (CLASS_NAME (objc_implementation_context)));
6649 else if (TREE_CODE (objc_implementation_context)
6650 == CATEGORY_IMPLEMENTATION_TYPE)
6651 warning ("incomplete implementation of category `%s'",
6653 (CLASS_SUPER_NAME (objc_implementation_context)));
6656 warning ("method definition for `%c%s' not found",
6657 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6660 chain = TREE_CHAIN (chain); /* next method... */
6665 /* Check whether the current interface (accessible via
6666 'objc_implementation_context') actually implements protocol P, along
6667 with any protocols that P inherits. */
6670 check_protocol (tree p, const char *type, const char *name)
6672 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6676 /* Ensure that all protocols have bodies! */
6679 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6680 CLASS_CLS_METHODS (objc_implementation_context),
6682 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6683 CLASS_NST_METHODS (objc_implementation_context),
6688 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6689 objc_implementation_context,
6691 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6692 objc_implementation_context,
6697 warning ("%s `%s' does not fully implement the `%s' protocol",
6698 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6701 /* Check protocols recursively. */
6702 if (PROTOCOL_LIST (p))
6704 tree subs = PROTOCOL_LIST (p);
6706 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6710 tree sub = TREE_VALUE (subs);
6712 /* If the superclass does not conform to the protocols
6713 inherited by P, then we must! */
6714 if (!super_class || !conforms_to_protocol (super_class, sub))
6715 check_protocol (sub, type, name);
6716 subs = TREE_CHAIN (subs);
6721 /* Check whether the current interface (accessible via
6722 'objc_implementation_context') actually implements the protocols listed
6726 check_protocols (tree proto_list, const char *type, const char *name)
6728 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6730 tree p = TREE_VALUE (proto_list);
6732 check_protocol (p, type, name);
6736 /* Make sure that the class CLASS_NAME is defined
6737 CODE says which kind of thing CLASS_NAME ought to be.
6738 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6739 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6742 start_class (enum tree_code code, tree class_name, tree super_name,
6748 if (current_namespace != global_namespace) {
6749 error ("Objective-C declarations may only appear in global scope");
6751 #endif /* OBJCPLUS */
6753 if (objc_implementation_context)
6755 warning ("`@end' missing in implementation context");
6756 finish_class (objc_implementation_context);
6757 objc_ivar_chain = NULL_TREE;
6758 objc_implementation_context = NULL_TREE;
6761 class = make_node (code);
6762 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6764 CLASS_NAME (class) = class_name;
6765 CLASS_SUPER_NAME (class) = super_name;
6766 CLASS_CLS_METHODS (class) = NULL_TREE;
6768 if (! is_class_name (class_name)
6769 && (decl = lookup_name (class_name)))
6771 error ("`%s' redeclared as different kind of symbol",
6772 IDENTIFIER_POINTER (class_name));
6773 error ("%Jprevious declaration of '%D'",
6777 if (code == CLASS_IMPLEMENTATION_TYPE)
6782 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6783 if (TREE_VALUE (chain) == class_name)
6785 error ("reimplementation of class `%s'",
6786 IDENTIFIER_POINTER (class_name));
6787 return error_mark_node;
6789 implemented_classes = tree_cons (NULL_TREE, class_name,
6790 implemented_classes);
6793 /* Reset for multiple classes per file. */
6796 objc_implementation_context = class;
6798 /* Lookup the interface for this implementation. */
6800 if (!(implementation_template = lookup_interface (class_name)))
6802 warning ("cannot find interface declaration for `%s'",
6803 IDENTIFIER_POINTER (class_name));
6804 add_class (implementation_template = objc_implementation_context);
6807 /* If a super class has been specified in the implementation,
6808 insure it conforms to the one specified in the interface. */
6811 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6813 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6814 const char *const name =
6815 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6816 error ("conflicting super class name `%s'",
6817 IDENTIFIER_POINTER (super_name));
6818 error ("previous declaration of `%s'", name);
6821 else if (! super_name)
6823 CLASS_SUPER_NAME (objc_implementation_context)
6824 = CLASS_SUPER_NAME (implementation_template);
6828 else if (code == CLASS_INTERFACE_TYPE)
6830 if (lookup_interface (class_name))
6832 error ("duplicate interface declaration for class `%s'",
6834 warning ("duplicate interface declaration for class `%s'",
6836 IDENTIFIER_POINTER (class_name));
6841 CLASS_PROTOCOL_LIST (class)
6842 = lookup_and_install_protocols (protocol_list);
6845 else if (code == CATEGORY_INTERFACE_TYPE)
6847 tree class_category_is_assoc_with;
6849 /* For a category, class_name is really the name of the class that
6850 the following set of methods will be associated with. We must
6851 find the interface so that can derive the objects template. */
6853 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6855 error ("cannot find interface declaration for `%s'",
6856 IDENTIFIER_POINTER (class_name));
6857 exit (FATAL_EXIT_CODE);
6860 add_category (class_category_is_assoc_with, class);
6863 CLASS_PROTOCOL_LIST (class)
6864 = lookup_and_install_protocols (protocol_list);
6867 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6869 /* Reset for multiple classes per file. */
6872 objc_implementation_context = class;
6874 /* For a category, class_name is really the name of the class that
6875 the following set of methods will be associated with. We must
6876 find the interface so that can derive the objects template. */
6878 if (!(implementation_template = lookup_interface (class_name)))
6880 error ("cannot find interface declaration for `%s'",
6881 IDENTIFIER_POINTER (class_name));
6882 exit (FATAL_EXIT_CODE);
6889 continue_class (tree class)
6891 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6892 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6894 struct imp_entry *imp_entry;
6897 /* Check consistency of the instance variables. */
6899 if (CLASS_IVARS (class))
6900 check_ivars (implementation_template, class);
6902 /* code generation */
6904 ivar_context = build_private_template (implementation_template);
6906 if (!objc_class_template)
6907 build_class_template ();
6909 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6911 imp_entry->next = imp_list;
6912 imp_entry->imp_context = class;
6913 imp_entry->imp_template = implementation_template;
6915 synth_forward_declarations ();
6916 imp_entry->class_decl = UOBJC_CLASS_decl;
6917 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6919 /* Append to front and increment count. */
6920 imp_list = imp_entry;
6921 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6926 return ivar_context;
6929 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6931 if (!CLASS_STATIC_TEMPLATE (class))
6933 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6934 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6935 CLASS_STATIC_TEMPLATE (class) = record;
6937 /* Mark this record as a class template for static typing. */
6938 TREE_STATIC_TEMPLATE (record) = 1;
6945 return error_mark_node;
6948 /* This is called once we see the "@end" in an interface/implementation. */
6951 finish_class (tree class)
6953 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6955 /* All code generation is done in finish_objc. */
6957 if (implementation_template != objc_implementation_context)
6959 /* Ensure that all method listed in the interface contain bodies. */
6960 check_methods (CLASS_CLS_METHODS (implementation_template),
6961 CLASS_CLS_METHODS (objc_implementation_context), '+');
6962 check_methods (CLASS_NST_METHODS (implementation_template),
6963 CLASS_NST_METHODS (objc_implementation_context), '-');
6965 if (CLASS_PROTOCOL_LIST (implementation_template))
6966 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6968 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6972 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6974 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6978 /* Ensure all method listed in the interface contain bodies. */
6979 check_methods (CLASS_CLS_METHODS (category),
6980 CLASS_CLS_METHODS (objc_implementation_context), '+');
6981 check_methods (CLASS_NST_METHODS (category),
6982 CLASS_NST_METHODS (objc_implementation_context), '-');
6984 if (CLASS_PROTOCOL_LIST (category))
6985 check_protocols (CLASS_PROTOCOL_LIST (category),
6987 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6991 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6994 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6995 char *string = (char *) alloca (strlen (class_name) + 3);
6997 /* extern struct objc_object *_<my_name>; */
6999 sprintf (string, "_%s", class_name);
7001 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
7002 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
7003 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7009 add_protocol (tree protocol)
7011 /* Put protocol on list in reverse order. */
7012 TREE_CHAIN (protocol) = protocol_chain;
7013 protocol_chain = protocol;
7014 return protocol_chain;
7018 lookup_protocol (tree ident)
7022 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7023 if (ident == PROTOCOL_NAME (chain))
7029 /* This function forward declares the protocols named by NAMES. If
7030 they are already declared or defined, the function has no effect. */
7033 objc_declare_protocols (tree names)
7038 if (current_namespace != global_namespace) {
7039 error ("Objective-C declarations may only appear in global scope");
7041 #endif /* OBJCPLUS */
7043 for (list = names; list; list = TREE_CHAIN (list))
7045 tree name = TREE_VALUE (list);
7047 if (lookup_protocol (name) == NULL_TREE)
7049 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7051 TYPE_BINFO (protocol) = make_tree_vec (2);
7052 PROTOCOL_NAME (protocol) = name;
7053 PROTOCOL_LIST (protocol) = NULL_TREE;
7054 add_protocol (protocol);
7055 PROTOCOL_DEFINED (protocol) = 0;
7056 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7062 start_protocol (enum tree_code code, tree name, tree list)
7067 if (current_namespace != global_namespace) {
7068 error ("Objective-C declarations may only appear in global scope");
7070 #endif /* OBJCPLUS */
7072 /* This is as good a place as any. Need to invoke
7073 push_tag_toplevel. */
7074 if (!objc_protocol_template)
7075 objc_protocol_template = build_protocol_template ();
7077 protocol = lookup_protocol (name);
7081 protocol = make_node (code);
7082 TYPE_BINFO (protocol) = make_tree_vec (2);
7084 PROTOCOL_NAME (protocol) = name;
7085 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7086 add_protocol (protocol);
7087 PROTOCOL_DEFINED (protocol) = 1;
7088 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7090 check_protocol_recursively (protocol, list);
7092 else if (! PROTOCOL_DEFINED (protocol))
7094 PROTOCOL_DEFINED (protocol) = 1;
7095 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7097 check_protocol_recursively (protocol, list);
7101 warning ("duplicate declaration for protocol `%s'",
7102 IDENTIFIER_POINTER (name));
7108 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7113 /* "Encode" a data type into a string, which grows in util_obstack.
7114 ??? What is the FORMAT? Someone please document this! */
7117 encode_type_qualifiers (tree declspecs)
7121 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7123 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7124 obstack_1grow (&util_obstack, 'r');
7125 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7126 obstack_1grow (&util_obstack, 'n');
7127 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7128 obstack_1grow (&util_obstack, 'N');
7129 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7130 obstack_1grow (&util_obstack, 'o');
7131 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7132 obstack_1grow (&util_obstack, 'O');
7133 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7134 obstack_1grow (&util_obstack, 'R');
7135 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7136 obstack_1grow (&util_obstack, 'V');
7140 /* Encode a pointer type. */
7143 encode_pointer (tree type, int curtype, int format)
7145 tree pointer_to = TREE_TYPE (type);
7147 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7149 if (OBJC_TYPE_NAME (pointer_to)
7150 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7152 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7154 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7156 obstack_1grow (&util_obstack, '@');
7159 else if (TREE_STATIC_TEMPLATE (pointer_to))
7161 if (generating_instance_variables)
7163 obstack_1grow (&util_obstack, '@');
7164 obstack_1grow (&util_obstack, '"');
7165 obstack_grow (&util_obstack, name, strlen (name));
7166 obstack_1grow (&util_obstack, '"');
7171 obstack_1grow (&util_obstack, '@');
7175 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7177 obstack_1grow (&util_obstack, '#');
7180 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7182 obstack_1grow (&util_obstack, ':');
7187 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7188 && TYPE_MODE (pointer_to) == QImode)
7190 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7191 ? OBJC_TYPE_NAME (pointer_to)
7192 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7194 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7196 obstack_1grow (&util_obstack, '*');
7201 /* We have a type that does not get special treatment. */
7203 /* NeXT extension */
7204 obstack_1grow (&util_obstack, '^');
7205 encode_type (pointer_to, curtype, format);
7209 encode_array (tree type, int curtype, int format)
7211 tree an_int_cst = TYPE_SIZE (type);
7212 tree array_of = TREE_TYPE (type);
7215 /* An incomplete array is treated like a pointer. */
7216 if (an_int_cst == NULL)
7218 encode_pointer (type, curtype, format);
7222 sprintf (buffer, "[%ld",
7223 (long) (TREE_INT_CST_LOW (an_int_cst)
7224 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7226 obstack_grow (&util_obstack, buffer, strlen (buffer));
7227 encode_type (array_of, curtype, format);
7228 obstack_1grow (&util_obstack, ']');
7233 encode_aggregate_within (tree type, int curtype, int format, int left,
7237 /* NB: aggregates that are pointed to have slightly different encoding
7238 rules in that you never encode the names of instance variables. */
7240 = (obstack_object_size (&util_obstack) > 0
7241 && *(obstack_next_free (&util_obstack) - 1) == '^');
7243 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7244 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7246 /* Traverse struct aliases; it is important to get the
7247 original struct and its tag name (if any). */
7248 type = TYPE_MAIN_VARIANT (type);
7249 name = OBJC_TYPE_NAME (type);
7250 /* Open parenth/bracket. */
7251 obstack_1grow (&util_obstack, left);
7253 /* Encode the struct/union tag name, or '?' if a tag was
7254 not provided. Typedef aliases do not qualify. */
7255 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7257 /* Did this struct have a tag? */
7258 && !TYPE_WAS_ANONYMOUS (type)
7261 obstack_grow (&util_obstack,
7262 IDENTIFIER_POINTER (name),
7263 strlen (IDENTIFIER_POINTER (name)));
7265 obstack_1grow (&util_obstack, '?');
7267 /* Encode the types (and possibly names) of the inner fields,
7269 if (inline_contents)
7271 tree fields = TYPE_FIELDS (type);
7273 obstack_1grow (&util_obstack, '=');
7274 for (; fields; fields = TREE_CHAIN (fields))
7277 /* C++ static members, and things that are not fields at all,
7278 should not appear in the encoding. */
7279 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7282 if (generating_instance_variables && !pointed_to)
7284 tree fname = DECL_NAME (fields);
7286 obstack_1grow (&util_obstack, '"');
7287 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7288 obstack_grow (&util_obstack,
7289 IDENTIFIER_POINTER (fname),
7290 strlen (IDENTIFIER_POINTER (fname)));
7291 obstack_1grow (&util_obstack, '"');
7293 encode_field_decl (fields, curtype, format);
7296 /* Close parenth/bracket. */
7297 obstack_1grow (&util_obstack, right);
7301 encode_aggregate (tree type, int curtype, int format)
7303 enum tree_code code = TREE_CODE (type);
7309 encode_aggregate_within (type, curtype, format, '{', '}');
7314 encode_aggregate_within (type, curtype, format, '(', ')');
7319 obstack_1grow (&util_obstack, 'i');
7327 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7331 encode_next_bitfield (int width)
7334 sprintf (buffer, "b%d", width);
7335 obstack_grow (&util_obstack, buffer, strlen (buffer));
7338 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7340 encode_type (tree type, int curtype, int format)
7342 enum tree_code code = TREE_CODE (type);
7345 if (code == INTEGER_TYPE)
7347 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7349 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7350 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7352 if (type == long_unsigned_type_node
7353 || type == long_integer_type_node)
7354 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7356 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7358 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7361 obstack_1grow (&util_obstack, c);
7364 else if (code == REAL_TYPE)
7366 /* Floating point types. */
7367 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7369 case 32: c = 'f'; break;
7371 case 128: c = 'd'; break;
7374 obstack_1grow (&util_obstack, c);
7377 else if (code == VOID_TYPE)
7378 obstack_1grow (&util_obstack, 'v');
7380 else if (code == BOOLEAN_TYPE)
7381 obstack_1grow (&util_obstack, 'B');
7383 else if (code == ARRAY_TYPE)
7384 encode_array (type, curtype, format);
7386 else if (code == POINTER_TYPE)
7387 encode_pointer (type, curtype, format);
7389 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7390 encode_aggregate (type, curtype, format);
7392 else if (code == FUNCTION_TYPE) /* '?' */
7393 obstack_1grow (&util_obstack, '?');
7397 encode_gnu_bitfield (int position, tree type, int size)
7399 enum tree_code code = TREE_CODE (type);
7401 char charType = '?';
7403 if (code == INTEGER_TYPE)
7405 if (integer_zerop (TYPE_MIN_VALUE (type)))
7407 /* Unsigned integer types. */
7409 if (TYPE_MODE (type) == QImode)
7411 else if (TYPE_MODE (type) == HImode)
7413 else if (TYPE_MODE (type) == SImode)
7415 if (type == long_unsigned_type_node)
7420 else if (TYPE_MODE (type) == DImode)
7425 /* Signed integer types. */
7427 if (TYPE_MODE (type) == QImode)
7429 else if (TYPE_MODE (type) == HImode)
7431 else if (TYPE_MODE (type) == SImode)
7433 if (type == long_integer_type_node)
7439 else if (TYPE_MODE (type) == DImode)
7443 else if (code == ENUMERAL_TYPE)
7448 sprintf (buffer, "b%d%c%d", position, charType, size);
7449 obstack_grow (&util_obstack, buffer, strlen (buffer));
7453 encode_field_decl (tree field_decl, int curtype, int format)
7458 /* C++ static members, and things that are not fields at all,
7459 should not appear in the encoding. */
7460 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7464 type = TREE_TYPE (field_decl);
7466 /* Generate the bitfield typing information, if needed. Note the difference
7467 between GNU and NeXT runtimes. */
7468 if (DECL_BIT_FIELD_TYPE (field_decl))
7470 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7472 if (flag_next_runtime)
7473 encode_next_bitfield (size);
7475 encode_gnu_bitfield (int_bit_position (field_decl),
7476 DECL_BIT_FIELD_TYPE (field_decl), size);
7479 encode_type (TREE_TYPE (field_decl), curtype, format);
7483 objc_expr_last (tree complex_expr)
7488 while ((next = TREE_OPERAND (complex_expr, 0)))
7489 complex_expr = next;
7491 return complex_expr;
7495 synth_self_and_ucmd_args (void)
7499 if (objc_method_context
7500 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7501 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7503 /* Really a `struct objc_class *'. However, we allow people to
7504 assign to self, which changes its type midstream. */
7505 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7507 push_parm_decl (build_tree_list
7508 (build_tree_list (decl_specs,
7509 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7512 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (objc_selector_type));
7513 push_parm_decl (build_tree_list
7514 (build_tree_list (decl_specs,
7515 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7519 /* Transform a method definition into a function definition as follows:
7520 - synthesize the first two arguments, "self" and "_cmd". */
7523 start_method_def (tree method)
7525 /* Required to implement _msgSuper. */
7526 objc_method_context = method;
7527 UOBJC_SUPER_decl = NULL_TREE;
7529 /* Must be called BEFORE start_function. */
7531 declare_parm_level ();
7533 /* Generate prototype declarations for arguments..."new-style". */
7534 synth_self_and_ucmd_args ();
7536 /* Generate argument declarations if a keyword_decl. */
7537 if (METHOD_SEL_ARGS (method))
7539 tree arglist = METHOD_SEL_ARGS (method);
7542 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7543 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7547 tree last_expr = objc_expr_last (arg_decl);
7549 /* Unite the abstract decl with its name. */
7550 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7551 push_parm_decl (build_tree_list
7552 (build_tree_list (arg_spec, arg_decl),
7556 /* Unhook: restore the abstract declarator. */
7557 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7562 push_parm_decl (build_tree_list
7563 (build_tree_list (arg_spec,
7564 KEYWORD_ARG_NAME (arglist)),
7567 arglist = TREE_CHAIN (arglist);
7572 if (METHOD_ADD_ARGS (method) != NULL_TREE
7573 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7575 /* We have a variable length selector - in "prototype" format. */
7576 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7579 /* This must be done prior to calling pushdecl. pushdecl is
7580 going to change our chain on us. */
7581 tree nextkey = TREE_CHAIN (akey);
7589 warn_with_method (const char *message, int mtype, tree method)
7591 /* Add a readable method name to the warning. */
7592 warning ("%J%s `%c%s'", method,
7593 message, mtype, gen_method_decl (method, errbuf));
7596 /* Return 1 if METHOD is consistent with PROTO. */
7599 comp_method_with_proto (tree method, tree proto)
7601 /* Create a function template node at most once. */
7602 if (!function1_template)
7603 function1_template = make_node (FUNCTION_TYPE);
7605 /* Install argument types - normally set by build_function_type. */
7606 TYPE_ARG_TYPES (function1_template)
7607 = get_arg_type_list (proto, METHOD_DEF, 0);
7609 /* install return type */
7610 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7612 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7615 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7618 objc_types_are_equivalent (tree type1, tree type2)
7622 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7624 type1 = TYPE_PROTOCOL_LIST (type1);
7625 type2 = TYPE_PROTOCOL_LIST (type2);
7626 if (list_length (type1) == list_length (type2))
7628 for (; type2; type2 = TREE_CHAIN (type2))
7629 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7636 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7639 comp_proto_with_proto (tree proto1, tree proto2)
7643 /* The following test is needed in case there are hashing
7645 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7648 /* Compare return types. */
7649 type1 = groktypename (TREE_TYPE (proto1));
7650 type2 = groktypename (TREE_TYPE (proto2));
7652 if (!objc_types_are_equivalent (type1, type2))
7655 /* Compare argument types. */
7656 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7657 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7659 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7661 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7665 return (!type1 && !type2);
7668 /* - Generate an identifier for the function. the format is "_n_cls",
7669 where 1 <= n <= nMethods, and cls is the name the implementation we
7671 - Install the return type from the method declaration.
7672 - If we have a prototype, check for type consistency. */
7675 really_start_method (tree method, tree parmlist)
7677 tree sc_spec, ret_spec, ret_decl, decl_specs;
7678 tree method_decl, method_id;
7679 const char *sel_name, *class_name, *cat_name;
7682 /* Synth the storage class & assemble the return type. */
7683 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7684 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7685 decl_specs = chainon (sc_spec, ret_spec);
7687 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7688 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7689 cat_name = ((TREE_CODE (objc_implementation_context)
7690 == CLASS_IMPLEMENTATION_TYPE)
7692 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7695 /* Make sure this is big enough for any plausible method label. */
7696 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7697 + (cat_name ? strlen (cat_name) : 0));
7699 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7700 class_name, cat_name, sel_name, method_slot);
7702 method_id = get_identifier (buf);
7705 /* Objective-C methods cannot be overloaded, so we don't need
7706 the type encoding appended. It looks bad anyway... */
7707 push_lang_context (lang_name_c);
7710 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7712 /* Check the declarator portion of the return type for the method. */
7713 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7715 /* Unite the complex decl (specified in the abstract decl) with the
7716 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7717 tree save_expr = objc_expr_last (ret_decl);
7719 TREE_OPERAND (save_expr, 0) = method_decl;
7720 method_decl = ret_decl;
7722 /* Fool the parser into thinking it is starting a function. */
7723 start_function (decl_specs, method_decl, NULL_TREE);
7725 /* Unhook: this has the effect of restoring the abstract declarator. */
7726 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7731 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7733 /* Fool the parser into thinking it is starting a function. */
7734 start_function (decl_specs, method_decl, NULL_TREE);
7736 /* Unhook: this has the effect of restoring the abstract declarator. */
7737 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7741 /* set self_decl from the first argument...this global is used by
7742 * build_ivar_reference().build_indirect_ref().
7744 self_decl = DECL_ARGUMENTS (current_function_decl);
7746 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7747 * the following: warning:unused parameter `struct objc_selector * _cmd'
7749 TREE_USED (self_decl) = 1;
7750 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7751 /* Ditto for the underlying (static) C function. */
7752 TREE_USED (current_function_decl) = 1;
7753 pop_lang_context ();
7756 METHOD_DEFINITION (method) = current_function_decl;
7758 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7760 if (implementation_template != objc_implementation_context)
7763 = lookup_method_static (implementation_template,
7764 METHOD_SEL_NAME (method),
7765 TREE_CODE (method) == CLASS_METHOD_DECL);
7769 if (!comp_method_with_proto (method, proto))
7771 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7773 warn_with_method ("conflicting types for", type, method);
7774 warn_with_method ("previous declaration of", type, proto);
7779 /* We have a method @implementation even though we did not
7780 see a corresponding @interface declaration (which is allowed
7781 by Objective-C rules). Go ahead and place the method in
7782 the @interface anyway, so that message dispatch lookups
7784 tree interface = implementation_template;
7786 if (TREE_CODE (objc_implementation_context)
7787 == CATEGORY_IMPLEMENTATION_TYPE)
7788 interface = lookup_category
7790 CLASS_SUPER_NAME (objc_implementation_context));
7793 objc_add_method (interface, copy_node (method),
7794 TREE_CODE (method) == CLASS_METHOD_DECL);
7799 /* The following routine is always called...this "architecture" is to
7800 accommodate "old-style" variable length selectors.
7802 - a:a b:b // prototype ; id c; id d; // old-style. */
7805 continue_method_def (void)
7809 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7810 /* We have a `, ...' immediately following the selector. */
7811 parmlist = get_parm_info (/*ellipsis=*/true);
7813 parmlist = get_parm_info (/*ellipsis=*/false);
7816 /* Set self_decl from the first argument...this global is used by
7817 build_ivar_reference calling build_indirect_ref. */
7818 self_decl = TREE_PURPOSE (parmlist);
7819 #endif /* !OBJCPLUS */
7822 really_start_method (objc_method_context, parmlist);
7823 store_parm_decls ();
7826 static void *UOBJC_SUPER_scope = 0;
7828 /* _n_Method (id self, SEL sel, ...)
7830 struct objc_super _S;
7831 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7835 get_super_receiver (void)
7837 if (objc_method_context)
7839 tree super_expr, super_expr_list;
7841 if (!UOBJC_SUPER_decl)
7843 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7844 build_tree_list (NULL_TREE,
7845 objc_super_template),
7848 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7850 /* This prevents `unused variable' warnings when compiling with -Wall. */
7851 TREE_USED (UOBJC_SUPER_decl) = 1;
7852 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7854 UOBJC_SUPER_scope = get_current_scope ();
7857 /* Set receiver to self. */
7858 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7859 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7860 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7862 /* Set class to begin searching. */
7864 super_expr = build_component_ref (UOBJC_SUPER_decl,
7865 get_identifier ("super_class"));
7867 super_expr = build_component_ref (UOBJC_SUPER_decl,
7868 get_identifier ("class"));
7871 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7873 /* [_cls, __cls]Super are "pre-built" in
7874 synth_forward_declarations. */
7876 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7877 ((TREE_CODE (objc_method_context)
7878 == INSTANCE_METHOD_DECL)
7880 : uucls_super_ref));
7884 /* We have a category. */
7886 tree super_name = CLASS_SUPER_NAME (implementation_template);
7889 /* Barf if super used in a category of Object. */
7892 error ("no super class declared in interface for `%s'",
7893 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7894 return error_mark_node;
7897 if (flag_next_runtime && !flag_zero_link)
7899 super_class = get_class_reference (super_name);
7900 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7901 /* If we are in a class method, we must retrieve the
7902 _metaclass_ for the current class, pointed at by
7903 the class's "isa" pointer. The following assumes that
7904 "isa" is the first ivar in a class (which it must be). */
7906 = build_indirect_ref
7907 (build_c_cast (build_pointer_type (objc_class_type),
7908 super_class), "unary *");
7912 add_class_reference (super_name);
7913 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7914 ? objc_get_class_decl : objc_get_meta_class_decl);
7915 assemble_external (super_class);
7917 = build_function_call
7921 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7922 IDENTIFIER_POINTER (super_name))));
7926 = build_modify_expr (super_expr, NOP_EXPR,
7927 build_c_cast (TREE_TYPE (super_expr),
7931 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7933 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7934 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7936 return build_compound_expr (super_expr_list);
7940 error ("[super ...] must appear in a method context");
7941 return error_mark_node;
7945 /* When exiting a scope, sever links to a 'super' declaration (if any)
7946 therein contained. */
7949 objc_clear_super_receiver (void)
7951 if (objc_method_context
7952 && UOBJC_SUPER_scope == get_current_scope ()) {
7953 UOBJC_SUPER_decl = 0;
7954 UOBJC_SUPER_scope = 0;
7959 objc_expand_function_end (void)
7961 /* This routine may also get called for C functions, including those
7962 nested within ObjC methods. In such cases, method encoding is
7964 if (objc_method_context == NULL_TREE
7965 || DECL_INITIAL (objc_method_context) != current_function_decl)
7968 METHOD_ENCODING (objc_method_context)
7969 = encode_method_prototype (objc_method_context);
7973 finish_method_def (void)
7975 lang_expand_function_end = objc_expand_function_end;
7976 /* We cannot validly inline ObjC methods, at least not without a language
7977 extension to declare that a method need not be dynamically
7978 dispatched, so suppress all thoughts of doing so. */
7979 DECL_INLINE (current_function_decl) = 0;
7980 DECL_UNINLINABLE (current_function_decl) = 1;
7983 lang_expand_function_end = NULL;
7985 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7986 since the optimizer may find "may be used before set" errors. */
7987 objc_method_context = NULL_TREE;
7992 lang_report_error_function (tree decl)
7994 if (objc_method_context)
7996 fprintf (stderr, "In method `%s'\n",
7997 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8007 is_complex_decl (tree type)
8009 return (TREE_CODE (type) == ARRAY_TYPE
8010 || TREE_CODE (type) == FUNCTION_TYPE
8011 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8015 /* Code to convert a decl node into text for a declaration in C. */
8017 static char tmpbuf[256];
8020 adorn_decl (tree decl, char *str)
8022 enum tree_code code = TREE_CODE (decl);
8024 if (code == ARRAY_REF)
8026 tree an_int_cst = TREE_OPERAND (decl, 1);
8028 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8029 sprintf (str + strlen (str), "[%ld]",
8030 (long) TREE_INT_CST_LOW (an_int_cst));
8035 else if (code == ARRAY_TYPE)
8037 tree an_int_cst = TYPE_SIZE (decl);
8038 tree array_of = TREE_TYPE (decl);
8040 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8041 sprintf (str + strlen (str), "[%ld]",
8042 (long) (TREE_INT_CST_LOW (an_int_cst)
8043 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8048 else if (code == CALL_EXPR)
8050 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8055 gen_declaration_1 (chain, str);
8056 chain = TREE_CHAIN (chain);
8063 else if (code == FUNCTION_TYPE)
8065 tree chain = TYPE_ARG_TYPES (decl);
8068 while (chain && TREE_VALUE (chain) != void_type_node)
8070 gen_declaration_1 (TREE_VALUE (chain), str);
8071 chain = TREE_CHAIN (chain);
8072 if (chain && TREE_VALUE (chain) != void_type_node)
8078 else if (code == INDIRECT_REF)
8080 strcpy (tmpbuf, "*");
8081 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8085 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8087 chain = TREE_CHAIN (chain))
8089 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8091 strcat (tmpbuf, " ");
8092 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8096 strcat (tmpbuf, " ");
8098 strcat (tmpbuf, str);
8099 strcpy (str, tmpbuf);
8102 else if (code == POINTER_TYPE)
8104 strcpy (tmpbuf, "*");
8105 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8107 if (TYPE_READONLY (decl))
8108 strcat (tmpbuf, " const");
8109 if (TYPE_VOLATILE (decl))
8110 strcat (tmpbuf, " volatile");
8112 strcat (tmpbuf, " ");
8114 strcat (tmpbuf, str);
8115 strcpy (str, tmpbuf);
8120 gen_declarator (tree decl, char *buf, const char *name)
8124 enum tree_code code = TREE_CODE (decl);
8134 op = TREE_OPERAND (decl, 0);
8136 /* We have a pointer to a function or array...(*)(), (*)[] */
8137 if ((code == ARRAY_REF || code == CALL_EXPR)
8138 && op && TREE_CODE (op) == INDIRECT_REF)
8141 str = gen_declarator (op, buf, name);
8145 strcpy (tmpbuf, "(");
8146 strcat (tmpbuf, str);
8147 strcat (tmpbuf, ")");
8148 strcpy (str, tmpbuf);
8151 adorn_decl (decl, str);
8160 /* This clause is done iteratively rather than recursively. */
8163 op = (is_complex_decl (TREE_TYPE (decl))
8164 ? TREE_TYPE (decl) : NULL_TREE);
8166 adorn_decl (decl, str);
8168 /* We have a pointer to a function or array...(*)(), (*)[] */
8169 if (code == POINTER_TYPE
8170 && op && (TREE_CODE (op) == FUNCTION_TYPE
8171 || TREE_CODE (op) == ARRAY_TYPE))
8173 strcpy (tmpbuf, "(");
8174 strcat (tmpbuf, str);
8175 strcat (tmpbuf, ")");
8176 strcpy (str, tmpbuf);
8179 decl = (is_complex_decl (TREE_TYPE (decl))
8180 ? TREE_TYPE (decl) : NULL_TREE);
8183 while (decl && (code = TREE_CODE (decl)))
8188 case IDENTIFIER_NODE:
8189 /* Will only happen if we are processing a "raw" expr-decl. */
8190 strcpy (buf, IDENTIFIER_POINTER (decl));
8201 /* We have an abstract declarator or a _DECL node. */
8209 gen_declspecs (tree declspecs, char *buf, int raw)
8215 for (chain = nreverse (copy_list (declspecs));
8216 chain; chain = TREE_CHAIN (chain))
8218 tree aspec = TREE_VALUE (chain);
8220 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8221 strcat (buf, IDENTIFIER_POINTER (aspec));
8222 else if (TREE_CODE (aspec) == RECORD_TYPE)
8224 if (OBJC_TYPE_NAME (aspec))
8226 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8228 if (! TREE_STATIC_TEMPLATE (aspec))
8229 strcat (buf, "struct ");
8230 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8235 tree chain = protocol_list;
8242 (PROTOCOL_NAME (TREE_VALUE (chain))));
8243 chain = TREE_CHAIN (chain);
8252 strcat (buf, "untagged struct");
8255 else if (TREE_CODE (aspec) == UNION_TYPE)
8257 if (OBJC_TYPE_NAME (aspec))
8259 if (! TREE_STATIC_TEMPLATE (aspec))
8260 strcat (buf, "union ");
8261 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8264 strcat (buf, "untagged union");
8267 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8269 if (OBJC_TYPE_NAME (aspec))
8271 if (! TREE_STATIC_TEMPLATE (aspec))
8272 strcat (buf, "enum ");
8273 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8276 strcat (buf, "untagged enum");
8279 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8280 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8282 else if (IS_ID (aspec))
8284 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8289 tree chain = protocol_list;
8296 (PROTOCOL_NAME (TREE_VALUE (chain))));
8297 chain = TREE_CHAIN (chain);
8304 if (TREE_CHAIN (chain))
8310 /* Type qualifiers. */
8311 if (TYPE_READONLY (declspecs))
8312 strcat (buf, "const ");
8313 if (TYPE_VOLATILE (declspecs))
8314 strcat (buf, "volatile ");
8316 switch (TREE_CODE (declspecs))
8318 /* Type specifiers. */
8321 declspecs = TYPE_MAIN_VARIANT (declspecs);
8323 /* Signed integer types. */
8325 if (declspecs == short_integer_type_node)
8326 strcat (buf, "short int ");
8327 else if (declspecs == integer_type_node)
8328 strcat (buf, "int ");
8329 else if (declspecs == long_integer_type_node)
8330 strcat (buf, "long int ");
8331 else if (declspecs == long_long_integer_type_node)
8332 strcat (buf, "long long int ");
8333 else if (declspecs == signed_char_type_node
8334 || declspecs == char_type_node)
8335 strcat (buf, "char ");
8337 /* Unsigned integer types. */
8339 else if (declspecs == short_unsigned_type_node)
8340 strcat (buf, "unsigned short ");
8341 else if (declspecs == unsigned_type_node)
8342 strcat (buf, "unsigned int ");
8343 else if (declspecs == long_unsigned_type_node)
8344 strcat (buf, "unsigned long ");
8345 else if (declspecs == long_long_unsigned_type_node)
8346 strcat (buf, "unsigned long long ");
8347 else if (declspecs == unsigned_char_type_node)
8348 strcat (buf, "unsigned char ");
8352 declspecs = TYPE_MAIN_VARIANT (declspecs);
8354 if (declspecs == float_type_node)
8355 strcat (buf, "float ");
8356 else if (declspecs == double_type_node)
8357 strcat (buf, "double ");
8358 else if (declspecs == long_double_type_node)
8359 strcat (buf, "long double ");
8363 if (OBJC_TYPE_NAME (declspecs)
8364 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8366 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8368 if (! TREE_STATIC_TEMPLATE (declspecs))
8369 strcat (buf, "struct ");
8370 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8374 tree chain = protocol_list;
8381 (PROTOCOL_NAME (TREE_VALUE (chain))));
8382 chain = TREE_CHAIN (chain);
8391 strcat (buf, "untagged struct");
8397 if (OBJC_TYPE_NAME (declspecs)
8398 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8400 strcat (buf, "union ");
8401 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8406 strcat (buf, "untagged union ");
8410 if (OBJC_TYPE_NAME (declspecs)
8411 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8413 strcat (buf, "enum ");
8414 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8419 strcat (buf, "untagged enum ");
8423 strcat (buf, "void ");
8428 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8433 tree chain = protocol_list;
8440 (PROTOCOL_NAME (TREE_VALUE (chain))));
8441 chain = TREE_CHAIN (chain);
8457 /* Given a tree node, produce a printable description of it in the given
8458 buffer, overwriting the buffer. */
8461 gen_declaration (tree atype_or_adecl, char *buf)
8464 gen_declaration_1 (atype_or_adecl, buf);
8468 /* Given a tree node, append a printable description to the end of the
8472 gen_declaration_1 (tree atype_or_adecl, char *buf)
8476 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8478 tree declspecs; /* "identifier_node", "record_type" */
8479 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8480 tree width = NULL_TREE; /* for bitfields */
8482 /* We have a "raw", abstract declarator (typename). */
8483 declarator = TREE_VALUE (atype_or_adecl);
8484 /* In the case of raw ivars, the declarator itself is a list,
8485 and contains bitfield widths. */
8486 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8488 width = TREE_VALUE (declarator);
8489 declarator = TREE_PURPOSE (declarator);
8491 declspecs = TREE_PURPOSE (atype_or_adecl);
8493 gen_declspecs (declspecs, buf, 1);
8497 strcat (buf, gen_declarator (declarator, declbuf, ""));
8500 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8501 TREE_INT_CST_LOW (width));
8507 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8508 tree declarator; /* "array_type", "function_type", "pointer_type". */
8510 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8511 || TREE_CODE (atype_or_adecl) == PARM_DECL
8512 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8513 atype = TREE_TYPE (atype_or_adecl);
8515 /* Assume we have a *_type node. */
8516 atype = atype_or_adecl;
8518 if (is_complex_decl (atype))
8522 /* Get the declaration specifier; it is at the end of the list. */
8523 declarator = chain = atype;
8525 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8526 while (is_complex_decl (chain));
8533 declarator = NULL_TREE;
8536 gen_declspecs (declspecs, buf, 0);
8538 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8539 || TREE_CODE (atype_or_adecl) == PARM_DECL
8540 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8542 const char *const decl_name =
8543 (DECL_NAME (atype_or_adecl)
8544 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8549 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8552 else if (decl_name[0])
8555 strcat (buf, decl_name);
8558 else if (declarator)
8561 strcat (buf, gen_declarator (declarator, declbuf, ""));
8566 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8568 /* Given a method tree, put a printable description into the given
8569 buffer (overwriting) and return a pointer to the buffer. */
8572 gen_method_decl (tree method, char *buf)
8577 if (RAW_TYPESPEC (method) != objc_object_reference)
8580 gen_declaration_1 (TREE_TYPE (method), buf);
8584 chain = METHOD_SEL_ARGS (method);
8587 /* We have a chain of keyword_decls. */
8590 if (KEYWORD_KEY_NAME (chain))
8591 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8594 if (RAW_TYPESPEC (chain) != objc_object_reference)
8597 gen_declaration_1 (TREE_TYPE (chain), buf);
8601 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8602 if ((chain = TREE_CHAIN (chain)))
8607 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8608 strcat (buf, ", ...");
8609 else if (METHOD_ADD_ARGS (method))
8611 /* We have a tree list node as generate by get_parm_info. */
8612 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8614 /* Know we have a chain of parm_decls. */
8618 gen_declaration_1 (chain, buf);
8619 chain = TREE_CHAIN (chain);
8625 /* We have a unary selector. */
8626 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8634 /* Dump an @interface declaration of the supplied class CHAIN to the
8635 supplied file FP. Used to implement the -gen-decls option (which
8636 prints out an @interface declaration of all classes compiled in
8637 this run); potentially useful for debugging the compiler too. */
8639 dump_interface (FILE *fp, tree chain)
8641 /* FIXME: A heap overflow here whenever a method (or ivar)
8642 declaration is so long that it doesn't fit in the buffer. The
8643 code and all the related functions should be rewritten to avoid
8644 using fixed size buffers. */
8645 char *buf = (char *) xmalloc (1024 * 10);
8646 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8647 tree ivar_decls = CLASS_RAW_IVARS (chain);
8648 tree nst_methods = CLASS_NST_METHODS (chain);
8649 tree cls_methods = CLASS_CLS_METHODS (chain);
8651 fprintf (fp, "\n@interface %s", my_name);
8653 /* CLASS_SUPER_NAME is used to store the superclass name for
8654 classes, and the category name for categories. */
8655 if (CLASS_SUPER_NAME (chain))
8657 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8659 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8660 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8662 fprintf (fp, " (%s)\n", name);
8666 fprintf (fp, " : %s\n", name);
8672 /* FIXME - the following doesn't seem to work at the moment. */
8675 fprintf (fp, "{\n");
8678 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8679 ivar_decls = TREE_CHAIN (ivar_decls);
8682 fprintf (fp, "}\n");
8687 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8688 nst_methods = TREE_CHAIN (nst_methods);
8693 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8694 cls_methods = TREE_CHAIN (cls_methods);
8697 fprintf (fp, "@end\n");
8700 /* Demangle function for Objective-C */
8702 objc_demangle (const char *mangled)
8704 char *demangled, *cp;
8706 if (mangled[0] == '_' &&
8707 (mangled[1] == 'i' || mangled[1] == 'c') &&
8710 cp = demangled = xmalloc(strlen(mangled) + 2);
8711 if (mangled[1] == 'i')
8712 *cp++ = '-'; /* for instance method */
8714 *cp++ = '+'; /* for class method */
8715 *cp++ = '['; /* opening left brace */
8716 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8717 while (*cp && *cp == '_')
8718 cp++; /* skip any initial underbars in class name */
8719 cp = strchr(cp, '_'); /* find first non-initial underbar */
8722 free(demangled); /* not mangled name */
8725 if (cp[1] == '_') /* easy case: no category name */
8727 *cp++ = ' '; /* replace two '_' with one ' ' */
8728 strcpy(cp, mangled + (cp - demangled) + 2);
8732 *cp++ = '('; /* less easy case: category name */
8733 cp = strchr(cp, '_');
8736 free(demangled); /* not mangled name */
8740 *cp++ = ' '; /* overwriting 1st char of method name... */
8741 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8743 while (*cp && *cp == '_')
8744 cp++; /* skip any initial underbars in method name */
8747 *cp = ':'; /* replace remaining '_' with ':' */
8748 *cp++ = ']'; /* closing right brace */
8749 *cp++ = 0; /* string terminator */
8753 return mangled; /* not an objc mangled name */
8757 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8759 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8765 gcc_obstack_init (&util_obstack);
8766 util_firstobj = (char *) obstack_finish (&util_obstack);
8768 errbuf = (char *) xmalloc (BUFSIZE);
8770 synth_module_prologue ();
8776 struct imp_entry *impent;
8778 /* The internally generated initializers appear to have missing braces.
8779 Don't warn about this. */
8780 int save_warn_missing_braces = warn_missing_braces;
8781 warn_missing_braces = 0;
8783 /* A missing @end may not be detected by the parser. */
8784 if (objc_implementation_context)
8786 warning ("`@end' missing in implementation context");
8787 finish_class (objc_implementation_context);
8788 objc_ivar_chain = NULL_TREE;
8789 objc_implementation_context = NULL_TREE;
8792 /* Process the static instances here because initialization of objc_symtab
8794 if (objc_static_instances)
8795 generate_static_references ();
8797 if (imp_list || class_names_chain
8798 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8799 generate_objc_symtab_decl ();
8801 for (impent = imp_list; impent; impent = impent->next)
8803 objc_implementation_context = impent->imp_context;
8804 implementation_template = impent->imp_template;
8806 UOBJC_CLASS_decl = impent->class_decl;
8807 UOBJC_METACLASS_decl = impent->meta_decl;
8809 /* Dump the @interface of each class as we compile it, if the
8810 -gen-decls option is in use. TODO: Dump the classes in the
8811 order they were found, rather than in reverse order as we
8813 if (flag_gen_declaration)
8815 dump_interface (gen_declaration_file, objc_implementation_context);
8818 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8820 /* all of the following reference the string pool... */
8821 generate_ivar_lists ();
8822 generate_dispatch_tables ();
8823 generate_shared_structures ();
8827 generate_dispatch_tables ();
8828 generate_category (objc_implementation_context);
8832 /* If we are using an array of selectors, we must always
8833 finish up the array decl even if no selectors were used. */
8834 if (! flag_next_runtime || sel_ref_chain)
8835 build_selector_translation_table ();
8838 generate_protocols ();
8840 if (flag_replace_objc_classes && imp_list)
8841 generate_objc_image_info ();
8843 if (objc_implementation_context || class_names_chain || objc_static_instances
8844 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8846 /* Arrange for ObjC data structures to be initialized at run time. */
8847 rtx init_sym = build_module_descriptor ();
8848 if (init_sym && targetm.have_ctors_dtors)
8849 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8852 /* Dump the class references. This forces the appropriate classes
8853 to be linked into the executable image, preserving unix archive
8854 semantics. This can be removed when we move to a more dynamically
8855 linked environment. */
8857 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8859 handle_class_ref (chain);
8860 if (TREE_PURPOSE (chain))
8861 generate_classref_translation_entry (chain);
8864 for (impent = imp_list; impent; impent = impent->next)
8865 handle_impent (impent);
8867 /* Dump the string table last. */
8869 generate_strings ();
8876 /* Run through the selector hash tables and print a warning for any
8877 selector which has multiple methods. */
8879 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8881 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8882 check_duplicates (hsh, 0, 1);
8883 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8884 check_duplicates (hsh, 0, 1);
8888 warn_missing_braces = save_warn_missing_braces;
8891 /* Subroutines of finish_objc. */
8894 generate_classref_translation_entry (tree chain)
8896 tree expr, name, decl_specs, decl, sc_spec;
8899 type = TREE_TYPE (TREE_PURPOSE (chain));
8901 expr = add_objc_string (TREE_VALUE (chain), class_names);
8902 expr = build_c_cast (type, expr); /* cast! */
8904 name = DECL_NAME (TREE_PURPOSE (chain));
8906 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8908 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8909 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8911 /* The decl that is returned from start_decl is the one that we
8912 forward declared in build_class_reference. */
8913 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8914 DECL_CONTEXT (decl) = NULL_TREE;
8915 finish_decl (decl, expr, NULL_TREE);
8920 handle_class_ref (tree chain)
8922 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8923 char *string = (char *) alloca (strlen (name) + 30);
8927 sprintf (string, "%sobjc_class_name_%s",
8928 (flag_next_runtime ? "." : "__"), name);
8930 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8931 if (flag_next_runtime)
8933 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8938 /* Make a decl for this name, so we can use its address in a tree. */
8939 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8940 DECL_EXTERNAL (decl) = 1;
8941 TREE_PUBLIC (decl) = 1;
8944 rest_of_decl_compilation (decl, 0, 0, 0);
8946 /* Make a decl for the address. */
8947 sprintf (string, "%sobjc_class_ref_%s",
8948 (flag_next_runtime ? "." : "__"), name);
8949 exp = build1 (ADDR_EXPR, string_type_node, decl);
8950 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8951 DECL_INITIAL (decl) = exp;
8952 TREE_STATIC (decl) = 1;
8953 TREE_USED (decl) = 1;
8956 rest_of_decl_compilation (decl, 0, 0, 0);
8960 handle_impent (struct imp_entry *impent)
8964 objc_implementation_context = impent->imp_context;
8965 implementation_template = impent->imp_template;
8967 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8969 const char *const class_name =
8970 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8972 string = (char *) alloca (strlen (class_name) + 30);
8974 sprintf (string, "%sobjc_class_name_%s",
8975 (flag_next_runtime ? "." : "__"), class_name);
8977 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8979 const char *const class_name =
8980 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8981 const char *const class_super_name =
8982 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8984 string = (char *) alloca (strlen (class_name)
8985 + strlen (class_super_name) + 30);
8987 /* Do the same for categories. Even though no references to
8988 these symbols are generated automatically by the compiler, it
8989 gives you a handle to pull them into an archive by hand. */
8990 sprintf (string, "*%sobjc_category_name_%s_%s",
8991 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8996 #ifdef ASM_DECLARE_CLASS_REFERENCE
8997 if (flag_next_runtime)
8999 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9007 init = build_int_2 (0, 0);
9008 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
9009 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9010 TREE_PUBLIC (decl) = 1;
9011 TREE_READONLY (decl) = 1;
9012 TREE_USED (decl) = 1;
9013 TREE_CONSTANT (decl) = 1;
9014 DECL_CONTEXT (decl) = 0;
9015 DECL_ARTIFICIAL (decl) = 1;
9016 DECL_INITIAL (decl) = init;
9017 assemble_variable (decl, 1, 0, 0);
9021 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9022 later requires that ObjC translation units participating in F&C be
9023 specially marked. The following routine accomplishes this. */
9025 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9028 generate_objc_image_info (void)
9030 tree sc_spec, decl, initlist;
9032 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9034 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9035 tree_cons (NULL_TREE,
9038 build_index_type (build_int_2 (1, 0))),
9043 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9044 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9045 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9047 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9048 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9049 finish_decl (decl, initlist, NULL_TREE);
9052 /* Look up ID as an instance variable. */
9055 lookup_objc_ivar (tree id)
9059 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9060 /* We have a message to super. */
9061 return get_super_receiver ();
9062 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9064 if (is_private (decl))
9067 return build_ivar_reference (id);
9073 #include "gt-objc-objc-act.h"
9074 #include "gtype-objc.h"