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 ();
523 /* Finalize Objective-C runtime data. No need to generate tables
524 and code if only checking syntax. */
525 if (!flag_syntax_only)
528 if (gen_declaration_file)
529 fclose (gen_declaration_file);
533 define_decl (tree declarator, tree declspecs)
535 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
536 finish_decl (decl, NULL_TREE, NULL_TREE);
540 /* Return the first occurrence of a method declaration corresponding
541 to sel_name in rproto_list. Search rproto_list recursively.
542 If is_class is 0, search for instance methods, otherwise for class
545 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
551 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
553 p = TREE_VALUE (rproto);
555 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
557 if ((fnd = lookup_method (is_class
558 ? PROTOCOL_CLS_METHODS (p)
559 : PROTOCOL_NST_METHODS (p), sel_name)))
561 else if (PROTOCOL_LIST (p))
562 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
567 ; /* An identifier...if we could not find a protocol. */
578 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
582 /* Make sure the protocol is supported by the object on the rhs. */
583 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
586 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
588 p = TREE_VALUE (rproto);
590 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
595 else if (PROTOCOL_LIST (p))
596 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
605 ; /* An identifier...if we could not find a protocol. */
611 /* Return true if TYPE is 'id'. */
614 objc_is_object_id (tree type)
616 return OBJC_TYPE_NAME (type) == objc_object_id;
620 objc_is_class_id (tree type)
622 return OBJC_TYPE_NAME (type) == objc_class_id;
625 /* Return 1 if LHS and RHS are compatible types for assignment or
626 various other operations. Return 0 if they are incompatible, and
627 return -1 if we choose to not decide (because the types are really
628 just C types, not ObjC specific ones). When the operation is
629 REFLEXIVE (typically comparisons), check for compatibility in
630 either direction; when it's not (typically assignments), don't.
632 This function is called in two cases: when both lhs and rhs are
633 pointers to records (in which case we check protocols too), and
634 when both lhs and rhs are records (in which case we check class
637 Warnings about classes/protocols not implementing a protocol are
638 emitted here (multiple of those warnings might be emitted for a
639 single line!); generic warnings about incompatible assignments and
640 lacks of casts in comparisons are/must be emitted by the caller if
645 objc_comptypes (tree lhs, tree rhs, int reflexive)
647 /* New clause for protocols. */
649 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
650 manage the ObjC ones, and leave the rest to the C code. */
651 if (TREE_CODE (lhs) == POINTER_TYPE
652 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
653 && TREE_CODE (rhs) == POINTER_TYPE
654 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
656 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
657 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
661 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
662 tree rproto, rproto_list;
665 /* <Protocol> = <Protocol> */
668 rproto_list = TYPE_PROTOCOL_LIST (rhs);
672 /* An assignment between objects of type 'id
673 <Protocol>'; make sure the protocol on the lhs is
674 supported by the object on the rhs. */
675 for (lproto = lproto_list; lproto;
676 lproto = TREE_CHAIN (lproto))
678 p = TREE_VALUE (lproto);
679 rproto = lookup_protocol_in_reflist (rproto_list, p);
683 ("object does not conform to the `%s' protocol",
684 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
690 /* Obscure case - a comparison between two objects
691 of type 'id <Protocol>'. Check that either the
692 protocol on the lhs is supported by the object on
693 the rhs, or viceversa. */
695 /* Check if the protocol on the lhs is supported by the
696 object on the rhs. */
697 for (lproto = lproto_list; lproto;
698 lproto = TREE_CHAIN (lproto))
700 p = TREE_VALUE (lproto);
701 rproto = lookup_protocol_in_reflist (rproto_list, p);
705 /* Check failed - check if the protocol on the rhs
706 is supported by the object on the lhs. */
707 for (rproto = rproto_list; rproto;
708 rproto = TREE_CHAIN (rproto))
710 p = TREE_VALUE (rproto);
711 lproto = lookup_protocol_in_reflist (lproto_list,
716 /* This check failed too: incompatible */
726 /* <Protocol> = <class> * */
727 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
729 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
732 /* Make sure the protocol is supported by the object on
734 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
736 p = TREE_VALUE (lproto);
738 rinter = lookup_interface (rname);
740 while (rinter && !rproto)
744 rproto_list = CLASS_PROTOCOL_LIST (rinter);
745 rproto = lookup_protocol_in_reflist (rproto_list, p);
746 /* If the underlying ObjC class does not have
747 the protocol we're looking for, check for "one-off"
748 protocols (e.g., `NSObject<MyProt> *foo;') attached
752 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
753 rproto = lookup_protocol_in_reflist (rproto_list, p);
756 /* Check for protocols adopted by categories. */
757 cat = CLASS_CATEGORY_LIST (rinter);
758 while (cat && !rproto)
760 rproto_list = CLASS_PROTOCOL_LIST (cat);
761 rproto = lookup_protocol_in_reflist (rproto_list, p);
762 cat = CLASS_CATEGORY_LIST (cat);
765 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
769 warning ("class `%s' does not implement the `%s' protocol",
770 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
771 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
775 /* <Protocol> = id */
776 else if (objc_is_object_id (TREE_TYPE (rhs)))
780 /* <Protocol> = Class */
781 else if (objc_is_class_id (TREE_TYPE (rhs)))
785 /* <Protocol> = ?? : let comptypes decide. */
788 else if (rhs_is_proto)
790 /* <class> * = <Protocol> */
791 if (TYPED_OBJECT (TREE_TYPE (lhs)))
795 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
797 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
799 /* Make sure the protocol is supported by the object on
801 for (rproto = rproto_list; rproto;
802 rproto = TREE_CHAIN (rproto))
804 tree p = TREE_VALUE (rproto);
806 rinter = lookup_interface (rname);
808 while (rinter && !lproto)
812 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
813 lproto = lookup_protocol_in_reflist (lproto_list, p);
814 /* If the underlying ObjC class does not
815 have the protocol we're looking for,
816 check for "one-off" protocols (e.g.,
817 `NSObject<MyProt> *foo;') attached to the
821 lproto_list = TYPE_PROTOCOL_LIST
823 lproto = lookup_protocol_in_reflist
827 /* Check for protocols adopted by categories. */
828 cat = CLASS_CATEGORY_LIST (rinter);
829 while (cat && !lproto)
831 lproto_list = CLASS_PROTOCOL_LIST (cat);
832 lproto = lookup_protocol_in_reflist (lproto_list,
834 cat = CLASS_CATEGORY_LIST (cat);
837 rinter = lookup_interface (CLASS_SUPER_NAME
842 warning ("class `%s' does not implement the `%s' protocol",
843 IDENTIFIER_POINTER (OBJC_TYPE_NAME
845 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
852 /* id = <Protocol> */
853 else if (objc_is_object_id (TREE_TYPE (lhs)))
857 /* Class = <Protocol> */
858 else if (objc_is_class_id (TREE_TYPE (lhs)))
862 /* ??? = <Protocol> : let comptypes decide */
870 /* Attention: we shouldn't defer to comptypes here. One bad
871 side effect would be that we might loose the REFLEXIVE
874 lhs = TREE_TYPE (lhs);
875 rhs = TREE_TYPE (rhs);
879 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
881 /* Nothing to do with ObjC - let immediately comptypes take
882 responsibility for checking. */
886 /* `id' = `<class> *' `<class> *' = `id': always allow it.
888 'Object *o = [[Object alloc] init]; falls
889 in the case <class> * = `id'.
891 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
892 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
895 /* `id' = `Class', `Class' = `id' */
897 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
898 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
901 /* `Class' != `<class> *' && `<class> *' != `Class'! */
902 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
903 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
906 /* `<class> *' = `<class> *' */
908 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
910 tree lname = OBJC_TYPE_NAME (lhs);
911 tree rname = OBJC_TYPE_NAME (rhs);
917 /* If the left hand side is a super class of the right hand side,
919 for (inter = lookup_interface (rname); inter;
920 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
921 if (lname == CLASS_SUPER_NAME (inter))
924 /* Allow the reverse when reflexive. */
926 for (inter = lookup_interface (lname); inter;
927 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
928 if (rname == CLASS_SUPER_NAME (inter))
934 /* Not an ObjC type - let comptypes do the check. */
938 /* Called from finish_decl. */
941 objc_check_decl (tree decl)
943 tree type = TREE_TYPE (decl);
945 if (TREE_CODE (type) != RECORD_TYPE)
947 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
948 error ("statically allocated instance of Objective-C class `%s'",
949 IDENTIFIER_POINTER (type));
952 /* Implement static typing. At this point, we know we have an interface. */
955 get_static_reference (tree interface, tree protocols)
957 tree type = xref_tag (RECORD_TYPE, interface);
961 tree t, m = TYPE_MAIN_VARIANT (type);
963 t = copy_node (type);
965 /* Add this type to the chain of variants of TYPE. */
966 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
967 TYPE_NEXT_VARIANT (m) = t;
969 /* Look up protocols and install in lang specific list. Note
970 that the protocol list can have a different lifetime than T! */
971 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
973 /* This forces a new pointer type to be created later
974 (in build_pointer_type)...so that the new template
975 we just created will actually be used...what a hack! */
976 if (TYPE_POINTER_TO (t))
977 TYPE_POINTER_TO (t) = NULL_TREE;
985 /* Return a declaration corresponding to a protocol list qualified 'id'. */
987 get_protocol_reference (tree protocols)
989 tree type_decl = lookup_name (objc_id_id);
992 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
994 type = TREE_TYPE (type_decl);
995 if (TYPE_MAIN_VARIANT (type) != objc_id_type)
996 warning ("unexpected type for `id' (%s)",
997 gen_declaration (type, errbuf));
1001 error ("undefined type `id', please import <objc/objc.h>");
1002 return error_mark_node;
1005 /* This clause creates a new pointer type that is qualified with
1006 the protocol specification...this info is used later to do more
1007 elaborate type checking. */
1011 tree t, m = TYPE_MAIN_VARIANT (type);
1013 t = copy_node (type);
1015 /* Add this type to the chain of variants of TYPE. */
1016 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1017 TYPE_NEXT_VARIANT (m) = t;
1019 /* Look up protocols...and install in lang specific list */
1020 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1022 /* This forces a new pointer type to be created later
1023 (in build_pointer_type)...so that the new template
1024 we just created will actually be used...what a hack! */
1025 if (TYPE_POINTER_TO (t))
1026 TYPE_POINTER_TO (t) = NULL_TREE;
1033 /* Check for circular dependencies in protocols. The arguments are
1034 PROTO, the protocol to check, and LIST, a list of protocol it
1038 check_protocol_recursively (tree proto, tree list)
1042 for (p = list; p; p = TREE_CHAIN (p))
1044 tree pp = TREE_VALUE (p);
1046 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1047 pp = lookup_protocol (pp);
1050 fatal_error ("protocol `%s' has circular dependency",
1051 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1053 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1057 /* Look up PROTOCOLS, and return a list of those that are found.
1058 If none are found, return NULL. */
1061 lookup_and_install_protocols (tree protocols)
1064 tree return_value = NULL_TREE;
1066 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1068 tree ident = TREE_VALUE (proto);
1069 tree p = lookup_protocol (ident);
1072 error ("cannot find protocol declaration for `%s'",
1073 IDENTIFIER_POINTER (ident));
1075 return_value = chainon (return_value,
1076 build_tree_list (NULL_TREE, p));
1079 return return_value;
1082 /* Create and push a decl for a built-in external variable or field NAME.
1084 TYPE is its data type. */
1087 create_builtin_decl (enum tree_code code, tree type, const char *name)
1089 tree decl = build_decl (code, get_identifier (name), type);
1091 if (code == VAR_DECL)
1093 TREE_STATIC (decl) = 1;
1094 make_decl_rtl (decl, 0);
1096 DECL_ARTIFICIAL (decl) = 1;
1102 /* Find the decl for the constant string class. */
1105 setup_string_decl (void)
1107 if (!string_class_decl)
1109 if (!constant_string_global_id)
1113 /* %s in format will provide room for terminating null */
1114 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1115 + strlen (constant_string_class_name);
1116 name = xmalloc (length);
1117 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1118 constant_string_class_name);
1119 constant_string_global_id = get_identifier (name);
1121 string_class_decl = lookup_name (constant_string_global_id);
1125 /* Purpose: "play" parser, creating/installing representations
1126 of the declarations that are required by Objective-C.
1130 type_spec--------->sc_spec
1131 (tree_list) (tree_list)
1134 identifier_node identifier_node */
1137 synth_module_prologue (void)
1141 /* Defined in `objc.h' */
1142 objc_object_id = get_identifier (TAG_OBJECT);
1144 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1146 objc_id_type = build_pointer_type (objc_object_reference);
1148 objc_id_id = get_identifier (TYPE_ID);
1149 objc_class_id = get_identifier (TAG_CLASS);
1151 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1152 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1153 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1154 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, temp_type));
1156 /* Declare type of selector-objects that represent an operation name. */
1158 if (flag_next_runtime)
1159 /* `struct objc_selector *' */
1161 = build_pointer_type (xref_tag (RECORD_TYPE,
1162 get_identifier (TAG_SELECTOR)));
1164 /* `const struct objc_selector *' */
1166 = build_pointer_type
1167 (build_qualified_type (xref_tag (RECORD_TYPE,
1168 get_identifier (TAG_SELECTOR)),
1171 /* Declare receiver type used for dispatching messages to 'super'. */
1173 /* `struct objc_super *' */
1174 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1175 get_identifier (TAG_SUPER)));
1177 if (flag_next_runtime)
1179 /* NB: In order to call one of the ..._stret (struct-returning)
1180 functions, the function *MUST* first be cast to a signature that
1181 corresponds to the actual ObjC method being invoked. This is
1182 what is done by the build_objc_method_call() routine below. */
1184 /* id objc_msgSend (id, SEL, ...); */
1185 /* id objc_msgSendNonNil (id, SEL, ...); */
1186 /* id objc_msgSend_stret (id, SEL, ...); */
1187 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1189 = build_function_type (objc_id_type,
1190 tree_cons (NULL_TREE, objc_id_type,
1191 tree_cons (NULL_TREE,
1194 umsg_decl = builtin_function (TAG_MSGSEND,
1195 temp_type, 0, NOT_BUILT_IN,
1197 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1198 temp_type, 0, NOT_BUILT_IN,
1200 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1201 temp_type, 0, NOT_BUILT_IN,
1203 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1204 temp_type, 0, NOT_BUILT_IN,
1207 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1208 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1210 = build_function_type (objc_id_type,
1211 tree_cons (NULL_TREE, objc_super_type,
1212 tree_cons (NULL_TREE,
1215 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1216 temp_type, 0, NOT_BUILT_IN,
1218 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1219 temp_type, 0, NOT_BUILT_IN, 0,
1224 /* GNU runtime messenger entry points. */
1226 /* typedef id (*IMP)(id, SEL, ...); */
1228 = build_pointer_type
1229 (build_function_type (objc_id_type,
1230 tree_cons (NULL_TREE, objc_id_type,
1231 tree_cons (NULL_TREE,
1235 /* IMP objc_msg_lookup (id, SEL); */
1237 = build_function_type (IMP_type,
1238 tree_cons (NULL_TREE, objc_id_type,
1239 tree_cons (NULL_TREE,
1242 umsg_decl = builtin_function (TAG_MSGSEND,
1243 temp_type, 0, NOT_BUILT_IN,
1246 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1248 = build_function_type (IMP_type,
1249 tree_cons (NULL_TREE, objc_super_type,
1250 tree_cons (NULL_TREE,
1253 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1254 temp_type, 0, NOT_BUILT_IN,
1258 /* id objc_getClass (const char *); */
1260 temp_type = build_function_type (objc_id_type,
1261 tree_cons (NULL_TREE,
1262 const_string_type_node,
1266 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1269 /* id objc_getMetaClass (const char *); */
1271 objc_get_meta_class_decl
1272 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1274 build_super_template ();
1275 build_objc_exception_stuff ();
1276 if (flag_next_runtime)
1277 build_next_objc_exception_stuff ();
1279 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1281 if (! flag_next_runtime)
1283 if (flag_typed_selectors)
1285 /* Suppress outputting debug symbols, because
1286 dbxout_init hasn'r been called yet. */
1287 enum debug_info_type save_write_symbols = write_symbols;
1288 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1289 write_symbols = NO_DEBUG;
1290 debug_hooks = &do_nothing_debug_hooks;
1292 build_selector_template ();
1293 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1295 write_symbols = save_write_symbols;
1296 debug_hooks = save_hooks;
1299 temp_type = build_array_type (objc_selector_type, NULL_TREE);
1301 layout_type (temp_type);
1302 UOBJC_SELECTOR_TABLE_decl
1303 = create_builtin_decl (VAR_DECL, temp_type,
1304 "_OBJC_SELECTOR_TABLE");
1306 /* Avoid warning when not sending messages. */
1307 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1310 /* Forward declare constant_string_id and constant_string_type. */
1311 if (!constant_string_class_name)
1312 constant_string_class_name = default_constant_string_class_name;
1314 constant_string_id = get_identifier (constant_string_class_name);
1315 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1317 /* Pre-build the following entities - for speed/convenience. */
1318 self_id = get_identifier ("self");
1319 ucmd_id = get_identifier ("_cmd");
1321 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1322 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1326 /* Ensure that the ivar list for NSConstantString/NXConstantString
1327 (or whatever was specified via `-fconstant-string-class')
1328 contains fields at least as large as the following three, so that
1329 the runtime can stomp on them with confidence:
1331 struct STRING_OBJECT_CLASS_NAME
1335 unsigned int length;
1339 check_string_class_template (void)
1341 tree field_decl = TYPE_FIELDS (constant_string_type);
1343 #define AT_LEAST_AS_LARGE_AS(F, T) \
1344 (F && TREE_CODE (F) == FIELD_DECL \
1345 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1346 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1348 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1351 field_decl = TREE_CHAIN (field_decl);
1352 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1355 field_decl = TREE_CHAIN (field_decl);
1356 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1358 #undef AT_LEAST_AS_LARGE_AS
1361 /* Avoid calling `check_string_class_template ()' more than once. */
1362 static GTY(()) int string_layout_checked;
1364 /* Custom build_string which sets TREE_TYPE! */
1367 my_build_string (int len, const char *str)
1369 return fix_string_type (build_string (len, str));
1372 /* Given a chain of STRING_CST's, build a static instance of
1373 NXConstantString which points at the concatenation of those
1374 strings. We place the string object in the __string_objects
1375 section of the __OBJC segment. The Objective-C runtime will
1376 initialize the isa pointers of the string objects to point at the
1377 NXConstantString class object. */
1380 build_objc_string_object (tree string)
1382 tree initlist, constructor, constant_string_class;
1386 string = fix_string_type (string);
1388 constant_string_class = lookup_interface (constant_string_id);
1389 if (!constant_string_class
1390 || !(constant_string_type
1391 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1393 error ("cannot find interface declaration for `%s'",
1394 IDENTIFIER_POINTER (constant_string_id));
1395 return error_mark_node;
1398 /* Call to 'combine_strings' has been moved above. */
1399 TREE_SET_CODE (string, STRING_CST);
1400 length = TREE_STRING_LENGTH (string) - 1;
1402 if (!string_layout_checked)
1404 /* The NSConstantString/NXConstantString ivar layout is now
1406 if (!check_string_class_template ())
1408 error ("interface `%s' does not have valid constant string layout",
1409 IDENTIFIER_POINTER (constant_string_id));
1410 return error_mark_node;
1412 add_class_reference (constant_string_id);
1414 fields = TYPE_FIELDS (constant_string_type);
1416 /* & ((NXConstantString) { NULL, string, length }) */
1418 if (flag_next_runtime)
1420 /* For the NeXT runtime, we can generate a literal reference
1421 to the string class, don't need to run a constructor. */
1422 setup_string_decl ();
1423 if (string_class_decl == NULL_TREE)
1425 error ("cannot find reference tag for class `%s'",
1426 IDENTIFIER_POINTER (constant_string_id));
1427 return error_mark_node;
1429 initlist = build_tree_list
1431 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1435 initlist = build_tree_list (fields, build_int_2 (0, 0));
1438 fields = TREE_CHAIN (fields);
1441 = tree_cons (fields, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1444 fields = TREE_CHAIN (fields);
1446 initlist = tree_cons (fields, build_int_2 (length, 0), initlist);
1447 constructor = objc_build_constructor (constant_string_type,
1448 nreverse (initlist));
1450 if (!flag_next_runtime)
1453 = objc_add_static_instance (constructor, constant_string_type);
1456 return (build_unary_op (ADDR_EXPR, constructor, 1));
1459 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1461 static GTY(()) int num_static_inst;
1464 objc_add_static_instance (tree constructor, tree class_decl)
1469 /* Find the list of static instances for the CLASS_DECL. Create one if
1471 for (chain = &objc_static_instances;
1472 *chain && TREE_VALUE (*chain) != class_decl;
1473 chain = &TREE_CHAIN (*chain));
1476 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1477 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1480 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1481 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1482 DECL_COMMON (decl) = 1;
1483 TREE_STATIC (decl) = 1;
1484 DECL_ARTIFICIAL (decl) = 1;
1485 DECL_INITIAL (decl) = constructor;
1487 /* We may be writing something else just now.
1488 Postpone till end of input. */
1489 DECL_DEFER_OUTPUT (decl) = 1;
1490 pushdecl_top_level (decl);
1491 rest_of_decl_compilation (decl, 0, 1, 0);
1493 /* Add the DECL to the head of this CLASS' list. */
1494 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1499 /* Build a static constant CONSTRUCTOR
1500 with type TYPE and elements ELTS. */
1503 objc_build_constructor (tree type, tree elts)
1505 tree constructor, f, e;
1507 /* ??? Most of the places that we build constructors, we don't fill in
1508 the type of integers properly. Convert them all en masse. */
1509 if (TREE_CODE (type) == ARRAY_TYPE)
1511 f = TREE_TYPE (type);
1512 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1513 for (e = elts; e ; e = TREE_CHAIN (e))
1514 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1518 f = TYPE_FIELDS (type);
1519 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1520 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1521 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1522 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1525 constructor = build_constructor (type, elts);
1526 TREE_CONSTANT (constructor) = 1;
1527 TREE_STATIC (constructor) = 1;
1528 TREE_READONLY (constructor) = 1;
1531 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1532 build_unary_op (wasn't true in 2.7.2.1 days) */
1533 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1538 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1540 /* Predefine the following data type:
1548 void *defs[cls_def_cnt + cat_def_cnt];
1552 build_objc_symtab_template (void)
1554 tree field_decl, field_decl_chain;
1556 objc_symtab_template
1557 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1559 /* long sel_ref_cnt; */
1561 field_decl = create_builtin_decl (FIELD_DECL,
1562 long_integer_type_node,
1564 field_decl_chain = field_decl;
1568 field_decl = create_builtin_decl (FIELD_DECL,
1569 build_pointer_type (objc_selector_type),
1571 chainon (field_decl_chain, field_decl);
1573 /* short cls_def_cnt; */
1575 field_decl = create_builtin_decl (FIELD_DECL,
1576 short_integer_type_node,
1578 chainon (field_decl_chain, field_decl);
1580 /* short cat_def_cnt; */
1582 field_decl = create_builtin_decl (FIELD_DECL,
1583 short_integer_type_node,
1585 chainon (field_decl_chain, field_decl);
1587 if (imp_count || cat_count || !flag_next_runtime)
1589 /* void *defs[imp_count + cat_count (+ 1)]; */
1590 /* NB: The index is one less than the size of the array. */
1591 int index = imp_count + cat_count
1592 + (flag_next_runtime? -1: 0);
1593 field_decl = create_builtin_decl
1597 build_index_type (build_int_2 (index, 0))),
1599 chainon (field_decl_chain, field_decl);
1602 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1605 /* Create the initial value for the `defs' field of _objc_symtab.
1606 This is a CONSTRUCTOR. */
1609 init_def_list (tree type)
1611 tree expr, initlist = NULL_TREE;
1612 struct imp_entry *impent;
1615 for (impent = imp_list; impent; impent = impent->next)
1617 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1619 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1620 initlist = tree_cons (NULL_TREE, expr, initlist);
1625 for (impent = imp_list; impent; impent = impent->next)
1627 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1629 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1630 initlist = tree_cons (NULL_TREE, expr, initlist);
1634 if (!flag_next_runtime)
1636 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1639 if (static_instances_decl)
1640 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1642 expr = build_int_2 (0, 0);
1644 initlist = tree_cons (NULL_TREE, expr, initlist);
1647 return objc_build_constructor (type, nreverse (initlist));
1650 /* Construct the initial value for all of _objc_symtab. */
1653 init_objc_symtab (tree type)
1657 /* sel_ref_cnt = { ..., 5, ... } */
1659 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1661 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1663 if (flag_next_runtime || ! sel_ref_chain)
1664 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1666 initlist = tree_cons (NULL_TREE,
1667 build_unary_op (ADDR_EXPR,
1668 UOBJC_SELECTOR_TABLE_decl, 1),
1671 /* cls_def_cnt = { ..., 5, ... } */
1673 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1675 /* cat_def_cnt = { ..., 5, ... } */
1677 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1679 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1681 if (imp_count || cat_count || !flag_next_runtime)
1684 tree field = TYPE_FIELDS (type);
1685 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1687 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1691 return objc_build_constructor (type, nreverse (initlist));
1694 /* Generate forward declarations for metadata such as
1695 'OBJC_CLASS_...'. */
1698 build_metadata_decl (const char *name, tree type)
1700 tree decl, decl_specs;
1701 /* extern struct TYPE NAME_<name>; */
1702 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1703 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1704 decl = define_decl (synth_id_with_class_suffix
1706 objc_implementation_context),
1708 TREE_USED (decl) = 1;
1709 DECL_ARTIFICIAL (decl) = 1;
1710 TREE_PUBLIC (decl) = 0;
1714 /* Push forward-declarations of all the categories so that
1715 init_def_list can use them in a CONSTRUCTOR. */
1718 forward_declare_categories (void)
1720 struct imp_entry *impent;
1721 tree sav = objc_implementation_context;
1723 for (impent = imp_list; impent; impent = impent->next)
1725 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1727 /* Set an invisible arg to synth_id_with_class_suffix. */
1728 objc_implementation_context = impent->imp_context;
1729 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1730 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1731 objc_category_template);
1734 objc_implementation_context = sav;
1737 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1738 and initialized appropriately. */
1741 generate_objc_symtab_decl (void)
1745 if (!objc_category_template)
1746 build_category_template ();
1748 /* forward declare categories */
1750 forward_declare_categories ();
1752 if (!objc_symtab_template)
1753 build_objc_symtab_template ();
1755 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1757 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1758 tree_cons (NULL_TREE,
1759 objc_symtab_template, sc_spec),
1763 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1764 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1765 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1766 finish_decl (UOBJC_SYMBOLS_decl,
1767 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1772 init_module_descriptor (tree type)
1774 tree initlist, expr;
1776 /* version = { 1, ... } */
1778 expr = build_int_2 (OBJC_VERSION, 0);
1779 initlist = build_tree_list (NULL_TREE, expr);
1781 /* size = { ..., sizeof (struct objc_module), ... } */
1783 expr = size_in_bytes (objc_module_template);
1784 initlist = tree_cons (NULL_TREE, expr, initlist);
1786 /* name = { ..., "foo.m", ... } */
1788 expr = add_objc_string (get_identifier (input_filename), class_names);
1789 initlist = tree_cons (NULL_TREE, expr, initlist);
1791 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1793 if (UOBJC_SYMBOLS_decl)
1794 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1796 expr = build_int_2 (0, 0);
1797 initlist = tree_cons (NULL_TREE, expr, initlist);
1799 return objc_build_constructor (type, nreverse (initlist));
1802 /* Write out the data structures to describe Objective C classes defined.
1803 If appropriate, compile and output a setup function to initialize them.
1804 Return a symbol_ref to the function to call to initialize the Objective C
1805 data structures for this file (and perhaps for other files also).
1807 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1810 build_module_descriptor (void)
1812 tree decl_specs, field_decl, field_decl_chain;
1814 objc_module_template
1815 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1819 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1820 field_decl = get_identifier ("version");
1821 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1822 field_decl_chain = field_decl;
1826 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1827 field_decl = get_identifier ("size");
1828 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1829 chainon (field_decl_chain, field_decl);
1833 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1834 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1835 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1836 chainon (field_decl_chain, field_decl);
1838 /* struct objc_symtab *symtab; */
1840 decl_specs = get_identifier (UTAG_SYMTAB);
1841 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1842 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1843 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1844 chainon (field_decl_chain, field_decl);
1846 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1848 /* Create an instance of "objc_module". */
1850 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1851 build_tree_list (NULL_TREE,
1852 ridpointers[(int) RID_STATIC]));
1854 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1855 decl_specs, 1, NULL_TREE);
1857 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1858 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1859 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1861 finish_decl (UOBJC_MODULES_decl,
1862 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1865 /* Mark the decl to avoid "defined but not used" warning. */
1866 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1868 mark_decl_referenced (UOBJC_MODULES_decl);
1870 /* Generate a constructor call for the module descriptor.
1871 This code was generated by reading the grammar rules
1872 of c-parse.in; Therefore, it may not be the most efficient
1873 way of generating the requisite code. */
1875 if (flag_next_runtime)
1879 tree parms, execclass_decl, decelerator, void_list_node_1;
1880 tree init_function_name, init_function_decl, compound;
1882 /* Declare void __objc_execClass (void *); */
1884 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1885 execclass_decl = build_decl (FUNCTION_DECL,
1886 get_identifier (TAG_EXECCLASS),
1887 build_function_type (void_type_node,
1888 tree_cons (NULL_TREE, ptr_type_node,
1891 DECL_EXTERNAL (execclass_decl) = 1;
1892 DECL_ARTIFICIAL (execclass_decl) = 1;
1893 TREE_PUBLIC (execclass_decl) = 1;
1894 pushdecl (execclass_decl);
1895 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1896 assemble_external (execclass_decl);
1898 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1900 init_function_name = get_file_function_name ('I');
1901 start_function (void_list_node_1,
1902 build_nt (CALL_EXPR, init_function_name,
1903 tree_cons (NULL_TREE, NULL_TREE,
1907 store_parm_decls ();
1908 compound = c_begin_compound_stmt (true);
1910 init_function_decl = current_function_decl;
1911 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1912 TREE_USED (init_function_decl) = 1;
1913 /* Don't let this one be deferred. */
1914 DECL_INLINE (init_function_decl) = 0;
1915 DECL_UNINLINABLE (init_function_decl) = 1;
1918 = build_tree_list (NULL_TREE,
1919 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1920 decelerator = build_function_call (execclass_decl, parms);
1922 add_stmt (decelerator);
1923 add_stmt (c_end_compound_stmt (compound, true));
1927 return XEXP (DECL_RTL (init_function_decl), 0);
1931 /* Return the DECL of the string IDENT in the SECTION. */
1934 get_objc_string_decl (tree ident, enum string_section section)
1938 if (section == class_names)
1939 chain = class_names_chain;
1940 else if (section == meth_var_names)
1941 chain = meth_var_names_chain;
1942 else if (section == meth_var_types)
1943 chain = meth_var_types_chain;
1947 for (; chain != 0; chain = TREE_CHAIN (chain))
1948 if (TREE_VALUE (chain) == ident)
1949 return (TREE_PURPOSE (chain));
1955 /* Output references to all statically allocated objects. Return the DECL
1956 for the array built. */
1959 generate_static_references (void)
1961 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1962 tree class_name, class, decl, initlist;
1963 tree cl_chain, in_chain;
1964 int num_inst, num_class;
1967 if (flag_next_runtime)
1970 for (cl_chain = objc_static_instances, num_class = 0;
1971 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1973 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1974 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1976 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1977 ident = get_identifier (buf);
1979 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
1980 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1981 build_tree_list (NULL_TREE,
1982 ridpointers[(int) RID_STATIC]));
1983 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1984 DECL_CONTEXT (decl) = 0;
1985 DECL_ARTIFICIAL (decl) = 1;
1986 TREE_USED (decl) = 1;
1988 /* Output {class_name, ...}. */
1989 class = TREE_VALUE (cl_chain);
1990 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
1991 initlist = build_tree_list (NULL_TREE,
1992 build_unary_op (ADDR_EXPR, class_name, 1));
1994 /* Output {..., instance, ...}. */
1995 for (in_chain = TREE_PURPOSE (cl_chain);
1996 in_chain; in_chain = TREE_CHAIN (in_chain))
1998 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1999 initlist = tree_cons (NULL_TREE, expr, initlist);
2002 /* Output {..., NULL}. */
2003 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2005 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2006 finish_decl (decl, expr, NULL_TREE);
2008 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2011 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2012 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2013 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
2014 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2015 build_tree_list (NULL_TREE,
2016 ridpointers[(int) RID_STATIC]));
2017 static_instances_decl
2018 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2019 TREE_USED (static_instances_decl) = 1;
2020 DECL_CONTEXT (static_instances_decl) = 0;
2021 DECL_ARTIFICIAL (static_instances_decl) = 1;
2022 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2024 finish_decl (static_instances_decl, expr, NULL_TREE);
2025 rest_of_decl_compilation (static_instances_decl, 0, 0, 0);
2028 /* Output all strings. */
2031 generate_strings (void)
2033 tree sc_spec, decl_specs, expr_decl;
2034 tree chain, string_expr;
2037 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2039 string = TREE_VALUE (chain);
2040 decl = TREE_PURPOSE (chain);
2042 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2043 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2044 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2045 NULL_TREE, NULL_TREE);
2046 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2047 DECL_CONTEXT (decl) = NULL_TREE;
2048 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2049 IDENTIFIER_POINTER (string));
2050 finish_decl (decl, string_expr, NULL_TREE);
2053 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2055 string = TREE_VALUE (chain);
2056 decl = TREE_PURPOSE (chain);
2058 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2059 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2060 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2061 NULL_TREE, NULL_TREE);
2062 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2063 DECL_CONTEXT (decl) = NULL_TREE;
2064 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2065 IDENTIFIER_POINTER (string));
2066 finish_decl (decl, string_expr, NULL_TREE);
2069 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2071 string = TREE_VALUE (chain);
2072 decl = TREE_PURPOSE (chain);
2074 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2075 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2076 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2077 NULL_TREE, NULL_TREE);
2078 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2079 DECL_CONTEXT (decl) = NULL_TREE;
2080 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2081 IDENTIFIER_POINTER (string));
2082 finish_decl (decl, string_expr, NULL_TREE);
2086 static GTY(()) int selector_reference_idx;
2089 build_selector_reference_decl (void)
2094 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2096 ident = get_identifier (buf);
2098 decl = build_decl (VAR_DECL, ident, objc_selector_type);
2099 DECL_EXTERNAL (decl) = 1;
2100 TREE_PUBLIC (decl) = 0;
2101 TREE_USED (decl) = 1;
2102 DECL_ARTIFICIAL (decl) = 1;
2103 DECL_CONTEXT (decl) = 0;
2105 make_decl_rtl (decl, 0);
2106 pushdecl_top_level (decl);
2111 /* Just a handy wrapper for add_objc_string. */
2114 build_selector (tree ident)
2116 tree expr = add_objc_string (ident, meth_var_names);
2117 if (flag_typed_selectors)
2120 return build_c_cast (objc_selector_type, expr); /* cast! */
2124 build_selector_translation_table (void)
2126 tree sc_spec, decl_specs;
2127 tree chain, initlist = NULL_TREE;
2129 tree decl = NULL_TREE, var_decl, name;
2131 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2135 if (warn_selector && objc_implementation_context)
2139 for (method_chain = meth_var_names_chain;
2141 method_chain = TREE_CHAIN (method_chain))
2143 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2151 /* Adjust line number for warning message. */
2152 int save_lineno = input_line;
2153 if (flag_next_runtime && TREE_PURPOSE (chain))
2154 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2155 warning ("creating selector for non existant method %s",
2156 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2157 input_line = save_lineno;
2161 expr = build_selector (TREE_VALUE (chain));
2163 if (flag_next_runtime)
2165 name = DECL_NAME (TREE_PURPOSE (chain));
2167 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2169 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2170 decl_specs = tree_cons (NULL_TREE, objc_selector_type, sc_spec);
2174 /* The `decl' that is returned from start_decl is the one that we
2175 forward declared in `build_selector_reference' */
2176 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2179 /* add one for the '\0' character */
2180 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2182 if (flag_next_runtime)
2183 finish_decl (decl, expr, NULL_TREE);
2186 if (flag_typed_selectors)
2188 tree eltlist = NULL_TREE;
2189 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2190 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2191 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2192 expr = objc_build_constructor (objc_selector_template,
2193 nreverse (eltlist));
2195 initlist = tree_cons (NULL_TREE, expr, initlist);
2200 if (! flag_next_runtime)
2202 /* Cause the variable and its initial value to be actually output. */
2203 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2204 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2205 /* NULL terminate the list and fix the decl for output. */
2206 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2207 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2208 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2209 nreverse (initlist));
2210 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2211 current_function_decl = NULL_TREE;
2216 get_proto_encoding (tree proto)
2221 if (! METHOD_ENCODING (proto))
2223 encoding = encode_method_prototype (proto);
2224 METHOD_ENCODING (proto) = encoding;
2227 encoding = METHOD_ENCODING (proto);
2229 return add_objc_string (encoding, meth_var_types);
2232 return build_int_2 (0, 0);
2235 /* sel_ref_chain is a list whose "value" fields will be instances of
2236 identifier_node that represent the selector. */
2239 build_typed_selector_reference (tree ident, tree prototype)
2241 tree *chain = &sel_ref_chain;
2247 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2248 goto return_at_index;
2251 chain = &TREE_CHAIN (*chain);
2254 *chain = tree_cons (prototype, ident, NULL_TREE);
2257 expr = build_unary_op (ADDR_EXPR,
2258 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2259 build_int_2 (index, 0)),
2261 return build_c_cast (objc_selector_type, expr);
2265 build_selector_reference (tree ident)
2267 tree *chain = &sel_ref_chain;
2273 if (TREE_VALUE (*chain) == ident)
2274 return (flag_next_runtime
2275 ? TREE_PURPOSE (*chain)
2276 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2277 build_int_2 (index, 0)));
2280 chain = &TREE_CHAIN (*chain);
2283 expr = build_selector_reference_decl ();
2285 *chain = tree_cons (expr, ident, NULL_TREE);
2287 return (flag_next_runtime
2289 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2290 build_int_2 (index, 0)));
2293 static GTY(()) int class_reference_idx;
2296 build_class_reference_decl (void)
2301 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2303 ident = get_identifier (buf);
2305 decl = build_decl (VAR_DECL, ident, objc_class_type);
2306 DECL_EXTERNAL (decl) = 1;
2307 TREE_PUBLIC (decl) = 0;
2308 TREE_USED (decl) = 1;
2309 DECL_CONTEXT (decl) = 0;
2310 DECL_ARTIFICIAL (decl) = 1;
2312 make_decl_rtl (decl, 0);
2313 pushdecl_top_level (decl);
2318 /* Create a class reference, but don't create a variable to reference
2322 add_class_reference (tree ident)
2326 if ((chain = cls_ref_chain))
2331 if (ident == TREE_VALUE (chain))
2335 chain = TREE_CHAIN (chain);
2339 /* Append to the end of the list */
2340 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2343 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2346 /* Get a class reference, creating it if necessary. Also create the
2347 reference variable. */
2350 get_class_reference (tree ident)
2355 if (processing_template_decl)
2356 /* Must wait until template instantiation time. */
2357 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2358 if (TREE_CODE (ident) == TYPE_DECL)
2359 ident = DECL_NAME (ident);
2363 if (!(ident = is_class_name (ident)))
2365 error ("`%s' is not an Objective-C class name or alias",
2366 IDENTIFIER_POINTER (orig_ident));
2367 return error_mark_node;
2370 if (flag_next_runtime && !flag_zero_link)
2375 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2376 if (TREE_VALUE (*chain) == ident)
2378 if (! TREE_PURPOSE (*chain))
2379 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2381 return TREE_PURPOSE (*chain);
2384 decl = build_class_reference_decl ();
2385 *chain = tree_cons (decl, ident, NULL_TREE);
2392 add_class_reference (ident);
2394 params = build_tree_list (NULL_TREE,
2395 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2396 IDENTIFIER_POINTER (ident)));
2398 assemble_external (objc_get_class_decl);
2399 return build_function_call (objc_get_class_decl, params);
2403 /* For each string section we have a chain which maps identifier nodes
2404 to decls for the strings. */
2407 add_objc_string (tree ident, enum string_section section)
2411 if (section == class_names)
2412 chain = &class_names_chain;
2413 else if (section == meth_var_names)
2414 chain = &meth_var_names_chain;
2415 else if (section == meth_var_types)
2416 chain = &meth_var_types_chain;
2422 if (TREE_VALUE (*chain) == ident)
2423 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2425 chain = &TREE_CHAIN (*chain);
2428 decl = build_objc_string_decl (section);
2430 *chain = tree_cons (decl, ident, NULL_TREE);
2432 return build_unary_op (ADDR_EXPR, decl, 1);
2435 static GTY(()) int class_names_idx;
2436 static GTY(()) int meth_var_names_idx;
2437 static GTY(()) int meth_var_types_idx;
2440 build_objc_string_decl (enum string_section section)
2445 if (section == class_names)
2446 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2447 else if (section == meth_var_names)
2448 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2449 else if (section == meth_var_types)
2450 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2452 ident = get_identifier (buf);
2454 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2455 DECL_EXTERNAL (decl) = 1;
2456 TREE_PUBLIC (decl) = 0;
2457 TREE_USED (decl) = 1;
2458 TREE_CONSTANT (decl) = 1;
2459 DECL_CONTEXT (decl) = 0;
2460 DECL_ARTIFICIAL (decl) = 1;
2462 make_decl_rtl (decl, 0);
2463 pushdecl_top_level (decl);
2470 objc_declare_alias (tree alias_ident, tree class_ident)
2472 tree underlying_class;
2475 if (current_namespace != global_namespace) {
2476 error ("Objective-C declarations may only appear in global scope");
2478 #endif /* OBJCPLUS */
2480 if (!(underlying_class = is_class_name (class_ident)))
2481 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2482 else if (is_class_name (alias_ident))
2483 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2485 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2489 objc_declare_class (tree ident_list)
2493 if (current_namespace != global_namespace) {
2494 error ("Objective-C declarations may only appear in global scope");
2496 #endif /* OBJCPLUS */
2498 for (list = ident_list; list; list = TREE_CHAIN (list))
2500 tree ident = TREE_VALUE (list);
2502 if (! is_class_name (ident))
2504 tree record = lookup_name (ident);
2506 if (record && ! TREE_STATIC_TEMPLATE (record))
2508 error ("`%s' redeclared as different kind of symbol",
2509 IDENTIFIER_POINTER (ident));
2510 error ("%Jprevious declaration of '%D'",
2514 record = xref_tag (RECORD_TYPE, ident);
2515 TREE_STATIC_TEMPLATE (record) = 1;
2516 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2522 is_class_name (tree ident)
2526 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2527 && identifier_global_value (ident))
2528 ident = identifier_global_value (ident);
2529 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2530 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2533 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2534 ident = TYPE_NAME (ident);
2535 if (ident && TREE_CODE (ident) == TYPE_DECL)
2536 ident = DECL_NAME (ident);
2538 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2541 if (lookup_interface (ident))
2544 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2546 if (ident == TREE_VALUE (chain))
2550 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2552 if (ident == TREE_VALUE (chain))
2553 return TREE_PURPOSE (chain);
2559 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2560 class instance. This is needed by other parts of the compiler to
2561 handle ObjC types gracefully. */
2564 objc_is_object_ptr (tree type)
2566 type = TYPE_MAIN_VARIANT (type);
2567 if (!type || TREE_CODE (type) != POINTER_TYPE)
2569 /* NB: This function may be called before the ObjC front-end has
2570 been initialized, in which case OBJC_ID_TYPE will be NULL. */
2571 if (objc_id_type && type && TYPE_P (type)
2573 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2575 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2579 lookup_interface (tree ident)
2584 if (ident && TREE_CODE (ident) == TYPE_DECL)
2585 ident = DECL_NAME (ident);
2587 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2589 if (ident == CLASS_NAME (chain))
2595 /* Implement @defs (<classname>) within struct bodies. */
2598 get_class_ivars_from_name (tree class_name)
2600 tree interface = lookup_interface (class_name);
2601 tree field, fields = NULL_TREE;
2605 tree raw_ivar = get_class_ivars (interface, 1);
2607 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2608 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2610 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2611 TREE_PURPOSE (raw_ivar),
2612 TREE_VALUE (TREE_VALUE (raw_ivar)));
2614 finish_member_declaration (field);
2616 fields = chainon (fields, field);
2621 error ("cannot find interface declaration for `%s'",
2622 IDENTIFIER_POINTER (class_name));
2627 /* Used by: build_private_template, continue_class,
2628 and for @defs constructs. */
2631 get_class_ivars (tree interface, int raw)
2633 tree my_name, super_name, ivar_chain;
2635 my_name = CLASS_NAME (interface);
2636 super_name = CLASS_SUPER_NAME (interface);
2638 ivar_chain = CLASS_RAW_IVARS (interface);
2641 ivar_chain = CLASS_IVARS (interface);
2642 /* Save off a pristine copy of the leaf ivars (i.e, those not
2643 inherited from a super class). */
2644 if (!CLASS_OWN_IVARS (interface))
2645 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2651 tree super_interface = lookup_interface (super_name);
2653 if (!super_interface)
2655 /* fatal did not work with 2 args...should fix */
2656 error ("cannot find interface declaration for `%s', superclass of `%s'",
2657 IDENTIFIER_POINTER (super_name),
2658 IDENTIFIER_POINTER (my_name));
2659 exit (FATAL_EXIT_CODE);
2662 if (super_interface == interface)
2663 fatal_error ("circular inheritance in interface declaration for `%s'",
2664 IDENTIFIER_POINTER (super_name));
2666 interface = super_interface;
2667 my_name = CLASS_NAME (interface);
2668 super_name = CLASS_SUPER_NAME (interface);
2670 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2673 tree head = copy_list (op1);
2675 /* Prepend super class ivars...make a copy of the list, we
2676 do not want to alter the original. */
2677 chainon (head, ivar_chain);
2686 objc_create_temporary_var (tree type)
2690 decl = build_decl (VAR_DECL, NULL_TREE, type);
2691 TREE_USED (decl) = 1;
2692 DECL_ARTIFICIAL (decl) = 1;
2693 DECL_IGNORED_P (decl) = 1;
2694 DECL_CONTEXT (decl) = current_function_decl;
2699 /* Exception handling constructs. We begin by having the parser do most
2700 of the work and passing us blocks. What we do next depends on whether
2701 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2702 We abstract all of this in a handful of appropriately named routines. */
2704 /* Stack of open try blocks. */
2706 struct objc_try_context
2708 struct objc_try_context *outer;
2710 /* Statements (or statement lists) as processed by the parser. */
2714 /* Some file position locations. */
2715 location_t try_locus;
2716 location_t end_try_locus;
2717 location_t end_catch_locus;
2718 location_t finally_locus;
2719 location_t end_finally_locus;
2721 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2722 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2725 /* The CATCH_EXPR of an open @catch clause. */
2728 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2734 static struct objc_try_context *cur_try_context;
2736 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2737 that represents TYPE. For Objective-C, this is just the class name. */
2738 /* ??? Isn't there a class object or some such? Is it easy to get? */
2741 objc_eh_runtime_type (tree type)
2743 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2746 /* Initialize exception handling. */
2749 objc_init_exceptions (void)
2751 static bool done = false;
2757 if (!flag_objc_exceptions)
2758 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2759 "exception syntax");
2761 if (!flag_objc_sjlj_exceptions)
2763 c_eh_initialized_p = true;
2764 eh_personality_libfunc
2765 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2766 ? "__gnu_objc_personality_sj0"
2767 : "__gnu_objc_personality_v0");
2768 using_eh_for_cleanups ();
2769 lang_eh_runtime_type = objc_eh_runtime_type;
2773 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2774 we'll arrange for it to be initialized (and associated with a binding)
2778 objc_build_exc_ptr (void)
2780 if (flag_objc_sjlj_exceptions)
2782 tree var = cur_try_context->caught_decl;
2785 var = objc_create_temporary_var (objc_id_type);
2786 cur_try_context->caught_decl = var;
2791 return build (EXC_PTR_EXPR, objc_id_type);
2794 /* Build "objc_exception_try_exit(&_stack)". */
2797 next_sjlj_build_try_exit (void)
2800 t = build_fold_addr_expr (cur_try_context->stack_decl);
2801 t = tree_cons (NULL, t, NULL);
2802 t = build_function_call (objc_exception_try_exit_decl, t);
2807 objc_exception_try_enter (&_stack);
2808 if (_setjmp(&_stack.buf))
2812 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2813 empty, ready for the caller to fill them in. */
2816 next_sjlj_build_enter_and_setjmp (void)
2818 tree t, enter, sj, cond;
2820 t = build_fold_addr_expr (cur_try_context->stack_decl);
2821 t = tree_cons (NULL, t, NULL);
2822 enter = build_function_call (objc_exception_try_enter_decl, t);
2824 t = build_component_ref (cur_try_context->stack_decl,
2825 get_identifier ("buf"));
2826 t = build_fold_addr_expr (t);
2827 t = convert (ptr_type_node, t);
2828 t = tree_cons (NULL, t, NULL);
2829 sj = build_function_call (objc_setjmp_decl, t);
2831 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2832 cond = lang_hooks.truthvalue_conversion (cond);
2834 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2838 DECL = objc_exception_extract(&_stack);
2842 next_sjlj_build_exc_extract (tree decl)
2846 t = build_fold_addr_expr (cur_try_context->stack_decl);
2847 t = tree_cons (NULL, t, NULL);
2848 t = build_function_call (objc_exception_extract_decl, t);
2849 t = convert (TREE_TYPE (decl), t);
2850 t = build (MODIFY_EXPR, void_type_node, decl, t);
2856 if (objc_exception_match(obj_get_class(TYPE), _caught)
2863 objc_exception_try_exit(&_stack);
2865 from the sequence of CATCH_EXPRs in the current try context. */
2868 next_sjlj_build_catch_list (void)
2870 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
2872 tree *last = &catch_seq;
2873 bool saw_id = false;
2875 for (; !tsi_end_p (i); tsi_next (&i))
2877 tree stmt = tsi_stmt (i);
2878 tree type = CATCH_TYPES (stmt);
2879 tree body = CATCH_BODY (stmt);
2891 if (type == error_mark_node)
2892 cond = error_mark_node;
2895 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
2896 t = get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
2897 args = tree_cons (NULL, t, args);
2898 t = build_function_call (objc_exception_match_decl, args);
2899 cond = lang_hooks.truthvalue_conversion (t);
2901 t = build (COND_EXPR, void_type_node, cond, body, NULL);
2902 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
2905 last = &COND_EXPR_ELSE (t);
2911 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
2912 cur_try_context->caught_decl);
2913 annotate_with_locus (t, cur_try_context->end_catch_locus);
2914 append_to_statement_list (t, last);
2916 t = next_sjlj_build_try_exit ();
2917 annotate_with_locus (t, cur_try_context->end_catch_locus);
2918 append_to_statement_list (t, last);
2924 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
2925 exception handling. We aim to build:
2928 struct _objc_exception_data _stack;
2929 id volatile _rethrow = 0;
2932 objc_exception_try_enter (&_stack);
2933 if (_setjmp(&_stack.buf))
2935 id _caught = objc_exception_extract(&_stack);
2936 objc_exception_try_enter (&_stack);
2937 if (_setjmp(&_stack.buf))
2938 _rethrow = objc_exception_extract(&_stack);
2948 objc_exception_try_exit(&_stack);
2951 objc_exception_throw(_rethrow);
2955 If CATCH-LIST is empty, we can omit all of the block containing
2956 "_caught" except for the setting of _rethrow. Note the use of
2957 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
2958 but handles goto and other exits from the block. */
2961 next_sjlj_build_try_catch_finally (void)
2963 tree rethrow_decl, stack_decl, t;
2964 tree catch_seq, try_fin, bind;
2966 /* Create the declarations involved. */
2967 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
2968 stack_decl = objc_create_temporary_var (t);
2969 cur_try_context->stack_decl = stack_decl;
2971 rethrow_decl = objc_create_temporary_var (objc_id_type);
2972 cur_try_context->rethrow_decl = rethrow_decl;
2973 TREE_THIS_VOLATILE (rethrow_decl) = 1;
2974 TREE_CHAIN (rethrow_decl) = stack_decl;
2976 /* Build the outermost varible binding level. */
2977 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
2978 annotate_with_locus (bind, cur_try_context->try_locus);
2979 TREE_SIDE_EFFECTS (bind) = 1;
2981 /* Initialize rethrow_decl. */
2982 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
2983 convert (objc_id_type, null_pointer_node));
2984 annotate_with_locus (t, cur_try_context->try_locus);
2985 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
2987 /* Build the outermost TRY_FINALLY_EXPR. */
2988 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
2989 annotate_with_locus (try_fin, cur_try_context->try_locus);
2990 TREE_SIDE_EFFECTS (try_fin) = 1;
2991 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
2993 /* Create the complete catch sequence. */
2994 if (cur_try_context->catch_list)
2996 tree caught_decl = objc_build_exc_ptr ();
2997 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
2999 t = next_sjlj_build_exc_extract (caught_decl);
3000 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3002 t = next_sjlj_build_enter_and_setjmp ();
3003 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3004 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3005 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3008 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3009 annotate_with_locus (catch_seq, cur_try_context->end_try_locus);
3011 /* Build the main register-and-try if statement. */
3012 t = next_sjlj_build_enter_and_setjmp ();
3013 annotate_with_locus (t, cur_try_context->try_locus);
3014 COND_EXPR_THEN (t) = catch_seq;
3015 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3016 TREE_OPERAND (try_fin, 0) = t;
3018 /* Build the complete FINALLY statement list. */
3019 t = next_sjlj_build_try_exit ();
3020 t = build_stmt (COND_EXPR,
3021 lang_hooks.truthvalue_conversion (rethrow_decl),
3023 annotate_with_locus (t, cur_try_context->finally_locus);
3024 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3026 append_to_statement_list (cur_try_context->finally_body,
3027 &TREE_OPERAND (try_fin, 1));
3029 t = tree_cons (NULL, rethrow_decl, NULL);
3030 t = build_function_call (objc_exception_throw_decl, t);
3031 t = build_stmt (COND_EXPR,
3032 lang_hooks.truthvalue_conversion (rethrow_decl),
3034 annotate_with_locus (t, cur_try_context->end_finally_locus);
3035 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3040 /* Called just after parsing the @try and its associated BODY. We now
3041 must prepare for the tricky bits -- handling the catches and finally. */
3044 objc_begin_try_stmt (location_t try_locus, tree body)
3046 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3047 c->outer = cur_try_context;
3049 c->try_locus = try_locus;
3050 c->end_try_locus = input_location;
3051 cur_try_context = c;
3053 objc_init_exceptions ();
3056 /* Called just after parsing "@catch (parm)". Open a binding level,
3057 enter PARM into the binding level, and initialize it. Leave the
3058 binding level open while the body of the compound statement is parsed. */
3061 objc_begin_catch_clause (tree parm)
3063 tree compound, decl, type, t;
3065 /* Begin a new scope that the entire catch clause will live in. */
3066 compound = c_begin_compound_stmt (1);
3068 /* Turn the raw declarator/declspecs into a decl in the current scope. */
3069 decl = define_decl (TREE_VALUE (TREE_PURPOSE (parm)),
3070 TREE_PURPOSE (TREE_PURPOSE (parm)));
3072 /* Since a decl is required here by syntax, don't warn if its unused. */
3073 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3074 be what the previous objc implementation did. */
3075 TREE_USED (decl) = 1;
3077 /* Verify that the type of the catch is valid. It must be a pointer
3078 to an Objective-C class, or "id" (which is catch-all). */
3079 type = TREE_TYPE (decl);
3080 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3082 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3084 error ("@catch parameter is not a known Objective-C class type");
3085 type = error_mark_node;
3087 else if (cur_try_context->catch_list)
3089 /* Examine previous @catch clauses and see if we've already
3090 caught the type in question. */
3091 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3092 for (; !tsi_end_p (i); tsi_next (&i))
3094 tree stmt = tsi_stmt (i);
3095 t = CATCH_TYPES (stmt);
3096 if (t == error_mark_node)
3098 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3100 warning ("exception of type %<%T%> will be caught",
3102 warning ("%H by earlier handler for %<%T%>",
3103 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_id_type));
3109 /* Record the data for the catch in the try context so that we can
3110 finalize it later. */
3111 t = build_stmt (CATCH_EXPR, type, compound);
3112 cur_try_context->current_catch = t;
3114 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3115 t = objc_build_exc_ptr ();
3116 t = convert (TREE_TYPE (decl), t);
3117 t = build (MODIFY_EXPR, void_type_node, decl, t);
3121 /* Called just after parsing the closing brace of a @catch clause. Close
3122 the open binding level, and record a CATCH_EXPR for it. */
3125 objc_finish_catch_clause (void)
3127 tree c = cur_try_context->current_catch;
3128 cur_try_context->current_catch = NULL;
3129 cur_try_context->end_catch_locus = input_location;
3131 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3132 append_to_statement_list (c, &cur_try_context->catch_list);
3135 /* Called after parsing a @finally clause and its associated BODY.
3136 Record the body for later placement. */
3139 objc_build_finally_clause (location_t finally_locus, tree body)
3141 cur_try_context->finally_body = body;
3142 cur_try_context->finally_locus = finally_locus;
3143 cur_try_context->end_finally_locus = input_location;
3146 /* Called to finalize a @try construct. */
3149 objc_finish_try_stmt (void)
3151 struct objc_try_context *c = cur_try_context;
3154 if (c->catch_list == NULL && c->finally_body == NULL)
3155 error ("`@try' without `@catch' or `@finally'");
3157 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3158 if (flag_objc_sjlj_exceptions)
3160 if (!cur_try_context->finally_body)
3162 cur_try_context->finally_locus = input_location;
3163 cur_try_context->end_finally_locus = input_location;
3165 stmt = next_sjlj_build_try_catch_finally ();
3169 /* Otherwise, nest the CATCH inside a FINALLY. */
3173 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3174 annotate_with_locus (stmt, cur_try_context->try_locus);
3176 if (c->finally_body)
3178 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3179 annotate_with_locus (stmt, cur_try_context->try_locus);
3184 cur_try_context = c->outer;
3189 objc_build_throw_stmt (tree throw_expr)
3193 objc_init_exceptions ();
3195 if (throw_expr == NULL)
3197 /* If we're not inside a @catch block, there is no "current
3198 exception" to be rethrown. */
3199 if (cur_try_context == NULL
3200 || cur_try_context->current_catch == NULL)
3202 error ("%<@throw%> (rethrow) used outside of a @catch block");
3206 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3207 value that we get from the runtime. */
3208 throw_expr = objc_build_exc_ptr ();
3211 /* A throw is just a call to the runtime throw function with the
3212 object as a parameter. */
3213 args = tree_cons (NULL, throw_expr, NULL);
3214 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3218 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3222 /* First lock the mutex. */
3223 mutex = save_expr (mutex);
3224 args = tree_cons (NULL, mutex, NULL);
3225 call = build_function_call (objc_sync_enter_decl, args);
3226 annotate_with_locus (call, start_locus);
3229 /* Build the mutex unlock. */
3230 args = tree_cons (NULL, mutex, NULL);
3231 call = build_function_call (objc_sync_exit_decl, args);
3232 annotate_with_locus (call, input_location);
3234 /* Put the that and the body in a TRY_FINALLY. */
3235 objc_begin_try_stmt (start_locus, body);
3236 objc_build_finally_clause (input_location, call);
3237 objc_finish_try_stmt ();
3241 /* Predefine the following data type:
3243 struct _objc_exception_data
3249 /* The following yuckiness should prevent users from having to #include
3250 <setjmp.h> in their code... */
3252 #ifdef TARGET_POWERPC
3253 /* snarfed from /usr/include/ppc/setjmp.h */
3254 #define _JBLEN (26 + 36 + 129 + 1)
3256 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3261 build_next_objc_exception_stuff (void)
3263 tree field_decl, field_decl_chain, index, temp_type;
3265 /* Suppress outputting debug symbols, because
3266 dbxout_init hasn't been called yet. */
3267 enum debug_info_type save_write_symbols = write_symbols;
3268 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3270 write_symbols = NO_DEBUG;
3271 debug_hooks = &do_nothing_debug_hooks;
3273 objc_exception_data_template
3274 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3276 /* int buf[_JBLEN]; */
3278 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3279 field_decl = create_builtin_decl (FIELD_DECL,
3280 build_array_type (integer_type_node, index),
3282 field_decl_chain = field_decl;
3284 /* void *pointers[4]; */
3286 index = build_index_type (build_int_2 (4 - 1, 0));
3287 field_decl = create_builtin_decl (FIELD_DECL,
3288 build_array_type (ptr_type_node, index),
3290 chainon (field_decl_chain, field_decl);
3292 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3294 /* int _setjmp(...); */
3295 /* If the user includes <setjmp.h>, this shall be superseded by
3296 'int _setjmp(jmp_buf);' */
3297 temp_type = build_function_type (integer_type_node, NULL_TREE);
3299 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3301 /* id objc_exception_extract(struct _objc_exception_data *); */
3303 = build_function_type (objc_id_type,
3304 tree_cons (NULL_TREE,
3305 build_pointer_type (objc_exception_data_template),
3307 objc_exception_extract_decl
3308 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3309 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3310 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3312 = build_function_type (void_type_node,
3313 tree_cons (NULL_TREE,
3314 build_pointer_type (objc_exception_data_template),
3316 objc_exception_try_enter_decl
3317 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3318 objc_exception_try_exit_decl
3319 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3321 /* int objc_exception_match(id, id); */
3323 = build_function_type (integer_type_node,
3324 tree_cons (NULL_TREE, objc_id_type,
3325 tree_cons (NULL_TREE, objc_id_type,
3327 objc_exception_match_decl
3328 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3330 write_symbols = save_write_symbols;
3331 debug_hooks = save_hooks;
3335 build_objc_exception_stuff (void)
3337 tree noreturn_list, nothrow_list, temp_type;
3339 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3340 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3342 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3343 /* void objc_sync_enter(id); */
3344 /* void objc_sync_exit(id); */
3345 temp_type = build_function_type (void_type_node,
3346 tree_cons (NULL_TREE, objc_id_type,
3348 objc_exception_throw_decl
3349 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3351 objc_sync_enter_decl
3352 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3353 NULL, nothrow_list);
3355 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3356 NULL, nothrow_list);
3360 /* struct <classname> {
3361 struct objc_class *isa;
3366 build_private_template (tree class)
3370 if (CLASS_STATIC_TEMPLATE (class))
3372 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3373 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3377 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3378 ivar_context = get_class_ivars (class, 0);
3380 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3382 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3384 /* mark this record as class template - for class type checking */
3385 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3389 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3391 build1 (INDIRECT_REF, NULL_TREE,
3394 return ivar_context;
3397 /* Begin code generation for protocols... */
3399 /* struct objc_protocol {
3400 char *protocol_name;
3401 struct objc_protocol **protocol_list;
3402 struct objc_method_desc *instance_methods;
3403 struct objc_method_desc *class_methods;
3407 build_protocol_template (void)
3409 tree decl_specs, field_decl, field_decl_chain;
3412 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3414 /* struct objc_class *isa; */
3416 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3417 get_identifier (UTAG_CLASS)));
3418 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3419 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3420 field_decl_chain = field_decl;
3422 /* char *protocol_name; */
3424 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3426 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3427 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3428 chainon (field_decl_chain, field_decl);
3430 /* struct objc_protocol **protocol_list; */
3432 decl_specs = build_tree_list (NULL_TREE, template);
3434 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3435 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3436 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3437 chainon (field_decl_chain, field_decl);
3439 /* struct objc_method_list *instance_methods; */
3442 = build_tree_list (NULL_TREE,
3443 xref_tag (RECORD_TYPE,
3444 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3446 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3447 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3448 chainon (field_decl_chain, field_decl);
3450 /* struct objc_method_list *class_methods; */
3453 = build_tree_list (NULL_TREE,
3454 xref_tag (RECORD_TYPE,
3455 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3457 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3458 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3459 chainon (field_decl_chain, field_decl);
3461 return finish_struct (template, field_decl_chain, NULL_TREE);
3465 build_descriptor_table_initializer (tree type, tree entries)
3467 tree initlist = NULL_TREE;
3471 tree eltlist = NULL_TREE;
3474 = tree_cons (NULL_TREE,
3475 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3477 = tree_cons (NULL_TREE,
3478 add_objc_string (METHOD_ENCODING (entries),
3483 = tree_cons (NULL_TREE,
3484 objc_build_constructor (type, nreverse (eltlist)),
3487 entries = TREE_CHAIN (entries);
3491 return objc_build_constructor (build_array_type (type, 0),
3492 nreverse (initlist));
3495 /* struct objc_method_prototype_list {
3497 struct objc_method_prototype {
3504 build_method_prototype_list_template (tree list_type, int size)
3506 tree objc_ivar_list_record;
3507 tree decl_specs, field_decl, field_decl_chain;
3509 /* Generate an unnamed struct definition. */
3511 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3513 /* int method_count; */
3515 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3516 field_decl = get_identifier ("method_count");
3517 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3518 field_decl_chain = field_decl;
3520 /* struct objc_method method_list[]; */
3522 decl_specs = build_tree_list (NULL_TREE, list_type);
3523 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3524 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
3525 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3526 chainon (field_decl_chain, field_decl);
3528 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3530 return objc_ivar_list_record;
3534 build_method_prototype_template (void)
3537 tree decl_specs, field_decl, field_decl_chain;
3540 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3542 /* struct objc_selector *_cmd; */
3543 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3544 get_identifier (TAG_SELECTOR)), NULL_TREE);
3545 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3546 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3547 field_decl_chain = field_decl;
3549 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3551 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3552 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3553 chainon (field_decl_chain, field_decl);
3555 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3557 return proto_record;
3561 objc_method_parm_type (tree type)
3563 type = groktypename (TREE_TYPE (type));
3564 if (TREE_CODE (type) == TYPE_DECL)
3565 type = TREE_TYPE (type);
3566 return TYPE_MAIN_VARIANT (type);
3570 objc_encoded_type_size (tree type)
3572 int sz = int_size_in_bytes (type);
3574 /* Make all integer and enum types at least as large
3576 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3577 || TREE_CODE (type) == BOOLEAN_TYPE
3578 || TREE_CODE (type) == ENUMERAL_TYPE))
3579 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3580 /* Treat arrays as pointers, since that's how they're
3582 else if (TREE_CODE (type) == ARRAY_TYPE)
3583 sz = int_size_in_bytes (ptr_type_node);
3588 encode_method_prototype (tree method_decl)
3595 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3596 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3598 /* Encode return type. */
3599 encode_type (objc_method_parm_type (method_decl),
3600 obstack_object_size (&util_obstack),
3601 OBJC_ENCODE_INLINE_DEFS);
3604 /* The first two arguments (self and _cmd) are pointers; account for
3606 i = int_size_in_bytes (ptr_type_node);
3607 parm_offset = 2 * i;
3608 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3609 parms = TREE_CHAIN (parms))
3611 tree type = objc_method_parm_type (parms);
3612 int sz = objc_encoded_type_size (type);
3614 /* If a type size is not known, bail out. */
3617 error ("%Jtype '%D' does not have a known size",
3619 /* Pretend that the encoding succeeded; the compilation will
3620 fail nevertheless. */
3621 goto finish_encoding;
3626 sprintf (buf, "%d@0:%d", parm_offset, i);
3627 obstack_grow (&util_obstack, buf, strlen (buf));
3629 /* Argument types. */
3630 parm_offset = 2 * i;
3631 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3632 parms = TREE_CHAIN (parms))
3634 tree type = objc_method_parm_type (parms);
3636 /* Process argument qualifiers for user supplied arguments. */
3637 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3640 encode_type (type, obstack_object_size (&util_obstack),
3641 OBJC_ENCODE_INLINE_DEFS);
3643 /* Compute offset. */
3644 sprintf (buf, "%d", parm_offset);
3645 parm_offset += objc_encoded_type_size (type);
3647 obstack_grow (&util_obstack, buf, strlen (buf));
3651 obstack_1grow (&util_obstack, '\0');
3652 result = get_identifier (obstack_finish (&util_obstack));
3653 obstack_free (&util_obstack, util_firstobj);
3658 generate_descriptor_table (tree type, const char *name, int size, tree list,
3661 tree sc_spec, decl_specs, decl, initlist;
3663 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3664 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3666 decl = start_decl (synth_id_with_class_suffix (name, proto),
3667 decl_specs, 1, NULL_TREE);
3668 DECL_CONTEXT (decl) = NULL_TREE;
3670 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3671 initlist = tree_cons (NULL_TREE, list, initlist);
3673 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3680 generate_method_descriptors (tree protocol)
3682 tree initlist, chain, method_list_template;
3683 tree cast, variable_length_type;
3686 if (!objc_method_prototype_template)
3687 objc_method_prototype_template = build_method_prototype_template ();
3689 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3690 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3692 variable_length_type = groktypename (cast);
3694 chain = PROTOCOL_CLS_METHODS (protocol);
3697 size = list_length (chain);
3699 method_list_template
3700 = build_method_prototype_list_template (objc_method_prototype_template,
3704 = build_descriptor_table_initializer (objc_method_prototype_template,
3707 UOBJC_CLASS_METHODS_decl
3708 = generate_descriptor_table (method_list_template,
3709 "_OBJC_PROTOCOL_CLASS_METHODS",
3710 size, initlist, protocol);
3711 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3714 UOBJC_CLASS_METHODS_decl = 0;
3716 chain = PROTOCOL_NST_METHODS (protocol);
3719 size = list_length (chain);
3721 method_list_template
3722 = build_method_prototype_list_template (objc_method_prototype_template,
3725 = build_descriptor_table_initializer (objc_method_prototype_template,
3728 UOBJC_INSTANCE_METHODS_decl
3729 = generate_descriptor_table (method_list_template,
3730 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3731 size, initlist, protocol);
3732 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3735 UOBJC_INSTANCE_METHODS_decl = 0;
3739 generate_protocol_references (tree plist)
3743 /* Forward declare protocols referenced. */
3744 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3746 tree proto = TREE_VALUE (lproto);
3748 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3749 && PROTOCOL_NAME (proto))
3751 if (! PROTOCOL_FORWARD_DECL (proto))
3752 build_protocol_reference (proto);
3754 if (PROTOCOL_LIST (proto))
3755 generate_protocol_references (PROTOCOL_LIST (proto));
3760 /* For each protocol which was referenced either from a @protocol()
3761 expression, or because a class/category implements it (then a
3762 pointer to the protocol is stored in the struct describing the
3763 class/category), we create a statically allocated instance of the
3764 Protocol class. The code is written in such a way as to generate
3765 as few Protocol objects as possible; we generate a unique Protocol
3766 instance for each protocol, and we don't generate a Protocol
3767 instance if the protocol is never referenced (either from a
3768 @protocol() or from a class/category implementation). These
3769 statically allocated objects can be referred to via the static
3770 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3772 The statically allocated Protocol objects that we generate here
3773 need to be fixed up at runtime in order to be used: the 'isa'
3774 pointer of the objects need to be set up to point to the 'Protocol'
3775 class, as known at runtime.
3777 The NeXT runtime fixes up all protocols at program startup time,
3778 before main() is entered. It uses a low-level trick to look up all
3779 those symbols, then loops on them and fixes them up.
3781 The GNU runtime as well fixes up all protocols before user code
3782 from the module is executed; it requires pointers to those symbols
3783 to be put in the objc_symtab (which is then passed as argument to
3784 the function __objc_exec_class() which the compiler sets up to be
3785 executed automatically when the module is loaded); setup of those
3786 Protocol objects happen in two ways in the GNU runtime: all
3787 Protocol objects referred to by a class or category implementation
3788 are fixed up when the class/category is loaded; all Protocol
3789 objects referred to by a @protocol() expression are added by the
3790 compiler to the list of statically allocated instances to fixup
3791 (the same list holding the statically allocated constant string
3792 objects). Because, as explained above, the compiler generates as
3793 few Protocol objects as possible, some Protocol object might end up
3794 being referenced multiple times when compiled with the GNU runtime,
3795 and end up being fixed up multiple times at runtime inizialization.
3796 But that doesn't hurt, it's just a little inefficient. */
3799 generate_protocols (void)
3802 tree sc_spec, decl_specs, decl;
3803 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3806 if (! objc_protocol_template)
3807 objc_protocol_template = build_protocol_template ();
3809 /* If a protocol was directly referenced, pull in indirect references. */
3810 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3811 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3812 generate_protocol_references (PROTOCOL_LIST (p));
3814 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3816 tree nst_methods = PROTOCOL_NST_METHODS (p);
3817 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3819 /* If protocol wasn't referenced, don't generate any code. */
3820 if (! PROTOCOL_FORWARD_DECL (p))
3823 /* Make sure we link in the Protocol class. */
3824 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3828 if (! METHOD_ENCODING (nst_methods))
3830 encoding = encode_method_prototype (nst_methods);
3831 METHOD_ENCODING (nst_methods) = encoding;
3833 nst_methods = TREE_CHAIN (nst_methods);
3838 if (! METHOD_ENCODING (cls_methods))
3840 encoding = encode_method_prototype (cls_methods);
3841 METHOD_ENCODING (cls_methods) = encoding;
3844 cls_methods = TREE_CHAIN (cls_methods);
3846 generate_method_descriptors (p);
3848 if (PROTOCOL_LIST (p))
3849 refs_decl = generate_protocol_list (p);
3853 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3855 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3857 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3859 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3860 decl_specs, 1, NULL_TREE);
3862 DECL_CONTEXT (decl) = NULL_TREE;
3864 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3870 (build_tree_list (build_tree_list (NULL_TREE,
3871 objc_protocol_template),
3872 build1 (INDIRECT_REF, NULL_TREE,
3873 build1 (INDIRECT_REF, NULL_TREE,
3876 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3877 TREE_TYPE (refs_expr) = cast_type2;
3880 refs_expr = build_int_2 (0, 0);
3882 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3883 by generate_method_descriptors, which is called above. */
3884 initlist = build_protocol_initializer (TREE_TYPE (decl),
3885 protocol_name_expr, refs_expr,
3886 UOBJC_INSTANCE_METHODS_decl,
3887 UOBJC_CLASS_METHODS_decl);
3888 finish_decl (decl, initlist, NULL_TREE);
3890 /* Mark the decl as used to avoid "defined but not used" warning. */
3891 TREE_USED (decl) = 1;
3896 build_protocol_initializer (tree type, tree protocol_name,
3897 tree protocol_list, tree instance_methods,
3900 tree initlist = NULL_TREE, expr;
3903 cast_type = groktypename
3905 (build_tree_list (NULL_TREE,
3906 xref_tag (RECORD_TYPE,
3907 get_identifier (UTAG_CLASS))),
3908 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3910 /* Filling the "isa" in with one allows the runtime system to
3911 detect that the version change...should remove before final release. */
3913 expr = build_int_2 (PROTOCOL_VERSION, 0);
3914 TREE_TYPE (expr) = cast_type;
3915 initlist = tree_cons (NULL_TREE, expr, initlist);
3916 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3917 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3919 if (!instance_methods)
3920 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3923 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3924 initlist = tree_cons (NULL_TREE, expr, initlist);
3928 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3931 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3932 initlist = tree_cons (NULL_TREE, expr, initlist);
3935 return objc_build_constructor (type, nreverse (initlist));
3938 /* struct objc_category {
3939 char *category_name;
3941 struct objc_method_list *instance_methods;
3942 struct objc_method_list *class_methods;
3943 struct objc_protocol_list *protocols;
3947 build_category_template (void)
3949 tree decl_specs, field_decl, field_decl_chain;
3951 objc_category_template = start_struct (RECORD_TYPE,
3952 get_identifier (UTAG_CATEGORY));
3953 /* char *category_name; */
3955 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3957 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3958 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3959 field_decl_chain = field_decl;
3961 /* char *class_name; */
3963 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3964 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3965 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3966 chainon (field_decl_chain, field_decl);
3968 /* struct objc_method_list *instance_methods; */
3970 decl_specs = build_tree_list (NULL_TREE,
3971 xref_tag (RECORD_TYPE,
3972 get_identifier (UTAG_METHOD_LIST)));
3974 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3975 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3976 chainon (field_decl_chain, field_decl);
3978 /* struct objc_method_list *class_methods; */
3980 decl_specs = build_tree_list (NULL_TREE,
3981 xref_tag (RECORD_TYPE,
3982 get_identifier (UTAG_METHOD_LIST)));
3984 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3985 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3986 chainon (field_decl_chain, field_decl);
3988 /* struct objc_protocol **protocol_list; */
3990 decl_specs = build_tree_list (NULL_TREE,
3991 xref_tag (RECORD_TYPE,
3992 get_identifier (UTAG_PROTOCOL)));
3994 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3995 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3996 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3997 chainon (field_decl_chain, field_decl);
3999 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4002 /* struct objc_selector {
4008 build_selector_template (void)
4011 tree decl_specs, field_decl, field_decl_chain;
4013 objc_selector_template
4014 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4018 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4019 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4020 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4021 field_decl_chain = field_decl;
4023 /* char *sel_type; */
4025 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4026 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4027 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4028 chainon (field_decl_chain, field_decl);
4030 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4033 /* struct objc_class {
4034 struct objc_class *isa;
4035 struct objc_class *super_class;
4040 struct objc_ivar_list *ivars;
4041 struct objc_method_list *methods;
4042 if (flag_next_runtime)
4043 struct objc_cache *cache;
4045 struct sarray *dtable;
4046 struct objc_class *subclass_list;
4047 struct objc_class *sibling_class;
4049 struct objc_protocol_list *protocols;
4050 if (flag_next_runtime)
4052 void *gc_object_type;
4055 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4056 the NeXT/Apple runtime; still, the compiler must generate them to
4057 maintain backward binary compatibility (and to allow for future
4061 build_class_template (void)
4063 tree decl_specs, field_decl, field_decl_chain;
4066 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4068 /* struct objc_class *isa; */
4070 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4071 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4072 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4073 field_decl_chain = field_decl;
4075 /* struct objc_class *super_class; */
4077 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4079 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4080 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4081 chainon (field_decl_chain, field_decl);
4085 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4086 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4087 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4088 chainon (field_decl_chain, field_decl);
4092 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4093 field_decl = get_identifier ("version");
4094 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4095 chainon (field_decl_chain, field_decl);
4099 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4100 field_decl = get_identifier ("info");
4101 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4102 chainon (field_decl_chain, field_decl);
4104 /* long instance_size; */
4106 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4107 field_decl = get_identifier ("instance_size");
4108 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4109 chainon (field_decl_chain, field_decl);
4111 /* struct objc_ivar_list *ivars; */
4113 decl_specs = build_tree_list (NULL_TREE,
4114 xref_tag (RECORD_TYPE,
4115 get_identifier (UTAG_IVAR_LIST)));
4116 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4117 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4118 chainon (field_decl_chain, field_decl);
4120 /* struct objc_method_list *methods; */
4122 decl_specs = build_tree_list (NULL_TREE,
4123 xref_tag (RECORD_TYPE,
4124 get_identifier (UTAG_METHOD_LIST)));
4125 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4126 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4127 chainon (field_decl_chain, field_decl);
4129 if (flag_next_runtime)
4131 /* struct objc_cache *cache; */
4133 decl_specs = build_tree_list (NULL_TREE,
4134 xref_tag (RECORD_TYPE,
4135 get_identifier ("objc_cache")));
4136 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4137 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4138 chainon (field_decl_chain, field_decl);
4142 /* struct sarray *dtable; */
4144 decl_specs = build_tree_list (NULL_TREE,
4145 xref_tag (RECORD_TYPE,
4146 get_identifier ("sarray")));
4147 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4148 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4149 chainon (field_decl_chain, field_decl);
4151 /* struct objc_class *subclass_list; */
4153 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4155 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4156 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4157 chainon (field_decl_chain, field_decl);
4159 /* struct objc_class *sibling_class; */
4161 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4163 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4164 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4165 chainon (field_decl_chain, field_decl);
4168 /* struct objc_protocol **protocol_list; */
4170 decl_specs = build_tree_list (NULL_TREE,
4171 xref_tag (RECORD_TYPE,
4172 get_identifier (UTAG_PROTOCOL)));
4174 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4176 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4177 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4178 chainon (field_decl_chain, field_decl);
4180 if (flag_next_runtime)
4184 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4185 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4187 = grokfield (field_decl, decl_specs, NULL_TREE);
4188 chainon (field_decl_chain, field_decl);
4191 /* void *gc_object_type; */
4193 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4194 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4195 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4196 chainon (field_decl_chain, field_decl);
4198 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4201 /* Generate appropriate forward declarations for an implementation. */
4204 synth_forward_declarations (void)
4208 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4209 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4210 objc_class_template);
4212 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4213 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4214 objc_class_template);
4216 mark_decl_referenced (UOBJC_CLASS_decl);
4217 mark_decl_referenced (UOBJC_METACLASS_decl);
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 (TREE_VALUE (TREE_VALUE (rawimpdecls)))
4262 /* t1 is the bit-field type, so t2 must be converted to the
4263 bit-field type for comparison as well. */
4264 unsigned HOST_WIDE_INT width
4265 = tree_low_cst (TREE_VALUE (TREE_VALUE (rawimpdecls)), 1);
4266 if (width != TYPE_PRECISION (t2))
4267 t2 = build_nonstandard_integer_type (width, TYPE_UNSIGNED (t2));
4270 if (!comptypes (t1, t2)
4271 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4272 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4274 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4276 error_with_ivar ("conflicting instance variable type",
4277 impdecls, rawimpdecls);
4278 error_with_ivar ("previous declaration of",
4279 intdecls, rawintdecls);
4281 else /* both the type and the name don't match */
4283 error ("inconsistent instance variable specification");
4288 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4290 error_with_ivar ("conflicting instance variable name",
4291 impdecls, rawimpdecls);
4292 error_with_ivar ("previous declaration of",
4293 intdecls, rawintdecls);
4296 intdecls = TREE_CHAIN (intdecls);
4297 impdecls = TREE_CHAIN (impdecls);
4298 rawintdecls = TREE_CHAIN (rawintdecls);
4299 rawimpdecls = TREE_CHAIN (rawimpdecls);
4303 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4304 This needs to be done just once per compilation. */
4307 build_super_template (void)
4309 tree decl_specs, field_decl, field_decl_chain;
4311 /* Suppress outputting debug symbols, because
4312 dbxout_init hasn't been called yet. */
4313 enum debug_info_type save_write_symbols = write_symbols;
4314 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4316 write_symbols = NO_DEBUG;
4317 debug_hooks = &do_nothing_debug_hooks;
4319 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4321 /* struct objc_object *self; */
4323 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4324 field_decl = get_identifier ("self");
4325 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4326 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4327 field_decl_chain = field_decl;
4330 /* struct objc_class *super_class; */
4332 /* struct objc_class *class; */
4335 decl_specs = get_identifier (UTAG_CLASS);
4336 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4338 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4340 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4343 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4344 chainon (field_decl_chain, field_decl);
4346 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4348 write_symbols = save_write_symbols;
4349 debug_hooks = save_hooks;
4352 /* struct objc_ivar {
4359 build_ivar_template (void)
4361 tree objc_ivar_id, objc_ivar_record;
4362 tree decl_specs, field_decl, field_decl_chain;
4364 objc_ivar_id = get_identifier (UTAG_IVAR);
4365 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4367 /* char *ivar_name; */
4369 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4370 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4372 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4373 field_decl_chain = field_decl;
4375 /* char *ivar_type; */
4377 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4378 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4380 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4381 chainon (field_decl_chain, field_decl);
4383 /* int ivar_offset; */
4385 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4386 field_decl = get_identifier ("ivar_offset");
4388 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4389 chainon (field_decl_chain, field_decl);
4391 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4393 return objc_ivar_record;
4398 struct objc_ivar ivar_list[ivar_count];
4402 build_ivar_list_template (tree list_type, int size)
4404 tree objc_ivar_list_record;
4405 tree decl_specs, field_decl, field_decl_chain;
4407 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4409 /* int ivar_count; */
4411 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4412 field_decl = get_identifier ("ivar_count");
4414 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4415 field_decl_chain = field_decl;
4417 /* struct objc_ivar ivar_list[]; */
4419 decl_specs = build_tree_list (NULL_TREE, list_type);
4420 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4421 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
4423 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4424 chainon (field_decl_chain, field_decl);
4426 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4428 return objc_ivar_list_record;
4434 struct objc_method method_list[method_count];
4438 build_method_list_template (tree list_type, int size)
4440 tree objc_ivar_list_record;
4441 tree decl_specs, field_decl, field_decl_chain;
4443 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4445 /* int method_next; */
4450 xref_tag (RECORD_TYPE,
4451 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4453 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4454 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4455 field_decl_chain = field_decl;
4457 /* int method_count; */
4459 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4460 field_decl = get_identifier ("method_count");
4462 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4463 chainon (field_decl_chain, field_decl);
4465 /* struct objc_method method_list[]; */
4467 decl_specs = build_tree_list (NULL_TREE, list_type);
4468 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4469 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
4471 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4472 chainon (field_decl_chain, field_decl);
4474 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4476 return objc_ivar_list_record;
4480 build_ivar_list_initializer (tree type, tree field_decl)
4482 tree initlist = NULL_TREE;
4486 tree ivar = NULL_TREE;
4489 if (DECL_NAME (field_decl))
4490 ivar = tree_cons (NULL_TREE,
4491 add_objc_string (DECL_NAME (field_decl),
4495 /* Unnamed bit-field ivar (yuck). */
4496 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4499 encode_field_decl (field_decl,
4500 obstack_object_size (&util_obstack),
4501 OBJC_ENCODE_DONT_INLINE_DEFS);
4503 /* Null terminate string. */
4504 obstack_1grow (&util_obstack, 0);
4508 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4511 obstack_free (&util_obstack, util_firstobj);
4514 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4515 initlist = tree_cons (NULL_TREE,
4516 objc_build_constructor (type, nreverse (ivar)),
4519 field_decl = TREE_CHAIN (field_decl);
4520 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4524 return objc_build_constructor (build_array_type (type, 0),
4525 nreverse (initlist));
4529 generate_ivars_list (tree type, const char *name, int size, tree list)
4531 tree sc_spec, decl_specs, decl, initlist;
4533 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4534 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4536 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4537 decl_specs, 1, NULL_TREE);
4539 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4540 initlist = tree_cons (NULL_TREE, list, initlist);
4543 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4549 /* Count only the fields occurring in T. */
4551 ivar_list_length (tree t)
4555 for (; t; t = TREE_CHAIN (t))
4556 if (TREE_CODE (t) == FIELD_DECL)
4563 generate_ivar_lists (void)
4565 tree initlist, ivar_list_template, chain;
4566 tree cast, variable_length_type;
4569 generating_instance_variables = 1;
4571 if (!objc_ivar_template)
4572 objc_ivar_template = build_ivar_template ();
4576 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4577 get_identifier (UTAG_IVAR_LIST))),
4579 variable_length_type = groktypename (cast);
4581 /* Only generate class variables for the root of the inheritance
4582 hierarchy since these will be the same for every class. */
4584 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4585 && (chain = TYPE_FIELDS (objc_class_template)))
4587 size = ivar_list_length (chain);
4589 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4590 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4592 UOBJC_CLASS_VARIABLES_decl
4593 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4595 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4598 UOBJC_CLASS_VARIABLES_decl = 0;
4600 chain = CLASS_IVARS (implementation_template);
4603 size = ivar_list_length (chain);
4604 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4605 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4607 UOBJC_INSTANCE_VARIABLES_decl
4608 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4610 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4613 UOBJC_INSTANCE_VARIABLES_decl = 0;
4615 generating_instance_variables = 0;
4619 build_dispatch_table_initializer (tree type, tree entries)
4621 tree initlist = NULL_TREE;
4625 tree elemlist = NULL_TREE;
4627 elemlist = tree_cons (NULL_TREE,
4628 build_selector (METHOD_SEL_NAME (entries)),
4631 /* Generate the method encoding if we don't have one already. */
4632 if (! METHOD_ENCODING (entries))
4633 METHOD_ENCODING (entries) =
4634 encode_method_prototype (entries);
4636 elemlist = tree_cons (NULL_TREE,
4637 add_objc_string (METHOD_ENCODING (entries),
4641 elemlist = tree_cons (NULL_TREE,
4642 build_unary_op (ADDR_EXPR,
4643 METHOD_DEFINITION (entries), 1),
4646 initlist = tree_cons (NULL_TREE,
4647 objc_build_constructor (type, nreverse (elemlist)),
4650 entries = TREE_CHAIN (entries);
4654 return objc_build_constructor (build_array_type (type, 0),
4655 nreverse (initlist));
4658 /* To accomplish method prototyping without generating all kinds of
4659 inane warnings, the definition of the dispatch table entries were
4662 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4664 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4667 build_method_template (void)
4670 tree decl_specs, field_decl, field_decl_chain;
4672 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4674 /* struct objc_selector *_cmd; */
4675 decl_specs = tree_cons (NULL_TREE,
4676 xref_tag (RECORD_TYPE,
4677 get_identifier (TAG_SELECTOR)),
4679 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4681 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4682 field_decl_chain = field_decl;
4684 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4685 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4686 get_identifier ("method_types"));
4687 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4688 chainon (field_decl_chain, field_decl);
4692 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4693 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4694 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4695 chainon (field_decl_chain, field_decl);
4697 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4704 generate_dispatch_table (tree type, const char *name, int size, tree list)
4706 tree sc_spec, decl_specs, decl, initlist;
4708 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4709 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4711 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4712 decl_specs, 1, NULL_TREE);
4714 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4715 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4716 initlist = tree_cons (NULL_TREE, list, initlist);
4719 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4726 mark_referenced_methods (void)
4728 struct imp_entry *impent;
4731 for (impent = imp_list; impent; impent = impent->next)
4733 chain = CLASS_CLS_METHODS (impent->imp_context);
4736 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4737 chain = TREE_CHAIN (chain);
4740 chain = CLASS_NST_METHODS (impent->imp_context);
4743 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4744 chain = TREE_CHAIN (chain);
4750 generate_dispatch_tables (void)
4752 tree initlist, chain, method_list_template;
4753 tree cast, variable_length_type;
4756 if (!objc_method_template)
4757 objc_method_template = build_method_template ();
4761 (build_tree_list (NULL_TREE,
4762 xref_tag (RECORD_TYPE,
4763 get_identifier (UTAG_METHOD_LIST))),
4766 variable_length_type = groktypename (cast);
4768 chain = CLASS_CLS_METHODS (objc_implementation_context);
4771 size = list_length (chain);
4773 method_list_template
4774 = build_method_list_template (objc_method_template, size);
4776 = build_dispatch_table_initializer (objc_method_template, chain);
4778 UOBJC_CLASS_METHODS_decl
4779 = generate_dispatch_table (method_list_template,
4780 ((TREE_CODE (objc_implementation_context)
4781 == CLASS_IMPLEMENTATION_TYPE)
4782 ? "_OBJC_CLASS_METHODS"
4783 : "_OBJC_CATEGORY_CLASS_METHODS"),
4785 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4788 UOBJC_CLASS_METHODS_decl = 0;
4790 chain = CLASS_NST_METHODS (objc_implementation_context);
4793 size = list_length (chain);
4795 method_list_template
4796 = build_method_list_template (objc_method_template, size);
4798 = build_dispatch_table_initializer (objc_method_template, chain);
4800 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4801 UOBJC_INSTANCE_METHODS_decl
4802 = generate_dispatch_table (method_list_template,
4803 "_OBJC_INSTANCE_METHODS",
4806 /* We have a category. */
4807 UOBJC_INSTANCE_METHODS_decl
4808 = generate_dispatch_table (method_list_template,
4809 "_OBJC_CATEGORY_INSTANCE_METHODS",
4811 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4814 UOBJC_INSTANCE_METHODS_decl = 0;
4818 generate_protocol_list (tree i_or_p)
4820 tree initlist, decl_specs, sc_spec;
4821 tree refs_decl, expr_decl, lproto, e, plist;
4825 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4826 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4827 plist = CLASS_PROTOCOL_LIST (i_or_p);
4828 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4829 plist = PROTOCOL_LIST (i_or_p);
4833 cast_type = groktypename
4835 (build_tree_list (NULL_TREE,
4836 xref_tag (RECORD_TYPE,
4837 get_identifier (UTAG_PROTOCOL))),
4838 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4841 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4842 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4843 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4846 /* Build initializer. */
4847 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4849 e = build_int_2 (size, 0);
4850 TREE_TYPE (e) = cast_type;
4851 initlist = tree_cons (NULL_TREE, e, initlist);
4853 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4855 tree pval = TREE_VALUE (lproto);
4857 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4858 && PROTOCOL_FORWARD_DECL (pval))
4860 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4861 initlist = tree_cons (NULL_TREE, e, initlist);
4865 /* static struct objc_protocol *refs[n]; */
4867 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4868 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4869 get_identifier (UTAG_PROTOCOL)),
4872 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4873 expr_decl = build_nt (ARRAY_REF,
4874 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4876 build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
4877 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4878 expr_decl = build_nt (ARRAY_REF,
4879 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4881 build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
4882 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4884 = build_nt (ARRAY_REF,
4885 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4887 build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
4891 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4893 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4894 DECL_CONTEXT (refs_decl) = NULL_TREE;
4896 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4897 nreverse (initlist)),
4904 build_category_initializer (tree type, tree cat_name, tree class_name,
4905 tree instance_methods, tree class_methods,
4908 tree initlist = NULL_TREE, expr;
4910 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4911 initlist = tree_cons (NULL_TREE, class_name, initlist);
4913 if (!instance_methods)
4914 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4917 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4918 initlist = tree_cons (NULL_TREE, expr, initlist);
4921 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4924 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4925 initlist = tree_cons (NULL_TREE, expr, initlist);
4928 /* protocol_list = */
4930 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4933 tree cast_type2 = groktypename
4935 (build_tree_list (NULL_TREE,
4936 xref_tag (RECORD_TYPE,
4937 get_identifier (UTAG_PROTOCOL))),
4938 build1 (INDIRECT_REF, NULL_TREE,
4939 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4941 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4942 TREE_TYPE (expr) = cast_type2;
4943 initlist = tree_cons (NULL_TREE, expr, initlist);
4946 return objc_build_constructor (type, nreverse (initlist));
4949 /* struct objc_class {
4950 struct objc_class *isa;
4951 struct objc_class *super_class;
4956 struct objc_ivar_list *ivars;
4957 struct objc_method_list *methods;
4958 if (flag_next_runtime)
4959 struct objc_cache *cache;
4961 struct sarray *dtable;
4962 struct objc_class *subclass_list;
4963 struct objc_class *sibling_class;
4965 struct objc_protocol_list *protocols;
4966 if (flag_next_runtime)
4968 void *gc_object_type;
4972 build_shared_structure_initializer (tree type, tree isa, tree super,
4973 tree name, tree size, int status,
4974 tree dispatch_table, tree ivar_list,
4977 tree initlist = NULL_TREE, expr;
4980 initlist = tree_cons (NULL_TREE, isa, initlist);
4983 initlist = tree_cons (NULL_TREE, super, initlist);
4986 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4989 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4992 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4994 /* instance_size = */
4995 initlist = tree_cons (NULL_TREE, size, initlist);
4997 /* objc_ivar_list = */
4999 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5002 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
5003 initlist = tree_cons (NULL_TREE, expr, initlist);
5006 /* objc_method_list = */
5007 if (!dispatch_table)
5008 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5011 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
5012 initlist = tree_cons (NULL_TREE, expr, initlist);
5015 if (flag_next_runtime)
5016 /* method_cache = */
5017 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5021 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5023 /* subclass_list = */
5024 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5026 /* sibling_class = */
5027 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5030 /* protocol_list = */
5031 if (! protocol_list)
5032 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5038 (build_tree_list (NULL_TREE,
5039 xref_tag (RECORD_TYPE,
5040 get_identifier (UTAG_PROTOCOL))),
5041 build1 (INDIRECT_REF, NULL_TREE,
5042 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5044 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5045 TREE_TYPE (expr) = cast_type2;
5046 initlist = tree_cons (NULL_TREE, expr, initlist);
5049 if (flag_next_runtime)
5051 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5053 /* gc_object_type = NULL */
5054 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5056 return objc_build_constructor (type, nreverse (initlist));
5059 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5062 lookup_category (tree class, tree cat_name)
5064 tree category = CLASS_CATEGORY_LIST (class);
5066 while (category && CLASS_SUPER_NAME (category) != cat_name)
5067 category = CLASS_CATEGORY_LIST (category);
5071 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5074 generate_category (tree cat)
5076 tree sc_spec, decl_specs, decl;
5077 tree initlist, cat_name_expr, class_name_expr;
5078 tree protocol_decl, category;
5080 add_class_reference (CLASS_NAME (cat));
5081 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5083 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5085 category = lookup_category (implementation_template,
5086 CLASS_SUPER_NAME (cat));
5088 if (category && CLASS_PROTOCOL_LIST (category))
5090 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5091 protocol_decl = generate_protocol_list (category);
5096 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5097 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5099 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5100 objc_implementation_context),
5101 decl_specs, 1, NULL_TREE);
5103 initlist = build_category_initializer (TREE_TYPE (decl),
5104 cat_name_expr, class_name_expr,
5105 UOBJC_INSTANCE_METHODS_decl,
5106 UOBJC_CLASS_METHODS_decl,
5109 finish_decl (decl, initlist, NULL_TREE);
5112 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5113 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5116 generate_shared_structures (void)
5118 tree sc_spec, decl_specs, decl;
5119 tree name_expr, super_expr, root_expr;
5120 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5121 tree cast_type, initlist, protocol_decl;
5123 my_super_id = CLASS_SUPER_NAME (implementation_template);
5126 add_class_reference (my_super_id);
5128 /* Compute "my_root_id" - this is required for code generation.
5129 the "isa" for all meta class structures points to the root of
5130 the inheritance hierarchy (e.g. "__Object")... */
5131 my_root_id = my_super_id;
5134 tree my_root_int = lookup_interface (my_root_id);
5136 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5137 my_root_id = CLASS_SUPER_NAME (my_root_int);
5144 /* No super class. */
5145 my_root_id = CLASS_NAME (implementation_template);
5148 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5149 objc_class_template),
5150 build1 (INDIRECT_REF,
5151 NULL_TREE, NULL_TREE)));
5153 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5156 /* Install class `isa' and `super' pointers at runtime. */
5159 super_expr = add_objc_string (my_super_id, class_names);
5160 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5163 super_expr = build_int_2 (0, 0);
5165 root_expr = add_objc_string (my_root_id, class_names);
5166 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5168 if (CLASS_PROTOCOL_LIST (implementation_template))
5170 generate_protocol_references
5171 (CLASS_PROTOCOL_LIST (implementation_template));
5172 protocol_decl = generate_protocol_list (implementation_template);
5177 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5179 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5180 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5182 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5186 = build_shared_structure_initializer
5188 root_expr, super_expr, name_expr,
5189 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5191 UOBJC_CLASS_METHODS_decl,
5192 UOBJC_CLASS_VARIABLES_decl,
5195 finish_decl (decl, initlist, NULL_TREE);
5197 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5199 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5203 = build_shared_structure_initializer
5205 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5206 super_expr, name_expr,
5207 convert (integer_type_node,
5208 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5209 (implementation_template))),
5211 UOBJC_INSTANCE_METHODS_decl,
5212 UOBJC_INSTANCE_VARIABLES_decl,
5215 finish_decl (decl, initlist, NULL_TREE);
5219 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5222 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5223 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5225 const char *const class_name
5226 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5227 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5228 sprintf (string, "%s_%s", preamble,
5229 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5231 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5232 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5234 /* We have a category. */
5235 const char *const class_name
5236 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5237 const char *const class_super_name
5238 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5239 string = (char *) alloca (strlen (preamble)
5240 + strlen (class_name)
5241 + strlen (class_super_name)
5243 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5245 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5247 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5249 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5250 sprintf (string, "%s_%s", preamble, protocol_name);
5255 return get_identifier (string);
5259 is_objc_type_qualifier (tree node)
5261 return (TREE_CODE (node) == IDENTIFIER_NODE
5262 && (node == ridpointers [(int) RID_CONST]
5263 || node == ridpointers [(int) RID_VOLATILE]
5264 || node == ridpointers [(int) RID_IN]
5265 || node == ridpointers [(int) RID_OUT]
5266 || node == ridpointers [(int) RID_INOUT]
5267 || node == ridpointers [(int) RID_BYCOPY]
5268 || node == ridpointers [(int) RID_BYREF]
5269 || node == ridpointers [(int) RID_ONEWAY]));
5272 /* If type is empty or only type qualifiers are present, add default
5273 type of id (otherwise grokdeclarator will default to int). */
5276 adjust_type_for_id_default (tree type)
5278 tree declspecs, chain;
5281 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5282 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5284 declspecs = TREE_PURPOSE (type);
5286 /* Determine if a typespec is present. */
5287 for (chain = declspecs;
5289 chain = TREE_CHAIN (chain))
5291 if (TYPED_OBJECT (TREE_VALUE (chain))
5292 && !(TREE_VALUE (type)
5293 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5294 error ("can not use an object as parameter to a method\n");
5295 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5299 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5301 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5306 selector ':' '(' typename ')' identifier
5309 Transform an Objective-C keyword argument into
5310 the C equivalent parameter declarator.
5312 In: key_name, an "identifier_node" (optional).
5313 arg_type, a "tree_list" (optional).
5314 arg_name, an "identifier_node".
5316 Note: It would be really nice to strongly type the preceding
5317 arguments in the function prototype; however, then I
5318 could not use the "accessor" macros defined in "tree.h".
5320 Out: an instance of "keyword_decl". */
5323 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5327 /* If no type is specified, default to "id". */
5328 arg_type = adjust_type_for_id_default (arg_type);
5330 keyword_decl = make_node (KEYWORD_DECL);
5332 TREE_TYPE (keyword_decl) = arg_type;
5333 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5334 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5336 return keyword_decl;
5339 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5342 build_keyword_selector (tree selector)
5345 tree key_chain, key_name;
5348 /* Scan the selector to see how much space we'll need. */
5349 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5351 if (TREE_CODE (selector) == KEYWORD_DECL)
5352 key_name = KEYWORD_KEY_NAME (key_chain);
5353 else if (TREE_CODE (selector) == TREE_LIST)
5354 key_name = TREE_PURPOSE (key_chain);
5359 len += IDENTIFIER_LENGTH (key_name) + 1;
5361 /* Just a ':' arg. */
5365 buf = (char *) alloca (len + 1);
5366 /* Start the buffer out as an empty string. */
5369 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5371 if (TREE_CODE (selector) == KEYWORD_DECL)
5372 key_name = KEYWORD_KEY_NAME (key_chain);
5373 else if (TREE_CODE (selector) == TREE_LIST)
5375 key_name = TREE_PURPOSE (key_chain);
5376 /* The keyword decl chain will later be used as a function argument
5377 chain. Unhook the selector itself so as to not confuse other
5378 parts of the compiler. */
5379 TREE_PURPOSE (key_chain) = NULL_TREE;
5385 strcat (buf, IDENTIFIER_POINTER (key_name));
5389 return get_identifier (buf);
5392 /* Used for declarations and definitions. */
5395 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5400 /* If no type is specified, default to "id". */
5401 ret_type = adjust_type_for_id_default (ret_type);
5403 method_decl = make_node (code);
5404 TREE_TYPE (method_decl) = ret_type;
5406 /* If we have a keyword selector, create an identifier_node that
5407 represents the full selector name (`:' included)... */
5408 if (TREE_CODE (selector) == KEYWORD_DECL)
5410 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5411 METHOD_SEL_ARGS (method_decl) = selector;
5412 METHOD_ADD_ARGS (method_decl) = add_args;
5416 METHOD_SEL_NAME (method_decl) = selector;
5417 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5418 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5424 #define METHOD_DEF 0
5425 #define METHOD_REF 1
5427 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5428 an argument list for method METH. CONTEXT is either METHOD_DEF or
5429 METHOD_REF, saying whether we are trying to define a method or call
5430 one. SUPERFLAG says this is for a send to super; this makes a
5431 difference for the NeXT calling sequence in which the lookup and
5432 the method call are done together. If METH is null, user-defined
5433 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5436 get_arg_type_list (tree meth, int context, int superflag)
5440 /* Receiver type. */
5441 if (flag_next_runtime && superflag)
5442 arglist = build_tree_list (NULL_TREE, objc_super_type);
5443 else if (context == METHOD_DEF)
5444 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5446 arglist = build_tree_list (NULL_TREE, objc_id_type);
5448 /* Selector type - will eventually change to `int'. */
5449 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5451 /* No actual method prototype given -- assume that remaining arguments
5456 /* Build a list of argument types. */
5457 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5459 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5460 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5463 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5464 /* We have a `, ...' immediately following the selector,
5465 finalize the arglist...simulate get_parm_info (true). */
5467 else if (METHOD_ADD_ARGS (meth))
5469 /* we have a variable length selector */
5470 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5471 chainon (arglist, add_arg_list);
5474 /* finalize the arglist...simulate get_parm_info (false) */
5475 chainon (arglist, void_list_node);
5481 check_duplicates (hash hsh, int methods, int is_class)
5483 tree meth = NULL_TREE;
5491 /* We have two or more methods with the same name but
5495 warning ("multiple %s named `%c%s' found",
5496 methods ? "methods" : "selectors",
5497 (is_class ? '+' : '-'),
5498 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5500 warn_with_method (methods ? "using" : "found",
5501 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5505 for (loop = hsh->list; loop; loop = loop->next)
5506 warn_with_method ("also found",
5507 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5516 /* If RECEIVER is a class reference, return the identifier node for
5517 the referenced class. RECEIVER is created by get_class_reference,
5518 so we check the exact form created depending on which runtimes are
5522 receiver_is_class_object (tree receiver, int self, int super)
5524 tree chain, exp, arg;
5526 /* The receiver is 'self' or 'super' in the context of a class method. */
5527 if (objc_method_context
5528 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5531 ? CLASS_SUPER_NAME (implementation_template)
5532 : CLASS_NAME (implementation_template));
5534 if (flag_next_runtime)
5536 /* The receiver is a variable created by
5537 build_class_reference_decl. */
5538 if (TREE_CODE (receiver) == VAR_DECL
5539 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5540 /* Look up the identifier. */
5541 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5542 if (TREE_PURPOSE (chain) == receiver)
5543 return TREE_VALUE (chain);
5546 /* The receiver is a function call that returns an id. Check if
5547 it is a call to objc_getClass, if so, pick up the class name. */
5548 if (TREE_CODE (receiver) == CALL_EXPR
5549 && (exp = TREE_OPERAND (receiver, 0))
5550 && TREE_CODE (exp) == ADDR_EXPR
5551 && (exp = TREE_OPERAND (exp, 0))
5552 && TREE_CODE (exp) == FUNCTION_DECL
5553 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5554 prototypes for objc_get_class(). Thankfully, they seem to share the
5555 same function type. */
5556 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5557 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5558 /* We have a call to objc_get_class/objc_getClass! */
5559 && (arg = TREE_OPERAND (receiver, 1))
5560 && TREE_CODE (arg) == TREE_LIST
5561 && (arg = TREE_VALUE (arg)))
5564 if (TREE_CODE (arg) == ADDR_EXPR
5565 && (arg = TREE_OPERAND (arg, 0))
5566 && TREE_CODE (arg) == STRING_CST)
5567 /* Finally, we have the class name. */
5568 return get_identifier (TREE_STRING_POINTER (arg));
5573 /* If we are currently building a message expr, this holds
5574 the identifier of the selector of the message. This is
5575 used when printing warnings about argument mismatches. */
5577 static tree current_objc_message_selector = 0;
5580 objc_message_selector (void)
5582 return current_objc_message_selector;
5585 /* Construct an expression for sending a message.
5586 MESS has the object to send to in TREE_PURPOSE
5587 and the argument list (including selector) in TREE_VALUE.
5589 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5590 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5593 build_message_expr (tree mess)
5595 tree receiver = TREE_PURPOSE (mess);
5597 tree args = TREE_VALUE (mess);
5598 tree method_params = NULL_TREE;
5600 if (TREE_CODE (receiver) == ERROR_MARK)
5601 return error_mark_node;
5603 /* Obtain the full selector name. */
5604 if (TREE_CODE (args) == IDENTIFIER_NODE)
5605 /* A unary selector. */
5607 else if (TREE_CODE (args) == TREE_LIST)
5608 sel_name = build_keyword_selector (args);
5612 /* Build the parameter list to give to the method. */
5613 if (TREE_CODE (args) == TREE_LIST)
5615 tree chain = args, prev = NULL_TREE;
5617 /* We have a keyword selector--check for comma expressions. */
5620 tree element = TREE_VALUE (chain);
5622 /* We have a comma expression, must collapse... */
5623 if (TREE_CODE (element) == TREE_LIST)
5626 TREE_CHAIN (prev) = element;
5631 chain = TREE_CHAIN (chain);
5633 method_params = args;
5637 if (processing_template_decl)
5638 /* Must wait until template instantiation time. */
5639 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5643 return finish_message_expr (receiver, sel_name, method_params);
5646 /* Look up method SEL_NAME that would be suitable for receiver
5647 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5648 nonzero), and report on any duplicates. */
5651 lookup_method_in_hash_lists (tree sel_name, int is_class)
5653 hash method_prototype = NULL;
5656 method_prototype = hash_lookup (nst_method_hash_list,
5659 if (!method_prototype)
5661 method_prototype = hash_lookup (cls_method_hash_list,
5666 return check_duplicates (method_prototype, 1, is_class);
5669 /* The 'finish_message_expr' routine is called from within
5670 'build_message_expr' for non-template functions. In the case of
5671 C++ template functions, it is called from 'build_expr_from_tree'
5672 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5675 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5677 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5678 tree selector, retval, class_tree;
5679 int self, super, have_cast;
5681 /* Extract the receiver of the message, as well as its type
5682 (where the latter may take the form of a cast or be inferred
5683 from the implementation context). */
5685 while (TREE_CODE (rtype) == COMPOUND_EXPR
5686 || TREE_CODE (rtype) == MODIFY_EXPR
5687 || TREE_CODE (rtype) == NOP_EXPR
5688 || TREE_CODE (rtype) == COMPONENT_REF)
5689 rtype = TREE_OPERAND (rtype, 0);
5690 self = (rtype == self_decl);
5691 super = (rtype == UOBJC_SUPER_decl);
5692 rtype = TREE_TYPE (receiver);
5693 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5694 || (TREE_CODE (receiver) == COMPOUND_EXPR
5695 && !IS_SUPER (rtype)));
5697 /* If the receiver is a class object, retrieve the corresponding
5698 @interface, if one exists. */
5699 class_tree = receiver_is_class_object (receiver, self, super);
5701 /* Now determine the receiver type (if an explicit cast has not been
5706 rtype = lookup_interface (class_tree);
5707 /* Handle `self' and `super'. */
5710 if (!CLASS_SUPER_NAME (implementation_template))
5712 error ("no super class declared in @interface for `%s'",
5713 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5714 return error_mark_node;
5716 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5719 rtype = lookup_interface (CLASS_NAME (implementation_template));
5722 /* If receiver is of type `id' or `Class' (or if the @interface for a
5723 class is not visible), we shall be satisfied with the existence of
5724 any instance or class method. */
5725 if (!rtype || IS_ID (rtype)
5726 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5729 rtype = xref_tag (RECORD_TYPE, class_tree);
5730 else if (IS_ID (rtype))
5732 rprotos = TYPE_PROTOCOL_LIST (rtype);
5736 class_tree = TYPE_NAME (rtype) = get_identifier ("Class");
5740 = lookup_method_in_protocol_list (rprotos, sel_name,
5741 class_tree != NULL_TREE);
5742 if (!method_prototype && !rprotos)
5744 = lookup_method_in_hash_lists (sel_name,
5745 class_tree != NULL_TREE);
5749 tree orig_rtype = rtype, saved_rtype;
5751 if (TREE_CODE (rtype) == POINTER_TYPE)
5752 rtype = TREE_TYPE (rtype);
5753 /* Traverse typedef aliases */
5754 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5755 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5756 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5757 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5758 saved_rtype = rtype;
5759 if (TYPED_OBJECT (rtype))
5761 rprotos = TYPE_PROTOCOL_LIST (rtype);
5762 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5764 /* If we could not find an @interface declaration, we must have
5765 only seen a @class declaration; so, we cannot say anything
5766 more intelligent about which methods the receiver will
5769 rtype = saved_rtype;
5770 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5771 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5773 /* We have a valid ObjC class name. Look up the method name
5774 in the published @interface for the class (and its
5777 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5779 /* If the method was not found in the @interface, it may still
5780 exist locally as part of the @implementation. */
5781 if (!method_prototype && objc_implementation_context
5782 && CLASS_NAME (objc_implementation_context)
5783 == OBJC_TYPE_NAME (rtype))
5787 ? CLASS_CLS_METHODS (objc_implementation_context)
5788 : CLASS_NST_METHODS (objc_implementation_context)),
5791 /* If we haven't found a candidate method by now, try looking for
5792 it in the protocol list. */
5793 if (!method_prototype && rprotos)
5795 = lookup_method_in_protocol_list (rprotos, sel_name,
5796 class_tree != NULL_TREE);
5800 warning ("invalid receiver type `%s'",
5801 gen_declaration (orig_rtype, errbuf));
5802 rtype = rprotos = NULL_TREE;
5806 if (!method_prototype)
5808 static bool warn_missing_methods = false;
5811 warning ("`%s' may not respond to `%c%s'",
5812 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5813 (class_tree ? '+' : '-'),
5814 IDENTIFIER_POINTER (sel_name));
5816 warning ("`%c%s' not implemented by protocol(s)",
5817 (class_tree ? '+' : '-'),
5818 IDENTIFIER_POINTER (sel_name));
5819 if (!warn_missing_methods)
5821 warning ("(Messages without a matching method signature");
5822 warning ("will be assumed to return `id' and accept");
5823 warning ("`...' as arguments.)");
5824 warn_missing_methods = true;
5828 /* Save the selector name for printing error messages. */
5829 current_objc_message_selector = sel_name;
5831 /* Build the parameters list for looking up the method.
5832 These are the object itself and the selector. */
5834 if (flag_typed_selectors)
5835 selector = build_typed_selector_reference (sel_name, method_prototype);
5837 selector = build_selector_reference (sel_name);
5839 retval = build_objc_method_call (super, method_prototype,
5841 selector, method_params);
5843 current_objc_message_selector = 0;
5848 /* Build a tree expression to send OBJECT the operation SELECTOR,
5849 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5850 assuming the method has prototype METHOD_PROTOTYPE.
5851 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5852 Use METHOD_PARAMS as list of args to pass to the method.
5853 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5856 build_objc_method_call (int super_flag, tree method_prototype,
5857 tree lookup_object, tree selector,
5860 tree sender = (super_flag ? umsg_super_decl :
5861 (!flag_next_runtime || flag_nil_receivers
5863 : umsg_nonnil_decl));
5864 tree rcv_p = (super_flag ? objc_super_type : objc_id_type);
5866 /* If a prototype for the method to be called exists, then cast
5867 the sender's return type and arguments to match that of the method.
5868 Otherwise, leave sender as is. */
5871 ? groktypename (TREE_TYPE (method_prototype))
5874 = build_pointer_type
5875 (build_function_type
5878 (method_prototype, METHOD_REF, super_flag)));
5881 lookup_object = build_c_cast (rcv_p, lookup_object);
5883 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5884 lookup_object = save_expr (lookup_object);
5886 if (flag_next_runtime)
5888 /* If we are returning a struct in memory, and the address
5889 of that memory location is passed as a hidden first
5890 argument, then change which messenger entry point this
5891 expr will call. NB: Note that sender_cast remains
5892 unchanged (it already has a struct return type). */
5893 if (!targetm.calls.struct_value_rtx (0, 0)
5894 && (TREE_CODE (ret_type) == RECORD_TYPE
5895 || TREE_CODE (ret_type) == UNION_TYPE)
5896 && targetm.calls.return_in_memory (ret_type, 0))
5897 sender = (super_flag ? umsg_super_stret_decl :
5898 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5900 method_params = tree_cons (NULL_TREE, lookup_object,
5901 tree_cons (NULL_TREE, selector,
5903 method = build_fold_addr_expr (sender);
5907 /* This is the portable (GNU) way. */
5910 /* First, call the lookup function to get a pointer to the method,
5911 then cast the pointer, then call it with the method arguments. */
5913 object = (super_flag ? self_decl : lookup_object);
5915 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5916 t = tree_cons (NULL_TREE, lookup_object, t);
5917 method = build_function_call (sender, t);
5919 /* Pass the object to the method. */
5920 method_params = tree_cons (NULL_TREE, object,
5921 tree_cons (NULL_TREE, selector,
5925 /* ??? Selector is not at this point something we can use inside
5926 the compiler itself. Set it to garbage for the nonce. */
5927 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5928 return build_function_call (t, method_params);
5932 build_protocol_reference (tree p)
5934 tree decl, ident, ptype;
5936 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5938 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5940 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5941 objc_protocol_template),
5944 if (identifier_global_value (ident))
5945 decl = identifier_global_value (ident); /* Set by pushdecl. */
5948 decl = build_decl (VAR_DECL, ident, ptype);
5949 DECL_EXTERNAL (decl) = 1;
5950 TREE_PUBLIC (decl) = 0;
5951 TREE_USED (decl) = 1;
5952 DECL_ARTIFICIAL (decl) = 1;
5954 make_decl_rtl (decl, 0);
5955 pushdecl_top_level (decl);
5958 PROTOCOL_FORWARD_DECL (p) = decl;
5961 /* This function is called by the parser when (and only when) a
5962 @protocol() expression is found, in order to compile it. */
5964 build_protocol_expr (tree protoname)
5967 tree p = lookup_protocol (protoname);
5971 error ("cannot find protocol declaration for `%s'",
5972 IDENTIFIER_POINTER (protoname));
5973 return error_mark_node;
5976 if (!PROTOCOL_FORWARD_DECL (p))
5977 build_protocol_reference (p);
5979 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5981 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5982 if we have it, rather than converting it here. */
5983 expr = convert (objc_protocol_type, expr);
5985 /* The @protocol() expression is being compiled into a pointer to a
5986 statically allocated instance of the Protocol class. To become
5987 usable at runtime, the 'isa' pointer of the instance need to be
5988 fixed up at runtime by the runtime library, to point to the
5989 actual 'Protocol' class. */
5991 /* For the GNU runtime, put the static Protocol instance in the list
5992 of statically allocated instances, so that we make sure that its
5993 'isa' pointer is fixed up at runtime by the GNU runtime library
5994 to point to the Protocol class (at runtime, when loading the
5995 module, the GNU runtime library loops on the statically allocated
5996 instances (as found in the defs field in objc_symtab) and fixups
5997 all the 'isa' pointers of those objects). */
5998 if (! flag_next_runtime)
6000 /* This type is a struct containing the fields of a Protocol
6001 object. (Cfr. objc_protocol_type instead is the type of a pointer
6002 to such a struct). */
6003 tree protocol_struct_type = xref_tag
6004 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6007 /* Look for the list of Protocol statically allocated instances
6008 to fixup at runtime. Create a new list to hold Protocol
6009 statically allocated instances, if the list is not found. At
6010 present there is only another list, holding NSConstantString
6011 static instances to be fixed up at runtime. */
6012 for (chain = &objc_static_instances;
6013 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6014 chain = &TREE_CHAIN (*chain));
6017 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6018 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6022 /* Add this statically allocated instance to the Protocol list. */
6023 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6024 PROTOCOL_FORWARD_DECL (p),
6025 TREE_PURPOSE (*chain));
6032 /* This function is called by the parser when a @selector() expression
6033 is found, in order to compile it. It is only called by the parser
6034 and only to compile a @selector(). */
6036 build_selector_expr (tree selnamelist)
6040 /* Obtain the full selector name. */
6041 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6042 /* A unary selector. */
6043 selname = selnamelist;
6044 else if (TREE_CODE (selnamelist) == TREE_LIST)
6045 selname = build_keyword_selector (selnamelist);
6049 /* If we are required to check @selector() expressions as they
6050 are found, check that the selector has been declared. */
6051 if (warn_undeclared_selector)
6053 /* Look the selector up in the list of all known class and
6054 instance methods (up to this line) to check that the selector
6058 /* First try with instance methods. */
6059 hsh = hash_lookup (nst_method_hash_list, selname);
6061 /* If not found, try with class methods. */
6064 hsh = hash_lookup (cls_method_hash_list, selname);
6067 /* If still not found, print out a warning. */
6070 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6075 if (flag_typed_selectors)
6076 return build_typed_selector_reference (selname, 0);
6078 return build_selector_reference (selname);
6082 build_encode_expr (tree type)
6087 encode_type (type, obstack_object_size (&util_obstack),
6088 OBJC_ENCODE_INLINE_DEFS);
6089 obstack_1grow (&util_obstack, 0); /* null terminate string */
6090 string = obstack_finish (&util_obstack);
6092 /* Synthesize a string that represents the encoded struct/union. */
6093 result = my_build_string (strlen (string) + 1, string);
6094 obstack_free (&util_obstack, util_firstobj);
6099 build_ivar_reference (tree id)
6101 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6103 /* Historically, a class method that produced objects (factory
6104 method) would assign `self' to the instance that it
6105 allocated. This would effectively turn the class method into
6106 an instance method. Following this assignment, the instance
6107 variables could be accessed. That practice, while safe,
6108 violates the simple rule that a class method should not refer
6109 to an instance variable. It's better to catch the cases
6110 where this is done unknowingly than to support the above
6112 warning ("instance variable `%s' accessed in class method",
6113 IDENTIFIER_POINTER (id));
6114 TREE_TYPE (self_decl) = objc_instance_type; /* cast */
6117 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6120 /* Compute a hash value for a given method SEL_NAME. */
6123 hash_func (tree sel_name)
6125 const unsigned char *s
6126 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6130 h = h * 67 + *s++ - 113;
6137 nst_method_hash_list
6138 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6139 cls_method_hash_list
6140 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6143 /* WARNING!!!! hash_enter is called with a method, and will peek
6144 inside to find its selector! But hash_lookup is given a selector
6145 directly, and looks for the selector that's inside the found
6146 entry's key (method) for comparison. */
6149 hash_enter (hash *hashlist, tree method)
6152 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6154 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6156 obj->next = hashlist[slot];
6159 hashlist[slot] = obj; /* append to front */
6163 hash_lookup (hash *hashlist, tree sel_name)
6167 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6171 if (sel_name == METHOD_SEL_NAME (target->key))
6174 target = target->next;
6180 hash_add_attr (hash entry, tree value)
6184 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6185 obj->next = entry->list;
6188 entry->list = obj; /* append to front */
6192 lookup_method (tree mchain, tree method)
6196 if (TREE_CODE (method) == IDENTIFIER_NODE)
6199 key = METHOD_SEL_NAME (method);
6203 if (METHOD_SEL_NAME (mchain) == key)
6206 mchain = TREE_CHAIN (mchain);
6212 lookup_method_static (tree interface, tree ident, int is_class)
6214 tree meth = NULL_TREE, root_inter = NULL_TREE;
6215 tree inter = interface;
6219 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6220 tree category = inter;
6222 /* First, look up the method in the class itself. */
6223 if ((meth = lookup_method (chain, ident)))
6226 /* Failing that, look for the method in each category of the class. */
6227 while ((category = CLASS_CATEGORY_LIST (category)))
6229 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6231 /* Check directly in each category. */
6232 if ((meth = lookup_method (chain, ident)))
6235 /* Failing that, check in each category's protocols. */
6236 if (CLASS_PROTOCOL_LIST (category))
6238 if ((meth = (lookup_method_in_protocol_list
6239 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6244 /* If not found in categories, check in protocols of the main class. */
6245 if (CLASS_PROTOCOL_LIST (inter))
6247 if ((meth = (lookup_method_in_protocol_list
6248 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6252 /* Failing that, climb up the inheritance hierarchy. */
6254 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6258 /* If no class (factory) method was found, check if an _instance_
6259 method of the same name exists in the root class. This is what
6260 the Objective-C runtime will do. If an instance method was not
6262 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6265 /* Add the method to the hash list if it doesn't contain an identical
6268 add_method_to_hash_list (hash *hash_list, tree method)
6272 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6274 /* Install on a global chain. */
6275 hash_enter (hash_list, method);
6279 /* Check types against those; if different, add to a list. */
6281 int already_there = comp_proto_with_proto (method, hsh->key);
6282 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6283 already_there |= comp_proto_with_proto (method, loop->value);
6285 hash_add_attr (hsh, method);
6290 objc_add_method (tree class, tree method, int is_class)
6294 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6296 /* put method on list in reverse order */
6299 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6300 CLASS_CLS_METHODS (class) = method;
6304 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6305 CLASS_NST_METHODS (class) = method;
6310 /* When processing an @interface for a class or category, give hard
6311 errors on methods with identical selectors but differing argument
6312 and/or return types. We do not do this for @implementations, because
6313 C/C++ will do it for us (i.e., there will be duplicate function
6314 definition errors). */
6315 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6316 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6317 && !comp_proto_with_proto (method, mth))
6318 error ("duplicate declaration of method `%c%s'",
6319 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6323 add_method_to_hash_list (cls_method_hash_list, method);
6326 add_method_to_hash_list (nst_method_hash_list, method);
6328 /* Instance methods in root classes (and categories thereof)
6329 may acts as class methods as a last resort. */
6330 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6331 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6332 class = lookup_interface (CLASS_NAME (class));
6334 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6335 && !CLASS_SUPER_NAME (class))
6336 add_method_to_hash_list (cls_method_hash_list, method);
6343 add_class (tree class)
6345 /* Put interfaces on list in reverse order. */
6346 TREE_CHAIN (class) = interface_chain;
6347 interface_chain = class;
6348 return interface_chain;
6352 add_category (tree class, tree category)
6354 /* Put categories on list in reverse order. */
6355 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6359 warning ("duplicate interface declaration for category `%s(%s)'",
6360 IDENTIFIER_POINTER (CLASS_NAME (class)),
6361 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6365 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6366 CLASS_CATEGORY_LIST (class) = category;
6370 /* Called after parsing each instance variable declaration. Necessary to
6371 preserve typedefs and implement public/private...
6373 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6376 add_instance_variable (tree class, int public, tree declarator,
6377 tree declspecs, tree width)
6379 tree field_decl = grokfield (declarator, declspecs, width);
6380 tree field_type = TREE_TYPE (field_decl);
6381 const char *ivar_name = DECL_NAME (field_decl)
6382 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6387 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6389 error ("illegal reference type specified for instance variable `%s'",
6391 /* Return class as is without adding this ivar. */
6396 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6397 || TYPE_SIZE (field_type) == error_mark_node
6398 /* 'type[0]' is allowed, but 'type[]' is not! */
6400 || (TYPE_SIZE (field_type) == bitsize_zero_node
6401 && !TREE_OPERAND (declarator, 1))
6405 error ("instance variable `%s' has unknown size", ivar_name);
6406 /* Return class as is without adding this ivar. */
6411 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6412 cannot be ivars; ditto for classes with vtables. */
6413 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6414 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6416 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6417 if(TYPE_POLYMORPHIC_P (field_type)) {
6418 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6419 error ("type `%s' has virtual member functions", type_name);
6420 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6421 type_name, ivar_name);
6422 /* Return class as is without adding this ivar. */
6425 /* user-defined constructors and destructors are not known to Obj-C and
6426 hence will not be called. This may or may not be a problem. */
6427 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6428 warning ("type `%s' has a user-defined constructor", type_name);
6429 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6430 warning ("type `%s' has a user-defined destructor", type_name);
6431 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6435 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6439 TREE_PUBLIC (field_decl) = 0;
6440 TREE_PRIVATE (field_decl) = 0;
6441 TREE_PROTECTED (field_decl) = 1;
6445 TREE_PUBLIC (field_decl) = 1;
6446 TREE_PRIVATE (field_decl) = 0;
6447 TREE_PROTECTED (field_decl) = 0;
6451 TREE_PUBLIC (field_decl) = 0;
6452 TREE_PRIVATE (field_decl) = 1;
6453 TREE_PROTECTED (field_decl) = 0;
6458 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6459 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6460 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6465 is_ivar (tree decl_chain, tree ident)
6467 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6468 if (DECL_NAME (decl_chain) == ident)
6473 /* True if the ivar is private and we are not in its implementation. */
6476 is_private (tree decl)
6478 return (TREE_PRIVATE (decl)
6479 && ! is_ivar (CLASS_IVARS (implementation_template),
6483 /* We have an instance variable reference;, check to see if it is public. */
6486 objc_is_public (tree expr, tree identifier)
6488 tree basetype = TREE_TYPE (expr);
6489 enum tree_code code = TREE_CODE (basetype);
6492 if (code == RECORD_TYPE)
6494 if (TREE_STATIC_TEMPLATE (basetype))
6496 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6498 error ("cannot find interface declaration for `%s'",
6499 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6503 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6505 if (TREE_PUBLIC (decl))
6508 /* Important difference between the Stepstone translator:
6509 all instance variables should be public within the context
6510 of the implementation. */
6511 if (objc_implementation_context
6512 && (((TREE_CODE (objc_implementation_context)
6513 == CLASS_IMPLEMENTATION_TYPE)
6514 || (TREE_CODE (objc_implementation_context)
6515 == CATEGORY_IMPLEMENTATION_TYPE))
6516 && (CLASS_NAME (objc_implementation_context)
6517 == OBJC_TYPE_NAME (basetype))))
6519 int private = is_private (decl);
6522 error ("instance variable `%s' is declared private",
6523 IDENTIFIER_POINTER (DECL_NAME (decl)));
6527 /* The 2.95.2 compiler sometimes allowed C functions to access
6528 non-@public ivars. We will let this slide for now... */
6529 if (!objc_method_context)
6531 warning ("instance variable `%s' is %s; "
6532 "this will be a hard error in the future",
6533 IDENTIFIER_POINTER (identifier),
6534 TREE_PRIVATE (decl) ? "@private" : "@protected");
6538 error ("instance variable `%s' is declared %s",
6539 IDENTIFIER_POINTER (identifier),
6540 TREE_PRIVATE (decl) ? "private" : "protected");
6545 else if (objc_implementation_context && (basetype == objc_object_reference))
6547 TREE_TYPE (expr) = uprivate_record;
6548 warning ("static access to object of type `id'");
6555 /* Make sure all entries in CHAIN are also in LIST. */
6558 check_methods (tree chain, tree list, int mtype)
6564 if (!lookup_method (list, chain))
6568 if (TREE_CODE (objc_implementation_context)
6569 == CLASS_IMPLEMENTATION_TYPE)
6570 warning ("incomplete implementation of class `%s'",
6571 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6572 else if (TREE_CODE (objc_implementation_context)
6573 == CATEGORY_IMPLEMENTATION_TYPE)
6574 warning ("incomplete implementation of category `%s'",
6575 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6579 warning ("method definition for `%c%s' not found",
6580 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6583 chain = TREE_CHAIN (chain);
6589 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6592 conforms_to_protocol (tree class, tree protocol)
6594 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6596 tree p = CLASS_PROTOCOL_LIST (class);
6597 while (p && TREE_VALUE (p) != protocol)
6602 tree super = (CLASS_SUPER_NAME (class)
6603 ? lookup_interface (CLASS_SUPER_NAME (class))
6605 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6614 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6615 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6618 check_methods_accessible (tree chain, tree context, int mtype)
6622 tree base_context = context;
6626 context = base_context;
6630 list = CLASS_CLS_METHODS (context);
6632 list = CLASS_NST_METHODS (context);
6634 if (lookup_method (list, chain))
6637 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6638 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6639 context = (CLASS_SUPER_NAME (context)
6640 ? lookup_interface (CLASS_SUPER_NAME (context))
6643 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6644 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6645 context = (CLASS_NAME (context)
6646 ? lookup_interface (CLASS_NAME (context))
6652 if (context == NULL_TREE)
6656 if (TREE_CODE (objc_implementation_context)
6657 == CLASS_IMPLEMENTATION_TYPE)
6658 warning ("incomplete implementation of class `%s'",
6660 (CLASS_NAME (objc_implementation_context)));
6661 else if (TREE_CODE (objc_implementation_context)
6662 == CATEGORY_IMPLEMENTATION_TYPE)
6663 warning ("incomplete implementation of category `%s'",
6665 (CLASS_SUPER_NAME (objc_implementation_context)));
6668 warning ("method definition for `%c%s' not found",
6669 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6672 chain = TREE_CHAIN (chain); /* next method... */
6677 /* Check whether the current interface (accessible via
6678 'objc_implementation_context') actually implements protocol P, along
6679 with any protocols that P inherits. */
6682 check_protocol (tree p, const char *type, const char *name)
6684 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6688 /* Ensure that all protocols have bodies! */
6691 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6692 CLASS_CLS_METHODS (objc_implementation_context),
6694 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6695 CLASS_NST_METHODS (objc_implementation_context),
6700 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6701 objc_implementation_context,
6703 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6704 objc_implementation_context,
6709 warning ("%s `%s' does not fully implement the `%s' protocol",
6710 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6713 /* Check protocols recursively. */
6714 if (PROTOCOL_LIST (p))
6716 tree subs = PROTOCOL_LIST (p);
6718 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6722 tree sub = TREE_VALUE (subs);
6724 /* If the superclass does not conform to the protocols
6725 inherited by P, then we must! */
6726 if (!super_class || !conforms_to_protocol (super_class, sub))
6727 check_protocol (sub, type, name);
6728 subs = TREE_CHAIN (subs);
6733 /* Check whether the current interface (accessible via
6734 'objc_implementation_context') actually implements the protocols listed
6738 check_protocols (tree proto_list, const char *type, const char *name)
6740 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6742 tree p = TREE_VALUE (proto_list);
6744 check_protocol (p, type, name);
6748 /* Make sure that the class CLASS_NAME is defined
6749 CODE says which kind of thing CLASS_NAME ought to be.
6750 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6751 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6754 start_class (enum tree_code code, tree class_name, tree super_name,
6760 if (current_namespace != global_namespace) {
6761 error ("Objective-C declarations may only appear in global scope");
6763 #endif /* OBJCPLUS */
6765 if (objc_implementation_context)
6767 warning ("`@end' missing in implementation context");
6768 finish_class (objc_implementation_context);
6769 objc_ivar_chain = NULL_TREE;
6770 objc_implementation_context = NULL_TREE;
6773 class = make_node (code);
6774 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6776 CLASS_NAME (class) = class_name;
6777 CLASS_SUPER_NAME (class) = super_name;
6778 CLASS_CLS_METHODS (class) = NULL_TREE;
6780 if (! is_class_name (class_name)
6781 && (decl = lookup_name (class_name)))
6783 error ("`%s' redeclared as different kind of symbol",
6784 IDENTIFIER_POINTER (class_name));
6785 error ("%Jprevious declaration of '%D'",
6789 if (code == CLASS_IMPLEMENTATION_TYPE)
6794 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6795 if (TREE_VALUE (chain) == class_name)
6797 error ("reimplementation of class `%s'",
6798 IDENTIFIER_POINTER (class_name));
6799 return error_mark_node;
6801 implemented_classes = tree_cons (NULL_TREE, class_name,
6802 implemented_classes);
6805 /* Reset for multiple classes per file. */
6808 objc_implementation_context = class;
6810 /* Lookup the interface for this implementation. */
6812 if (!(implementation_template = lookup_interface (class_name)))
6814 warning ("cannot find interface declaration for `%s'",
6815 IDENTIFIER_POINTER (class_name));
6816 add_class (implementation_template = objc_implementation_context);
6819 /* If a super class has been specified in the implementation,
6820 insure it conforms to the one specified in the interface. */
6823 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6825 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6826 const char *const name =
6827 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6828 error ("conflicting super class name `%s'",
6829 IDENTIFIER_POINTER (super_name));
6830 error ("previous declaration of `%s'", name);
6833 else if (! super_name)
6835 CLASS_SUPER_NAME (objc_implementation_context)
6836 = CLASS_SUPER_NAME (implementation_template);
6840 else if (code == CLASS_INTERFACE_TYPE)
6842 if (lookup_interface (class_name))
6844 error ("duplicate interface declaration for class `%s'",
6846 warning ("duplicate interface declaration for class `%s'",
6848 IDENTIFIER_POINTER (class_name));
6853 CLASS_PROTOCOL_LIST (class)
6854 = lookup_and_install_protocols (protocol_list);
6857 else if (code == CATEGORY_INTERFACE_TYPE)
6859 tree class_category_is_assoc_with;
6861 /* For a category, class_name is really the name of the class that
6862 the following set of methods will be associated with. We must
6863 find the interface so that can derive the objects template. */
6865 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6867 error ("cannot find interface declaration for `%s'",
6868 IDENTIFIER_POINTER (class_name));
6869 exit (FATAL_EXIT_CODE);
6872 add_category (class_category_is_assoc_with, class);
6875 CLASS_PROTOCOL_LIST (class)
6876 = lookup_and_install_protocols (protocol_list);
6879 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6881 /* Reset for multiple classes per file. */
6884 objc_implementation_context = class;
6886 /* For a category, class_name is really the name of the class that
6887 the following set of methods will be associated with. We must
6888 find the interface so that can derive the objects template. */
6890 if (!(implementation_template = lookup_interface (class_name)))
6892 error ("cannot find interface declaration for `%s'",
6893 IDENTIFIER_POINTER (class_name));
6894 exit (FATAL_EXIT_CODE);
6901 continue_class (tree class)
6903 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6904 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6906 struct imp_entry *imp_entry;
6909 /* Check consistency of the instance variables. */
6911 if (CLASS_IVARS (class))
6912 check_ivars (implementation_template, class);
6914 /* code generation */
6916 ivar_context = build_private_template (implementation_template);
6918 if (!objc_class_template)
6919 build_class_template ();
6921 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6923 imp_entry->next = imp_list;
6924 imp_entry->imp_context = class;
6925 imp_entry->imp_template = implementation_template;
6927 synth_forward_declarations ();
6928 imp_entry->class_decl = UOBJC_CLASS_decl;
6929 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6931 /* Append to front and increment count. */
6932 imp_list = imp_entry;
6933 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6938 return ivar_context;
6941 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6943 if (!CLASS_STATIC_TEMPLATE (class))
6945 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6946 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6947 CLASS_STATIC_TEMPLATE (class) = record;
6949 /* Mark this record as a class template for static typing. */
6950 TREE_STATIC_TEMPLATE (record) = 1;
6957 return error_mark_node;
6960 /* This is called once we see the "@end" in an interface/implementation. */
6963 finish_class (tree class)
6965 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6967 /* All code generation is done in finish_objc. */
6969 if (implementation_template != objc_implementation_context)
6971 /* Ensure that all method listed in the interface contain bodies. */
6972 check_methods (CLASS_CLS_METHODS (implementation_template),
6973 CLASS_CLS_METHODS (objc_implementation_context), '+');
6974 check_methods (CLASS_NST_METHODS (implementation_template),
6975 CLASS_NST_METHODS (objc_implementation_context), '-');
6977 if (CLASS_PROTOCOL_LIST (implementation_template))
6978 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6980 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6984 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6986 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6990 /* Ensure all method listed in the interface contain bodies. */
6991 check_methods (CLASS_CLS_METHODS (category),
6992 CLASS_CLS_METHODS (objc_implementation_context), '+');
6993 check_methods (CLASS_NST_METHODS (category),
6994 CLASS_NST_METHODS (objc_implementation_context), '-');
6996 if (CLASS_PROTOCOL_LIST (category))
6997 check_protocols (CLASS_PROTOCOL_LIST (category),
6999 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7003 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7006 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
7007 char *string = (char *) alloca (strlen (class_name) + 3);
7009 /* extern struct objc_object *_<my_name>; */
7011 sprintf (string, "_%s", class_name);
7013 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
7014 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
7015 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7021 add_protocol (tree protocol)
7023 /* Put protocol on list in reverse order. */
7024 TREE_CHAIN (protocol) = protocol_chain;
7025 protocol_chain = protocol;
7026 return protocol_chain;
7030 lookup_protocol (tree ident)
7034 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7035 if (ident == PROTOCOL_NAME (chain))
7041 /* This function forward declares the protocols named by NAMES. If
7042 they are already declared or defined, the function has no effect. */
7045 objc_declare_protocols (tree names)
7050 if (current_namespace != global_namespace) {
7051 error ("Objective-C declarations may only appear in global scope");
7053 #endif /* OBJCPLUS */
7055 for (list = names; list; list = TREE_CHAIN (list))
7057 tree name = TREE_VALUE (list);
7059 if (lookup_protocol (name) == NULL_TREE)
7061 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7063 TYPE_LANG_SLOT_1 (protocol)
7064 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7065 PROTOCOL_NAME (protocol) = name;
7066 PROTOCOL_LIST (protocol) = NULL_TREE;
7067 add_protocol (protocol);
7068 PROTOCOL_DEFINED (protocol) = 0;
7069 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7075 start_protocol (enum tree_code code, tree name, tree list)
7080 if (current_namespace != global_namespace) {
7081 error ("Objective-C declarations may only appear in global scope");
7083 #endif /* OBJCPLUS */
7085 /* This is as good a place as any. Need to invoke
7086 push_tag_toplevel. */
7087 if (!objc_protocol_template)
7088 objc_protocol_template = build_protocol_template ();
7090 protocol = lookup_protocol (name);
7094 protocol = make_node (code);
7095 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7097 PROTOCOL_NAME (protocol) = name;
7098 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7099 add_protocol (protocol);
7100 PROTOCOL_DEFINED (protocol) = 1;
7101 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7103 check_protocol_recursively (protocol, list);
7105 else if (! PROTOCOL_DEFINED (protocol))
7107 PROTOCOL_DEFINED (protocol) = 1;
7108 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7110 check_protocol_recursively (protocol, list);
7114 warning ("duplicate declaration for protocol `%s'",
7115 IDENTIFIER_POINTER (name));
7121 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7126 /* "Encode" a data type into a string, which grows in util_obstack.
7127 ??? What is the FORMAT? Someone please document this! */
7130 encode_type_qualifiers (tree declspecs)
7134 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7136 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7137 obstack_1grow (&util_obstack, 'r');
7138 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7139 obstack_1grow (&util_obstack, 'n');
7140 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7141 obstack_1grow (&util_obstack, 'N');
7142 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7143 obstack_1grow (&util_obstack, 'o');
7144 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7145 obstack_1grow (&util_obstack, 'O');
7146 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7147 obstack_1grow (&util_obstack, 'R');
7148 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7149 obstack_1grow (&util_obstack, 'V');
7153 /* Encode a pointer type. */
7156 encode_pointer (tree type, int curtype, int format)
7158 tree pointer_to = TREE_TYPE (type);
7160 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7162 if (OBJC_TYPE_NAME (pointer_to)
7163 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7165 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7167 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7169 obstack_1grow (&util_obstack, '@');
7172 else if (TREE_STATIC_TEMPLATE (pointer_to))
7174 if (generating_instance_variables)
7176 obstack_1grow (&util_obstack, '@');
7177 obstack_1grow (&util_obstack, '"');
7178 obstack_grow (&util_obstack, name, strlen (name));
7179 obstack_1grow (&util_obstack, '"');
7184 obstack_1grow (&util_obstack, '@');
7188 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7190 obstack_1grow (&util_obstack, '#');
7193 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7195 obstack_1grow (&util_obstack, ':');
7200 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7201 && TYPE_MODE (pointer_to) == QImode)
7203 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7204 ? OBJC_TYPE_NAME (pointer_to)
7205 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7207 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7209 obstack_1grow (&util_obstack, '*');
7214 /* We have a type that does not get special treatment. */
7216 /* NeXT extension */
7217 obstack_1grow (&util_obstack, '^');
7218 encode_type (pointer_to, curtype, format);
7222 encode_array (tree type, int curtype, int format)
7224 tree an_int_cst = TYPE_SIZE (type);
7225 tree array_of = TREE_TYPE (type);
7228 /* An incomplete array is treated like a pointer. */
7229 if (an_int_cst == NULL)
7231 encode_pointer (type, curtype, format);
7235 sprintf (buffer, "[%ld",
7236 (long) (TREE_INT_CST_LOW (an_int_cst)
7237 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7239 obstack_grow (&util_obstack, buffer, strlen (buffer));
7240 encode_type (array_of, curtype, format);
7241 obstack_1grow (&util_obstack, ']');
7246 encode_aggregate_within (tree type, int curtype, int format, int left,
7250 /* NB: aggregates that are pointed to have slightly different encoding
7251 rules in that you never encode the names of instance variables. */
7253 = (obstack_object_size (&util_obstack) > 0
7254 && *(obstack_next_free (&util_obstack) - 1) == '^');
7256 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7257 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7259 /* Traverse struct aliases; it is important to get the
7260 original struct and its tag name (if any). */
7261 type = TYPE_MAIN_VARIANT (type);
7262 name = OBJC_TYPE_NAME (type);
7263 /* Open parenth/bracket. */
7264 obstack_1grow (&util_obstack, left);
7266 /* Encode the struct/union tag name, or '?' if a tag was
7267 not provided. Typedef aliases do not qualify. */
7268 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7270 /* Did this struct have a tag? */
7271 && !TYPE_WAS_ANONYMOUS (type)
7274 obstack_grow (&util_obstack,
7275 IDENTIFIER_POINTER (name),
7276 strlen (IDENTIFIER_POINTER (name)));
7278 obstack_1grow (&util_obstack, '?');
7280 /* Encode the types (and possibly names) of the inner fields,
7282 if (inline_contents)
7284 tree fields = TYPE_FIELDS (type);
7286 obstack_1grow (&util_obstack, '=');
7287 for (; fields; fields = TREE_CHAIN (fields))
7290 /* C++ static members, and things that are not fields at all,
7291 should not appear in the encoding. */
7292 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7295 if (generating_instance_variables && !pointed_to)
7297 tree fname = DECL_NAME (fields);
7299 obstack_1grow (&util_obstack, '"');
7300 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7301 obstack_grow (&util_obstack,
7302 IDENTIFIER_POINTER (fname),
7303 strlen (IDENTIFIER_POINTER (fname)));
7304 obstack_1grow (&util_obstack, '"');
7306 encode_field_decl (fields, curtype, format);
7309 /* Close parenth/bracket. */
7310 obstack_1grow (&util_obstack, right);
7314 encode_aggregate (tree type, int curtype, int format)
7316 enum tree_code code = TREE_CODE (type);
7322 encode_aggregate_within (type, curtype, format, '{', '}');
7327 encode_aggregate_within (type, curtype, format, '(', ')');
7332 obstack_1grow (&util_obstack, 'i');
7340 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7344 encode_next_bitfield (int width)
7347 sprintf (buffer, "b%d", width);
7348 obstack_grow (&util_obstack, buffer, strlen (buffer));
7351 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7353 encode_type (tree type, int curtype, int format)
7355 enum tree_code code = TREE_CODE (type);
7358 if (code == INTEGER_TYPE)
7360 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7362 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7363 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7365 if (type == long_unsigned_type_node
7366 || type == long_integer_type_node)
7367 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7369 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7371 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7374 obstack_1grow (&util_obstack, c);
7377 else if (code == REAL_TYPE)
7379 /* Floating point types. */
7380 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7382 case 32: c = 'f'; break;
7384 case 128: c = 'd'; break;
7387 obstack_1grow (&util_obstack, c);
7390 else if (code == VOID_TYPE)
7391 obstack_1grow (&util_obstack, 'v');
7393 else if (code == BOOLEAN_TYPE)
7394 obstack_1grow (&util_obstack, 'B');
7396 else if (code == ARRAY_TYPE)
7397 encode_array (type, curtype, format);
7399 else if (code == POINTER_TYPE)
7400 encode_pointer (type, curtype, format);
7402 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7403 encode_aggregate (type, curtype, format);
7405 else if (code == FUNCTION_TYPE) /* '?' */
7406 obstack_1grow (&util_obstack, '?');
7410 encode_gnu_bitfield (int position, tree type, int size)
7412 enum tree_code code = TREE_CODE (type);
7414 char charType = '?';
7416 if (code == INTEGER_TYPE)
7418 if (integer_zerop (TYPE_MIN_VALUE (type)))
7420 /* Unsigned integer types. */
7422 if (TYPE_MODE (type) == QImode)
7424 else if (TYPE_MODE (type) == HImode)
7426 else if (TYPE_MODE (type) == SImode)
7428 if (type == long_unsigned_type_node)
7433 else if (TYPE_MODE (type) == DImode)
7438 /* Signed integer types. */
7440 if (TYPE_MODE (type) == QImode)
7442 else if (TYPE_MODE (type) == HImode)
7444 else if (TYPE_MODE (type) == SImode)
7446 if (type == long_integer_type_node)
7452 else if (TYPE_MODE (type) == DImode)
7456 else if (code == ENUMERAL_TYPE)
7461 sprintf (buffer, "b%d%c%d", position, charType, size);
7462 obstack_grow (&util_obstack, buffer, strlen (buffer));
7466 encode_field_decl (tree field_decl, int curtype, int format)
7471 /* C++ static members, and things that are not fields at all,
7472 should not appear in the encoding. */
7473 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7477 type = TREE_TYPE (field_decl);
7479 /* Generate the bitfield typing information, if needed. Note the difference
7480 between GNU and NeXT runtimes. */
7481 if (DECL_BIT_FIELD_TYPE (field_decl))
7483 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7485 if (flag_next_runtime)
7486 encode_next_bitfield (size);
7488 encode_gnu_bitfield (int_bit_position (field_decl),
7489 DECL_BIT_FIELD_TYPE (field_decl), size);
7492 encode_type (TREE_TYPE (field_decl), curtype, format);
7496 objc_expr_last (tree complex_expr)
7501 while ((next = TREE_OPERAND (complex_expr, 0)))
7502 complex_expr = next;
7504 return complex_expr;
7508 synth_self_and_ucmd_args (void)
7512 if (objc_method_context
7513 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7514 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7516 /* Really a `struct objc_class *'. However, we allow people to
7517 assign to self, which changes its type midstream. */
7518 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7520 push_parm_decl (build_tree_list
7521 (build_tree_list (decl_specs,
7522 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7525 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (objc_selector_type));
7526 push_parm_decl (build_tree_list
7527 (build_tree_list (decl_specs,
7528 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7532 /* Transform a method definition into a function definition as follows:
7533 - synthesize the first two arguments, "self" and "_cmd". */
7536 start_method_def (tree method)
7538 /* Required to implement _msgSuper. */
7539 objc_method_context = method;
7540 UOBJC_SUPER_decl = NULL_TREE;
7542 /* Must be called BEFORE start_function. */
7544 declare_parm_level ();
7546 /* Generate prototype declarations for arguments..."new-style". */
7547 synth_self_and_ucmd_args ();
7549 /* Generate argument declarations if a keyword_decl. */
7550 if (METHOD_SEL_ARGS (method))
7552 tree arglist = METHOD_SEL_ARGS (method);
7555 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7556 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7560 tree last_expr = objc_expr_last (arg_decl);
7562 /* Unite the abstract decl with its name. */
7563 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7564 push_parm_decl (build_tree_list
7565 (build_tree_list (arg_spec, arg_decl),
7569 /* Unhook: restore the abstract declarator. */
7570 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7575 push_parm_decl (build_tree_list
7576 (build_tree_list (arg_spec,
7577 KEYWORD_ARG_NAME (arglist)),
7580 arglist = TREE_CHAIN (arglist);
7585 if (METHOD_ADD_ARGS (method) != NULL_TREE
7586 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7588 /* We have a variable length selector - in "prototype" format. */
7589 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7592 /* This must be done prior to calling pushdecl. pushdecl is
7593 going to change our chain on us. */
7594 tree nextkey = TREE_CHAIN (akey);
7602 warn_with_method (const char *message, int mtype, tree method)
7604 /* Add a readable method name to the warning. */
7605 warning ("%J%s `%c%s'", method,
7606 message, mtype, gen_method_decl (method, errbuf));
7609 /* Return 1 if METHOD is consistent with PROTO. */
7612 comp_method_with_proto (tree method, tree proto)
7614 /* Create a function template node at most once. */
7615 if (!function1_template)
7616 function1_template = make_node (FUNCTION_TYPE);
7618 /* Install argument types - normally set by build_function_type. */
7619 TYPE_ARG_TYPES (function1_template)
7620 = get_arg_type_list (proto, METHOD_DEF, 0);
7622 /* install return type */
7623 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7625 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7628 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7631 objc_types_are_equivalent (tree type1, tree type2)
7635 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7637 type1 = TYPE_PROTOCOL_LIST (type1);
7638 type2 = TYPE_PROTOCOL_LIST (type2);
7639 if (list_length (type1) == list_length (type2))
7641 for (; type2; type2 = TREE_CHAIN (type2))
7642 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7649 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7652 comp_proto_with_proto (tree proto1, tree proto2)
7656 /* The following test is needed in case there are hashing
7658 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7661 /* Compare return types. */
7662 type1 = groktypename (TREE_TYPE (proto1));
7663 type2 = groktypename (TREE_TYPE (proto2));
7665 if (!objc_types_are_equivalent (type1, type2))
7668 /* Compare argument types. */
7669 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7670 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7672 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7674 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7678 return (!type1 && !type2);
7681 /* - Generate an identifier for the function. the format is "_n_cls",
7682 where 1 <= n <= nMethods, and cls is the name the implementation we
7684 - Install the return type from the method declaration.
7685 - If we have a prototype, check for type consistency. */
7688 really_start_method (tree method, tree parmlist)
7690 tree sc_spec, ret_spec, ret_decl, decl_specs;
7691 tree method_decl, method_id;
7692 const char *sel_name, *class_name, *cat_name;
7695 /* Synth the storage class & assemble the return type. */
7696 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7697 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7698 decl_specs = chainon (sc_spec, ret_spec);
7700 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7701 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7702 cat_name = ((TREE_CODE (objc_implementation_context)
7703 == CLASS_IMPLEMENTATION_TYPE)
7705 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7708 /* Make sure this is big enough for any plausible method label. */
7709 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7710 + (cat_name ? strlen (cat_name) : 0));
7712 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7713 class_name, cat_name, sel_name, method_slot);
7715 method_id = get_identifier (buf);
7718 /* Objective-C methods cannot be overloaded, so we don't need
7719 the type encoding appended. It looks bad anyway... */
7720 push_lang_context (lang_name_c);
7723 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7725 /* Check the declarator portion of the return type for the method. */
7726 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7728 /* Unite the complex decl (specified in the abstract decl) with the
7729 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7730 tree save_expr = objc_expr_last (ret_decl);
7732 TREE_OPERAND (save_expr, 0) = method_decl;
7733 method_decl = ret_decl;
7735 /* Fool the parser into thinking it is starting a function. */
7736 start_function (decl_specs, method_decl, NULL_TREE);
7738 /* Unhook: this has the effect of restoring the abstract declarator. */
7739 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7744 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7746 /* Fool the parser into thinking it is starting a function. */
7747 start_function (decl_specs, method_decl, NULL_TREE);
7749 /* Unhook: this has the effect of restoring the abstract declarator. */
7750 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7754 /* set self_decl from the first argument...this global is used by
7755 * build_ivar_reference().build_indirect_ref().
7757 self_decl = DECL_ARGUMENTS (current_function_decl);
7759 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7760 * the following: warning:unused parameter `struct objc_selector * _cmd'
7762 TREE_USED (self_decl) = 1;
7763 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7764 /* Ditto for the underlying (static) C function. */
7765 TREE_USED (current_function_decl) = 1;
7766 pop_lang_context ();
7769 METHOD_DEFINITION (method) = current_function_decl;
7771 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7773 if (implementation_template != objc_implementation_context)
7776 = lookup_method_static (implementation_template,
7777 METHOD_SEL_NAME (method),
7778 TREE_CODE (method) == CLASS_METHOD_DECL);
7782 if (!comp_method_with_proto (method, proto))
7784 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7786 warn_with_method ("conflicting types for", type, method);
7787 warn_with_method ("previous declaration of", type, proto);
7792 /* We have a method @implementation even though we did not
7793 see a corresponding @interface declaration (which is allowed
7794 by Objective-C rules). Go ahead and place the method in
7795 the @interface anyway, so that message dispatch lookups
7797 tree interface = implementation_template;
7799 if (TREE_CODE (objc_implementation_context)
7800 == CATEGORY_IMPLEMENTATION_TYPE)
7801 interface = lookup_category
7803 CLASS_SUPER_NAME (objc_implementation_context));
7806 objc_add_method (interface, copy_node (method),
7807 TREE_CODE (method) == CLASS_METHOD_DECL);
7812 /* The following routine is always called...this "architecture" is to
7813 accommodate "old-style" variable length selectors.
7815 - a:a b:b // prototype ; id c; id d; // old-style. */
7818 continue_method_def (void)
7822 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7823 /* We have a `, ...' immediately following the selector. */
7824 parmlist = get_parm_info (/*ellipsis=*/true);
7826 parmlist = get_parm_info (/*ellipsis=*/false);
7829 /* Set self_decl from the first argument...this global is used by
7830 build_ivar_reference calling build_indirect_ref. */
7831 self_decl = TREE_PURPOSE (parmlist);
7832 #endif /* !OBJCPLUS */
7835 really_start_method (objc_method_context, parmlist);
7836 store_parm_decls ();
7839 static void *UOBJC_SUPER_scope = 0;
7841 /* _n_Method (id self, SEL sel, ...)
7843 struct objc_super _S;
7844 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7848 get_super_receiver (void)
7850 if (objc_method_context)
7852 tree super_expr, super_expr_list;
7854 if (!UOBJC_SUPER_decl)
7856 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7857 build_tree_list (NULL_TREE,
7858 objc_super_template),
7861 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7863 /* This prevents `unused variable' warnings when compiling with -Wall. */
7864 TREE_USED (UOBJC_SUPER_decl) = 1;
7865 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7867 UOBJC_SUPER_scope = get_current_scope ();
7870 /* Set receiver to self. */
7871 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7872 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7873 super_expr_list = super_expr;
7875 /* Set class to begin searching. */
7877 super_expr = build_component_ref (UOBJC_SUPER_decl,
7878 get_identifier ("super_class"));
7880 super_expr = build_component_ref (UOBJC_SUPER_decl,
7881 get_identifier ("class"));
7884 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7886 /* [_cls, __cls]Super are "pre-built" in
7887 synth_forward_declarations. */
7889 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7890 ((TREE_CODE (objc_method_context)
7891 == INSTANCE_METHOD_DECL)
7893 : uucls_super_ref));
7897 /* We have a category. */
7899 tree super_name = CLASS_SUPER_NAME (implementation_template);
7902 /* Barf if super used in a category of Object. */
7905 error ("no super class declared in interface for `%s'",
7906 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7907 return error_mark_node;
7910 if (flag_next_runtime && !flag_zero_link)
7912 super_class = get_class_reference (super_name);
7913 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7914 /* If we are in a class method, we must retrieve the
7915 _metaclass_ for the current class, pointed at by
7916 the class's "isa" pointer. The following assumes that
7917 "isa" is the first ivar in a class (which it must be). */
7919 = build_indirect_ref
7920 (build_c_cast (build_pointer_type (objc_class_type),
7921 super_class), "unary *");
7925 add_class_reference (super_name);
7926 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7927 ? objc_get_class_decl : objc_get_meta_class_decl);
7928 assemble_external (super_class);
7930 = build_function_call
7934 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7935 IDENTIFIER_POINTER (super_name))));
7939 = build_modify_expr (super_expr, NOP_EXPR,
7940 build_c_cast (TREE_TYPE (super_expr),
7944 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7946 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7947 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7949 return super_expr_list;
7953 error ("[super ...] must appear in a method context");
7954 return error_mark_node;
7958 /* When exiting a scope, sever links to a 'super' declaration (if any)
7959 therein contained. */
7962 objc_clear_super_receiver (void)
7964 if (objc_method_context
7965 && UOBJC_SUPER_scope == get_current_scope ()) {
7966 UOBJC_SUPER_decl = 0;
7967 UOBJC_SUPER_scope = 0;
7972 objc_expand_function_end (void)
7974 /* This routine may also get called for C functions, including those
7975 nested within ObjC methods. In such cases, method encoding is
7977 if (objc_method_context == NULL_TREE
7978 || DECL_INITIAL (objc_method_context) != current_function_decl)
7981 METHOD_ENCODING (objc_method_context)
7982 = encode_method_prototype (objc_method_context);
7986 finish_method_def (void)
7988 lang_expand_function_end = objc_expand_function_end;
7989 /* We cannot validly inline ObjC methods, at least not without a language
7990 extension to declare that a method need not be dynamically
7991 dispatched, so suppress all thoughts of doing so. */
7992 DECL_INLINE (current_function_decl) = 0;
7993 DECL_UNINLINABLE (current_function_decl) = 1;
7996 lang_expand_function_end = NULL;
7998 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7999 since the optimizer may find "may be used before set" errors. */
8000 objc_method_context = NULL_TREE;
8005 lang_report_error_function (tree decl)
8007 if (objc_method_context)
8009 fprintf (stderr, "In method `%s'\n",
8010 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8020 is_complex_decl (tree type)
8022 return (TREE_CODE (type) == ARRAY_TYPE
8023 || TREE_CODE (type) == FUNCTION_TYPE
8024 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8028 /* Code to convert a decl node into text for a declaration in C. */
8030 static char tmpbuf[256];
8033 adorn_decl (tree decl, char *str)
8035 enum tree_code code = TREE_CODE (decl);
8037 if (code == ARRAY_REF)
8039 tree an_int_cst = TREE_OPERAND (decl, 1);
8041 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8042 sprintf (str + strlen (str), "[%ld]",
8043 (long) TREE_INT_CST_LOW (an_int_cst));
8048 else if (code == ARRAY_TYPE)
8050 tree an_int_cst = TYPE_SIZE (decl);
8051 tree array_of = TREE_TYPE (decl);
8053 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8054 sprintf (str + strlen (str), "[%ld]",
8055 (long) (TREE_INT_CST_LOW (an_int_cst)
8056 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8061 else if (code == CALL_EXPR)
8063 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8068 gen_declaration_1 (chain, str);
8069 chain = TREE_CHAIN (chain);
8076 else if (code == FUNCTION_TYPE)
8078 tree chain = TYPE_ARG_TYPES (decl);
8081 while (chain && TREE_VALUE (chain) != void_type_node)
8083 gen_declaration_1 (TREE_VALUE (chain), str);
8084 chain = TREE_CHAIN (chain);
8085 if (chain && TREE_VALUE (chain) != void_type_node)
8091 else if (code == INDIRECT_REF)
8093 strcpy (tmpbuf, "*");
8094 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8098 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8100 chain = TREE_CHAIN (chain))
8102 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8104 strcat (tmpbuf, " ");
8105 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8109 strcat (tmpbuf, " ");
8111 strcat (tmpbuf, str);
8112 strcpy (str, tmpbuf);
8115 else if (code == POINTER_TYPE)
8117 strcpy (tmpbuf, "*");
8118 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8120 if (TYPE_READONLY (decl))
8121 strcat (tmpbuf, " const");
8122 if (TYPE_VOLATILE (decl))
8123 strcat (tmpbuf, " volatile");
8125 strcat (tmpbuf, " ");
8127 strcat (tmpbuf, str);
8128 strcpy (str, tmpbuf);
8133 gen_declarator (tree decl, char *buf, const char *name)
8137 enum tree_code code = TREE_CODE (decl);
8147 op = TREE_OPERAND (decl, 0);
8149 /* We have a pointer to a function or array...(*)(), (*)[] */
8150 if ((code == ARRAY_REF || code == CALL_EXPR)
8151 && op && TREE_CODE (op) == INDIRECT_REF)
8154 str = gen_declarator (op, buf, name);
8158 strcpy (tmpbuf, "(");
8159 strcat (tmpbuf, str);
8160 strcat (tmpbuf, ")");
8161 strcpy (str, tmpbuf);
8164 adorn_decl (decl, str);
8173 /* This clause is done iteratively rather than recursively. */
8176 op = (is_complex_decl (TREE_TYPE (decl))
8177 ? TREE_TYPE (decl) : NULL_TREE);
8179 adorn_decl (decl, str);
8181 /* We have a pointer to a function or array...(*)(), (*)[] */
8182 if (code == POINTER_TYPE
8183 && op && (TREE_CODE (op) == FUNCTION_TYPE
8184 || TREE_CODE (op) == ARRAY_TYPE))
8186 strcpy (tmpbuf, "(");
8187 strcat (tmpbuf, str);
8188 strcat (tmpbuf, ")");
8189 strcpy (str, tmpbuf);
8192 decl = (is_complex_decl (TREE_TYPE (decl))
8193 ? TREE_TYPE (decl) : NULL_TREE);
8196 while (decl && (code = TREE_CODE (decl)))
8201 case IDENTIFIER_NODE:
8202 /* Will only happen if we are processing a "raw" expr-decl. */
8203 strcpy (buf, IDENTIFIER_POINTER (decl));
8214 /* We have an abstract declarator or a _DECL node. */
8222 gen_declspecs (tree declspecs, char *buf, int raw)
8228 for (chain = nreverse (copy_list (declspecs));
8229 chain; chain = TREE_CHAIN (chain))
8231 tree aspec = TREE_VALUE (chain);
8233 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8234 strcat (buf, IDENTIFIER_POINTER (aspec));
8235 else if (TREE_CODE (aspec) == RECORD_TYPE)
8237 if (OBJC_TYPE_NAME (aspec))
8239 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8241 if (! TREE_STATIC_TEMPLATE (aspec))
8242 strcat (buf, "struct ");
8243 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8248 tree chain = protocol_list;
8255 (PROTOCOL_NAME (TREE_VALUE (chain))));
8256 chain = TREE_CHAIN (chain);
8265 strcat (buf, "untagged struct");
8268 else if (TREE_CODE (aspec) == UNION_TYPE)
8270 if (OBJC_TYPE_NAME (aspec))
8272 if (! TREE_STATIC_TEMPLATE (aspec))
8273 strcat (buf, "union ");
8274 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8277 strcat (buf, "untagged union");
8280 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8282 if (OBJC_TYPE_NAME (aspec))
8284 if (! TREE_STATIC_TEMPLATE (aspec))
8285 strcat (buf, "enum ");
8286 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8289 strcat (buf, "untagged enum");
8292 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8293 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8295 else if (IS_ID (aspec))
8297 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8302 tree chain = protocol_list;
8309 (PROTOCOL_NAME (TREE_VALUE (chain))));
8310 chain = TREE_CHAIN (chain);
8317 if (TREE_CHAIN (chain))
8323 /* Type qualifiers. */
8324 if (TYPE_READONLY (declspecs))
8325 strcat (buf, "const ");
8326 if (TYPE_VOLATILE (declspecs))
8327 strcat (buf, "volatile ");
8329 switch (TREE_CODE (declspecs))
8331 /* Type specifiers. */
8334 declspecs = TYPE_MAIN_VARIANT (declspecs);
8336 /* Signed integer types. */
8338 if (declspecs == short_integer_type_node)
8339 strcat (buf, "short int ");
8340 else if (declspecs == integer_type_node)
8341 strcat (buf, "int ");
8342 else if (declspecs == long_integer_type_node)
8343 strcat (buf, "long int ");
8344 else if (declspecs == long_long_integer_type_node)
8345 strcat (buf, "long long int ");
8346 else if (declspecs == signed_char_type_node
8347 || declspecs == char_type_node)
8348 strcat (buf, "char ");
8350 /* Unsigned integer types. */
8352 else if (declspecs == short_unsigned_type_node)
8353 strcat (buf, "unsigned short ");
8354 else if (declspecs == unsigned_type_node)
8355 strcat (buf, "unsigned int ");
8356 else if (declspecs == long_unsigned_type_node)
8357 strcat (buf, "unsigned long ");
8358 else if (declspecs == long_long_unsigned_type_node)
8359 strcat (buf, "unsigned long long ");
8360 else if (declspecs == unsigned_char_type_node)
8361 strcat (buf, "unsigned char ");
8365 declspecs = TYPE_MAIN_VARIANT (declspecs);
8367 if (declspecs == float_type_node)
8368 strcat (buf, "float ");
8369 else if (declspecs == double_type_node)
8370 strcat (buf, "double ");
8371 else if (declspecs == long_double_type_node)
8372 strcat (buf, "long double ");
8376 if (OBJC_TYPE_NAME (declspecs)
8377 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8379 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8381 if (! TREE_STATIC_TEMPLATE (declspecs))
8382 strcat (buf, "struct ");
8383 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8387 tree chain = protocol_list;
8394 (PROTOCOL_NAME (TREE_VALUE (chain))));
8395 chain = TREE_CHAIN (chain);
8404 strcat (buf, "untagged struct");
8410 if (OBJC_TYPE_NAME (declspecs)
8411 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8413 strcat (buf, "union ");
8414 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8419 strcat (buf, "untagged union ");
8423 if (OBJC_TYPE_NAME (declspecs)
8424 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8426 strcat (buf, "enum ");
8427 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8432 strcat (buf, "untagged enum ");
8436 strcat (buf, "void ");
8441 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8446 tree chain = protocol_list;
8453 (PROTOCOL_NAME (TREE_VALUE (chain))));
8454 chain = TREE_CHAIN (chain);
8470 /* Given a tree node, produce a printable description of it in the given
8471 buffer, overwriting the buffer. */
8474 gen_declaration (tree atype_or_adecl, char *buf)
8477 gen_declaration_1 (atype_or_adecl, buf);
8481 /* Given a tree node, append a printable description to the end of the
8485 gen_declaration_1 (tree atype_or_adecl, char *buf)
8489 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8491 tree declspecs; /* "identifier_node", "record_type" */
8492 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8493 tree width = NULL_TREE; /* for bitfields */
8495 /* We have a "raw", abstract declarator (typename). */
8496 declarator = TREE_VALUE (atype_or_adecl);
8497 /* In the case of raw ivars, the declarator itself is a list,
8498 and contains bitfield widths. */
8499 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8501 width = TREE_VALUE (declarator);
8502 declarator = TREE_PURPOSE (declarator);
8504 declspecs = TREE_PURPOSE (atype_or_adecl);
8506 gen_declspecs (declspecs, buf, 1);
8510 strcat (buf, gen_declarator (declarator, declbuf, ""));
8513 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8514 TREE_INT_CST_LOW (width));
8520 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8521 tree declarator; /* "array_type", "function_type", "pointer_type". */
8523 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8524 || TREE_CODE (atype_or_adecl) == PARM_DECL
8525 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8526 atype = TREE_TYPE (atype_or_adecl);
8528 /* Assume we have a *_type node. */
8529 atype = atype_or_adecl;
8531 if (is_complex_decl (atype))
8535 /* Get the declaration specifier; it is at the end of the list. */
8536 declarator = chain = atype;
8538 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8539 while (is_complex_decl (chain));
8546 declarator = NULL_TREE;
8549 gen_declspecs (declspecs, buf, 0);
8551 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8552 || TREE_CODE (atype_or_adecl) == PARM_DECL
8553 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8555 const char *const decl_name =
8556 (DECL_NAME (atype_or_adecl)
8557 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8562 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8565 else if (decl_name[0])
8568 strcat (buf, decl_name);
8571 else if (declarator)
8574 strcat (buf, gen_declarator (declarator, declbuf, ""));
8579 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8581 /* Given a method tree, put a printable description into the given
8582 buffer (overwriting) and return a pointer to the buffer. */
8585 gen_method_decl (tree method, char *buf)
8590 if (RAW_TYPESPEC (method) != objc_object_reference)
8593 gen_declaration_1 (TREE_TYPE (method), buf);
8597 chain = METHOD_SEL_ARGS (method);
8600 /* We have a chain of keyword_decls. */
8603 if (KEYWORD_KEY_NAME (chain))
8604 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8607 if (RAW_TYPESPEC (chain) != objc_object_reference)
8610 gen_declaration_1 (TREE_TYPE (chain), buf);
8614 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8615 if ((chain = TREE_CHAIN (chain)))
8620 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8621 strcat (buf, ", ...");
8622 else if (METHOD_ADD_ARGS (method))
8624 /* We have a tree list node as generate by get_parm_info. */
8625 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8627 /* Know we have a chain of parm_decls. */
8631 gen_declaration_1 (chain, buf);
8632 chain = TREE_CHAIN (chain);
8638 /* We have a unary selector. */
8639 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8647 /* Dump an @interface declaration of the supplied class CHAIN to the
8648 supplied file FP. Used to implement the -gen-decls option (which
8649 prints out an @interface declaration of all classes compiled in
8650 this run); potentially useful for debugging the compiler too. */
8652 dump_interface (FILE *fp, tree chain)
8654 /* FIXME: A heap overflow here whenever a method (or ivar)
8655 declaration is so long that it doesn't fit in the buffer. The
8656 code and all the related functions should be rewritten to avoid
8657 using fixed size buffers. */
8658 char *buf = (char *) xmalloc (1024 * 10);
8659 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8660 tree ivar_decls = CLASS_RAW_IVARS (chain);
8661 tree nst_methods = CLASS_NST_METHODS (chain);
8662 tree cls_methods = CLASS_CLS_METHODS (chain);
8664 fprintf (fp, "\n@interface %s", my_name);
8666 /* CLASS_SUPER_NAME is used to store the superclass name for
8667 classes, and the category name for categories. */
8668 if (CLASS_SUPER_NAME (chain))
8670 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8672 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8673 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8675 fprintf (fp, " (%s)\n", name);
8679 fprintf (fp, " : %s\n", name);
8685 /* FIXME - the following doesn't seem to work at the moment. */
8688 fprintf (fp, "{\n");
8691 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8692 ivar_decls = TREE_CHAIN (ivar_decls);
8695 fprintf (fp, "}\n");
8700 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8701 nst_methods = TREE_CHAIN (nst_methods);
8706 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8707 cls_methods = TREE_CHAIN (cls_methods);
8710 fprintf (fp, "@end\n");
8713 /* Demangle function for Objective-C */
8715 objc_demangle (const char *mangled)
8717 char *demangled, *cp;
8719 if (mangled[0] == '_' &&
8720 (mangled[1] == 'i' || mangled[1] == 'c') &&
8723 cp = demangled = xmalloc(strlen(mangled) + 2);
8724 if (mangled[1] == 'i')
8725 *cp++ = '-'; /* for instance method */
8727 *cp++ = '+'; /* for class method */
8728 *cp++ = '['; /* opening left brace */
8729 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8730 while (*cp && *cp == '_')
8731 cp++; /* skip any initial underbars in class name */
8732 cp = strchr(cp, '_'); /* find first non-initial underbar */
8735 free(demangled); /* not mangled name */
8738 if (cp[1] == '_') /* easy case: no category name */
8740 *cp++ = ' '; /* replace two '_' with one ' ' */
8741 strcpy(cp, mangled + (cp - demangled) + 2);
8745 *cp++ = '('; /* less easy case: category name */
8746 cp = strchr(cp, '_');
8749 free(demangled); /* not mangled name */
8753 *cp++ = ' '; /* overwriting 1st char of method name... */
8754 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8756 while (*cp && *cp == '_')
8757 cp++; /* skip any initial underbars in method name */
8760 *cp = ':'; /* replace remaining '_' with ':' */
8761 *cp++ = ']'; /* closing right brace */
8762 *cp++ = 0; /* string terminator */
8766 return mangled; /* not an objc mangled name */
8770 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8772 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8778 gcc_obstack_init (&util_obstack);
8779 util_firstobj = (char *) obstack_finish (&util_obstack);
8781 errbuf = (char *) xmalloc (BUFSIZE);
8783 synth_module_prologue ();
8789 struct imp_entry *impent;
8791 /* The internally generated initializers appear to have missing braces.
8792 Don't warn about this. */
8793 int save_warn_missing_braces = warn_missing_braces;
8794 warn_missing_braces = 0;
8796 /* A missing @end may not be detected by the parser. */
8797 if (objc_implementation_context)
8799 warning ("`@end' missing in implementation context");
8800 finish_class (objc_implementation_context);
8801 objc_ivar_chain = NULL_TREE;
8802 objc_implementation_context = NULL_TREE;
8805 /* Process the static instances here because initialization of objc_symtab
8807 if (objc_static_instances)
8808 generate_static_references ();
8810 if (imp_list || class_names_chain
8811 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8812 generate_objc_symtab_decl ();
8814 for (impent = imp_list; impent; impent = impent->next)
8816 objc_implementation_context = impent->imp_context;
8817 implementation_template = impent->imp_template;
8819 UOBJC_CLASS_decl = impent->class_decl;
8820 UOBJC_METACLASS_decl = impent->meta_decl;
8822 /* Dump the @interface of each class as we compile it, if the
8823 -gen-decls option is in use. TODO: Dump the classes in the
8824 order they were found, rather than in reverse order as we
8826 if (flag_gen_declaration)
8828 dump_interface (gen_declaration_file, objc_implementation_context);
8831 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8833 /* all of the following reference the string pool... */
8834 generate_ivar_lists ();
8835 generate_dispatch_tables ();
8836 generate_shared_structures ();
8840 generate_dispatch_tables ();
8841 generate_category (objc_implementation_context);
8845 /* If we are using an array of selectors, we must always
8846 finish up the array decl even if no selectors were used. */
8847 if (! flag_next_runtime || sel_ref_chain)
8848 build_selector_translation_table ();
8851 generate_protocols ();
8853 if (flag_replace_objc_classes && imp_list)
8854 generate_objc_image_info ();
8856 if (objc_implementation_context || class_names_chain || objc_static_instances
8857 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8859 /* Arrange for ObjC data structures to be initialized at run time. */
8860 rtx init_sym = build_module_descriptor ();
8861 if (init_sym && targetm.have_ctors_dtors)
8862 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8865 /* Dump the class references. This forces the appropriate classes
8866 to be linked into the executable image, preserving unix archive
8867 semantics. This can be removed when we move to a more dynamically
8868 linked environment. */
8870 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8872 handle_class_ref (chain);
8873 if (TREE_PURPOSE (chain))
8874 generate_classref_translation_entry (chain);
8877 for (impent = imp_list; impent; impent = impent->next)
8878 handle_impent (impent);
8880 /* Dump the string table last. */
8882 generate_strings ();
8889 /* Run through the selector hash tables and print a warning for any
8890 selector which has multiple methods. */
8892 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8894 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8895 check_duplicates (hsh, 0, 1);
8896 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8897 check_duplicates (hsh, 0, 1);
8901 warn_missing_braces = save_warn_missing_braces;
8904 /* Subroutines of finish_objc. */
8907 generate_classref_translation_entry (tree chain)
8909 tree expr, name, decl_specs, decl, sc_spec;
8912 type = TREE_TYPE (TREE_PURPOSE (chain));
8914 expr = add_objc_string (TREE_VALUE (chain), class_names);
8915 expr = build_c_cast (type, expr); /* cast! */
8917 name = DECL_NAME (TREE_PURPOSE (chain));
8919 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8921 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8922 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8924 /* The decl that is returned from start_decl is the one that we
8925 forward declared in build_class_reference. */
8926 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8927 DECL_CONTEXT (decl) = NULL_TREE;
8928 finish_decl (decl, expr, NULL_TREE);
8933 handle_class_ref (tree chain)
8935 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8936 char *string = (char *) alloca (strlen (name) + 30);
8940 sprintf (string, "%sobjc_class_name_%s",
8941 (flag_next_runtime ? "." : "__"), name);
8943 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8944 if (flag_next_runtime)
8946 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8951 /* Make a decl for this name, so we can use its address in a tree. */
8952 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8953 DECL_EXTERNAL (decl) = 1;
8954 TREE_PUBLIC (decl) = 1;
8957 rest_of_decl_compilation (decl, 0, 0, 0);
8959 /* Make a decl for the address. */
8960 sprintf (string, "%sobjc_class_ref_%s",
8961 (flag_next_runtime ? "." : "__"), name);
8962 exp = build1 (ADDR_EXPR, string_type_node, decl);
8963 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8964 DECL_INITIAL (decl) = exp;
8965 TREE_STATIC (decl) = 1;
8966 TREE_USED (decl) = 1;
8969 rest_of_decl_compilation (decl, 0, 0, 0);
8973 handle_impent (struct imp_entry *impent)
8977 objc_implementation_context = impent->imp_context;
8978 implementation_template = impent->imp_template;
8980 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8982 const char *const class_name =
8983 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8985 string = (char *) alloca (strlen (class_name) + 30);
8987 sprintf (string, "%sobjc_class_name_%s",
8988 (flag_next_runtime ? "." : "__"), class_name);
8990 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8992 const char *const class_name =
8993 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8994 const char *const class_super_name =
8995 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8997 string = (char *) alloca (strlen (class_name)
8998 + strlen (class_super_name) + 30);
9000 /* Do the same for categories. Even though no references to
9001 these symbols are generated automatically by the compiler, it
9002 gives you a handle to pull them into an archive by hand. */
9003 sprintf (string, "*%sobjc_category_name_%s_%s",
9004 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9009 #ifdef ASM_DECLARE_CLASS_REFERENCE
9010 if (flag_next_runtime)
9012 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9020 init = build_int_2 (0, 0);
9021 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
9022 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9023 TREE_PUBLIC (decl) = 1;
9024 TREE_READONLY (decl) = 1;
9025 TREE_USED (decl) = 1;
9026 TREE_CONSTANT (decl) = 1;
9027 DECL_CONTEXT (decl) = 0;
9028 DECL_ARTIFICIAL (decl) = 1;
9029 DECL_INITIAL (decl) = init;
9030 assemble_variable (decl, 1, 0, 0);
9034 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9035 later requires that ObjC translation units participating in F&C be
9036 specially marked. The following routine accomplishes this. */
9038 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9041 generate_objc_image_info (void)
9043 tree sc_spec, decl, initlist;
9045 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9047 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9048 tree_cons (NULL_TREE,
9051 build_index_type (build_int_2 (1, 0))),
9056 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9057 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9058 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9060 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9061 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9062 finish_decl (decl, initlist, NULL_TREE);
9065 /* Look up ID as an instance variable. */
9068 lookup_objc_ivar (tree id)
9072 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9073 /* We have a message to super. */
9074 return get_super_receiver ();
9075 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9077 if (is_private (decl))
9080 return build_ivar_reference (id);
9086 #include "gt-objc-objc-act.h"
9087 #include "gtype-objc.h"