1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
53 #include "langhooks.h"
64 #include "diagnostic.h"
66 #include "tree-iterator.h"
69 /* This is the default way of generating a method name. */
70 /* I am not sure it is really correct.
71 Perhaps there's a danger that it will make name conflicts
72 if method names contain underscores. -- rms. */
73 #ifndef OBJC_GEN_METHOD_LABEL
74 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
77 sprintf ((BUF), "_%s_%s_%s_%s", \
78 ((IS_INST) ? "i" : "c"), \
80 ((CAT_NAME)? (CAT_NAME) : ""), \
82 for (temp = (BUF); *temp; temp++) \
83 if (*temp == ':') *temp = '_'; \
87 /* These need specifying. */
88 #ifndef OBJC_FORWARDING_STACK_OFFSET
89 #define OBJC_FORWARDING_STACK_OFFSET 0
92 #ifndef OBJC_FORWARDING_MIN_OFFSET
93 #define OBJC_FORWARDING_MIN_OFFSET 0
96 /* Set up for use of obstacks. */
100 /* This obstack is used to accumulate the encoding of a data type. */
101 static struct obstack util_obstack;
103 /* This points to the beginning of obstack contents, so we can free
104 the whole contents. */
107 /* The version identifies which language generation and runtime
108 the module (file) was compiled for, and is recorded in the
109 module descriptor. */
111 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
112 #define PROTOCOL_VERSION 2
114 /* (Decide if these can ever be validly changed.) */
115 #define OBJC_ENCODE_INLINE_DEFS 0
116 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
118 /*** Private Interface (procedures) ***/
120 /* Used by compile_file. */
122 static void init_objc (void);
123 static void finish_objc (void);
125 /* Code generation. */
127 static void synth_module_prologue (void);
128 static tree objc_build_constructor (tree, tree);
129 static rtx build_module_descriptor (void);
130 static tree init_module_descriptor (tree);
131 static tree build_objc_method_call (int, tree, tree, tree, tree);
132 static void generate_strings (void);
133 static tree get_proto_encoding (tree);
134 static void build_selector_translation_table (void);
136 static tree objc_add_static_instance (tree, tree);
138 static void build_objc_exception_stuff (void);
139 static void build_next_objc_exception_stuff (void);
141 static tree build_ivar_template (void);
142 static tree build_method_template (void);
143 static tree build_private_template (tree);
144 static void build_class_template (void);
145 static void build_selector_template (void);
146 static void build_category_template (void);
147 static tree lookup_method_in_hash_lists (tree, int);
148 static void build_super_template (void);
149 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
150 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
151 static void synth_forward_declarations (void);
152 static int ivar_list_length (tree);
153 static tree get_class_ivars (tree, int);
154 static void generate_ivar_lists (void);
155 static void generate_dispatch_tables (void);
156 static void generate_shared_structures (void);
157 static tree generate_protocol_list (tree);
158 static void build_protocol_reference (tree);
160 static tree build_keyword_selector (tree);
161 static tree synth_id_with_class_suffix (const char *, tree);
163 static void generate_static_references (void);
164 static int check_methods_accessible (tree, tree, int);
165 static void encode_aggregate_within (tree, int, int, int, int);
166 static const char *objc_demangle (const char *);
167 static void objc_expand_function_end (void);
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash *nst_method_hash_list = 0;
172 hash *cls_method_hash_list = 0;
174 static size_t hash_func (tree);
175 static void hash_init (void);
176 static void hash_enter (hash *, tree);
177 static hash hash_lookup (hash *, tree);
178 static void hash_add_attr (hash, tree);
179 static tree lookup_method (tree, tree);
180 static tree lookup_method_static (tree, tree, int);
181 static void add_method_to_hash_list (hash *, tree);
182 static tree add_class (tree);
183 static void add_category (tree, tree);
184 static inline tree lookup_category (tree, tree);
188 class_names, /* class, category, protocol, module names */
189 meth_var_names, /* method and variable names */
190 meth_var_types /* method and variable type descriptors */
193 static tree add_objc_string (tree, enum string_section);
194 static tree get_objc_string_decl (tree, enum string_section);
195 static tree build_objc_string_decl (enum string_section);
196 static tree build_selector_reference_decl (void);
198 /* Protocol additions. */
200 static tree add_protocol (tree);
201 static tree lookup_protocol (tree);
202 static void check_protocol_recursively (tree, tree);
203 static tree lookup_and_install_protocols (tree);
207 static void encode_type_qualifiers (tree);
208 static void encode_pointer (tree, int, int);
209 static void encode_array (tree, int, int);
210 static void encode_aggregate (tree, int, int);
211 static void encode_next_bitfield (int);
212 static void encode_gnu_bitfield (int, tree, int);
213 static void encode_type (tree, int, int);
214 static void encode_field_decl (tree, int, int);
216 static void really_start_method (tree, tree);
217 static int comp_method_with_proto (tree, tree);
218 static int objc_types_are_equivalent (tree, tree);
219 static int comp_proto_with_proto (tree, tree);
220 static tree get_arg_type_list (tree, int, int);
221 static tree objc_expr_last (tree);
222 static void synth_self_and_ucmd_args (void);
224 /* Utilities for debugging and error diagnostics. */
226 static void warn_with_method (const char *, int, tree);
227 static void error_with_ivar (const char *, tree, tree);
228 static char *gen_method_decl (tree, char *);
229 static char *gen_declaration (tree, char *);
230 static void gen_declaration_1 (tree, char *);
231 static char *gen_declarator (tree, char *, const char *);
232 static int is_complex_decl (tree);
233 static void adorn_decl (tree, char *);
234 static void dump_interface (FILE *, tree);
236 /* Everything else. */
238 static tree define_decl (tree, tree);
239 static tree lookup_method_in_protocol_list (tree, tree, int);
240 static tree lookup_protocol_in_reflist (tree, tree);
241 static tree create_builtin_decl (enum tree_code, tree, const char *);
242 static void setup_string_decl (void);
243 static int check_string_class_template (void);
244 static tree my_build_string (int, const char *);
245 static void build_objc_symtab_template (void);
246 static tree init_def_list (tree);
247 static tree init_objc_symtab (tree);
248 static tree build_metadata_decl (const char *, tree);
249 static void forward_declare_categories (void);
250 static void generate_objc_symtab_decl (void);
251 static tree build_selector (tree);
252 static tree build_typed_selector_reference (tree, tree);
253 static tree build_selector_reference (tree);
254 static tree build_class_reference_decl (void);
255 static void add_class_reference (tree);
256 static tree build_protocol_template (void);
257 static tree build_descriptor_table_initializer (tree, tree);
258 static tree build_method_prototype_list_template (tree, int);
259 static tree build_method_prototype_template (void);
260 static tree objc_method_parm_type (tree);
261 static int objc_encoded_type_size (tree);
262 static tree encode_method_prototype (tree);
263 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
264 static void generate_method_descriptors (tree);
265 static void generate_protocol_references (tree);
266 static void generate_protocols (void);
267 static void check_ivars (tree, tree);
268 static tree build_ivar_list_template (tree, int);
269 static tree build_method_list_template (tree, int);
270 static tree build_ivar_list_initializer (tree, tree);
271 static tree generate_ivars_list (tree, const char *, int, tree);
272 static tree build_dispatch_table_initializer (tree, tree);
273 static tree generate_dispatch_table (tree, const char *, int, tree);
274 static tree build_shared_structure_initializer (tree, tree, tree, tree,
275 tree, int, tree, tree, tree);
276 static void generate_category (tree);
277 static int is_objc_type_qualifier (tree);
278 static tree adjust_type_for_id_default (tree);
279 static tree check_duplicates (hash, int, int);
280 static tree receiver_is_class_object (tree, int, int);
281 static int check_methods (tree, tree, int);
282 static int conforms_to_protocol (tree, tree);
283 static void check_protocol (tree, const char *, const char *);
284 static void check_protocols (tree, const char *, const char *);
285 static void gen_declspecs (tree, char *, int);
286 static void generate_classref_translation_entry (tree);
287 static void handle_class_ref (tree);
288 static void generate_struct_by_value_array (void)
290 static void mark_referenced_methods (void);
291 static void generate_objc_image_info (void);
293 /*** Private Interface (data) ***/
295 /* Reserved tag definitions. */
298 #define TAG_OBJECT "objc_object"
299 #define TAG_CLASS "objc_class"
300 #define TAG_SUPER "objc_super"
301 #define TAG_SELECTOR "objc_selector"
303 #define UTAG_CLASS "_objc_class"
304 #define UTAG_IVAR "_objc_ivar"
305 #define UTAG_IVAR_LIST "_objc_ivar_list"
306 #define UTAG_METHOD "_objc_method"
307 #define UTAG_METHOD_LIST "_objc_method_list"
308 #define UTAG_CATEGORY "_objc_category"
309 #define UTAG_MODULE "_objc_module"
310 #define UTAG_SYMTAB "_objc_symtab"
311 #define UTAG_SUPER "_objc_super"
312 #define UTAG_SELECTOR "_objc_selector"
314 #define UTAG_PROTOCOL "_objc_protocol"
315 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
316 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
318 /* Note that the string object global name is only needed for the
320 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
322 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
324 static const char *TAG_GETCLASS;
325 static const char *TAG_GETMETACLASS;
326 static const char *TAG_MSGSEND;
327 static const char *TAG_MSGSENDSUPER;
328 /* The NeXT Objective-C messenger may have two extra entry points, for use
329 when returning a structure. */
330 static const char *TAG_MSGSEND_STRET;
331 static const char *TAG_MSGSENDSUPER_STRET;
332 static const char *TAG_EXECCLASS;
333 static const char *default_constant_string_class_name;
335 /* Runtime metadata flags. */
336 #define CLS_FACTORY 0x0001L
337 #define CLS_META 0x0002L
339 #define OBJC_MODIFIER_STATIC 0x00000001
340 #define OBJC_MODIFIER_FINAL 0x00000002
341 #define OBJC_MODIFIER_PUBLIC 0x00000004
342 #define OBJC_MODIFIER_PRIVATE 0x00000008
343 #define OBJC_MODIFIER_PROTECTED 0x00000010
344 #define OBJC_MODIFIER_NATIVE 0x00000020
345 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
346 #define OBJC_MODIFIER_ABSTRACT 0x00000080
347 #define OBJC_MODIFIER_VOLATILE 0x00000100
348 #define OBJC_MODIFIER_TRANSIENT 0x00000200
349 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
351 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
352 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
353 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
354 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
355 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
356 #define TAG_EXCEPTIONMATCH "objc_exception_match"
357 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
358 #define TAG_SYNCENTER "objc_sync_enter"
359 #define TAG_SYNCEXIT "objc_sync_exit"
360 #define TAG_SETJMP "_setjmp"
361 #define TAG_RETURN_STRUCT "objc_return_struct"
363 #define UTAG_EXCDATA "_objc_exception_data"
365 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
366 tree objc_global_trees[OCTI_MAX];
368 static void handle_impent (struct imp_entry *);
370 struct imp_entry *imp_list = 0;
371 int imp_count = 0; /* `@implementation' */
372 int cat_count = 0; /* `@category' */
374 /* Use to generate method labels. */
375 static int method_slot = 0;
379 static char *errbuf; /* Buffer for error diagnostics */
381 /* Data imported from tree.c. */
383 extern enum debug_info_type write_symbols;
385 /* Data imported from toplev.c. */
387 extern const char *dump_base_name;
389 static int flag_typed_selectors;
391 FILE *gen_declaration_file;
393 /* Tells "encode_pointer/encode_aggregate" whether we are generating
394 type descriptors for instance variables (as opposed to methods).
395 Type descriptors for instance variables contain more information
396 than methods (for static typing and embedded structures). */
398 static int generating_instance_variables = 0;
400 /* Some platforms pass small structures through registers versus
401 through an invisible pointer. Determine at what size structure is
402 the transition point between the two possibilities. */
405 generate_struct_by_value_array (void)
408 tree field_decl, field_decl_chain;
410 int aggregate_in_mem[32];
413 /* Presumably no platform passes 32 byte structures in a register. */
414 for (i = 1; i < 32; i++)
418 /* Create an unnamed struct that has `i' character components */
419 type = start_struct (RECORD_TYPE, NULL_TREE);
421 strcpy (buffer, "c1");
422 field_decl = create_builtin_decl (FIELD_DECL,
425 field_decl_chain = field_decl;
427 for (j = 1; j < i; j++)
429 sprintf (buffer, "c%d", j + 1);
430 field_decl = create_builtin_decl (FIELD_DECL,
433 chainon (field_decl_chain, field_decl);
435 finish_struct (type, field_decl_chain, NULL_TREE);
437 aggregate_in_mem[i] = aggregate_value_p (type, 0);
438 if (!aggregate_in_mem[i])
442 /* We found some structures that are returned in registers instead of memory
443 so output the necessary data. */
446 for (i = 31; i >= 0; i--)
447 if (!aggregate_in_mem[i])
449 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
451 /* The first member of the structure is always 0 because we don't handle
452 structures with 0 members */
453 printf ("static int struct_forward_array[] = {\n 0");
455 for (j = 1; j <= i; j++)
456 printf (", %d", aggregate_in_mem[j]);
466 if (c_objc_common_init () == false)
469 /* Force the line number back to 0; check_newline will have
470 raised it to 1, which will make the builtin functions appear
471 not to be built in. */
474 /* If gen_declaration desired, open the output file. */
475 if (flag_gen_declaration)
477 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
478 gen_declaration_file = fopen (dumpname, "w");
479 if (gen_declaration_file == 0)
480 fatal_error ("can't open %s: %m", dumpname);
484 if (flag_next_runtime)
486 TAG_GETCLASS = "objc_getClass";
487 TAG_GETMETACLASS = "objc_getMetaClass";
488 TAG_MSGSEND = "objc_msgSend";
489 TAG_MSGSENDSUPER = "objc_msgSendSuper";
490 TAG_MSGSEND_STRET = "objc_msgSend_stret";
491 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
492 TAG_EXECCLASS = "__objc_execClass";
493 default_constant_string_class_name = "NSConstantString";
497 TAG_GETCLASS = "objc_get_class";
498 TAG_GETMETACLASS = "objc_get_meta_class";
499 TAG_MSGSEND = "objc_msg_lookup";
500 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
501 /* GNU runtime does not provide special functions to support
502 structure-returning methods. */
503 TAG_EXECCLASS = "__objc_exec_class";
504 default_constant_string_class_name = "NXConstantString";
505 flag_typed_selectors = 1;
508 objc_ellipsis_node = make_node (ERROR_MARK);
512 if (print_struct_values)
513 generate_struct_by_value_array ();
521 mark_referenced_methods ();
522 c_objc_common_finish_file ();
524 /* Finalize Objective-C runtime data. No need to generate tables
525 and code if only checking syntax. */
526 if (!flag_syntax_only)
529 if (gen_declaration_file)
530 fclose (gen_declaration_file);
534 define_decl (tree declarator, tree declspecs)
536 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
537 finish_decl (decl, NULL_TREE, NULL_TREE);
542 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
548 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
550 p = TREE_VALUE (rproto);
552 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
554 if ((fnd = lookup_method (class_meth
555 ? PROTOCOL_CLS_METHODS (p)
556 : PROTOCOL_NST_METHODS (p), sel_name)))
558 else if (PROTOCOL_LIST (p))
559 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
560 sel_name, class_meth);
564 ; /* An identifier...if we could not find a protocol. */
575 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
579 /* Make sure the protocol is supported by the object on the rhs. */
580 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
583 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
585 p = TREE_VALUE (rproto);
587 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
592 else if (PROTOCOL_LIST (p))
593 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
602 ; /* An identifier...if we could not find a protocol. */
608 /* Return true if TYPE is 'id'. */
611 objc_is_object_id (tree type)
613 return OBJC_TYPE_NAME (type) == objc_object_id;
617 objc_is_class_id (tree type)
619 return OBJC_TYPE_NAME (type) == objc_class_id;
622 /* Return 1 if LHS and RHS are compatible types for assignment or
623 various other operations. Return 0 if they are incompatible, and
624 return -1 if we choose to not decide (because the types are really
625 just C types, not ObjC specific ones). When the operation is
626 REFLEXIVE (typically comparisons), check for compatibility in
627 either direction; when it's not (typically assignments), don't.
629 This function is called in two cases: when both lhs and rhs are
630 pointers to records (in which case we check protocols too), and
631 when both lhs and rhs are records (in which case we check class
634 Warnings about classes/protocols not implementing a protocol are
635 emitted here (multiple of those warnings might be emitted for a
636 single line!); generic warnings about incompatible assignments and
637 lacks of casts in comparisons are/must be emitted by the caller if
642 objc_comptypes (tree lhs, tree rhs, int reflexive)
644 /* New clause for protocols. */
646 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
647 manage the ObjC ones, and leave the rest to the C code. */
648 if (TREE_CODE (lhs) == POINTER_TYPE
649 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
650 && TREE_CODE (rhs) == POINTER_TYPE
651 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
653 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
654 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
658 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
659 tree rproto, rproto_list;
662 /* <Protocol> = <Protocol> */
665 rproto_list = TYPE_PROTOCOL_LIST (rhs);
669 /* An assignment between objects of type 'id
670 <Protocol>'; make sure the protocol on the lhs is
671 supported by the object on the rhs. */
672 for (lproto = lproto_list; lproto;
673 lproto = TREE_CHAIN (lproto))
675 p = TREE_VALUE (lproto);
676 rproto = lookup_protocol_in_reflist (rproto_list, p);
680 ("object does not conform to the `%s' protocol",
681 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
687 /* Obscure case - a comparison between two objects
688 of type 'id <Protocol>'. Check that either the
689 protocol on the lhs is supported by the object on
690 the rhs, or viceversa. */
692 /* Check if the protocol on the lhs is supported by the
693 object on the rhs. */
694 for (lproto = lproto_list; lproto;
695 lproto = TREE_CHAIN (lproto))
697 p = TREE_VALUE (lproto);
698 rproto = lookup_protocol_in_reflist (rproto_list, p);
702 /* Check failed - check if the protocol on the rhs
703 is supported by the object on the lhs. */
704 for (rproto = rproto_list; rproto;
705 rproto = TREE_CHAIN (rproto))
707 p = TREE_VALUE (rproto);
708 lproto = lookup_protocol_in_reflist (lproto_list,
713 /* This check failed too: incompatible */
723 /* <Protocol> = <class> * */
724 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
726 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
729 /* Make sure the protocol is supported by the object on
731 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
733 p = TREE_VALUE (lproto);
735 rinter = lookup_interface (rname);
737 while (rinter && !rproto)
741 rproto_list = CLASS_PROTOCOL_LIST (rinter);
742 rproto = lookup_protocol_in_reflist (rproto_list, p);
743 /* If the underlying ObjC class does not have
744 the protocol we're looking for, check for "one-off"
745 protocols (e.g., `NSObject<MyProt> *foo;') attached
749 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
750 rproto = lookup_protocol_in_reflist (rproto_list, p);
753 /* Check for protocols adopted by categories. */
754 cat = CLASS_CATEGORY_LIST (rinter);
755 while (cat && !rproto)
757 rproto_list = CLASS_PROTOCOL_LIST (cat);
758 rproto = lookup_protocol_in_reflist (rproto_list, p);
759 cat = CLASS_CATEGORY_LIST (cat);
762 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
766 warning ("class `%s' does not implement the `%s' protocol",
767 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
768 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
772 /* <Protocol> = id */
773 else if (objc_is_object_id (TREE_TYPE (rhs)))
777 /* <Protocol> = Class */
778 else if (objc_is_class_id (TREE_TYPE (rhs)))
782 /* <Protocol> = ?? : let comptypes decide. */
785 else if (rhs_is_proto)
787 /* <class> * = <Protocol> */
788 if (TYPED_OBJECT (TREE_TYPE (lhs)))
792 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
794 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
796 /* Make sure the protocol is supported by the object on
798 for (rproto = rproto_list; rproto;
799 rproto = TREE_CHAIN (rproto))
801 tree p = TREE_VALUE (rproto);
803 rinter = lookup_interface (rname);
805 while (rinter && !lproto)
809 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
810 lproto = lookup_protocol_in_reflist (lproto_list, p);
811 /* If the underlying ObjC class does not
812 have the protocol we're looking for,
813 check for "one-off" protocols (e.g.,
814 `NSObject<MyProt> *foo;') attached to the
818 lproto_list = TYPE_PROTOCOL_LIST
820 lproto = lookup_protocol_in_reflist
824 /* Check for protocols adopted by categories. */
825 cat = CLASS_CATEGORY_LIST (rinter);
826 while (cat && !lproto)
828 lproto_list = CLASS_PROTOCOL_LIST (cat);
829 lproto = lookup_protocol_in_reflist (lproto_list,
831 cat = CLASS_CATEGORY_LIST (cat);
834 rinter = lookup_interface (CLASS_SUPER_NAME
839 warning ("class `%s' does not implement the `%s' protocol",
840 IDENTIFIER_POINTER (OBJC_TYPE_NAME
842 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
849 /* id = <Protocol> */
850 else if (objc_is_object_id (TREE_TYPE (lhs)))
854 /* Class = <Protocol> */
855 else if (objc_is_class_id (TREE_TYPE (lhs)))
859 /* ??? = <Protocol> : let comptypes decide */
867 /* Attention: we shouldn't defer to comptypes here. One bad
868 side effect would be that we might loose the REFLEXIVE
871 lhs = TREE_TYPE (lhs);
872 rhs = TREE_TYPE (rhs);
876 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
878 /* Nothing to do with ObjC - let immediately comptypes take
879 responsibility for checking. */
883 /* `id' = `<class> *' `<class> *' = `id': always allow it.
885 'Object *o = [[Object alloc] init]; falls
886 in the case <class> * = `id'.
888 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
889 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
892 /* `id' = `Class', `Class' = `id' */
894 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
895 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
898 /* `Class' != `<class> *' && `<class> *' != `Class'! */
899 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
900 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
903 /* `<class> *' = `<class> *' */
905 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
907 tree lname = OBJC_TYPE_NAME (lhs);
908 tree rname = OBJC_TYPE_NAME (rhs);
914 /* If the left hand side is a super class of the right hand side,
916 for (inter = lookup_interface (rname); inter;
917 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
918 if (lname == CLASS_SUPER_NAME (inter))
921 /* Allow the reverse when reflexive. */
923 for (inter = lookup_interface (lname); inter;
924 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
925 if (rname == CLASS_SUPER_NAME (inter))
931 /* Not an ObjC type - let comptypes do the check. */
935 /* Called from finish_decl. */
938 objc_check_decl (tree decl)
940 tree type = TREE_TYPE (decl);
942 if (TREE_CODE (type) != RECORD_TYPE)
944 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
945 error ("statically allocated instance of Objective-C class `%s'",
946 IDENTIFIER_POINTER (type));
949 /* Implement static typing. At this point, we know we have an interface. */
952 get_static_reference (tree interface, tree protocols)
954 tree type = xref_tag (RECORD_TYPE, interface);
958 tree t, m = TYPE_MAIN_VARIANT (type);
960 t = copy_node (type);
962 /* Add this type to the chain of variants of TYPE. */
963 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
964 TYPE_NEXT_VARIANT (m) = t;
966 /* Look up protocols and install in lang specific list. Note
967 that the protocol list can have a different lifetime than T! */
968 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
970 /* This forces a new pointer type to be created later
971 (in build_pointer_type)...so that the new template
972 we just created will actually be used...what a hack! */
973 if (TYPE_POINTER_TO (t))
974 TYPE_POINTER_TO (t) = NULL_TREE;
983 get_object_reference (tree protocols)
985 tree type_decl = lookup_name (objc_id_id);
988 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
990 type = TREE_TYPE (type_decl);
991 if (TYPE_MAIN_VARIANT (type) != id_type)
992 warning ("unexpected type for `id' (%s)",
993 gen_declaration (type, errbuf));
997 error ("undefined type `id', please import <objc/objc.h>");
998 return error_mark_node;
1001 /* This clause creates a new pointer type that is qualified with
1002 the protocol specification...this info is used later to do more
1003 elaborate type checking. */
1007 tree t, m = TYPE_MAIN_VARIANT (type);
1009 t = copy_node (type);
1011 /* Add this type to the chain of variants of TYPE. */
1012 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1013 TYPE_NEXT_VARIANT (m) = t;
1015 /* Look up protocols...and install in lang specific list */
1016 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1018 /* This forces a new pointer type to be created later
1019 (in build_pointer_type)...so that the new template
1020 we just created will actually be used...what a hack! */
1021 if (TYPE_POINTER_TO (t))
1022 TYPE_POINTER_TO (t) = NULL_TREE;
1029 /* Check for circular dependencies in protocols. The arguments are
1030 PROTO, the protocol to check, and LIST, a list of protocol it
1034 check_protocol_recursively (tree proto, tree list)
1038 for (p = list; p; p = TREE_CHAIN (p))
1040 tree pp = TREE_VALUE (p);
1042 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1043 pp = lookup_protocol (pp);
1046 fatal_error ("protocol `%s' has circular dependency",
1047 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1049 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1053 /* Look up PROTOCOLS, and return a list of those that are found.
1054 If none are found, return NULL. */
1057 lookup_and_install_protocols (tree protocols)
1060 tree return_value = NULL_TREE;
1062 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1064 tree ident = TREE_VALUE (proto);
1065 tree p = lookup_protocol (ident);
1068 error ("cannot find protocol declaration for `%s'",
1069 IDENTIFIER_POINTER (ident));
1071 return_value = chainon (return_value,
1072 build_tree_list (NULL_TREE, p));
1075 return return_value;
1078 /* Create and push a decl for a built-in external variable or field NAME.
1080 TYPE is its data type. */
1083 create_builtin_decl (enum tree_code code, tree type, const char *name)
1085 tree decl = build_decl (code, get_identifier (name), type);
1087 if (code == VAR_DECL)
1089 TREE_STATIC (decl) = 1;
1090 make_decl_rtl (decl, 0);
1092 DECL_ARTIFICIAL (decl) = 1;
1098 /* Find the decl for the constant string class. */
1101 setup_string_decl (void)
1103 if (!string_class_decl)
1105 if (!constant_string_global_id)
1109 /* %s in format will provide room for terminating null */
1110 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1111 + strlen (constant_string_class_name);
1112 name = xmalloc (length);
1113 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1114 constant_string_class_name);
1115 constant_string_global_id = get_identifier (name);
1117 string_class_decl = lookup_name (constant_string_global_id);
1121 /* Purpose: "play" parser, creating/installing representations
1122 of the declarations that are required by Objective-C.
1126 type_spec--------->sc_spec
1127 (tree_list) (tree_list)
1130 identifier_node identifier_node */
1133 synth_module_prologue (void)
1137 /* Defined in `objc.h' */
1138 objc_object_id = get_identifier (TAG_OBJECT);
1140 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1142 id_type = build_pointer_type (objc_object_reference);
1144 objc_id_id = get_identifier (TYPE_ID);
1145 objc_class_id = get_identifier (TAG_CLASS);
1147 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1148 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1149 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1150 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1153 /* Declare type of selector-objects that represent an operation name. */
1155 if (flag_next_runtime)
1156 /* `struct objc_selector *' */
1158 = build_pointer_type (xref_tag (RECORD_TYPE,
1159 get_identifier (TAG_SELECTOR)));
1161 /* `const struct objc_selector *' */
1163 = build_pointer_type
1164 (build_qualified_type (xref_tag (RECORD_TYPE,
1165 get_identifier (TAG_SELECTOR)),
1168 /* Declare receiver type used for dispatching messages to 'super'. */
1170 /* `struct objc_super *' */
1171 super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1172 get_identifier (TAG_SUPER)));
1174 if (flag_next_runtime)
1176 /* NB: In order to call one of the ..._stret (struct-returning)
1177 functions, the function *MUST* first be cast to a signature that
1178 corresponds to the actual ObjC method being invoked. This is
1179 what is done by the build_objc_method_call() routine below. */
1181 /* id objc_msgSend (id, SEL, ...); */
1182 /* id objc_msgSendNonNil (id, SEL, ...); */
1183 /* id objc_msgSend_stret (id, SEL, ...); */
1184 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1186 = build_function_type (id_type,
1187 tree_cons (NULL_TREE, id_type,
1188 tree_cons (NULL_TREE, selector_type,
1190 umsg_decl = builtin_function (TAG_MSGSEND,
1191 temp_type, 0, NOT_BUILT_IN,
1193 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1194 temp_type, 0, NOT_BUILT_IN,
1196 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1197 temp_type, 0, NOT_BUILT_IN,
1199 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1200 temp_type, 0, NOT_BUILT_IN,
1203 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1204 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1206 = build_function_type (id_type,
1207 tree_cons (NULL_TREE, super_type,
1208 tree_cons (NULL_TREE, selector_type,
1210 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1211 temp_type, 0, NOT_BUILT_IN,
1213 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1214 temp_type, 0, NOT_BUILT_IN, 0,
1219 /* GNU runtime messenger entry points. */
1221 /* typedef id (*IMP)(id, SEL, ...); */
1223 = build_pointer_type
1224 (build_function_type (id_type,
1225 tree_cons (NULL_TREE, id_type,
1226 tree_cons (NULL_TREE, selector_type,
1229 /* IMP objc_msg_lookup (id, SEL); */
1231 = build_function_type (IMP_type,
1232 tree_cons (NULL_TREE, id_type,
1233 tree_cons (NULL_TREE, selector_type,
1235 umsg_decl = builtin_function (TAG_MSGSEND,
1236 temp_type, 0, NOT_BUILT_IN,
1239 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1241 = build_function_type (IMP_type,
1242 tree_cons (NULL_TREE, super_type,
1243 tree_cons (NULL_TREE, selector_type,
1245 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1246 temp_type, 0, NOT_BUILT_IN,
1250 /* id objc_getClass (const char *); */
1252 temp_type = build_function_type (id_type,
1253 tree_cons (NULL_TREE,
1254 const_string_type_node,
1258 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1261 /* id objc_getMetaClass (const char *); */
1263 objc_get_meta_class_decl
1264 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1266 build_super_template ();
1267 build_objc_exception_stuff ();
1268 if (flag_next_runtime)
1269 build_next_objc_exception_stuff ();
1271 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1273 if (! flag_next_runtime)
1275 if (flag_typed_selectors)
1277 /* Suppress outputting debug symbols, because
1278 dbxout_init hasn'r been called yet. */
1279 enum debug_info_type save_write_symbols = write_symbols;
1280 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1281 write_symbols = NO_DEBUG;
1282 debug_hooks = &do_nothing_debug_hooks;
1284 build_selector_template ();
1285 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1287 write_symbols = save_write_symbols;
1288 debug_hooks = save_hooks;
1291 temp_type = build_array_type (selector_type, NULL_TREE);
1293 layout_type (temp_type);
1294 UOBJC_SELECTOR_TABLE_decl
1295 = create_builtin_decl (VAR_DECL, temp_type,
1296 "_OBJC_SELECTOR_TABLE");
1298 /* Avoid warning when not sending messages. */
1299 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1302 /* Forward declare constant_string_id and constant_string_type. */
1303 if (!constant_string_class_name)
1304 constant_string_class_name = default_constant_string_class_name;
1306 constant_string_id = get_identifier (constant_string_class_name);
1307 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1309 /* Pre-build the following entities - for speed/convenience. */
1310 self_id = get_identifier ("self");
1311 ucmd_id = get_identifier ("_cmd");
1313 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1314 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1318 /* Ensure that the ivar list for NSConstantString/NXConstantString
1319 (or whatever was specified via `-fconstant-string-class')
1320 contains fields at least as large as the following three, so that
1321 the runtime can stomp on them with confidence:
1323 struct STRING_OBJECT_CLASS_NAME
1327 unsigned int length;
1331 check_string_class_template (void)
1333 tree field_decl = TYPE_FIELDS (constant_string_type);
1335 #define AT_LEAST_AS_LARGE_AS(F, T) \
1336 (F && TREE_CODE (F) == FIELD_DECL \
1337 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1338 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1340 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1343 field_decl = TREE_CHAIN (field_decl);
1344 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1347 field_decl = TREE_CHAIN (field_decl);
1348 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1350 #undef AT_LEAST_AS_LARGE_AS
1353 /* Avoid calling `check_string_class_template ()' more than once. */
1354 static GTY(()) int string_layout_checked;
1356 /* Custom build_string which sets TREE_TYPE! */
1359 my_build_string (int len, const char *str)
1361 return fix_string_type (build_string (len, str));
1364 /* Given a chain of STRING_CST's, build a static instance of
1365 NXConstantString which points at the concatenation of those
1366 strings. We place the string object in the __string_objects
1367 section of the __OBJC segment. The Objective-C runtime will
1368 initialize the isa pointers of the string objects to point at the
1369 NXConstantString class object. */
1372 build_objc_string_object (tree string)
1374 tree initlist, constructor, constant_string_class;
1378 string = fix_string_type (string);
1380 constant_string_class = lookup_interface (constant_string_id);
1381 if (!constant_string_class
1382 || !(constant_string_type
1383 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1385 error ("cannot find interface declaration for `%s'",
1386 IDENTIFIER_POINTER (constant_string_id));
1387 return error_mark_node;
1390 /* Call to 'combine_strings' has been moved above. */
1391 TREE_SET_CODE (string, STRING_CST);
1392 length = TREE_STRING_LENGTH (string) - 1;
1394 if (!string_layout_checked)
1396 /* The NSConstantString/NXConstantString ivar layout is now
1398 if (!check_string_class_template ())
1400 error ("interface `%s' does not have valid constant string layout",
1401 IDENTIFIER_POINTER (constant_string_id));
1402 return error_mark_node;
1404 add_class_reference (constant_string_id);
1406 fields = TYPE_FIELDS (constant_string_type);
1408 /* & ((NXConstantString) { NULL, string, length }) */
1410 if (flag_next_runtime)
1412 /* For the NeXT runtime, we can generate a literal reference
1413 to the string class, don't need to run a constructor. */
1414 setup_string_decl ();
1415 if (string_class_decl == NULL_TREE)
1417 error ("cannot find reference tag for class `%s'",
1418 IDENTIFIER_POINTER (constant_string_id));
1419 return error_mark_node;
1421 initlist = build_tree_list
1423 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1427 initlist = build_tree_list (fields, build_int_2 (0, 0));
1430 fields = TREE_CHAIN (fields);
1433 = tree_cons (fields, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1436 fields = TREE_CHAIN (fields);
1438 initlist = tree_cons (fields, build_int_2 (length, 0), initlist);
1439 constructor = objc_build_constructor (constant_string_type,
1440 nreverse (initlist));
1442 if (!flag_next_runtime)
1445 = objc_add_static_instance (constructor, constant_string_type);
1448 return (build_unary_op (ADDR_EXPR, constructor, 1));
1451 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1453 static GTY(()) int num_static_inst;
1456 objc_add_static_instance (tree constructor, tree class_decl)
1461 /* Find the list of static instances for the CLASS_DECL. Create one if
1463 for (chain = &objc_static_instances;
1464 *chain && TREE_VALUE (*chain) != class_decl;
1465 chain = &TREE_CHAIN (*chain));
1468 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1469 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1472 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1473 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1474 DECL_COMMON (decl) = 1;
1475 TREE_STATIC (decl) = 1;
1476 DECL_ARTIFICIAL (decl) = 1;
1477 DECL_INITIAL (decl) = constructor;
1479 /* We may be writing something else just now.
1480 Postpone till end of input. */
1481 DECL_DEFER_OUTPUT (decl) = 1;
1482 pushdecl_top_level (decl);
1483 rest_of_decl_compilation (decl, 0, 1, 0);
1485 /* Add the DECL to the head of this CLASS' list. */
1486 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1491 /* Build a static constant CONSTRUCTOR
1492 with type TYPE and elements ELTS. */
1495 objc_build_constructor (tree type, tree elts)
1497 tree constructor, f, e;
1499 /* ??? Most of the places that we build constructors, we don't fill in
1500 the type of integers properly. Convert them all en masse. */
1501 if (TREE_CODE (type) == ARRAY_TYPE)
1503 f = TREE_TYPE (type);
1504 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1505 for (e = elts; e ; e = TREE_CHAIN (e))
1506 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1510 f = TYPE_FIELDS (type);
1511 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1512 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1513 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1514 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1517 constructor = build_constructor (type, elts);
1518 TREE_CONSTANT (constructor) = 1;
1519 TREE_STATIC (constructor) = 1;
1520 TREE_READONLY (constructor) = 1;
1523 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1524 build_unary_op (wasn't true in 2.7.2.1 days) */
1525 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1530 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1532 /* Predefine the following data type:
1540 void *defs[cls_def_cnt + cat_def_cnt];
1544 build_objc_symtab_template (void)
1546 tree field_decl, field_decl_chain;
1548 objc_symtab_template
1549 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1551 /* long sel_ref_cnt; */
1553 field_decl = create_builtin_decl (FIELD_DECL,
1554 long_integer_type_node,
1556 field_decl_chain = field_decl;
1560 field_decl = create_builtin_decl (FIELD_DECL,
1561 build_pointer_type (selector_type),
1563 chainon (field_decl_chain, field_decl);
1565 /* short cls_def_cnt; */
1567 field_decl = create_builtin_decl (FIELD_DECL,
1568 short_integer_type_node,
1570 chainon (field_decl_chain, field_decl);
1572 /* short cat_def_cnt; */
1574 field_decl = create_builtin_decl (FIELD_DECL,
1575 short_integer_type_node,
1577 chainon (field_decl_chain, field_decl);
1579 if (imp_count || cat_count || !flag_next_runtime)
1581 /* void *defs[imp_count + cat_count (+ 1)]; */
1582 /* NB: The index is one less than the size of the array. */
1583 int index = imp_count + cat_count
1584 + (flag_next_runtime? -1: 0);
1585 field_decl = create_builtin_decl
1589 build_index_type (build_int_2 (index, 0))),
1591 chainon (field_decl_chain, field_decl);
1594 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1597 /* Create the initial value for the `defs' field of _objc_symtab.
1598 This is a CONSTRUCTOR. */
1601 init_def_list (tree type)
1603 tree expr, initlist = NULL_TREE;
1604 struct imp_entry *impent;
1607 for (impent = imp_list; impent; impent = impent->next)
1609 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1611 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1612 initlist = tree_cons (NULL_TREE, expr, initlist);
1617 for (impent = imp_list; impent; impent = impent->next)
1619 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1621 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1622 initlist = tree_cons (NULL_TREE, expr, initlist);
1626 if (!flag_next_runtime)
1628 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1631 if (static_instances_decl)
1632 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1634 expr = build_int_2 (0, 0);
1636 initlist = tree_cons (NULL_TREE, expr, initlist);
1639 return objc_build_constructor (type, nreverse (initlist));
1642 /* Construct the initial value for all of _objc_symtab. */
1645 init_objc_symtab (tree type)
1649 /* sel_ref_cnt = { ..., 5, ... } */
1651 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1653 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1655 if (flag_next_runtime || ! sel_ref_chain)
1656 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1658 initlist = tree_cons (NULL_TREE,
1659 build_unary_op (ADDR_EXPR,
1660 UOBJC_SELECTOR_TABLE_decl, 1),
1663 /* cls_def_cnt = { ..., 5, ... } */
1665 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1667 /* cat_def_cnt = { ..., 5, ... } */
1669 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1671 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1673 if (imp_count || cat_count || !flag_next_runtime)
1676 tree field = TYPE_FIELDS (type);
1677 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1679 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1683 return objc_build_constructor (type, nreverse (initlist));
1686 /* Generate forward declarations for metadata such as
1687 'OBJC_CLASS_...'. */
1690 build_metadata_decl (const char *name, tree type)
1692 tree decl, decl_specs;
1693 /* extern struct TYPE NAME_<name>; */
1694 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1695 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1696 decl = define_decl (synth_id_with_class_suffix
1698 objc_implementation_context),
1700 TREE_USED (decl) = 1;
1701 DECL_ARTIFICIAL (decl) = 1;
1702 TREE_PUBLIC (decl) = 0;
1706 /* Push forward-declarations of all the categories so that
1707 init_def_list can use them in a CONSTRUCTOR. */
1710 forward_declare_categories (void)
1712 struct imp_entry *impent;
1713 tree sav = objc_implementation_context;
1715 for (impent = imp_list; impent; impent = impent->next)
1717 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1719 /* Set an invisible arg to synth_id_with_class_suffix. */
1720 objc_implementation_context = impent->imp_context;
1721 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1722 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1723 objc_category_template);
1726 objc_implementation_context = sav;
1729 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1730 and initialized appropriately. */
1733 generate_objc_symtab_decl (void)
1737 if (!objc_category_template)
1738 build_category_template ();
1740 /* forward declare categories */
1742 forward_declare_categories ();
1744 if (!objc_symtab_template)
1745 build_objc_symtab_template ();
1747 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1749 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1750 tree_cons (NULL_TREE,
1751 objc_symtab_template, sc_spec),
1755 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1756 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1757 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1758 finish_decl (UOBJC_SYMBOLS_decl,
1759 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1764 init_module_descriptor (tree type)
1766 tree initlist, expr;
1768 /* version = { 1, ... } */
1770 expr = build_int_2 (OBJC_VERSION, 0);
1771 initlist = build_tree_list (NULL_TREE, expr);
1773 /* size = { ..., sizeof (struct objc_module), ... } */
1775 expr = size_in_bytes (objc_module_template);
1776 initlist = tree_cons (NULL_TREE, expr, initlist);
1778 /* name = { ..., "foo.m", ... } */
1780 expr = add_objc_string (get_identifier (input_filename), class_names);
1781 initlist = tree_cons (NULL_TREE, expr, initlist);
1783 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1785 if (UOBJC_SYMBOLS_decl)
1786 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1788 expr = build_int_2 (0, 0);
1789 initlist = tree_cons (NULL_TREE, expr, initlist);
1791 return objc_build_constructor (type, nreverse (initlist));
1794 /* Write out the data structures to describe Objective C classes defined.
1795 If appropriate, compile and output a setup function to initialize them.
1796 Return a symbol_ref to the function to call to initialize the Objective C
1797 data structures for this file (and perhaps for other files also).
1799 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1802 build_module_descriptor (void)
1804 tree decl_specs, field_decl, field_decl_chain;
1806 objc_module_template
1807 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1811 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1812 field_decl = get_identifier ("version");
1813 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1814 field_decl_chain = field_decl;
1818 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1819 field_decl = get_identifier ("size");
1820 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1821 chainon (field_decl_chain, field_decl);
1825 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1826 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1827 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1828 chainon (field_decl_chain, field_decl);
1830 /* struct objc_symtab *symtab; */
1832 decl_specs = get_identifier (UTAG_SYMTAB);
1833 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1834 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1835 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1836 chainon (field_decl_chain, field_decl);
1838 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1840 /* Create an instance of "objc_module". */
1842 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1843 build_tree_list (NULL_TREE,
1844 ridpointers[(int) RID_STATIC]));
1846 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1847 decl_specs, 1, NULL_TREE);
1849 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1850 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1851 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1853 finish_decl (UOBJC_MODULES_decl,
1854 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1857 /* Mark the decl to avoid "defined but not used" warning. */
1858 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1860 /* Generate a constructor call for the module descriptor.
1861 This code was generated by reading the grammar rules
1862 of c-parse.in; Therefore, it may not be the most efficient
1863 way of generating the requisite code. */
1865 if (flag_next_runtime)
1869 tree parms, execclass_decl, decelerator, void_list_node_1;
1870 tree init_function_name, init_function_decl, compound;
1872 /* Declare void __objc_execClass (void *); */
1874 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1875 execclass_decl = build_decl (FUNCTION_DECL,
1876 get_identifier (TAG_EXECCLASS),
1877 build_function_type (void_type_node,
1878 tree_cons (NULL_TREE, ptr_type_node,
1881 DECL_EXTERNAL (execclass_decl) = 1;
1882 DECL_ARTIFICIAL (execclass_decl) = 1;
1883 TREE_PUBLIC (execclass_decl) = 1;
1884 pushdecl (execclass_decl);
1885 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1886 assemble_external (execclass_decl);
1888 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1890 init_function_name = get_file_function_name ('I');
1891 start_function (void_list_node_1,
1892 build_nt (CALL_EXPR, init_function_name,
1893 tree_cons (NULL_TREE, NULL_TREE,
1897 store_parm_decls ();
1898 compound = c_begin_compound_stmt (true);
1900 init_function_decl = current_function_decl;
1901 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1902 TREE_USED (init_function_decl) = 1;
1903 /* Don't let this one be deferred. */
1904 DECL_INLINE (init_function_decl) = 0;
1905 DECL_UNINLINABLE (init_function_decl) = 1;
1908 = build_tree_list (NULL_TREE,
1909 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1910 decelerator = build_function_call (execclass_decl, parms);
1912 c_expand_expr_stmt (decelerator);
1913 add_stmt (c_end_compound_stmt (compound, true));
1917 return XEXP (DECL_RTL (init_function_decl), 0);
1921 /* Return the DECL of the string IDENT in the SECTION. */
1924 get_objc_string_decl (tree ident, enum string_section section)
1928 if (section == class_names)
1929 chain = class_names_chain;
1930 else if (section == meth_var_names)
1931 chain = meth_var_names_chain;
1932 else if (section == meth_var_types)
1933 chain = meth_var_types_chain;
1937 for (; chain != 0; chain = TREE_CHAIN (chain))
1938 if (TREE_VALUE (chain) == ident)
1939 return (TREE_PURPOSE (chain));
1945 /* Output references to all statically allocated objects. Return the DECL
1946 for the array built. */
1949 generate_static_references (void)
1951 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1952 tree class_name, class, decl, initlist;
1953 tree cl_chain, in_chain, type;
1954 int num_inst, num_class;
1957 if (flag_next_runtime)
1960 for (cl_chain = objc_static_instances, num_class = 0;
1961 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1963 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1964 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1966 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1967 ident = get_identifier (buf);
1969 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1970 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1971 build_tree_list (NULL_TREE,
1972 ridpointers[(int) RID_STATIC]));
1973 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1974 DECL_CONTEXT (decl) = 0;
1975 DECL_ARTIFICIAL (decl) = 1;
1977 /* Output {class_name, ...}. */
1978 class = TREE_VALUE (cl_chain);
1979 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
1980 initlist = build_tree_list (NULL_TREE,
1981 build_unary_op (ADDR_EXPR, class_name, 1));
1983 /* Output {..., instance, ...}. */
1984 for (in_chain = TREE_PURPOSE (cl_chain);
1985 in_chain; in_chain = TREE_CHAIN (in_chain))
1987 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1988 initlist = tree_cons (NULL_TREE, expr, initlist);
1991 /* Output {..., NULL}. */
1992 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1994 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
1995 finish_decl (decl, expr, NULL_TREE);
1996 TREE_USED (decl) = 1;
1998 type = build_array_type (build_pointer_type (void_type_node), 0);
1999 decl = build_decl (VAR_DECL, ident, type);
2000 TREE_USED (decl) = 1;
2001 TREE_STATIC (decl) = 1;
2003 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2006 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2007 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2008 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2009 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2010 build_tree_list (NULL_TREE,
2011 ridpointers[(int) RID_STATIC]));
2012 static_instances_decl
2013 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2014 TREE_USED (static_instances_decl) = 1;
2015 DECL_CONTEXT (static_instances_decl) = 0;
2016 DECL_ARTIFICIAL (static_instances_decl) = 1;
2017 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2019 finish_decl (static_instances_decl, expr, NULL_TREE);
2022 /* Output all strings. */
2025 generate_strings (void)
2027 tree sc_spec, decl_specs, expr_decl;
2028 tree chain, string_expr;
2031 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2033 string = TREE_VALUE (chain);
2034 decl = TREE_PURPOSE (chain);
2036 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2037 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2038 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2039 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2040 DECL_CONTEXT (decl) = NULL_TREE;
2041 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2042 IDENTIFIER_POINTER (string));
2043 finish_decl (decl, string_expr, NULL_TREE);
2046 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2048 string = TREE_VALUE (chain);
2049 decl = TREE_PURPOSE (chain);
2051 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2052 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2053 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2054 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2055 DECL_CONTEXT (decl) = NULL_TREE;
2056 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2057 IDENTIFIER_POINTER (string));
2058 finish_decl (decl, string_expr, NULL_TREE);
2061 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2063 string = TREE_VALUE (chain);
2064 decl = TREE_PURPOSE (chain);
2066 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2067 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2068 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2069 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2070 DECL_CONTEXT (decl) = NULL_TREE;
2071 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2072 IDENTIFIER_POINTER (string));
2073 finish_decl (decl, string_expr, NULL_TREE);
2077 static GTY(()) int selector_reference_idx;
2080 build_selector_reference_decl (void)
2085 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2087 ident = get_identifier (buf);
2089 decl = build_decl (VAR_DECL, ident, selector_type);
2090 DECL_EXTERNAL (decl) = 1;
2091 TREE_PUBLIC (decl) = 0;
2092 TREE_USED (decl) = 1;
2093 DECL_ARTIFICIAL (decl) = 1;
2094 DECL_CONTEXT (decl) = 0;
2096 make_decl_rtl (decl, 0);
2097 pushdecl_top_level (decl);
2102 /* Just a handy wrapper for add_objc_string. */
2105 build_selector (tree ident)
2107 tree expr = add_objc_string (ident, meth_var_names);
2108 if (flag_typed_selectors)
2111 return build_c_cast (selector_type, expr); /* cast! */
2115 build_selector_translation_table (void)
2117 tree sc_spec, decl_specs;
2118 tree chain, initlist = NULL_TREE;
2120 tree decl = NULL_TREE, var_decl, name;
2122 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2126 if (warn_selector && objc_implementation_context)
2130 for (method_chain = meth_var_names_chain;
2132 method_chain = TREE_CHAIN (method_chain))
2134 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2142 /* Adjust line number for warning message. */
2143 int save_lineno = input_line;
2144 if (flag_next_runtime && TREE_PURPOSE (chain))
2145 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2146 warning ("creating selector for non existant method %s",
2147 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2148 input_line = save_lineno;
2152 expr = build_selector (TREE_VALUE (chain));
2154 if (flag_next_runtime)
2156 name = DECL_NAME (TREE_PURPOSE (chain));
2158 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2160 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2161 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2165 /* The `decl' that is returned from start_decl is the one that we
2166 forward declared in `build_selector_reference' */
2167 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2170 /* add one for the '\0' character */
2171 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2173 if (flag_next_runtime)
2174 finish_decl (decl, expr, NULL_TREE);
2177 if (flag_typed_selectors)
2179 tree eltlist = NULL_TREE;
2180 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2181 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2182 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2183 expr = objc_build_constructor (objc_selector_template,
2184 nreverse (eltlist));
2186 initlist = tree_cons (NULL_TREE, expr, initlist);
2191 if (! flag_next_runtime)
2193 /* Cause the variable and its initial value to be actually output. */
2194 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2195 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2196 /* NULL terminate the list and fix the decl for output. */
2197 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2198 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2199 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2200 nreverse (initlist));
2201 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2202 current_function_decl = NULL_TREE;
2207 get_proto_encoding (tree proto)
2212 if (! METHOD_ENCODING (proto))
2214 encoding = encode_method_prototype (proto);
2215 METHOD_ENCODING (proto) = encoding;
2218 encoding = METHOD_ENCODING (proto);
2220 return add_objc_string (encoding, meth_var_types);
2223 return build_int_2 (0, 0);
2226 /* sel_ref_chain is a list whose "value" fields will be instances of
2227 identifier_node that represent the selector. */
2230 build_typed_selector_reference (tree ident, tree prototype)
2232 tree *chain = &sel_ref_chain;
2238 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2239 goto return_at_index;
2242 chain = &TREE_CHAIN (*chain);
2245 *chain = tree_cons (prototype, ident, NULL_TREE);
2248 expr = build_unary_op (ADDR_EXPR,
2249 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2250 build_int_2 (index, 0)),
2252 return build_c_cast (selector_type, expr);
2256 build_selector_reference (tree ident)
2258 tree *chain = &sel_ref_chain;
2264 if (TREE_VALUE (*chain) == ident)
2265 return (flag_next_runtime
2266 ? TREE_PURPOSE (*chain)
2267 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2268 build_int_2 (index, 0)));
2271 chain = &TREE_CHAIN (*chain);
2274 expr = build_selector_reference_decl ();
2276 *chain = tree_cons (expr, ident, NULL_TREE);
2278 return (flag_next_runtime
2280 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2281 build_int_2 (index, 0)));
2284 static GTY(()) int class_reference_idx;
2287 build_class_reference_decl (void)
2292 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2294 ident = get_identifier (buf);
2296 decl = build_decl (VAR_DECL, ident, objc_class_type);
2297 DECL_EXTERNAL (decl) = 1;
2298 TREE_PUBLIC (decl) = 0;
2299 TREE_USED (decl) = 1;
2300 DECL_CONTEXT (decl) = 0;
2301 DECL_ARTIFICIAL (decl) = 1;
2303 make_decl_rtl (decl, 0);
2304 pushdecl_top_level (decl);
2309 /* Create a class reference, but don't create a variable to reference
2313 add_class_reference (tree ident)
2317 if ((chain = cls_ref_chain))
2322 if (ident == TREE_VALUE (chain))
2326 chain = TREE_CHAIN (chain);
2330 /* Append to the end of the list */
2331 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2334 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2337 /* Get a class reference, creating it if necessary. Also create the
2338 reference variable. */
2341 get_class_reference (tree ident)
2346 if (processing_template_decl)
2347 /* Must wait until template instantiation time. */
2348 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2349 if (TREE_CODE (ident) == TYPE_DECL)
2350 ident = DECL_NAME (ident);
2354 if (!(ident = is_class_name (ident)))
2356 error ("`%s' is not an Objective-C class name or alias",
2357 IDENTIFIER_POINTER (orig_ident));
2358 return error_mark_node;
2361 if (flag_next_runtime && !flag_zero_link)
2366 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2367 if (TREE_VALUE (*chain) == ident)
2369 if (! TREE_PURPOSE (*chain))
2370 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2372 return TREE_PURPOSE (*chain);
2375 decl = build_class_reference_decl ();
2376 *chain = tree_cons (decl, ident, NULL_TREE);
2383 add_class_reference (ident);
2385 params = build_tree_list (NULL_TREE,
2386 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2387 IDENTIFIER_POINTER (ident)));
2389 assemble_external (objc_get_class_decl);
2390 return build_function_call (objc_get_class_decl, params);
2394 /* For each string section we have a chain which maps identifier nodes
2395 to decls for the strings. */
2398 add_objc_string (tree ident, enum string_section section)
2402 if (section == class_names)
2403 chain = &class_names_chain;
2404 else if (section == meth_var_names)
2405 chain = &meth_var_names_chain;
2406 else if (section == meth_var_types)
2407 chain = &meth_var_types_chain;
2413 if (TREE_VALUE (*chain) == ident)
2414 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2416 chain = &TREE_CHAIN (*chain);
2419 decl = build_objc_string_decl (section);
2421 *chain = tree_cons (decl, ident, NULL_TREE);
2423 return build_unary_op (ADDR_EXPR, decl, 1);
2426 static GTY(()) int class_names_idx;
2427 static GTY(()) int meth_var_names_idx;
2428 static GTY(()) int meth_var_types_idx;
2431 build_objc_string_decl (enum string_section section)
2436 if (section == class_names)
2437 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2438 else if (section == meth_var_names)
2439 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2440 else if (section == meth_var_types)
2441 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2443 ident = get_identifier (buf);
2445 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2446 DECL_EXTERNAL (decl) = 1;
2447 TREE_PUBLIC (decl) = 0;
2448 TREE_USED (decl) = 1;
2449 TREE_CONSTANT (decl) = 1;
2450 DECL_CONTEXT (decl) = 0;
2451 DECL_ARTIFICIAL (decl) = 1;
2453 make_decl_rtl (decl, 0);
2454 pushdecl_top_level (decl);
2461 objc_declare_alias (tree alias_ident, tree class_ident)
2463 tree underlying_class;
2466 if (current_namespace != global_namespace) {
2467 error ("Objective-C declarations may only appear in global scope");
2469 #endif /* OBJCPLUS */
2471 if (!(underlying_class = is_class_name (class_ident)))
2472 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2473 else if (is_class_name (alias_ident))
2474 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2476 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2480 objc_declare_class (tree ident_list)
2484 if (current_namespace != global_namespace) {
2485 error ("Objective-C declarations may only appear in global scope");
2487 #endif /* OBJCPLUS */
2489 for (list = ident_list; list; list = TREE_CHAIN (list))
2491 tree ident = TREE_VALUE (list);
2493 if (! is_class_name (ident))
2495 tree record = lookup_name (ident);
2497 if (record && ! TREE_STATIC_TEMPLATE (record))
2499 error ("`%s' redeclared as different kind of symbol",
2500 IDENTIFIER_POINTER (ident));
2501 error ("%Jprevious declaration of '%D'",
2505 record = xref_tag (RECORD_TYPE, ident);
2506 TREE_STATIC_TEMPLATE (record) = 1;
2507 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2513 is_class_name (tree ident)
2517 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2518 && identifier_global_value (ident))
2519 ident = identifier_global_value (ident);
2520 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2521 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2524 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2525 ident = TYPE_NAME (ident);
2526 if (ident && TREE_CODE (ident) == TYPE_DECL)
2527 ident = DECL_NAME (ident);
2529 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2532 if (lookup_interface (ident))
2535 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2537 if (ident == TREE_VALUE (chain))
2541 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2543 if (ident == TREE_VALUE (chain))
2544 return TREE_PURPOSE (chain);
2550 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2551 class instance. This is needed by other parts of the compiler to
2552 handle ObjC types gracefully. */
2555 objc_is_object_ptr (tree type)
2557 type = TYPE_MAIN_VARIANT (type);
2558 if (!type || TREE_CODE (type) != POINTER_TYPE)
2560 /* NB: This function may be called before the ObjC front-end has
2561 been initialized, in which case ID_TYPE will be NULL. */
2562 if (id_type && type && TYPE_P (type)
2564 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2566 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2570 lookup_interface (tree ident)
2575 if (ident && TREE_CODE (ident) == TYPE_DECL)
2576 ident = DECL_NAME (ident);
2578 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2580 if (ident == CLASS_NAME (chain))
2586 /* Implement @defs (<classname>) within struct bodies. */
2589 get_class_ivars_from_name (tree class_name)
2591 tree interface = lookup_interface (class_name);
2592 tree field, fields = NULL_TREE;
2596 tree raw_ivar = get_class_ivars (interface, 1);
2598 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2599 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2601 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2602 TREE_PURPOSE (raw_ivar),
2603 TREE_VALUE (TREE_VALUE (raw_ivar)));
2605 finish_member_declaration (field);
2607 fields = chainon (fields, field);
2612 error ("cannot find interface declaration for `%s'",
2613 IDENTIFIER_POINTER (class_name));
2618 /* Used by: build_private_template, continue_class,
2619 and for @defs constructs. */
2622 get_class_ivars (tree interface, int raw)
2624 tree my_name, super_name, ivar_chain;
2626 my_name = CLASS_NAME (interface);
2627 super_name = CLASS_SUPER_NAME (interface);
2629 ivar_chain = CLASS_RAW_IVARS (interface);
2632 ivar_chain = CLASS_IVARS (interface);
2633 /* Save off a pristine copy of the leaf ivars (i.e, those not
2634 inherited from a super class). */
2635 if (!CLASS_OWN_IVARS (interface))
2636 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2642 tree super_interface = lookup_interface (super_name);
2644 if (!super_interface)
2646 /* fatal did not work with 2 args...should fix */
2647 error ("cannot find interface declaration for `%s', superclass of `%s'",
2648 IDENTIFIER_POINTER (super_name),
2649 IDENTIFIER_POINTER (my_name));
2650 exit (FATAL_EXIT_CODE);
2653 if (super_interface == interface)
2654 fatal_error ("circular inheritance in interface declaration for `%s'",
2655 IDENTIFIER_POINTER (super_name));
2657 interface = super_interface;
2658 my_name = CLASS_NAME (interface);
2659 super_name = CLASS_SUPER_NAME (interface);
2661 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2664 tree head = copy_list (op1);
2666 /* Prepend super class ivars...make a copy of the list, we
2667 do not want to alter the original. */
2668 chainon (head, ivar_chain);
2677 objc_create_temporary_var (tree type)
2681 decl = build_decl (VAR_DECL, NULL_TREE, type);
2682 TREE_USED (decl) = 1;
2683 DECL_ARTIFICIAL (decl) = 1;
2684 DECL_IGNORED_P (decl) = 1;
2685 DECL_CONTEXT (decl) = current_function_decl;
2690 /* Exception handling constructs. We begin by having the parser do most
2691 of the work and passing us blocks. What we do next depends on whether
2692 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2693 We abstract all of this in a handful of appropriately named routines. */
2695 /* Stack of open try blocks. */
2697 struct objc_try_context
2699 struct objc_try_context *outer;
2701 /* Statements (or statement lists) as processed by the parser. */
2705 /* Some file position locations. */
2706 location_t try_locus;
2707 location_t end_try_locus;
2708 location_t end_catch_locus;
2709 location_t finally_locus;
2710 location_t end_finally_locus;
2712 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2713 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2716 /* The CATCH_EXPR of an open @catch clause. */
2719 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2725 static struct objc_try_context *cur_try_context;
2727 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2728 that represents TYPE. For Objective-C, this is just the class name. */
2729 /* ??? Isn't there a class object or some such? Is it easy to get? */
2732 objc_eh_runtime_type (tree type)
2734 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2737 /* Initialize exception handling. */
2740 objc_init_exceptions (void)
2742 static bool done = false;
2748 if (!flag_objc_exceptions)
2749 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2750 "exception syntax");
2752 if (!flag_objc_sjlj_exceptions)
2754 c_eh_initialized_p = true;
2755 eh_personality_libfunc
2756 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2757 ? "__gnu_objc_personality_sj0"
2758 : "__gnu_objc_personality_v0");
2759 using_eh_for_cleanups ();
2760 lang_eh_runtime_type = objc_eh_runtime_type;
2764 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2765 we'll arrange for it to be initialized (and associated with a binding)
2769 objc_build_exc_ptr (void)
2771 if (flag_objc_sjlj_exceptions)
2773 tree var = cur_try_context->caught_decl;
2776 var = objc_create_temporary_var (id_type);
2777 cur_try_context->caught_decl = var;
2782 return build (EXC_PTR_EXPR, id_type);
2785 /* Build "objc_exception_try_exit(&_stack)". */
2788 next_sjlj_build_try_exit (void)
2791 t = build_fold_addr_expr (cur_try_context->stack_decl);
2792 t = tree_cons (NULL, t, NULL);
2793 t = build_function_call (objc_exception_try_exit_decl, t);
2798 objc_exception_try_enter (&_stack);
2799 if (_setjmp(&_stack.buf))
2803 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2804 empty, ready for the caller to fill them in. */
2807 next_sjlj_build_enter_and_setjmp (void)
2809 tree t, enter, sj, cond;
2811 t = build_fold_addr_expr (cur_try_context->stack_decl);
2812 t = tree_cons (NULL, t, NULL);
2813 enter = build_function_call (objc_exception_try_enter_decl, t);
2815 t = build_component_ref (cur_try_context->stack_decl,
2816 get_identifier ("buf"));
2817 t = build_fold_addr_expr (t);
2818 t = convert (ptr_type_node, t);
2819 t = tree_cons (NULL, t, NULL);
2820 sj = build_function_call (objc_setjmp_decl, t);
2822 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2823 cond = lang_hooks.truthvalue_conversion (cond);
2825 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2829 DECL = objc_exception_extract(&_stack);
2833 next_sjlj_build_exc_extract (tree decl)
2837 t = build_fold_addr_expr (cur_try_context->stack_decl);
2838 t = tree_cons (NULL, t, NULL);
2839 t = build_function_call (objc_exception_extract_decl, t);
2840 t = convert (TREE_TYPE (decl), t);
2841 t = build (MODIFY_EXPR, void_type_node, decl, t);
2847 if (objc_exception_match(obj_get_class(TYPE), _caught)
2854 objc_exception_try_exit(&_stack);
2856 from the sequence of CATCH_EXPRs in the current try context. */
2859 next_sjlj_build_catch_list (void)
2861 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
2863 tree *last = &catch_seq;
2864 bool saw_id = false;
2866 for (; !tsi_end_p (i); tsi_next (&i))
2868 tree stmt = tsi_stmt (i);
2869 tree type = CATCH_TYPES (stmt);
2870 tree body = CATCH_BODY (stmt);
2882 if (type == error_mark_node)
2883 cond = error_mark_node;
2886 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
2887 t = get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
2888 args = tree_cons (NULL, t, args);
2889 t = build_function_call (objc_exception_match_decl, args);
2890 cond = lang_hooks.truthvalue_conversion (t);
2892 t = build (COND_EXPR, void_type_node, cond, body, NULL);
2893 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
2896 last = &COND_EXPR_ELSE (t);
2902 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
2903 cur_try_context->caught_decl);
2904 annotate_with_locus (t, cur_try_context->end_catch_locus);
2905 append_to_statement_list (t, last);
2907 t = next_sjlj_build_try_exit ();
2908 annotate_with_locus (t, cur_try_context->end_catch_locus);
2909 append_to_statement_list (t, last);
2915 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
2916 exception handling. We aim to build:
2919 struct _objc_exception_data _stack;
2920 id volatile _rethrow = 0;
2923 objc_exception_try_enter (&_stack);
2924 if (_setjmp(&_stack.buf))
2926 id _caught = objc_exception_extract(&_stack);
2927 objc_exception_try_enter (&_stack);
2928 if (_setjmp(&_stack.buf))
2929 _rethrow = objc_exception_extract(&_stack);
2939 objc_exception_try_exit(&_stack);
2942 objc_exception_throw(_rethrow);
2946 If CATCH-LIST is empty, we can omit all of the block containing
2947 "_caught" except for the setting of _rethrow. Note the use of
2948 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
2949 but handles goto and other exits from the block. */
2952 next_sjlj_build_try_catch_finally (void)
2954 tree rethrow_decl, stack_decl, t;
2955 tree catch_seq, try_fin, bind;
2957 /* Create the declarations involved. */
2958 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
2959 stack_decl = objc_create_temporary_var (t);
2960 cur_try_context->stack_decl = stack_decl;
2962 rethrow_decl = objc_create_temporary_var (id_type);
2963 cur_try_context->rethrow_decl = rethrow_decl;
2964 TREE_THIS_VOLATILE (rethrow_decl) = 1;
2965 TREE_CHAIN (rethrow_decl) = stack_decl;
2967 /* Build the outermost varible binding level. */
2968 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
2969 annotate_with_locus (bind, cur_try_context->try_locus);
2970 TREE_SIDE_EFFECTS (bind) = 1;
2972 /* Initialize rethrow_decl. */
2973 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
2974 convert (id_type, null_pointer_node));
2975 annotate_with_locus (t, cur_try_context->try_locus);
2976 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
2978 /* Build the outermost TRY_FINALLY_EXPR. */
2979 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
2980 annotate_with_locus (try_fin, cur_try_context->try_locus);
2981 TREE_SIDE_EFFECTS (try_fin) = 1;
2982 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
2984 /* Create the complete catch sequence. */
2985 if (cur_try_context->catch_list)
2987 tree caught_decl = objc_build_exc_ptr ();
2988 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
2990 t = next_sjlj_build_exc_extract (caught_decl);
2991 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
2993 t = next_sjlj_build_enter_and_setjmp ();
2994 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
2995 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
2996 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
2999 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3000 annotate_with_locus (catch_seq, cur_try_context->end_try_locus);
3002 /* Build the main register-and-try if statement. */
3003 t = next_sjlj_build_enter_and_setjmp ();
3004 annotate_with_locus (t, cur_try_context->try_locus);
3005 COND_EXPR_THEN (t) = catch_seq;
3006 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3007 TREE_OPERAND (try_fin, 0) = t;
3009 /* Build the complete FINALLY statement list. */
3010 t = next_sjlj_build_try_exit ();
3011 t = build_stmt (COND_EXPR,
3012 lang_hooks.truthvalue_conversion (rethrow_decl),
3014 annotate_with_locus (t, cur_try_context->finally_locus);
3015 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3017 append_to_statement_list (cur_try_context->finally_body,
3018 &TREE_OPERAND (try_fin, 1));
3020 t = tree_cons (NULL, rethrow_decl, NULL);
3021 t = build_function_call (objc_exception_throw_decl, t);
3022 t = build_stmt (COND_EXPR,
3023 lang_hooks.truthvalue_conversion (rethrow_decl),
3025 annotate_with_locus (t, cur_try_context->end_finally_locus);
3026 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3031 /* Called just after parsing the @try and its associated BODY. We now
3032 must prepare for the tricky bits -- handling the catches and finally. */
3035 objc_begin_try_stmt (location_t try_locus, tree body)
3037 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3038 c->outer = cur_try_context;
3040 c->try_locus = try_locus;
3041 c->end_try_locus = input_location;
3042 cur_try_context = c;
3044 objc_init_exceptions ();
3047 /* Called just after parsing "@catch (parm)". Open a binding level,
3048 enter PARM into the binding level, and initialize it. Leave the
3049 binding level open while the body of the compound statement is parsed. */
3052 objc_begin_catch_clause (tree parm)
3054 tree compound, decl, type, t;
3056 /* Begin a new scope that the entire catch clause will live in. */
3057 compound = c_begin_compound_stmt (1);
3059 /* Turn the raw declarator/declspecs into a decl in the current scope. */
3060 decl = define_decl (TREE_VALUE (TREE_PURPOSE (parm)),
3061 TREE_PURPOSE (TREE_PURPOSE (parm)));
3063 /* Since a decl is required here by syntax, don't warn if its unused. */
3064 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3065 be what the previous objc implementation did. */
3066 TREE_USED (decl) = 1;
3068 /* Verify that the type of the catch is valid. It must be a pointer
3069 to an Objective-C class, or "id" (which is catch-all). */
3070 type = TREE_TYPE (decl);
3071 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3073 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3075 error ("@catch parameter is not a known Objective-C class type");
3076 type = error_mark_node;
3078 else if (cur_try_context->catch_list)
3080 /* Examine previous @catch clauses and see if we've already
3081 caught the type in question. */
3082 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3083 for (; !tsi_end_p (i); tsi_next (&i))
3085 tree stmt = tsi_stmt (i);
3086 t = CATCH_TYPES (stmt);
3087 if (t == error_mark_node)
3089 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3091 warning ("exception of type %<%T%> will be caught",
3093 warning ("%H by earlier handler for %<%T%>",
3094 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : id_type));
3100 /* Record the data for the catch in the try context so that we can
3101 finalize it later. */
3102 t = build_stmt (CATCH_EXPR, type, compound);
3103 cur_try_context->current_catch = t;
3105 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3106 t = objc_build_exc_ptr ();
3107 t = convert (TREE_TYPE (decl), t);
3108 t = build (MODIFY_EXPR, void_type_node, decl, t);
3112 /* Called just after parsing the closing brace of a @catch clause. Close
3113 the open binding level, and record a CATCH_EXPR for it. */
3116 objc_finish_catch_clause (void)
3118 tree c = cur_try_context->current_catch;
3119 cur_try_context->current_catch = NULL;
3120 cur_try_context->end_catch_locus = input_location;
3122 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3123 append_to_statement_list (c, &cur_try_context->catch_list);
3126 /* Called after parsing a @finally clause and its associated BODY.
3127 Record the body for later placement. */
3130 objc_build_finally_clause (location_t finally_locus, tree body)
3132 cur_try_context->finally_body = body;
3133 cur_try_context->finally_locus = finally_locus;
3134 cur_try_context->end_finally_locus = input_location;
3137 /* Called to finalize a @try construct. */
3140 objc_finish_try_stmt (void)
3142 struct objc_try_context *c = cur_try_context;
3145 if (c->catch_list == NULL && c->finally_body == NULL)
3146 error ("`@try' without `@catch' or `@finally'");
3148 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3149 if (flag_objc_sjlj_exceptions)
3151 if (!cur_try_context->finally_body)
3153 cur_try_context->finally_locus = input_location;
3154 cur_try_context->end_finally_locus = input_location;
3156 stmt = next_sjlj_build_try_catch_finally ();
3160 /* Otherwise, nest the CATCH inside a FINALLY. */
3164 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3165 annotate_with_locus (stmt, cur_try_context->try_locus);
3167 if (c->finally_body)
3169 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3170 annotate_with_locus (stmt, cur_try_context->try_locus);
3175 cur_try_context = c->outer;
3180 objc_build_throw_stmt (tree throw_expr)
3184 if (throw_expr == NULL)
3186 /* If we're not inside a @catch block, there is no "current
3187 exception" to be rethrown. */
3188 if (cur_try_context == NULL
3189 || cur_try_context->current_catch == NULL)
3191 error ("%<@throw%> (rethrow) used outside of a @catch block");
3195 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3196 value that we get from the runtime. */
3197 throw_expr = objc_build_exc_ptr ();
3200 /* A throw is just a call to the runtime throw function with the
3201 object as a parameter. */
3202 func_params = tree_cons (NULL, throw_expr, NULL);
3203 add_stmt (build_function_call (objc_exception_throw_decl, func_params));
3205 objc_init_exceptions ();
3209 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3213 /* First lock the mutex. */
3214 mutex = save_expr (mutex);
3215 args = tree_cons (NULL, mutex, NULL);
3216 call = build_function_call (objc_sync_enter_decl, args);
3217 annotate_with_locus (call, start_locus);
3220 /* Build the mutex unlock. */
3221 args = tree_cons (NULL, mutex, NULL);
3222 call = build_function_call (objc_sync_exit_decl, args);
3223 annotate_with_locus (call, input_location);
3225 /* Put the that and the body in a TRY_FINALLY. */
3226 objc_begin_try_stmt (start_locus, body);
3227 objc_build_finally_clause (input_location, call);
3228 objc_finish_try_stmt ();
3232 /* Predefine the following data type:
3234 struct _objc_exception_data
3240 /* The following yuckiness should prevent users from having to #include
3241 <setjmp.h> in their code... */
3243 #ifdef TARGET_POWERPC
3244 /* snarfed from /usr/include/ppc/setjmp.h */
3245 #define _JBLEN (26 + 36 + 129 + 1)
3247 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3252 build_next_objc_exception_stuff (void)
3254 tree field_decl, field_decl_chain, index, temp_type;
3256 /* Suppress outputting debug symbols, because
3257 dbxout_init hasn't been called yet. */
3258 enum debug_info_type save_write_symbols = write_symbols;
3259 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3261 write_symbols = NO_DEBUG;
3262 debug_hooks = &do_nothing_debug_hooks;
3264 objc_exception_data_template
3265 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3267 /* int buf[_JBLEN]; */
3269 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3270 field_decl = create_builtin_decl (FIELD_DECL,
3271 build_array_type (integer_type_node, index),
3273 field_decl_chain = field_decl;
3275 /* void *pointers[4]; */
3277 index = build_index_type (build_int_2 (4 - 1, 0));
3278 field_decl = create_builtin_decl (FIELD_DECL,
3279 build_array_type (ptr_type_node, index),
3281 chainon (field_decl_chain, field_decl);
3283 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3285 /* int _setjmp(...); */
3286 /* If the user includes <setjmp.h>, this shall be superseded by
3287 'int _setjmp(jmp_buf);' */
3288 temp_type = build_function_type (integer_type_node, NULL_TREE);
3290 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3292 /* id objc_exception_extract(struct _objc_exception_data *); */
3294 = build_function_type (id_type,
3295 tree_cons (NULL_TREE,
3296 build_pointer_type (objc_exception_data_template),
3298 objc_exception_extract_decl
3299 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3300 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3301 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3303 = build_function_type (void_type_node,
3304 tree_cons (NULL_TREE,
3305 build_pointer_type (objc_exception_data_template),
3307 objc_exception_try_enter_decl
3308 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3309 objc_exception_try_exit_decl
3310 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3312 /* int objc_exception_match(id, id); */
3313 temp_type = build_function_type (integer_type_node,
3314 tree_cons (NULL_TREE, id_type,
3315 tree_cons (NULL_TREE, id_type,
3317 objc_exception_match_decl
3318 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3320 write_symbols = save_write_symbols;
3321 debug_hooks = save_hooks;
3325 build_objc_exception_stuff (void)
3327 tree noreturn_list, nothrow_list, temp_type;
3329 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3330 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3332 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3333 /* void objc_sync_enter(id); */
3334 /* void objc_sync_exit(id); */
3335 temp_type = build_function_type (void_type_node,
3336 tree_cons (NULL_TREE, id_type,
3338 objc_exception_throw_decl
3339 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3341 objc_sync_enter_decl
3342 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3343 NULL, nothrow_list);
3345 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3346 NULL, nothrow_list);
3350 /* struct <classname> {
3351 struct objc_class *isa;
3356 build_private_template (tree class)
3360 if (CLASS_STATIC_TEMPLATE (class))
3362 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3363 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3367 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3368 ivar_context = get_class_ivars (class, 0);
3370 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3372 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3374 /* mark this record as class template - for class type checking */
3375 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3379 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3381 build1 (INDIRECT_REF, NULL_TREE,
3384 return ivar_context;
3387 /* Begin code generation for protocols... */
3389 /* struct objc_protocol {
3390 char *protocol_name;
3391 struct objc_protocol **protocol_list;
3392 struct objc_method_desc *instance_methods;
3393 struct objc_method_desc *class_methods;
3397 build_protocol_template (void)
3399 tree decl_specs, field_decl, field_decl_chain;
3402 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3404 /* struct objc_class *isa; */
3406 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3407 get_identifier (UTAG_CLASS)));
3408 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3409 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3410 field_decl_chain = field_decl;
3412 /* char *protocol_name; */
3414 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3416 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3417 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3418 chainon (field_decl_chain, field_decl);
3420 /* struct objc_protocol **protocol_list; */
3422 decl_specs = build_tree_list (NULL_TREE, template);
3424 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3425 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3426 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3427 chainon (field_decl_chain, field_decl);
3429 /* struct objc_method_list *instance_methods; */
3432 = build_tree_list (NULL_TREE,
3433 xref_tag (RECORD_TYPE,
3434 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3436 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3437 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3438 chainon (field_decl_chain, field_decl);
3440 /* struct objc_method_list *class_methods; */
3443 = build_tree_list (NULL_TREE,
3444 xref_tag (RECORD_TYPE,
3445 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3447 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3448 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3449 chainon (field_decl_chain, field_decl);
3451 return finish_struct (template, field_decl_chain, NULL_TREE);
3455 build_descriptor_table_initializer (tree type, tree entries)
3457 tree initlist = NULL_TREE;
3461 tree eltlist = NULL_TREE;
3464 = tree_cons (NULL_TREE,
3465 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3467 = tree_cons (NULL_TREE,
3468 add_objc_string (METHOD_ENCODING (entries),
3473 = tree_cons (NULL_TREE,
3474 objc_build_constructor (type, nreverse (eltlist)),
3477 entries = TREE_CHAIN (entries);
3481 return objc_build_constructor (build_array_type (type, 0),
3482 nreverse (initlist));
3485 /* struct objc_method_prototype_list {
3487 struct objc_method_prototype {
3494 build_method_prototype_list_template (tree list_type, int size)
3496 tree objc_ivar_list_record;
3497 tree decl_specs, field_decl, field_decl_chain;
3499 /* Generate an unnamed struct definition. */
3501 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3503 /* int method_count; */
3505 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3506 field_decl = get_identifier ("method_count");
3507 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3508 field_decl_chain = field_decl;
3510 /* struct objc_method method_list[]; */
3512 decl_specs = build_tree_list (NULL_TREE, list_type);
3513 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3514 build_int_2 (size, 0));
3515 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3516 chainon (field_decl_chain, field_decl);
3518 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3520 return objc_ivar_list_record;
3524 build_method_prototype_template (void)
3527 tree decl_specs, field_decl, field_decl_chain;
3530 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3532 /* struct objc_selector *_cmd; */
3533 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3534 get_identifier (TAG_SELECTOR)), NULL_TREE);
3535 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3536 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3537 field_decl_chain = field_decl;
3539 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3541 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3542 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3543 chainon (field_decl_chain, field_decl);
3545 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3547 return proto_record;
3551 objc_method_parm_type (tree type)
3553 type = groktypename (TREE_TYPE (type));
3554 if (TREE_CODE (type) == TYPE_DECL)
3555 type = TREE_TYPE (type);
3556 return TYPE_MAIN_VARIANT (type);
3560 objc_encoded_type_size (tree type)
3562 int sz = int_size_in_bytes (type);
3564 /* Make all integer and enum types at least as large
3566 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3567 || TREE_CODE (type) == BOOLEAN_TYPE
3568 || TREE_CODE (type) == ENUMERAL_TYPE))
3569 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3570 /* Treat arrays as pointers, since that's how they're
3572 else if (TREE_CODE (type) == ARRAY_TYPE)
3573 sz = int_size_in_bytes (ptr_type_node);
3578 encode_method_prototype (tree method_decl)
3585 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3586 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3588 /* Encode return type. */
3589 encode_type (objc_method_parm_type (method_decl),
3590 obstack_object_size (&util_obstack),
3591 OBJC_ENCODE_INLINE_DEFS);
3594 /* The first two arguments (self and _cmd) are pointers; account for
3596 i = int_size_in_bytes (ptr_type_node);
3597 parm_offset = 2 * i;
3598 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3599 parms = TREE_CHAIN (parms))
3601 tree type = objc_method_parm_type (parms);
3602 int sz = objc_encoded_type_size (type);
3604 /* If a type size is not known, bail out. */
3607 error ("%Jtype '%D' does not have a known size",
3609 /* Pretend that the encoding succeeded; the compilation will
3610 fail nevertheless. */
3611 goto finish_encoding;
3616 sprintf (buf, "%d@0:%d", parm_offset, i);
3617 obstack_grow (&util_obstack, buf, strlen (buf));
3619 /* Argument types. */
3620 parm_offset = 2 * i;
3621 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3622 parms = TREE_CHAIN (parms))
3624 tree type = objc_method_parm_type (parms);
3626 /* Process argument qualifiers for user supplied arguments. */
3627 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3630 encode_type (type, obstack_object_size (&util_obstack),
3631 OBJC_ENCODE_INLINE_DEFS);
3633 /* Compute offset. */
3634 sprintf (buf, "%d", parm_offset);
3635 parm_offset += objc_encoded_type_size (type);
3637 obstack_grow (&util_obstack, buf, strlen (buf));
3641 obstack_1grow (&util_obstack, '\0');
3642 result = get_identifier (obstack_finish (&util_obstack));
3643 obstack_free (&util_obstack, util_firstobj);
3648 generate_descriptor_table (tree type, const char *name, int size, tree list,
3651 tree sc_spec, decl_specs, decl, initlist;
3653 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3654 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3656 decl = start_decl (synth_id_with_class_suffix (name, proto),
3657 decl_specs, 1, NULL_TREE);
3658 DECL_CONTEXT (decl) = NULL_TREE;
3660 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3661 initlist = tree_cons (NULL_TREE, list, initlist);
3663 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3670 generate_method_descriptors (tree protocol)
3672 tree initlist, chain, method_list_template;
3673 tree cast, variable_length_type;
3676 if (!objc_method_prototype_template)
3677 objc_method_prototype_template = build_method_prototype_template ();
3679 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3680 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3682 variable_length_type = groktypename (cast);
3684 chain = PROTOCOL_CLS_METHODS (protocol);
3687 size = list_length (chain);
3689 method_list_template
3690 = build_method_prototype_list_template (objc_method_prototype_template,
3694 = build_descriptor_table_initializer (objc_method_prototype_template,
3697 UOBJC_CLASS_METHODS_decl
3698 = generate_descriptor_table (method_list_template,
3699 "_OBJC_PROTOCOL_CLASS_METHODS",
3700 size, initlist, protocol);
3701 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3704 UOBJC_CLASS_METHODS_decl = 0;
3706 chain = PROTOCOL_NST_METHODS (protocol);
3709 size = list_length (chain);
3711 method_list_template
3712 = build_method_prototype_list_template (objc_method_prototype_template,
3715 = build_descriptor_table_initializer (objc_method_prototype_template,
3718 UOBJC_INSTANCE_METHODS_decl
3719 = generate_descriptor_table (method_list_template,
3720 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3721 size, initlist, protocol);
3722 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3725 UOBJC_INSTANCE_METHODS_decl = 0;
3729 generate_protocol_references (tree plist)
3733 /* Forward declare protocols referenced. */
3734 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3736 tree proto = TREE_VALUE (lproto);
3738 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3739 && PROTOCOL_NAME (proto))
3741 if (! PROTOCOL_FORWARD_DECL (proto))
3742 build_protocol_reference (proto);
3744 if (PROTOCOL_LIST (proto))
3745 generate_protocol_references (PROTOCOL_LIST (proto));
3750 /* For each protocol which was referenced either from a @protocol()
3751 expression, or because a class/category implements it (then a
3752 pointer to the protocol is stored in the struct describing the
3753 class/category), we create a statically allocated instance of the
3754 Protocol class. The code is written in such a way as to generate
3755 as few Protocol objects as possible; we generate a unique Protocol
3756 instance for each protocol, and we don't generate a Protocol
3757 instance if the protocol is never referenced (either from a
3758 @protocol() or from a class/category implementation). These
3759 statically allocated objects can be referred to via the static
3760 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3762 The statically allocated Protocol objects that we generate here
3763 need to be fixed up at runtime in order to be used: the 'isa'
3764 pointer of the objects need to be set up to point to the 'Protocol'
3765 class, as known at runtime.
3767 The NeXT runtime fixes up all protocols at program startup time,
3768 before main() is entered. It uses a low-level trick to look up all
3769 those symbols, then loops on them and fixes them up.
3771 The GNU runtime as well fixes up all protocols before user code
3772 from the module is executed; it requires pointers to those symbols
3773 to be put in the objc_symtab (which is then passed as argument to
3774 the function __objc_exec_class() which the compiler sets up to be
3775 executed automatically when the module is loaded); setup of those
3776 Protocol objects happen in two ways in the GNU runtime: all
3777 Protocol objects referred to by a class or category implementation
3778 are fixed up when the class/category is loaded; all Protocol
3779 objects referred to by a @protocol() expression are added by the
3780 compiler to the list of statically allocated instances to fixup
3781 (the same list holding the statically allocated constant string
3782 objects). Because, as explained above, the compiler generates as
3783 few Protocol objects as possible, some Protocol object might end up
3784 being referenced multiple times when compiled with the GNU runtime,
3785 and end up being fixed up multiple times at runtime inizialization.
3786 But that doesn't hurt, it's just a little inefficient. */
3789 generate_protocols (void)
3792 tree sc_spec, decl_specs, decl;
3793 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3796 if (! objc_protocol_template)
3797 objc_protocol_template = build_protocol_template ();
3799 /* If a protocol was directly referenced, pull in indirect references. */
3800 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3801 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3802 generate_protocol_references (PROTOCOL_LIST (p));
3804 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3806 tree nst_methods = PROTOCOL_NST_METHODS (p);
3807 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3809 /* If protocol wasn't referenced, don't generate any code. */
3810 if (! PROTOCOL_FORWARD_DECL (p))
3813 /* Make sure we link in the Protocol class. */
3814 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3818 if (! METHOD_ENCODING (nst_methods))
3820 encoding = encode_method_prototype (nst_methods);
3821 METHOD_ENCODING (nst_methods) = encoding;
3823 nst_methods = TREE_CHAIN (nst_methods);
3828 if (! METHOD_ENCODING (cls_methods))
3830 encoding = encode_method_prototype (cls_methods);
3831 METHOD_ENCODING (cls_methods) = encoding;
3834 cls_methods = TREE_CHAIN (cls_methods);
3836 generate_method_descriptors (p);
3838 if (PROTOCOL_LIST (p))
3839 refs_decl = generate_protocol_list (p);
3843 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3845 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3847 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3849 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3850 decl_specs, 1, NULL_TREE);
3852 DECL_CONTEXT (decl) = NULL_TREE;
3854 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3860 (build_tree_list (build_tree_list (NULL_TREE,
3861 objc_protocol_template),
3862 build1 (INDIRECT_REF, NULL_TREE,
3863 build1 (INDIRECT_REF, NULL_TREE,
3866 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3867 TREE_TYPE (refs_expr) = cast_type2;
3870 refs_expr = build_int_2 (0, 0);
3872 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3873 by generate_method_descriptors, which is called above. */
3874 initlist = build_protocol_initializer (TREE_TYPE (decl),
3875 protocol_name_expr, refs_expr,
3876 UOBJC_INSTANCE_METHODS_decl,
3877 UOBJC_CLASS_METHODS_decl);
3878 finish_decl (decl, initlist, NULL_TREE);
3880 /* Mark the decl as used to avoid "defined but not used" warning. */
3881 TREE_USED (decl) = 1;
3886 build_protocol_initializer (tree type, tree protocol_name,
3887 tree protocol_list, tree instance_methods,
3890 tree initlist = NULL_TREE, expr;
3893 cast_type = groktypename
3895 (build_tree_list (NULL_TREE,
3896 xref_tag (RECORD_TYPE,
3897 get_identifier (UTAG_CLASS))),
3898 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3900 /* Filling the "isa" in with one allows the runtime system to
3901 detect that the version change...should remove before final release. */
3903 expr = build_int_2 (PROTOCOL_VERSION, 0);
3904 TREE_TYPE (expr) = cast_type;
3905 initlist = tree_cons (NULL_TREE, expr, initlist);
3906 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3907 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3909 if (!instance_methods)
3910 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3913 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3914 initlist = tree_cons (NULL_TREE, expr, initlist);
3918 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3921 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3922 initlist = tree_cons (NULL_TREE, expr, initlist);
3925 return objc_build_constructor (type, nreverse (initlist));
3928 /* struct objc_category {
3929 char *category_name;
3931 struct objc_method_list *instance_methods;
3932 struct objc_method_list *class_methods;
3933 struct objc_protocol_list *protocols;
3937 build_category_template (void)
3939 tree decl_specs, field_decl, field_decl_chain;
3941 objc_category_template = start_struct (RECORD_TYPE,
3942 get_identifier (UTAG_CATEGORY));
3943 /* char *category_name; */
3945 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3947 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3948 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3949 field_decl_chain = field_decl;
3951 /* char *class_name; */
3953 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3954 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3955 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3956 chainon (field_decl_chain, field_decl);
3958 /* struct objc_method_list *instance_methods; */
3960 decl_specs = build_tree_list (NULL_TREE,
3961 xref_tag (RECORD_TYPE,
3962 get_identifier (UTAG_METHOD_LIST)));
3964 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3965 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3966 chainon (field_decl_chain, field_decl);
3968 /* struct objc_method_list *class_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 ("class_methods"));
3975 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3976 chainon (field_decl_chain, field_decl);
3978 /* struct objc_protocol **protocol_list; */
3980 decl_specs = build_tree_list (NULL_TREE,
3981 xref_tag (RECORD_TYPE,
3982 get_identifier (UTAG_PROTOCOL)));
3984 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3985 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3986 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3987 chainon (field_decl_chain, field_decl);
3989 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3992 /* struct objc_selector {
3998 build_selector_template (void)
4001 tree decl_specs, field_decl, field_decl_chain;
4003 objc_selector_template
4004 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4008 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4009 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4010 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4011 field_decl_chain = field_decl;
4013 /* char *sel_type; */
4015 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4016 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4017 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4018 chainon (field_decl_chain, field_decl);
4020 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4023 /* struct objc_class {
4024 struct objc_class *isa;
4025 struct objc_class *super_class;
4030 struct objc_ivar_list *ivars;
4031 struct objc_method_list *methods;
4032 if (flag_next_runtime)
4033 struct objc_cache *cache;
4035 struct sarray *dtable;
4036 struct objc_class *subclass_list;
4037 struct objc_class *sibling_class;
4039 struct objc_protocol_list *protocols;
4040 if (flag_next_runtime)
4042 void *gc_object_type;
4045 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4046 the NeXT/Apple runtime; still, the compiler must generate them to
4047 maintain backward binary compatibility (and to allow for future
4051 build_class_template (void)
4053 tree decl_specs, field_decl, field_decl_chain;
4056 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4058 /* struct objc_class *isa; */
4060 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4061 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4062 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4063 field_decl_chain = field_decl;
4065 /* struct objc_class *super_class; */
4067 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4069 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4070 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4071 chainon (field_decl_chain, field_decl);
4075 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4076 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4077 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4078 chainon (field_decl_chain, field_decl);
4082 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4083 field_decl = get_identifier ("version");
4084 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4085 chainon (field_decl_chain, field_decl);
4089 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4090 field_decl = get_identifier ("info");
4091 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4092 chainon (field_decl_chain, field_decl);
4094 /* long instance_size; */
4096 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4097 field_decl = get_identifier ("instance_size");
4098 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4099 chainon (field_decl_chain, field_decl);
4101 /* struct objc_ivar_list *ivars; */
4103 decl_specs = build_tree_list (NULL_TREE,
4104 xref_tag (RECORD_TYPE,
4105 get_identifier (UTAG_IVAR_LIST)));
4106 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4107 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4108 chainon (field_decl_chain, field_decl);
4110 /* struct objc_method_list *methods; */
4112 decl_specs = build_tree_list (NULL_TREE,
4113 xref_tag (RECORD_TYPE,
4114 get_identifier (UTAG_METHOD_LIST)));
4115 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4116 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4117 chainon (field_decl_chain, field_decl);
4119 if (flag_next_runtime)
4121 /* struct objc_cache *cache; */
4123 decl_specs = build_tree_list (NULL_TREE,
4124 xref_tag (RECORD_TYPE,
4125 get_identifier ("objc_cache")));
4126 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4127 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4128 chainon (field_decl_chain, field_decl);
4132 /* struct sarray *dtable; */
4134 decl_specs = build_tree_list (NULL_TREE,
4135 xref_tag (RECORD_TYPE,
4136 get_identifier ("sarray")));
4137 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4138 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4139 chainon (field_decl_chain, field_decl);
4141 /* struct objc_class *subclass_list; */
4143 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4145 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4146 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4147 chainon (field_decl_chain, field_decl);
4149 /* struct objc_class *sibling_class; */
4151 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4153 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4154 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4155 chainon (field_decl_chain, field_decl);
4158 /* struct objc_protocol **protocol_list; */
4160 decl_specs = build_tree_list (NULL_TREE,
4161 xref_tag (RECORD_TYPE,
4162 get_identifier (UTAG_PROTOCOL)));
4164 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4166 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4167 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4168 chainon (field_decl_chain, field_decl);
4170 if (flag_next_runtime)
4174 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4175 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4177 = grokfield (field_decl, decl_specs, NULL_TREE);
4178 chainon (field_decl_chain, field_decl);
4181 /* void *gc_object_type; */
4183 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4184 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4185 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4186 chainon (field_decl_chain, field_decl);
4188 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4191 /* Generate appropriate forward declarations for an implementation. */
4194 synth_forward_declarations (void)
4198 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4199 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4200 objc_class_template);
4202 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4203 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4204 objc_class_template);
4206 /* Pre-build the following entities - for speed/convenience. */
4208 an_id = get_identifier ("super_class");
4209 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4210 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4214 error_with_ivar (const char *message, tree decl, tree rawdecl)
4216 error ("%J%s `%s'", decl,
4217 message, gen_declaration (rawdecl, errbuf));
4222 check_ivars (tree inter, tree imp)
4224 tree intdecls = CLASS_IVARS (inter);
4225 tree impdecls = CLASS_IVARS (imp);
4226 tree rawintdecls = CLASS_RAW_IVARS (inter);
4227 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4234 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4235 intdecls = TREE_CHAIN (intdecls);
4237 if (intdecls == 0 && impdecls == 0)
4239 if (intdecls == 0 || impdecls == 0)
4241 error ("inconsistent instance variable specification");
4245 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4247 if (!comptypes (t1, t2)
4248 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4249 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4251 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4253 error_with_ivar ("conflicting instance variable type",
4254 impdecls, rawimpdecls);
4255 error_with_ivar ("previous declaration of",
4256 intdecls, rawintdecls);
4258 else /* both the type and the name don't match */
4260 error ("inconsistent instance variable specification");
4265 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4267 error_with_ivar ("conflicting instance variable name",
4268 impdecls, rawimpdecls);
4269 error_with_ivar ("previous declaration of",
4270 intdecls, rawintdecls);
4273 intdecls = TREE_CHAIN (intdecls);
4274 impdecls = TREE_CHAIN (impdecls);
4275 rawintdecls = TREE_CHAIN (rawintdecls);
4276 rawimpdecls = TREE_CHAIN (rawimpdecls);
4280 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4281 This needs to be done just once per compilation. */
4284 build_super_template (void)
4286 tree decl_specs, field_decl, field_decl_chain;
4288 /* Suppress outputting debug symbols, because
4289 dbxout_init hasn't been called yet. */
4290 enum debug_info_type save_write_symbols = write_symbols;
4291 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4293 write_symbols = NO_DEBUG;
4294 debug_hooks = &do_nothing_debug_hooks;
4296 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4298 /* struct objc_object *self; */
4300 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4301 field_decl = get_identifier ("self");
4302 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4303 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4304 field_decl_chain = field_decl;
4307 /* struct objc_class *super_class; */
4309 /* struct objc_class *class; */
4312 decl_specs = get_identifier (UTAG_CLASS);
4313 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4315 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4317 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4320 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4321 chainon (field_decl_chain, field_decl);
4323 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4325 write_symbols = save_write_symbols;
4326 debug_hooks = save_hooks;
4329 /* struct objc_ivar {
4336 build_ivar_template (void)
4338 tree objc_ivar_id, objc_ivar_record;
4339 tree decl_specs, field_decl, field_decl_chain;
4341 objc_ivar_id = get_identifier (UTAG_IVAR);
4342 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4344 /* char *ivar_name; */
4346 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4347 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4349 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4350 field_decl_chain = field_decl;
4352 /* char *ivar_type; */
4354 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4355 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4357 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4358 chainon (field_decl_chain, field_decl);
4360 /* int ivar_offset; */
4362 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4363 field_decl = get_identifier ("ivar_offset");
4365 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4366 chainon (field_decl_chain, field_decl);
4368 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4370 return objc_ivar_record;
4375 struct objc_ivar ivar_list[ivar_count];
4379 build_ivar_list_template (tree list_type, int size)
4381 tree objc_ivar_list_record;
4382 tree decl_specs, field_decl, field_decl_chain;
4384 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4386 /* int ivar_count; */
4388 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4389 field_decl = get_identifier ("ivar_count");
4391 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4392 field_decl_chain = field_decl;
4394 /* struct objc_ivar ivar_list[]; */
4396 decl_specs = build_tree_list (NULL_TREE, list_type);
4397 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4398 build_int_2 (size, 0));
4400 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4401 chainon (field_decl_chain, field_decl);
4403 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4405 return objc_ivar_list_record;
4411 struct objc_method method_list[method_count];
4415 build_method_list_template (tree list_type, int size)
4417 tree objc_ivar_list_record;
4418 tree decl_specs, field_decl, field_decl_chain;
4420 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4422 /* int method_next; */
4427 xref_tag (RECORD_TYPE,
4428 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4430 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4431 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4432 field_decl_chain = field_decl;
4434 /* int method_count; */
4436 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4437 field_decl = get_identifier ("method_count");
4439 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4440 chainon (field_decl_chain, field_decl);
4442 /* struct objc_method method_list[]; */
4444 decl_specs = build_tree_list (NULL_TREE, list_type);
4445 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4446 build_int_2 (size, 0));
4448 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4449 chainon (field_decl_chain, field_decl);
4451 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4453 return objc_ivar_list_record;
4457 build_ivar_list_initializer (tree type, tree field_decl)
4459 tree initlist = NULL_TREE;
4463 tree ivar = NULL_TREE;
4466 if (DECL_NAME (field_decl))
4467 ivar = tree_cons (NULL_TREE,
4468 add_objc_string (DECL_NAME (field_decl),
4472 /* Unnamed bit-field ivar (yuck). */
4473 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4476 encode_field_decl (field_decl,
4477 obstack_object_size (&util_obstack),
4478 OBJC_ENCODE_DONT_INLINE_DEFS);
4480 /* Null terminate string. */
4481 obstack_1grow (&util_obstack, 0);
4485 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4488 obstack_free (&util_obstack, util_firstobj);
4491 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4492 initlist = tree_cons (NULL_TREE,
4493 objc_build_constructor (type, nreverse (ivar)),
4496 field_decl = TREE_CHAIN (field_decl);
4497 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4501 return objc_build_constructor (build_array_type (type, 0),
4502 nreverse (initlist));
4506 generate_ivars_list (tree type, const char *name, int size, tree list)
4508 tree sc_spec, decl_specs, decl, initlist;
4510 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4511 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4513 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4514 decl_specs, 1, NULL_TREE);
4516 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4517 initlist = tree_cons (NULL_TREE, list, initlist);
4520 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4526 /* Count only the fields occurring in T. */
4528 ivar_list_length (tree t)
4532 for (; t; t = TREE_CHAIN (t))
4533 if (TREE_CODE (t) == FIELD_DECL)
4540 generate_ivar_lists (void)
4542 tree initlist, ivar_list_template, chain;
4543 tree cast, variable_length_type;
4546 generating_instance_variables = 1;
4548 if (!objc_ivar_template)
4549 objc_ivar_template = build_ivar_template ();
4553 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4554 get_identifier (UTAG_IVAR_LIST))),
4556 variable_length_type = groktypename (cast);
4558 /* Only generate class variables for the root of the inheritance
4559 hierarchy since these will be the same for every class. */
4561 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4562 && (chain = TYPE_FIELDS (objc_class_template)))
4564 size = ivar_list_length (chain);
4566 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4567 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4569 UOBJC_CLASS_VARIABLES_decl
4570 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4572 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4575 UOBJC_CLASS_VARIABLES_decl = 0;
4577 chain = CLASS_IVARS (implementation_template);
4580 size = ivar_list_length (chain);
4581 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4582 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4584 UOBJC_INSTANCE_VARIABLES_decl
4585 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4587 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4590 UOBJC_INSTANCE_VARIABLES_decl = 0;
4592 generating_instance_variables = 0;
4596 build_dispatch_table_initializer (tree type, tree entries)
4598 tree initlist = NULL_TREE;
4602 tree elemlist = NULL_TREE;
4604 elemlist = tree_cons (NULL_TREE,
4605 build_selector (METHOD_SEL_NAME (entries)),
4608 /* Generate the method encoding if we don't have one already. */
4609 if (! METHOD_ENCODING (entries))
4610 METHOD_ENCODING (entries) =
4611 encode_method_prototype (entries);
4613 elemlist = tree_cons (NULL_TREE,
4614 add_objc_string (METHOD_ENCODING (entries),
4618 elemlist = tree_cons (NULL_TREE,
4619 build_unary_op (ADDR_EXPR,
4620 METHOD_DEFINITION (entries), 1),
4623 initlist = tree_cons (NULL_TREE,
4624 objc_build_constructor (type, nreverse (elemlist)),
4627 entries = TREE_CHAIN (entries);
4631 return objc_build_constructor (build_array_type (type, 0),
4632 nreverse (initlist));
4635 /* To accomplish method prototyping without generating all kinds of
4636 inane warnings, the definition of the dispatch table entries were
4639 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4641 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4644 build_method_template (void)
4647 tree decl_specs, field_decl, field_decl_chain;
4649 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4651 /* struct objc_selector *_cmd; */
4652 decl_specs = tree_cons (NULL_TREE,
4653 xref_tag (RECORD_TYPE,
4654 get_identifier (TAG_SELECTOR)),
4656 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4658 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4659 field_decl_chain = field_decl;
4661 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4662 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4663 get_identifier ("method_types"));
4664 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4665 chainon (field_decl_chain, field_decl);
4669 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4670 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4671 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4672 chainon (field_decl_chain, field_decl);
4674 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4681 generate_dispatch_table (tree type, const char *name, int size, tree list)
4683 tree sc_spec, decl_specs, decl, initlist;
4685 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4686 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4688 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4689 decl_specs, 1, NULL_TREE);
4691 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4692 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4693 initlist = tree_cons (NULL_TREE, list, initlist);
4696 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4703 mark_referenced_methods (void)
4705 struct imp_entry *impent;
4708 for (impent = imp_list; impent; impent = impent->next)
4710 chain = CLASS_CLS_METHODS (impent->imp_context);
4713 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4714 chain = TREE_CHAIN (chain);
4717 chain = CLASS_NST_METHODS (impent->imp_context);
4720 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4721 chain = TREE_CHAIN (chain);
4727 generate_dispatch_tables (void)
4729 tree initlist, chain, method_list_template;
4730 tree cast, variable_length_type;
4733 if (!objc_method_template)
4734 objc_method_template = build_method_template ();
4738 (build_tree_list (NULL_TREE,
4739 xref_tag (RECORD_TYPE,
4740 get_identifier (UTAG_METHOD_LIST))),
4743 variable_length_type = groktypename (cast);
4745 chain = CLASS_CLS_METHODS (objc_implementation_context);
4748 size = list_length (chain);
4750 method_list_template
4751 = build_method_list_template (objc_method_template, size);
4753 = build_dispatch_table_initializer (objc_method_template, chain);
4755 UOBJC_CLASS_METHODS_decl
4756 = generate_dispatch_table (method_list_template,
4757 ((TREE_CODE (objc_implementation_context)
4758 == CLASS_IMPLEMENTATION_TYPE)
4759 ? "_OBJC_CLASS_METHODS"
4760 : "_OBJC_CATEGORY_CLASS_METHODS"),
4762 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4765 UOBJC_CLASS_METHODS_decl = 0;
4767 chain = CLASS_NST_METHODS (objc_implementation_context);
4770 size = list_length (chain);
4772 method_list_template
4773 = build_method_list_template (objc_method_template, size);
4775 = build_dispatch_table_initializer (objc_method_template, chain);
4777 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4778 UOBJC_INSTANCE_METHODS_decl
4779 = generate_dispatch_table (method_list_template,
4780 "_OBJC_INSTANCE_METHODS",
4783 /* We have a category. */
4784 UOBJC_INSTANCE_METHODS_decl
4785 = generate_dispatch_table (method_list_template,
4786 "_OBJC_CATEGORY_INSTANCE_METHODS",
4788 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4791 UOBJC_INSTANCE_METHODS_decl = 0;
4795 generate_protocol_list (tree i_or_p)
4797 tree initlist, decl_specs, sc_spec;
4798 tree refs_decl, expr_decl, lproto, e, plist;
4802 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4803 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4804 plist = CLASS_PROTOCOL_LIST (i_or_p);
4805 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4806 plist = PROTOCOL_LIST (i_or_p);
4810 cast_type = groktypename
4812 (build_tree_list (NULL_TREE,
4813 xref_tag (RECORD_TYPE,
4814 get_identifier (UTAG_PROTOCOL))),
4815 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4818 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4819 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4820 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4823 /* Build initializer. */
4824 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4826 e = build_int_2 (size, 0);
4827 TREE_TYPE (e) = cast_type;
4828 initlist = tree_cons (NULL_TREE, e, initlist);
4830 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4832 tree pval = TREE_VALUE (lproto);
4834 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4835 && PROTOCOL_FORWARD_DECL (pval))
4837 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4838 initlist = tree_cons (NULL_TREE, e, initlist);
4842 /* static struct objc_protocol *refs[n]; */
4844 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4845 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4846 get_identifier (UTAG_PROTOCOL)),
4849 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4850 expr_decl = build_nt (ARRAY_REF,
4851 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4853 build_int_2 (size + 2, 0));
4854 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4855 expr_decl = build_nt (ARRAY_REF,
4856 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4858 build_int_2 (size + 2, 0));
4859 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4861 = build_nt (ARRAY_REF,
4862 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4864 build_int_2 (size + 2, 0));
4868 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4870 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4871 DECL_CONTEXT (refs_decl) = NULL_TREE;
4873 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4874 nreverse (initlist)),
4881 build_category_initializer (tree type, tree cat_name, tree class_name,
4882 tree instance_methods, tree class_methods,
4885 tree initlist = NULL_TREE, expr;
4887 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4888 initlist = tree_cons (NULL_TREE, class_name, initlist);
4890 if (!instance_methods)
4891 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4894 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4895 initlist = tree_cons (NULL_TREE, expr, initlist);
4898 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4901 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4902 initlist = tree_cons (NULL_TREE, expr, initlist);
4905 /* protocol_list = */
4907 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4910 tree cast_type2 = groktypename
4912 (build_tree_list (NULL_TREE,
4913 xref_tag (RECORD_TYPE,
4914 get_identifier (UTAG_PROTOCOL))),
4915 build1 (INDIRECT_REF, NULL_TREE,
4916 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4918 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4919 TREE_TYPE (expr) = cast_type2;
4920 initlist = tree_cons (NULL_TREE, expr, initlist);
4923 return objc_build_constructor (type, nreverse (initlist));
4926 /* struct objc_class {
4927 struct objc_class *isa;
4928 struct objc_class *super_class;
4933 struct objc_ivar_list *ivars;
4934 struct objc_method_list *methods;
4935 if (flag_next_runtime)
4936 struct objc_cache *cache;
4938 struct sarray *dtable;
4939 struct objc_class *subclass_list;
4940 struct objc_class *sibling_class;
4942 struct objc_protocol_list *protocols;
4943 if (flag_next_runtime)
4945 void *gc_object_type;
4949 build_shared_structure_initializer (tree type, tree isa, tree super,
4950 tree name, tree size, int status,
4951 tree dispatch_table, tree ivar_list,
4954 tree initlist = NULL_TREE, expr;
4957 initlist = tree_cons (NULL_TREE, isa, initlist);
4960 initlist = tree_cons (NULL_TREE, super, initlist);
4963 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4966 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4969 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4971 /* instance_size = */
4972 initlist = tree_cons (NULL_TREE, size, initlist);
4974 /* objc_ivar_list = */
4976 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4979 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4980 initlist = tree_cons (NULL_TREE, expr, initlist);
4983 /* objc_method_list = */
4984 if (!dispatch_table)
4985 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4988 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4989 initlist = tree_cons (NULL_TREE, expr, initlist);
4992 if (flag_next_runtime)
4993 /* method_cache = */
4994 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4998 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5000 /* subclass_list = */
5001 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5003 /* sibling_class = */
5004 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5007 /* protocol_list = */
5008 if (! protocol_list)
5009 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5015 (build_tree_list (NULL_TREE,
5016 xref_tag (RECORD_TYPE,
5017 get_identifier (UTAG_PROTOCOL))),
5018 build1 (INDIRECT_REF, NULL_TREE,
5019 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5021 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5022 TREE_TYPE (expr) = cast_type2;
5023 initlist = tree_cons (NULL_TREE, expr, initlist);
5026 if (flag_next_runtime)
5028 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5030 /* gc_object_type = NULL */
5031 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5033 return objc_build_constructor (type, nreverse (initlist));
5036 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5039 lookup_category (tree class, tree cat_name)
5041 tree category = CLASS_CATEGORY_LIST (class);
5043 while (category && CLASS_SUPER_NAME (category) != cat_name)
5044 category = CLASS_CATEGORY_LIST (category);
5048 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5051 generate_category (tree cat)
5053 tree sc_spec, decl_specs, decl;
5054 tree initlist, cat_name_expr, class_name_expr;
5055 tree protocol_decl, category;
5057 add_class_reference (CLASS_NAME (cat));
5058 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5060 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5062 category = lookup_category (implementation_template,
5063 CLASS_SUPER_NAME (cat));
5065 if (category && CLASS_PROTOCOL_LIST (category))
5067 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5068 protocol_decl = generate_protocol_list (category);
5073 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5074 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5076 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5077 objc_implementation_context),
5078 decl_specs, 1, NULL_TREE);
5080 initlist = build_category_initializer (TREE_TYPE (decl),
5081 cat_name_expr, class_name_expr,
5082 UOBJC_INSTANCE_METHODS_decl,
5083 UOBJC_CLASS_METHODS_decl,
5086 finish_decl (decl, initlist, NULL_TREE);
5089 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5090 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5093 generate_shared_structures (void)
5095 tree sc_spec, decl_specs, decl;
5096 tree name_expr, super_expr, root_expr;
5097 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5098 tree cast_type, initlist, protocol_decl;
5100 my_super_id = CLASS_SUPER_NAME (implementation_template);
5103 add_class_reference (my_super_id);
5105 /* Compute "my_root_id" - this is required for code generation.
5106 the "isa" for all meta class structures points to the root of
5107 the inheritance hierarchy (e.g. "__Object")... */
5108 my_root_id = my_super_id;
5111 tree my_root_int = lookup_interface (my_root_id);
5113 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5114 my_root_id = CLASS_SUPER_NAME (my_root_int);
5121 /* No super class. */
5122 my_root_id = CLASS_NAME (implementation_template);
5125 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5126 objc_class_template),
5127 build1 (INDIRECT_REF,
5128 NULL_TREE, NULL_TREE)));
5130 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5133 /* Install class `isa' and `super' pointers at runtime. */
5136 super_expr = add_objc_string (my_super_id, class_names);
5137 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5140 super_expr = build_int_2 (0, 0);
5142 root_expr = add_objc_string (my_root_id, class_names);
5143 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5145 if (CLASS_PROTOCOL_LIST (implementation_template))
5147 generate_protocol_references
5148 (CLASS_PROTOCOL_LIST (implementation_template));
5149 protocol_decl = generate_protocol_list (implementation_template);
5154 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5156 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5157 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5159 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5163 = build_shared_structure_initializer
5165 root_expr, super_expr, name_expr,
5166 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5168 UOBJC_CLASS_METHODS_decl,
5169 UOBJC_CLASS_VARIABLES_decl,
5172 finish_decl (decl, initlist, NULL_TREE);
5174 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5176 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5180 = build_shared_structure_initializer
5182 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5183 super_expr, name_expr,
5184 convert (integer_type_node,
5185 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5186 (implementation_template))),
5188 UOBJC_INSTANCE_METHODS_decl,
5189 UOBJC_INSTANCE_VARIABLES_decl,
5192 finish_decl (decl, initlist, NULL_TREE);
5196 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5199 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5200 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5202 const char *const class_name
5203 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5204 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5205 sprintf (string, "%s_%s", preamble,
5206 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5208 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5209 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5211 /* We have a category. */
5212 const char *const class_name
5213 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5214 const char *const class_super_name
5215 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5216 string = (char *) alloca (strlen (preamble)
5217 + strlen (class_name)
5218 + strlen (class_super_name)
5220 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5222 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5224 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5226 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5227 sprintf (string, "%s_%s", preamble, protocol_name);
5232 return get_identifier (string);
5236 is_objc_type_qualifier (tree node)
5238 return (TREE_CODE (node) == IDENTIFIER_NODE
5239 && (node == ridpointers [(int) RID_CONST]
5240 || node == ridpointers [(int) RID_VOLATILE]
5241 || node == ridpointers [(int) RID_IN]
5242 || node == ridpointers [(int) RID_OUT]
5243 || node == ridpointers [(int) RID_INOUT]
5244 || node == ridpointers [(int) RID_BYCOPY]
5245 || node == ridpointers [(int) RID_BYREF]
5246 || node == ridpointers [(int) RID_ONEWAY]));
5249 /* If type is empty or only type qualifiers are present, add default
5250 type of id (otherwise grokdeclarator will default to int). */
5253 adjust_type_for_id_default (tree type)
5255 tree declspecs, chain;
5258 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5259 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5261 declspecs = TREE_PURPOSE (type);
5263 /* Determine if a typespec is present. */
5264 for (chain = declspecs;
5266 chain = TREE_CHAIN (chain))
5268 if (TYPED_OBJECT (TREE_VALUE (chain))
5269 && !(TREE_VALUE (type)
5270 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5271 error ("can not use an object as parameter to a method\n");
5272 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5276 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5278 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5283 selector ':' '(' typename ')' identifier
5286 Transform an Objective-C keyword argument into
5287 the C equivalent parameter declarator.
5289 In: key_name, an "identifier_node" (optional).
5290 arg_type, a "tree_list" (optional).
5291 arg_name, an "identifier_node".
5293 Note: It would be really nice to strongly type the preceding
5294 arguments in the function prototype; however, then I
5295 could not use the "accessor" macros defined in "tree.h".
5297 Out: an instance of "keyword_decl". */
5300 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5304 /* If no type is specified, default to "id". */
5305 arg_type = adjust_type_for_id_default (arg_type);
5307 keyword_decl = make_node (KEYWORD_DECL);
5309 TREE_TYPE (keyword_decl) = arg_type;
5310 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5311 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5313 return keyword_decl;
5316 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5319 build_keyword_selector (tree selector)
5322 tree key_chain, key_name;
5325 /* Scan the selector to see how much space we'll need. */
5326 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5328 if (TREE_CODE (selector) == KEYWORD_DECL)
5329 key_name = KEYWORD_KEY_NAME (key_chain);
5330 else if (TREE_CODE (selector) == TREE_LIST)
5331 key_name = TREE_PURPOSE (key_chain);
5336 len += IDENTIFIER_LENGTH (key_name) + 1;
5338 /* Just a ':' arg. */
5342 buf = (char *) alloca (len + 1);
5343 /* Start the buffer out as an empty string. */
5346 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5348 if (TREE_CODE (selector) == KEYWORD_DECL)
5349 key_name = KEYWORD_KEY_NAME (key_chain);
5350 else if (TREE_CODE (selector) == TREE_LIST)
5352 key_name = TREE_PURPOSE (key_chain);
5353 /* The keyword decl chain will later be used as a function argument
5354 chain. Unhook the selector itself so as to not confuse other
5355 parts of the compiler. */
5356 TREE_PURPOSE (key_chain) = NULL_TREE;
5362 strcat (buf, IDENTIFIER_POINTER (key_name));
5366 return get_identifier (buf);
5369 /* Used for declarations and definitions. */
5372 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5377 /* If no type is specified, default to "id". */
5378 ret_type = adjust_type_for_id_default (ret_type);
5380 method_decl = make_node (code);
5381 TREE_TYPE (method_decl) = ret_type;
5383 /* If we have a keyword selector, create an identifier_node that
5384 represents the full selector name (`:' included)... */
5385 if (TREE_CODE (selector) == KEYWORD_DECL)
5387 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5388 METHOD_SEL_ARGS (method_decl) = selector;
5389 METHOD_ADD_ARGS (method_decl) = add_args;
5393 METHOD_SEL_NAME (method_decl) = selector;
5394 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5395 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5401 #define METHOD_DEF 0
5402 #define METHOD_REF 1
5404 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5405 an argument list for method METH. CONTEXT is either METHOD_DEF or
5406 METHOD_REF, saying whether we are trying to define a method or call
5407 one. SUPERFLAG says this is for a send to super; this makes a
5408 difference for the NeXT calling sequence in which the lookup and
5409 the method call are done together. If METH is null, user-defined
5410 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5413 get_arg_type_list (tree meth, int context, int superflag)
5417 /* Receiver type. */
5418 if (flag_next_runtime && superflag)
5419 arglist = build_tree_list (NULL_TREE, super_type);
5420 else if (context == METHOD_DEF)
5421 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5423 arglist = build_tree_list (NULL_TREE, id_type);
5425 /* Selector type - will eventually change to `int'. */
5426 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
5428 /* No actual method prototype given -- assume that remaining arguments
5433 /* Build a list of argument types. */
5434 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5436 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5437 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5440 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5441 /* We have a `, ...' immediately following the selector,
5442 finalize the arglist...simulate get_parm_info (true). */
5444 else if (METHOD_ADD_ARGS (meth))
5446 /* we have a variable length selector */
5447 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5448 chainon (arglist, add_arg_list);
5451 /* finalize the arglist...simulate get_parm_info (false) */
5452 chainon (arglist, void_list_node);
5458 check_duplicates (hash hsh, int methods, int is_class)
5460 tree meth = NULL_TREE;
5468 /* We have two or more methods with the same name but
5472 warning ("multiple %s named `%c%s' found",
5473 methods ? "methods" : "selectors",
5474 (is_class ? '+' : '-'),
5475 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5477 warn_with_method (methods ? "using" : "found",
5478 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5482 for (loop = hsh->list; loop; loop = loop->next)
5483 warn_with_method ("also found",
5484 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5493 /* If RECEIVER is a class reference, return the identifier node for
5494 the referenced class. RECEIVER is created by get_class_reference,
5495 so we check the exact form created depending on which runtimes are
5499 receiver_is_class_object (tree receiver, int self, int super)
5501 tree chain, exp, arg;
5503 /* The receiver is 'self' or 'super' in the context of a class method. */
5504 if (objc_method_context
5505 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5508 ? CLASS_SUPER_NAME (implementation_template)
5509 : CLASS_NAME (implementation_template));
5511 if (flag_next_runtime)
5513 /* The receiver is a variable created by
5514 build_class_reference_decl. */
5515 if (TREE_CODE (receiver) == VAR_DECL
5516 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5517 /* Look up the identifier. */
5518 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5519 if (TREE_PURPOSE (chain) == receiver)
5520 return TREE_VALUE (chain);
5523 /* The receiver is a function call that returns an id. Check if
5524 it is a call to objc_getClass, if so, pick up the class name. */
5525 if (TREE_CODE (receiver) == CALL_EXPR
5526 && (exp = TREE_OPERAND (receiver, 0))
5527 && TREE_CODE (exp) == ADDR_EXPR
5528 && (exp = TREE_OPERAND (exp, 0))
5529 && TREE_CODE (exp) == FUNCTION_DECL
5530 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5531 prototypes for objc_get_class(). Thankfully, they seem to share the
5532 same function type. */
5533 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5534 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5535 /* We have a call to objc_get_class/objc_getClass! */
5536 && (arg = TREE_OPERAND (receiver, 1))
5537 && TREE_CODE (arg) == TREE_LIST
5538 && (arg = TREE_VALUE (arg)))
5541 if (TREE_CODE (arg) == ADDR_EXPR
5542 && (arg = TREE_OPERAND (arg, 0))
5543 && TREE_CODE (arg) == STRING_CST)
5544 /* Finally, we have the class name. */
5545 return get_identifier (TREE_STRING_POINTER (arg));
5550 /* If we are currently building a message expr, this holds
5551 the identifier of the selector of the message. This is
5552 used when printing warnings about argument mismatches. */
5554 static tree current_objc_message_selector = 0;
5557 objc_message_selector (void)
5559 return current_objc_message_selector;
5562 /* Construct an expression for sending a message.
5563 MESS has the object to send to in TREE_PURPOSE
5564 and the argument list (including selector) in TREE_VALUE.
5566 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5567 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5570 build_message_expr (tree mess)
5572 tree receiver = TREE_PURPOSE (mess);
5574 tree args = TREE_VALUE (mess);
5575 tree method_params = NULL_TREE;
5577 if (TREE_CODE (receiver) == ERROR_MARK)
5578 return error_mark_node;
5580 /* Obtain the full selector name. */
5581 if (TREE_CODE (args) == IDENTIFIER_NODE)
5582 /* A unary selector. */
5584 else if (TREE_CODE (args) == TREE_LIST)
5585 sel_name = build_keyword_selector (args);
5589 /* Build the parameter list to give to the method. */
5590 if (TREE_CODE (args) == TREE_LIST)
5592 tree chain = args, prev = NULL_TREE;
5594 /* We have a keyword selector--check for comma expressions. */
5597 tree element = TREE_VALUE (chain);
5599 /* We have a comma expression, must collapse... */
5600 if (TREE_CODE (element) == TREE_LIST)
5603 TREE_CHAIN (prev) = element;
5608 chain = TREE_CHAIN (chain);
5610 method_params = args;
5614 if (processing_template_decl)
5615 /* Must wait until template instantiation time. */
5616 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5620 return finish_message_expr (receiver, sel_name, method_params);
5623 /* Look up method SEL_NAME that would be suitable for receiver
5624 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5625 nonzero), and report on any duplicates. */
5628 lookup_method_in_hash_lists (tree sel_name, int is_class)
5630 hash method_prototype = NULL;
5633 method_prototype = hash_lookup (nst_method_hash_list,
5636 if (!method_prototype)
5638 method_prototype = hash_lookup (cls_method_hash_list,
5643 return check_duplicates (method_prototype, 1, is_class);
5646 /* The 'finish_message_expr' routine is called from within
5647 'build_message_expr' for non-template functions. In the case of
5648 C++ template functions, it is called from 'build_expr_from_tree'
5649 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5652 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5654 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5655 tree selector, retval, is_class;
5656 int self, super, have_cast;
5658 /* Extract the receiver of the message, as well as its type
5659 (where the latter may take the form of a cast or be inferred
5660 from the implementation context). */
5662 while (TREE_CODE (rtype) == COMPOUND_EXPR
5663 || TREE_CODE (rtype) == MODIFY_EXPR
5664 || TREE_CODE (rtype) == NOP_EXPR
5665 || TREE_CODE (rtype) == COMPONENT_REF)
5666 rtype = TREE_OPERAND (rtype, 0);
5667 self = (rtype == self_decl);
5668 super = (rtype == UOBJC_SUPER_decl);
5669 rtype = TREE_TYPE (receiver);
5670 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5671 || (TREE_CODE (receiver) == COMPOUND_EXPR
5672 && !IS_SUPER (rtype)));
5674 /* If the receiver is a class object, retrieve the corresponding
5675 @interface, if one exists. */
5676 is_class = receiver_is_class_object (receiver, self, super);
5678 /* Now determine the receiver type (if an explicit cast has not been
5683 rtype = lookup_interface (is_class);
5684 /* Handle `self' and `super'. */
5687 if (!CLASS_SUPER_NAME (implementation_template))
5689 error ("no super class declared in @interface for `%s'",
5690 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5691 return error_mark_node;
5693 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5696 rtype = lookup_interface (CLASS_NAME (implementation_template));
5699 /* If receiver is of type `id' or `Class' (or if the @interface for a
5700 class is not visible), we shall be satisfied with the existence of
5701 any instance or class method. */
5702 if (!rtype || IS_ID (rtype)
5703 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5706 rtype = xref_tag (RECORD_TYPE, is_class);
5707 else if (IS_ID (rtype))
5709 rprotos = TYPE_PROTOCOL_LIST (rtype);
5713 is_class = TYPE_NAME (rtype) = get_identifier ("Class");
5717 = lookup_method_in_protocol_list (rprotos, sel_name,
5718 is_class != NULL_TREE);
5719 if (!method_prototype && !rprotos)
5721 = lookup_method_in_hash_lists (sel_name,
5722 is_class != NULL_TREE);
5726 tree orig_rtype = rtype, saved_rtype;
5728 if (TREE_CODE (rtype) == POINTER_TYPE)
5729 rtype = TREE_TYPE (rtype);
5730 /* Traverse typedef aliases */
5731 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5732 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5733 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5734 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5735 saved_rtype = rtype;
5736 if (TYPED_OBJECT (rtype))
5738 rprotos = TYPE_PROTOCOL_LIST (rtype);
5739 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5741 /* If we could not find an @interface declaration, we must have
5742 only seen a @class declaration; so, we cannot say anything
5743 more intelligent about which methods the receiver will
5746 rtype = saved_rtype;
5747 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5748 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5750 /* We have a valid ObjC class name. Look up the method name
5751 in the published @interface for the class (and its
5754 = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
5756 /* If the method was not found in the @interface, it may still
5757 exist locally as part of the @implementation. */
5758 if (!method_prototype && objc_implementation_context
5759 && CLASS_NAME (objc_implementation_context)
5760 == OBJC_TYPE_NAME (rtype))
5764 ? CLASS_CLS_METHODS (objc_implementation_context)
5765 : CLASS_NST_METHODS (objc_implementation_context)),
5768 /* If we haven't found a candidate method by now, try looking for
5769 it in the protocol list. */
5770 if (!method_prototype && rprotos)
5772 = lookup_method_in_protocol_list (rprotos, sel_name,
5773 is_class != NULL_TREE);
5777 warning ("invalid receiver type `%s'",
5778 gen_declaration (orig_rtype, errbuf));
5779 rtype = rprotos = NULL_TREE;
5783 if (!method_prototype)
5785 static bool warn_missing_methods = false;
5788 warning ("`%s' may not respond to `%c%s'",
5789 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5790 (is_class ? '+' : '-'),
5791 IDENTIFIER_POINTER (sel_name));
5793 warning ("`%c%s' not implemented by protocol(s)",
5794 (is_class ? '+' : '-'),
5795 IDENTIFIER_POINTER (sel_name));
5796 if (!warn_missing_methods)
5798 warning ("(Messages without a matching method signature");
5799 warning ("will be assumed to return `id' and accept");
5800 warning ("`...' as arguments.)");
5801 warn_missing_methods = true;
5805 /* Save the selector name for printing error messages. */
5806 current_objc_message_selector = sel_name;
5808 /* Build the parameters list for looking up the method.
5809 These are the object itself and the selector. */
5811 if (flag_typed_selectors)
5812 selector = build_typed_selector_reference (sel_name, method_prototype);
5814 selector = build_selector_reference (sel_name);
5816 retval = build_objc_method_call (super, method_prototype,
5818 selector, method_params);
5820 current_objc_message_selector = 0;
5825 /* Build a tree expression to send OBJECT the operation SELECTOR,
5826 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5827 assuming the method has prototype METHOD_PROTOTYPE.
5828 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5829 Use METHOD_PARAMS as list of args to pass to the method.
5830 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5833 build_objc_method_call (int super_flag, tree method_prototype,
5834 tree lookup_object, tree selector,
5837 tree sender = (super_flag ? umsg_super_decl :
5838 (!flag_next_runtime || flag_nil_receivers
5840 : umsg_nonnil_decl));
5841 tree rcv_p = (super_flag ? super_type : id_type);
5843 /* If a prototype for the method to be called exists, then cast
5844 the sender's return type and arguments to match that of the method.
5845 Otherwise, leave sender as is. */
5848 ? groktypename (TREE_TYPE (method_prototype))
5851 = build_pointer_type
5852 (build_function_type
5855 (method_prototype, METHOD_REF, super_flag)));
5857 lookup_object = build_c_cast (rcv_p, lookup_object);
5859 if (flag_next_runtime)
5861 /* If we are returning a struct in memory, and the address
5862 of that memory location is passed as a hidden first
5863 argument, then change which messenger entry point this
5864 expr will call. NB: Note that sender_cast remains
5865 unchanged (it already has a struct return type). */
5866 if (!targetm.calls.struct_value_rtx (0, 0)
5867 && (TREE_CODE (ret_type) == RECORD_TYPE
5868 || TREE_CODE (ret_type) == UNION_TYPE)
5869 && targetm.calls.return_in_memory (ret_type, 0))
5870 sender = (super_flag ? umsg_super_stret_decl :
5871 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5873 method_params = tree_cons (NULL_TREE, lookup_object,
5874 tree_cons (NULL_TREE, selector,
5876 TREE_USED (sender) = 1;
5877 assemble_external (sender);
5878 /* We want to cast the sender, not convert it. */
5879 return build_function_call (build_c_cast (sender_cast, sender),
5884 /* This is the portable (GNU) way. */
5885 tree method, object;
5887 /* First, call the lookup function to get a pointer to the method,
5888 then cast the pointer, then call it with the method arguments.
5889 Use SAVE_EXPR to avoid evaluating the receiver twice. */
5890 lookup_object = save_expr (lookup_object);
5891 object = (super_flag ? self_decl : lookup_object);
5892 TREE_USED (sender) = 1;
5893 assemble_external (sender);
5895 = build_function_call (sender,
5896 tree_cons (NULL_TREE, lookup_object,
5897 tree_cons (NULL_TREE, selector,
5900 /* Pass the object to the method. */
5901 TREE_USED (method) = 1;
5902 assemble_external (method);
5903 return build_function_call
5904 (build_c_cast (sender_cast, method),
5905 tree_cons (NULL_TREE, object,
5906 tree_cons (NULL_TREE, selector, method_params)));
5911 build_protocol_reference (tree p)
5913 tree decl, ident, ptype;
5915 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5917 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5919 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5920 objc_protocol_template),
5923 if (identifier_global_value (ident))
5924 decl = identifier_global_value (ident); /* Set by pushdecl. */
5927 decl = build_decl (VAR_DECL, ident, ptype);
5928 DECL_EXTERNAL (decl) = 1;
5929 TREE_PUBLIC (decl) = 0;
5930 TREE_USED (decl) = 1;
5931 DECL_ARTIFICIAL (decl) = 1;
5933 make_decl_rtl (decl, 0);
5934 pushdecl_top_level (decl);
5937 PROTOCOL_FORWARD_DECL (p) = decl;
5940 /* This function is called by the parser when (and only when) a
5941 @protocol() expression is found, in order to compile it. */
5943 build_protocol_expr (tree protoname)
5946 tree p = lookup_protocol (protoname);
5950 error ("cannot find protocol declaration for `%s'",
5951 IDENTIFIER_POINTER (protoname));
5952 return error_mark_node;
5955 if (!PROTOCOL_FORWARD_DECL (p))
5956 build_protocol_reference (p);
5958 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5960 /* ??? Ideally we'd build the reference with protocol_type directly,
5961 if we have it, rather than converting it here. */
5962 expr = convert (protocol_type, expr);
5964 /* The @protocol() expression is being compiled into a pointer to a
5965 statically allocated instance of the Protocol class. To become
5966 usable at runtime, the 'isa' pointer of the instance need to be
5967 fixed up at runtime by the runtime library, to point to the
5968 actual 'Protocol' class. */
5970 /* For the GNU runtime, put the static Protocol instance in the list
5971 of statically allocated instances, so that we make sure that its
5972 'isa' pointer is fixed up at runtime by the GNU runtime library
5973 to point to the Protocol class (at runtime, when loading the
5974 module, the GNU runtime library loops on the statically allocated
5975 instances (as found in the defs field in objc_symtab) and fixups
5976 all the 'isa' pointers of those objects). */
5977 if (! flag_next_runtime)
5979 /* This type is a struct containing the fields of a Protocol
5980 object. (Cfr. protocol_type instead is the type of a pointer
5981 to such a struct). */
5982 tree protocol_struct_type = xref_tag
5983 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5986 /* Look for the list of Protocol statically allocated instances
5987 to fixup at runtime. Create a new list to hold Protocol
5988 statically allocated instances, if the list is not found. At
5989 present there is only another list, holding NSConstantString
5990 static instances to be fixed up at runtime. */
5991 for (chain = &objc_static_instances;
5992 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5993 chain = &TREE_CHAIN (*chain));
5996 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5997 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6001 /* Add this statically allocated instance to the Protocol list. */
6002 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6003 PROTOCOL_FORWARD_DECL (p),
6004 TREE_PURPOSE (*chain));
6011 /* This function is called by the parser when a @selector() expression
6012 is found, in order to compile it. It is only called by the parser
6013 and only to compile a @selector(). */
6015 build_selector_expr (tree selnamelist)
6019 /* Obtain the full selector name. */
6020 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6021 /* A unary selector. */
6022 selname = selnamelist;
6023 else if (TREE_CODE (selnamelist) == TREE_LIST)
6024 selname = build_keyword_selector (selnamelist);
6028 /* If we are required to check @selector() expressions as they
6029 are found, check that the selector has been declared. */
6030 if (warn_undeclared_selector)
6032 /* Look the selector up in the list of all known class and
6033 instance methods (up to this line) to check that the selector
6037 /* First try with instance methods. */
6038 hsh = hash_lookup (nst_method_hash_list, selname);
6040 /* If not found, try with class methods. */
6043 hsh = hash_lookup (cls_method_hash_list, selname);
6046 /* If still not found, print out a warning. */
6049 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6054 if (flag_typed_selectors)
6055 return build_typed_selector_reference (selname, 0);
6057 return build_selector_reference (selname);
6061 build_encode_expr (tree type)
6066 encode_type (type, obstack_object_size (&util_obstack),
6067 OBJC_ENCODE_INLINE_DEFS);
6068 obstack_1grow (&util_obstack, 0); /* null terminate string */
6069 string = obstack_finish (&util_obstack);
6071 /* Synthesize a string that represents the encoded struct/union. */
6072 result = my_build_string (strlen (string) + 1, string);
6073 obstack_free (&util_obstack, util_firstobj);
6078 build_ivar_reference (tree id)
6080 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6082 /* Historically, a class method that produced objects (factory
6083 method) would assign `self' to the instance that it
6084 allocated. This would effectively turn the class method into
6085 an instance method. Following this assignment, the instance
6086 variables could be accessed. That practice, while safe,
6087 violates the simple rule that a class method should not refer
6088 to an instance variable. It's better to catch the cases
6089 where this is done unknowingly than to support the above
6091 warning ("instance variable `%s' accessed in class method",
6092 IDENTIFIER_POINTER (id));
6093 TREE_TYPE (self_decl) = instance_type; /* cast */
6096 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6099 /* Compute a hash value for a given method SEL_NAME. */
6102 hash_func (tree sel_name)
6104 const unsigned char *s
6105 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6109 h = h * 67 + *s++ - 113;
6116 nst_method_hash_list
6117 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6118 cls_method_hash_list
6119 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6122 /* WARNING!!!! hash_enter is called with a method, and will peek
6123 inside to find its selector! But hash_lookup is given a selector
6124 directly, and looks for the selector that's inside the found
6125 entry's key (method) for comparison. */
6128 hash_enter (hash *hashlist, tree method)
6131 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6133 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6135 obj->next = hashlist[slot];
6138 hashlist[slot] = obj; /* append to front */
6142 hash_lookup (hash *hashlist, tree sel_name)
6146 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6150 if (sel_name == METHOD_SEL_NAME (target->key))
6153 target = target->next;
6159 hash_add_attr (hash entry, tree value)
6163 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6164 obj->next = entry->list;
6167 entry->list = obj; /* append to front */
6171 lookup_method (tree mchain, tree method)
6175 if (TREE_CODE (method) == IDENTIFIER_NODE)
6178 key = METHOD_SEL_NAME (method);
6182 if (METHOD_SEL_NAME (mchain) == key)
6185 mchain = TREE_CHAIN (mchain);
6191 lookup_method_static (tree interface, tree ident, int is_class)
6193 tree meth = NULL_TREE, root_inter = NULL_TREE;
6194 tree inter = interface;
6198 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6199 tree category = inter;
6201 /* First, look up the method in the class itself. */
6202 if ((meth = lookup_method (chain, ident)))
6205 /* Failing that, look for the method in each category of the class. */
6206 while ((category = CLASS_CATEGORY_LIST (category)))
6208 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6210 /* Check directly in each category. */
6211 if ((meth = lookup_method (chain, ident)))
6214 /* Failing that, check in each category's protocols. */
6215 if (CLASS_PROTOCOL_LIST (category))
6217 if ((meth = (lookup_method_in_protocol_list
6218 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6223 /* If not found in categories, check in protocols of the main class. */
6224 if (CLASS_PROTOCOL_LIST (inter))
6226 if ((meth = (lookup_method_in_protocol_list
6227 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6231 /* Failing that, climb up the inheritance hierarchy. */
6233 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6237 /* If no class (factory) method was found, check if an _instance_
6238 method of the same name exists in the root class. This is what
6239 the Objective-C runtime will do. If an instance method was not
6241 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6244 /* Add the method to the hash list if it doesn't contain an identical
6247 add_method_to_hash_list (hash *hash_list, tree method)
6251 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6253 /* Install on a global chain. */
6254 hash_enter (hash_list, method);
6258 /* Check types against those; if different, add to a list. */
6260 int already_there = comp_proto_with_proto (method, hsh->key);
6261 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6262 already_there |= comp_proto_with_proto (method, loop->value);
6264 hash_add_attr (hsh, method);
6269 objc_add_method (tree class, tree method, int is_class)
6273 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6275 /* put method on list in reverse order */
6278 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6279 CLASS_CLS_METHODS (class) = method;
6283 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6284 CLASS_NST_METHODS (class) = method;
6289 /* When processing an @interface for a class or category, give hard
6290 errors on methods with identical selectors but differing argument
6291 and/or return types. We do not do this for @implementations, because
6292 C/C++ will do it for us (i.e., there will be duplicate function
6293 definition errors). */
6294 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6295 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6296 && !comp_proto_with_proto (method, mth))
6297 error ("duplicate declaration of method `%c%s'",
6298 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6302 add_method_to_hash_list (cls_method_hash_list, method);
6305 add_method_to_hash_list (nst_method_hash_list, method);
6307 /* Instance methods in root classes (and categories thereof)
6308 may acts as class methods as a last resort. */
6309 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6310 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6311 class = lookup_interface (CLASS_NAME (class));
6313 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6314 && !CLASS_SUPER_NAME (class))
6315 add_method_to_hash_list (cls_method_hash_list, method);
6322 add_class (tree class)
6324 /* Put interfaces on list in reverse order. */
6325 TREE_CHAIN (class) = interface_chain;
6326 interface_chain = class;
6327 return interface_chain;
6331 add_category (tree class, tree category)
6333 /* Put categories on list in reverse order. */
6334 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6338 warning ("duplicate interface declaration for category `%s(%s)'",
6339 IDENTIFIER_POINTER (CLASS_NAME (class)),
6340 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6344 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6345 CLASS_CATEGORY_LIST (class) = category;
6349 /* Called after parsing each instance variable declaration. Necessary to
6350 preserve typedefs and implement public/private...
6352 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6355 add_instance_variable (tree class, int public, tree declarator,
6356 tree declspecs, tree width)
6358 tree field_decl = grokfield (declarator, declspecs, width);
6359 tree field_type = TREE_TYPE (field_decl);
6360 const char *ivar_name = DECL_NAME (field_decl)
6361 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6366 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6368 error ("illegal reference type specified for instance variable `%s'",
6370 /* Return class as is without adding this ivar. */
6375 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6376 || TYPE_SIZE (field_type) == error_mark_node
6377 /* 'type[0]' is allowed, but 'type[]' is not! */
6379 || (TYPE_SIZE (field_type) == bitsize_zero_node
6380 && !TREE_OPERAND (declarator, 1))
6384 error ("instance variable `%s' has unknown size", ivar_name);
6385 /* Return class as is without adding this ivar. */
6390 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6391 cannot be ivars; ditto for classes with vtables. */
6392 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6393 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6395 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6396 if(TYPE_POLYMORPHIC_P (field_type)) {
6397 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6398 error ("type `%s' has virtual member functions", type_name);
6399 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6400 type_name, ivar_name);
6401 /* Return class as is without adding this ivar. */
6404 /* user-defined constructors and destructors are not known to Obj-C and
6405 hence will not be called. This may or may not be a problem. */
6406 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6407 warning ("type `%s' has a user-defined constructor", type_name);
6408 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6409 warning ("type `%s' has a user-defined destructor", type_name);
6410 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6414 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6418 TREE_PUBLIC (field_decl) = 0;
6419 TREE_PRIVATE (field_decl) = 0;
6420 TREE_PROTECTED (field_decl) = 1;
6424 TREE_PUBLIC (field_decl) = 1;
6425 TREE_PRIVATE (field_decl) = 0;
6426 TREE_PROTECTED (field_decl) = 0;
6430 TREE_PUBLIC (field_decl) = 0;
6431 TREE_PRIVATE (field_decl) = 1;
6432 TREE_PROTECTED (field_decl) = 0;
6437 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6438 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6439 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6444 is_ivar (tree decl_chain, tree ident)
6446 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6447 if (DECL_NAME (decl_chain) == ident)
6452 /* True if the ivar is private and we are not in its implementation. */
6455 is_private (tree decl)
6457 return (TREE_PRIVATE (decl)
6458 && ! is_ivar (CLASS_IVARS (implementation_template),
6462 /* We have an instance variable reference;, check to see if it is public. */
6465 objc_is_public (tree expr, tree identifier)
6467 tree basetype = TREE_TYPE (expr);
6468 enum tree_code code = TREE_CODE (basetype);
6471 if (code == RECORD_TYPE)
6473 if (TREE_STATIC_TEMPLATE (basetype))
6475 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6477 error ("cannot find interface declaration for `%s'",
6478 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6482 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6484 if (TREE_PUBLIC (decl))
6487 /* Important difference between the Stepstone translator:
6488 all instance variables should be public within the context
6489 of the implementation. */
6490 if (objc_implementation_context
6491 && (((TREE_CODE (objc_implementation_context)
6492 == CLASS_IMPLEMENTATION_TYPE)
6493 || (TREE_CODE (objc_implementation_context)
6494 == CATEGORY_IMPLEMENTATION_TYPE))
6495 && (CLASS_NAME (objc_implementation_context)
6496 == OBJC_TYPE_NAME (basetype))))
6498 int private = is_private (decl);
6501 error ("instance variable `%s' is declared private",
6502 IDENTIFIER_POINTER (DECL_NAME (decl)));
6506 /* The 2.95.2 compiler sometimes allowed C functions to access
6507 non-@public ivars. We will let this slide for now... */
6508 if (!objc_method_context)
6510 warning ("instance variable `%s' is %s; "
6511 "this will be a hard error in the future",
6512 IDENTIFIER_POINTER (identifier),
6513 TREE_PRIVATE (decl) ? "@private" : "@protected");
6517 error ("instance variable `%s' is declared %s",
6518 IDENTIFIER_POINTER (identifier),
6519 TREE_PRIVATE (decl) ? "private" : "protected");
6524 else if (objc_implementation_context && (basetype == objc_object_reference))
6526 TREE_TYPE (expr) = uprivate_record;
6527 warning ("static access to object of type `id'");
6534 /* Make sure all entries in CHAIN are also in LIST. */
6537 check_methods (tree chain, tree list, int mtype)
6543 if (!lookup_method (list, chain))
6547 if (TREE_CODE (objc_implementation_context)
6548 == CLASS_IMPLEMENTATION_TYPE)
6549 warning ("incomplete implementation of class `%s'",
6550 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6551 else if (TREE_CODE (objc_implementation_context)
6552 == CATEGORY_IMPLEMENTATION_TYPE)
6553 warning ("incomplete implementation of category `%s'",
6554 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6558 warning ("method definition for `%c%s' not found",
6559 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6562 chain = TREE_CHAIN (chain);
6568 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6571 conforms_to_protocol (tree class, tree protocol)
6573 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6575 tree p = CLASS_PROTOCOL_LIST (class);
6576 while (p && TREE_VALUE (p) != protocol)
6581 tree super = (CLASS_SUPER_NAME (class)
6582 ? lookup_interface (CLASS_SUPER_NAME (class))
6584 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6593 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6594 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6597 check_methods_accessible (tree chain, tree context, int mtype)
6601 tree base_context = context;
6605 context = base_context;
6609 list = CLASS_CLS_METHODS (context);
6611 list = CLASS_NST_METHODS (context);
6613 if (lookup_method (list, chain))
6616 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6617 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6618 context = (CLASS_SUPER_NAME (context)
6619 ? lookup_interface (CLASS_SUPER_NAME (context))
6622 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6623 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6624 context = (CLASS_NAME (context)
6625 ? lookup_interface (CLASS_NAME (context))
6631 if (context == NULL_TREE)
6635 if (TREE_CODE (objc_implementation_context)
6636 == CLASS_IMPLEMENTATION_TYPE)
6637 warning ("incomplete implementation of class `%s'",
6639 (CLASS_NAME (objc_implementation_context)));
6640 else if (TREE_CODE (objc_implementation_context)
6641 == CATEGORY_IMPLEMENTATION_TYPE)
6642 warning ("incomplete implementation of category `%s'",
6644 (CLASS_SUPER_NAME (objc_implementation_context)));
6647 warning ("method definition for `%c%s' not found",
6648 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6651 chain = TREE_CHAIN (chain); /* next method... */
6656 /* Check whether the current interface (accessible via
6657 'objc_implementation_context') actually implements protocol P, along
6658 with any protocols that P inherits. */
6661 check_protocol (tree p, const char *type, const char *name)
6663 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6667 /* Ensure that all protocols have bodies! */
6670 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6671 CLASS_CLS_METHODS (objc_implementation_context),
6673 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6674 CLASS_NST_METHODS (objc_implementation_context),
6679 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6680 objc_implementation_context,
6682 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6683 objc_implementation_context,
6688 warning ("%s `%s' does not fully implement the `%s' protocol",
6689 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6692 /* Check protocols recursively. */
6693 if (PROTOCOL_LIST (p))
6695 tree subs = PROTOCOL_LIST (p);
6697 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6701 tree sub = TREE_VALUE (subs);
6703 /* If the superclass does not conform to the protocols
6704 inherited by P, then we must! */
6705 if (!super_class || !conforms_to_protocol (super_class, sub))
6706 check_protocol (sub, type, name);
6707 subs = TREE_CHAIN (subs);
6712 /* Check whether the current interface (accessible via
6713 'objc_implementation_context') actually implements the protocols listed
6717 check_protocols (tree proto_list, const char *type, const char *name)
6719 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6721 tree p = TREE_VALUE (proto_list);
6723 check_protocol (p, type, name);
6727 /* Make sure that the class CLASS_NAME is defined
6728 CODE says which kind of thing CLASS_NAME ought to be.
6729 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6730 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6733 start_class (enum tree_code code, tree class_name, tree super_name,
6739 if (current_namespace != global_namespace) {
6740 error ("Objective-C declarations may only appear in global scope");
6742 #endif /* OBJCPLUS */
6744 if (objc_implementation_context)
6746 warning ("`@end' missing in implementation context");
6747 finish_class (objc_implementation_context);
6748 objc_ivar_chain = NULL_TREE;
6749 objc_implementation_context = NULL_TREE;
6752 class = make_node (code);
6753 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6755 CLASS_NAME (class) = class_name;
6756 CLASS_SUPER_NAME (class) = super_name;
6757 CLASS_CLS_METHODS (class) = NULL_TREE;
6759 if (! is_class_name (class_name)
6760 && (decl = lookup_name (class_name)))
6762 error ("`%s' redeclared as different kind of symbol",
6763 IDENTIFIER_POINTER (class_name));
6764 error ("%Jprevious declaration of '%D'",
6768 if (code == CLASS_IMPLEMENTATION_TYPE)
6773 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6774 if (TREE_VALUE (chain) == class_name)
6776 error ("reimplementation of class `%s'",
6777 IDENTIFIER_POINTER (class_name));
6778 return error_mark_node;
6780 implemented_classes = tree_cons (NULL_TREE, class_name,
6781 implemented_classes);
6784 /* Reset for multiple classes per file. */
6787 objc_implementation_context = class;
6789 /* Lookup the interface for this implementation. */
6791 if (!(implementation_template = lookup_interface (class_name)))
6793 warning ("cannot find interface declaration for `%s'",
6794 IDENTIFIER_POINTER (class_name));
6795 add_class (implementation_template = objc_implementation_context);
6798 /* If a super class has been specified in the implementation,
6799 insure it conforms to the one specified in the interface. */
6802 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6804 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6805 const char *const name =
6806 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6807 error ("conflicting super class name `%s'",
6808 IDENTIFIER_POINTER (super_name));
6809 error ("previous declaration of `%s'", name);
6812 else if (! super_name)
6814 CLASS_SUPER_NAME (objc_implementation_context)
6815 = CLASS_SUPER_NAME (implementation_template);
6819 else if (code == CLASS_INTERFACE_TYPE)
6821 if (lookup_interface (class_name))
6823 error ("duplicate interface declaration for class `%s'",
6825 warning ("duplicate interface declaration for class `%s'",
6827 IDENTIFIER_POINTER (class_name));
6832 CLASS_PROTOCOL_LIST (class)
6833 = lookup_and_install_protocols (protocol_list);
6836 else if (code == CATEGORY_INTERFACE_TYPE)
6838 tree class_category_is_assoc_with;
6840 /* For a category, class_name is really the name of the class that
6841 the following set of methods will be associated with. We must
6842 find the interface so that can derive the objects template. */
6844 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6846 error ("cannot find interface declaration for `%s'",
6847 IDENTIFIER_POINTER (class_name));
6848 exit (FATAL_EXIT_CODE);
6851 add_category (class_category_is_assoc_with, class);
6854 CLASS_PROTOCOL_LIST (class)
6855 = lookup_and_install_protocols (protocol_list);
6858 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6860 /* Reset for multiple classes per file. */
6863 objc_implementation_context = class;
6865 /* For a category, class_name is really the name of the class that
6866 the following set of methods will be associated with. We must
6867 find the interface so that can derive the objects template. */
6869 if (!(implementation_template = lookup_interface (class_name)))
6871 error ("cannot find interface declaration for `%s'",
6872 IDENTIFIER_POINTER (class_name));
6873 exit (FATAL_EXIT_CODE);
6880 continue_class (tree class)
6882 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6883 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6885 struct imp_entry *imp_entry;
6888 /* Check consistency of the instance variables. */
6890 if (CLASS_IVARS (class))
6891 check_ivars (implementation_template, class);
6893 /* code generation */
6895 ivar_context = build_private_template (implementation_template);
6897 if (!objc_class_template)
6898 build_class_template ();
6900 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6902 imp_entry->next = imp_list;
6903 imp_entry->imp_context = class;
6904 imp_entry->imp_template = implementation_template;
6906 synth_forward_declarations ();
6907 imp_entry->class_decl = UOBJC_CLASS_decl;
6908 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6910 /* Append to front and increment count. */
6911 imp_list = imp_entry;
6912 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6917 return ivar_context;
6920 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6922 if (!CLASS_STATIC_TEMPLATE (class))
6924 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6925 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6926 CLASS_STATIC_TEMPLATE (class) = record;
6928 /* Mark this record as a class template for static typing. */
6929 TREE_STATIC_TEMPLATE (record) = 1;
6936 return error_mark_node;
6939 /* This is called once we see the "@end" in an interface/implementation. */
6942 finish_class (tree class)
6944 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6946 /* All code generation is done in finish_objc. */
6948 if (implementation_template != objc_implementation_context)
6950 /* Ensure that all method listed in the interface contain bodies. */
6951 check_methods (CLASS_CLS_METHODS (implementation_template),
6952 CLASS_CLS_METHODS (objc_implementation_context), '+');
6953 check_methods (CLASS_NST_METHODS (implementation_template),
6954 CLASS_NST_METHODS (objc_implementation_context), '-');
6956 if (CLASS_PROTOCOL_LIST (implementation_template))
6957 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6959 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6963 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6965 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6969 /* Ensure all method listed in the interface contain bodies. */
6970 check_methods (CLASS_CLS_METHODS (category),
6971 CLASS_CLS_METHODS (objc_implementation_context), '+');
6972 check_methods (CLASS_NST_METHODS (category),
6973 CLASS_NST_METHODS (objc_implementation_context), '-');
6975 if (CLASS_PROTOCOL_LIST (category))
6976 check_protocols (CLASS_PROTOCOL_LIST (category),
6978 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6982 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6985 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6986 char *string = (char *) alloca (strlen (class_name) + 3);
6988 /* extern struct objc_object *_<my_name>; */
6990 sprintf (string, "_%s", class_name);
6992 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6993 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6994 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7000 add_protocol (tree protocol)
7002 /* Put protocol on list in reverse order. */
7003 TREE_CHAIN (protocol) = protocol_chain;
7004 protocol_chain = protocol;
7005 return protocol_chain;
7009 lookup_protocol (tree ident)
7013 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7014 if (ident == PROTOCOL_NAME (chain))
7020 /* This function forward declares the protocols named by NAMES. If
7021 they are already declared or defined, the function has no effect. */
7024 objc_declare_protocols (tree names)
7029 if (current_namespace != global_namespace) {
7030 error ("Objective-C declarations may only appear in global scope");
7032 #endif /* OBJCPLUS */
7034 for (list = names; list; list = TREE_CHAIN (list))
7036 tree name = TREE_VALUE (list);
7038 if (lookup_protocol (name) == NULL_TREE)
7040 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7042 TYPE_BINFO (protocol) = make_tree_vec (2);
7043 PROTOCOL_NAME (protocol) = name;
7044 PROTOCOL_LIST (protocol) = NULL_TREE;
7045 add_protocol (protocol);
7046 PROTOCOL_DEFINED (protocol) = 0;
7047 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7053 start_protocol (enum tree_code code, tree name, tree list)
7058 if (current_namespace != global_namespace) {
7059 error ("Objective-C declarations may only appear in global scope");
7061 #endif /* OBJCPLUS */
7063 /* This is as good a place as any. Need to invoke
7064 push_tag_toplevel. */
7065 if (!objc_protocol_template)
7066 objc_protocol_template = build_protocol_template ();
7068 protocol = lookup_protocol (name);
7072 protocol = make_node (code);
7073 TYPE_BINFO (protocol) = make_tree_vec (2);
7075 PROTOCOL_NAME (protocol) = name;
7076 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7077 add_protocol (protocol);
7078 PROTOCOL_DEFINED (protocol) = 1;
7079 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7081 check_protocol_recursively (protocol, list);
7083 else if (! PROTOCOL_DEFINED (protocol))
7085 PROTOCOL_DEFINED (protocol) = 1;
7086 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7088 check_protocol_recursively (protocol, list);
7092 warning ("duplicate declaration for protocol `%s'",
7093 IDENTIFIER_POINTER (name));
7099 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7104 /* "Encode" a data type into a string, which grows in util_obstack.
7105 ??? What is the FORMAT? Someone please document this! */
7108 encode_type_qualifiers (tree declspecs)
7112 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7114 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7115 obstack_1grow (&util_obstack, 'r');
7116 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7117 obstack_1grow (&util_obstack, 'n');
7118 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7119 obstack_1grow (&util_obstack, 'N');
7120 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7121 obstack_1grow (&util_obstack, 'o');
7122 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7123 obstack_1grow (&util_obstack, 'O');
7124 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7125 obstack_1grow (&util_obstack, 'R');
7126 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7127 obstack_1grow (&util_obstack, 'V');
7131 /* Encode a pointer type. */
7134 encode_pointer (tree type, int curtype, int format)
7136 tree pointer_to = TREE_TYPE (type);
7138 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7140 if (OBJC_TYPE_NAME (pointer_to)
7141 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7143 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7145 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7147 obstack_1grow (&util_obstack, '@');
7150 else if (TREE_STATIC_TEMPLATE (pointer_to))
7152 if (generating_instance_variables)
7154 obstack_1grow (&util_obstack, '@');
7155 obstack_1grow (&util_obstack, '"');
7156 obstack_grow (&util_obstack, name, strlen (name));
7157 obstack_1grow (&util_obstack, '"');
7162 obstack_1grow (&util_obstack, '@');
7166 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7168 obstack_1grow (&util_obstack, '#');
7171 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7173 obstack_1grow (&util_obstack, ':');
7178 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7179 && TYPE_MODE (pointer_to) == QImode)
7181 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7182 ? OBJC_TYPE_NAME (pointer_to)
7183 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7185 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7187 obstack_1grow (&util_obstack, '*');
7192 /* We have a type that does not get special treatment. */
7194 /* NeXT extension */
7195 obstack_1grow (&util_obstack, '^');
7196 encode_type (pointer_to, curtype, format);
7200 encode_array (tree type, int curtype, int format)
7202 tree an_int_cst = TYPE_SIZE (type);
7203 tree array_of = TREE_TYPE (type);
7206 /* An incomplete array is treated like a pointer. */
7207 if (an_int_cst == NULL)
7209 encode_pointer (type, curtype, format);
7213 sprintf (buffer, "[%ld",
7214 (long) (TREE_INT_CST_LOW (an_int_cst)
7215 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7217 obstack_grow (&util_obstack, buffer, strlen (buffer));
7218 encode_type (array_of, curtype, format);
7219 obstack_1grow (&util_obstack, ']');
7224 encode_aggregate_within (tree type, int curtype, int format, int left,
7228 /* NB: aggregates that are pointed to have slightly different encoding
7229 rules in that you never encode the names of instance variables. */
7231 = (obstack_object_size (&util_obstack) > 0
7232 && *(obstack_next_free (&util_obstack) - 1) == '^');
7234 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7235 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7237 /* Traverse struct aliases; it is important to get the
7238 original struct and its tag name (if any). */
7239 type = TYPE_MAIN_VARIANT (type);
7240 name = OBJC_TYPE_NAME (type);
7241 /* Open parenth/bracket. */
7242 obstack_1grow (&util_obstack, left);
7244 /* Encode the struct/union tag name, or '?' if a tag was
7245 not provided. Typedef aliases do not qualify. */
7246 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7248 /* Did this struct have a tag? */
7249 && !TYPE_WAS_ANONYMOUS (type)
7252 obstack_grow (&util_obstack,
7253 IDENTIFIER_POINTER (name),
7254 strlen (IDENTIFIER_POINTER (name)));
7256 obstack_1grow (&util_obstack, '?');
7258 /* Encode the types (and possibly names) of the inner fields,
7260 if (inline_contents)
7262 tree fields = TYPE_FIELDS (type);
7264 obstack_1grow (&util_obstack, '=');
7265 for (; fields; fields = TREE_CHAIN (fields))
7268 /* C++ static members, and things that are not fields at all,
7269 should not appear in the encoding. */
7270 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7273 if (generating_instance_variables && !pointed_to)
7275 tree fname = DECL_NAME (fields);
7277 obstack_1grow (&util_obstack, '"');
7278 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7279 obstack_grow (&util_obstack,
7280 IDENTIFIER_POINTER (fname),
7281 strlen (IDENTIFIER_POINTER (fname)));
7282 obstack_1grow (&util_obstack, '"');
7284 encode_field_decl (fields, curtype, format);
7287 /* Close parenth/bracket. */
7288 obstack_1grow (&util_obstack, right);
7292 encode_aggregate (tree type, int curtype, int format)
7294 enum tree_code code = TREE_CODE (type);
7300 encode_aggregate_within (type, curtype, format, '{', '}');
7305 encode_aggregate_within (type, curtype, format, '(', ')');
7310 obstack_1grow (&util_obstack, 'i');
7318 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7322 encode_next_bitfield (int width)
7325 sprintf (buffer, "b%d", width);
7326 obstack_grow (&util_obstack, buffer, strlen (buffer));
7329 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7331 encode_type (tree type, int curtype, int format)
7333 enum tree_code code = TREE_CODE (type);
7336 if (code == INTEGER_TYPE)
7338 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7340 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7341 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7343 if (type == long_unsigned_type_node
7344 || type == long_integer_type_node)
7345 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7347 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7349 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7352 obstack_1grow (&util_obstack, c);
7355 else if (code == REAL_TYPE)
7357 /* Floating point types. */
7358 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7360 case 32: c = 'f'; break;
7362 case 128: c = 'd'; break;
7365 obstack_1grow (&util_obstack, c);
7368 else if (code == VOID_TYPE)
7369 obstack_1grow (&util_obstack, 'v');
7371 else if (code == BOOLEAN_TYPE)
7372 obstack_1grow (&util_obstack, 'B');
7374 else if (code == ARRAY_TYPE)
7375 encode_array (type, curtype, format);
7377 else if (code == POINTER_TYPE)
7378 encode_pointer (type, curtype, format);
7380 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7381 encode_aggregate (type, curtype, format);
7383 else if (code == FUNCTION_TYPE) /* '?' */
7384 obstack_1grow (&util_obstack, '?');
7388 encode_gnu_bitfield (int position, tree type, int size)
7390 enum tree_code code = TREE_CODE (type);
7392 char charType = '?';
7394 if (code == INTEGER_TYPE)
7396 if (integer_zerop (TYPE_MIN_VALUE (type)))
7398 /* Unsigned integer types. */
7400 if (TYPE_MODE (type) == QImode)
7402 else if (TYPE_MODE (type) == HImode)
7404 else if (TYPE_MODE (type) == SImode)
7406 if (type == long_unsigned_type_node)
7411 else if (TYPE_MODE (type) == DImode)
7416 /* Signed integer types. */
7418 if (TYPE_MODE (type) == QImode)
7420 else if (TYPE_MODE (type) == HImode)
7422 else if (TYPE_MODE (type) == SImode)
7424 if (type == long_integer_type_node)
7430 else if (TYPE_MODE (type) == DImode)
7434 else if (code == ENUMERAL_TYPE)
7439 sprintf (buffer, "b%d%c%d", position, charType, size);
7440 obstack_grow (&util_obstack, buffer, strlen (buffer));
7444 encode_field_decl (tree field_decl, int curtype, int format)
7449 /* C++ static members, and things that are not fields at all,
7450 should not appear in the encoding. */
7451 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7455 type = TREE_TYPE (field_decl);
7457 /* Generate the bitfield typing information, if needed. Note the difference
7458 between GNU and NeXT runtimes. */
7459 if (DECL_BIT_FIELD_TYPE (field_decl))
7461 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7463 if (flag_next_runtime)
7464 encode_next_bitfield (size);
7466 encode_gnu_bitfield (int_bit_position (field_decl),
7467 DECL_BIT_FIELD_TYPE (field_decl), size);
7470 encode_type (TREE_TYPE (field_decl), curtype, format);
7474 objc_expr_last (tree complex_expr)
7479 while ((next = TREE_OPERAND (complex_expr, 0)))
7480 complex_expr = next;
7482 return complex_expr;
7486 synth_self_and_ucmd_args (void)
7490 if (objc_method_context
7491 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7492 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7494 /* Really a `struct objc_class *'. However, we allow people to
7495 assign to self, which changes its type midstream. */
7496 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7498 push_parm_decl (build_tree_list
7499 (build_tree_list (decl_specs,
7500 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7503 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (selector_type));
7504 push_parm_decl (build_tree_list
7505 (build_tree_list (decl_specs,
7506 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7510 /* Transform a method definition into a function definition as follows:
7511 - synthesize the first two arguments, "self" and "_cmd". */
7514 start_method_def (tree method)
7516 /* Required to implement _msgSuper. */
7517 objc_method_context = method;
7518 UOBJC_SUPER_decl = NULL_TREE;
7520 /* Must be called BEFORE start_function. */
7522 declare_parm_level ();
7524 /* Generate prototype declarations for arguments..."new-style". */
7525 synth_self_and_ucmd_args ();
7527 /* Generate argument declarations if a keyword_decl. */
7528 if (METHOD_SEL_ARGS (method))
7530 tree arglist = METHOD_SEL_ARGS (method);
7533 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7534 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7538 tree last_expr = objc_expr_last (arg_decl);
7540 /* Unite the abstract decl with its name. */
7541 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7542 push_parm_decl (build_tree_list
7543 (build_tree_list (arg_spec, arg_decl),
7547 /* Unhook: restore the abstract declarator. */
7548 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7553 push_parm_decl (build_tree_list
7554 (build_tree_list (arg_spec,
7555 KEYWORD_ARG_NAME (arglist)),
7558 arglist = TREE_CHAIN (arglist);
7563 if (METHOD_ADD_ARGS (method) != NULL_TREE
7564 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7566 /* We have a variable length selector - in "prototype" format. */
7567 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7570 /* This must be done prior to calling pushdecl. pushdecl is
7571 going to change our chain on us. */
7572 tree nextkey = TREE_CHAIN (akey);
7580 warn_with_method (const char *message, int mtype, tree method)
7582 /* Add a readable method name to the warning. */
7583 warning ("%J%s `%c%s'", method,
7584 message, mtype, gen_method_decl (method, errbuf));
7587 /* Return 1 if METHOD is consistent with PROTO. */
7590 comp_method_with_proto (tree method, tree proto)
7592 /* Create a function template node at most once. */
7593 if (!function1_template)
7594 function1_template = make_node (FUNCTION_TYPE);
7596 /* Install argument types - normally set by build_function_type. */
7597 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7599 /* install return type */
7600 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7602 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7605 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7608 objc_types_are_equivalent (tree type1, tree type2)
7612 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7614 type1 = TYPE_PROTOCOL_LIST (type1);
7615 type2 = TYPE_PROTOCOL_LIST (type2);
7616 if (list_length (type1) == list_length (type2))
7618 for (; type2; type2 = TREE_CHAIN (type2))
7619 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7626 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7629 comp_proto_with_proto (tree proto1, tree proto2)
7633 /* The following test is needed in case there are hashing
7635 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7638 /* Compare return types. */
7639 type1 = groktypename (TREE_TYPE (proto1));
7640 type2 = groktypename (TREE_TYPE (proto2));
7642 if (!objc_types_are_equivalent (type1, type2))
7645 /* Compare argument types. */
7646 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7647 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7649 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7651 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7655 return (!type1 && !type2);
7658 /* - Generate an identifier for the function. the format is "_n_cls",
7659 where 1 <= n <= nMethods, and cls is the name the implementation we
7661 - Install the return type from the method declaration.
7662 - If we have a prototype, check for type consistency. */
7665 really_start_method (tree method, tree parmlist)
7667 tree sc_spec, ret_spec, ret_decl, decl_specs;
7668 tree method_decl, method_id;
7669 const char *sel_name, *class_name, *cat_name;
7672 /* Synth the storage class & assemble the return type. */
7673 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7674 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7675 decl_specs = chainon (sc_spec, ret_spec);
7677 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7678 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7679 cat_name = ((TREE_CODE (objc_implementation_context)
7680 == CLASS_IMPLEMENTATION_TYPE)
7682 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7685 /* Make sure this is big enough for any plausible method label. */
7686 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7687 + (cat_name ? strlen (cat_name) : 0));
7689 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7690 class_name, cat_name, sel_name, method_slot);
7692 method_id = get_identifier (buf);
7695 /* Objective-C methods cannot be overloaded, so we don't need
7696 the type encoding appended. It looks bad anyway... */
7697 push_lang_context (lang_name_c);
7700 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7702 /* Check the declarator portion of the return type for the method. */
7703 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7705 /* Unite the complex decl (specified in the abstract decl) with the
7706 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7707 tree save_expr = objc_expr_last (ret_decl);
7709 TREE_OPERAND (save_expr, 0) = method_decl;
7710 method_decl = ret_decl;
7712 /* Fool the parser into thinking it is starting a function. */
7713 start_function (decl_specs, method_decl, NULL_TREE);
7715 /* Unhook: this has the effect of restoring the abstract declarator. */
7716 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7721 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7723 /* Fool the parser into thinking it is starting a function. */
7724 start_function (decl_specs, method_decl, NULL_TREE);
7726 /* Unhook: this has the effect of restoring the abstract declarator. */
7727 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7731 /* set self_decl from the first argument...this global is used by
7732 * build_ivar_reference().build_indirect_ref().
7734 self_decl = DECL_ARGUMENTS (current_function_decl);
7736 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7737 * the following: warning:unused parameter `struct objc_selector * _cmd'
7739 TREE_USED (self_decl) = 1;
7740 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7741 /* Ditto for the underlying (static) C function. */
7742 TREE_USED (current_function_decl) = 1;
7743 pop_lang_context ();
7746 METHOD_DEFINITION (method) = current_function_decl;
7748 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7750 if (implementation_template != objc_implementation_context)
7753 = lookup_method_static (implementation_template,
7754 METHOD_SEL_NAME (method),
7755 TREE_CODE (method) == CLASS_METHOD_DECL);
7759 if (!comp_method_with_proto (method, proto))
7761 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7763 warn_with_method ("conflicting types for", type, method);
7764 warn_with_method ("previous declaration of", type, proto);
7769 /* We have a method @implementation even though we did not
7770 see a corresponding @interface declaration (which is allowed
7771 by Objective-C rules). Go ahead and place the method in
7772 the @interface anyway, so that message dispatch lookups
7774 tree interface = implementation_template;
7776 if (TREE_CODE (objc_implementation_context)
7777 == CATEGORY_IMPLEMENTATION_TYPE)
7778 interface = lookup_category
7780 CLASS_SUPER_NAME (objc_implementation_context));
7783 objc_add_method (interface, copy_node (method),
7784 TREE_CODE (method) == CLASS_METHOD_DECL);
7789 /* The following routine is always called...this "architecture" is to
7790 accommodate "old-style" variable length selectors.
7792 - a:a b:b // prototype ; id c; id d; // old-style. */
7795 continue_method_def (void)
7799 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7800 /* We have a `, ...' immediately following the selector. */
7801 parmlist = get_parm_info (/*ellipsis=*/true);
7803 parmlist = get_parm_info (/*ellipsis=*/false);
7806 /* Set self_decl from the first argument...this global is used by
7807 build_ivar_reference calling build_indirect_ref. */
7808 self_decl = TREE_PURPOSE (parmlist);
7809 #endif /* !OBJCPLUS */
7812 really_start_method (objc_method_context, parmlist);
7813 store_parm_decls ();
7816 static void *UOBJC_SUPER_scope = 0;
7818 /* _n_Method (id self, SEL sel, ...)
7820 struct objc_super _S;
7821 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7825 get_super_receiver (void)
7827 if (objc_method_context)
7829 tree super_expr, super_expr_list;
7831 if (!UOBJC_SUPER_decl)
7833 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7834 build_tree_list (NULL_TREE,
7835 objc_super_template),
7838 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7840 /* This prevents `unused variable' warnings when compiling with -Wall. */
7841 TREE_USED (UOBJC_SUPER_decl) = 1;
7842 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7844 UOBJC_SUPER_scope = get_current_scope ();
7847 /* Set receiver to self. */
7848 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7849 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7850 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7852 /* Set class to begin searching. */
7854 super_expr = build_component_ref (UOBJC_SUPER_decl,
7855 get_identifier ("super_class"));
7857 super_expr = build_component_ref (UOBJC_SUPER_decl,
7858 get_identifier ("class"));
7861 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7863 /* [_cls, __cls]Super are "pre-built" in
7864 synth_forward_declarations. */
7866 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7867 ((TREE_CODE (objc_method_context)
7868 == INSTANCE_METHOD_DECL)
7870 : uucls_super_ref));
7874 /* We have a category. */
7876 tree super_name = CLASS_SUPER_NAME (implementation_template);
7879 /* Barf if super used in a category of Object. */
7882 error ("no super class declared in interface for `%s'",
7883 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7884 return error_mark_node;
7887 if (flag_next_runtime && !flag_zero_link)
7889 super_class = get_class_reference (super_name);
7890 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7891 /* If we are in a class method, we must retrieve the
7892 _metaclass_ for the current class, pointed at by
7893 the class's "isa" pointer. The following assumes that
7894 "isa" is the first ivar in a class (which it must be). */
7896 = build_indirect_ref
7897 (build_c_cast (build_pointer_type (objc_class_type),
7898 super_class), "unary *");
7902 add_class_reference (super_name);
7903 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7904 ? objc_get_class_decl : objc_get_meta_class_decl);
7905 assemble_external (super_class);
7907 = build_function_call
7911 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7912 IDENTIFIER_POINTER (super_name))));
7916 = build_modify_expr (super_expr, NOP_EXPR,
7917 build_c_cast (TREE_TYPE (super_expr),
7921 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7923 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7924 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7926 return build_compound_expr (super_expr_list);
7930 error ("[super ...] must appear in a method context");
7931 return error_mark_node;
7935 /* When exiting a scope, sever links to a 'super' declaration (if any)
7936 therein contained. */
7939 objc_clear_super_receiver (void)
7941 if (objc_method_context
7942 && UOBJC_SUPER_scope == get_current_scope ()) {
7943 UOBJC_SUPER_decl = 0;
7944 UOBJC_SUPER_scope = 0;
7949 objc_expand_function_end (void)
7951 /* This routine may also get called for C functions, including those
7952 nested within ObjC methods. In such cases, method encoding is
7954 if (objc_method_context == NULL_TREE
7955 || DECL_INITIAL (objc_method_context) != current_function_decl)
7958 METHOD_ENCODING (objc_method_context)
7959 = encode_method_prototype (objc_method_context);
7963 finish_method_def (void)
7965 lang_expand_function_end = objc_expand_function_end;
7966 /* We cannot validly inline ObjC methods, at least not without a language
7967 extension to declare that a method need not be dynamically
7968 dispatched, so suppress all thoughts of doing so. */
7969 DECL_INLINE (current_function_decl) = 0;
7970 DECL_UNINLINABLE (current_function_decl) = 1;
7973 lang_expand_function_end = NULL;
7975 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7976 since the optimizer may find "may be used before set" errors. */
7977 objc_method_context = NULL_TREE;
7982 lang_report_error_function (tree decl)
7984 if (objc_method_context)
7986 fprintf (stderr, "In method `%s'\n",
7987 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7997 is_complex_decl (tree type)
7999 return (TREE_CODE (type) == ARRAY_TYPE
8000 || TREE_CODE (type) == FUNCTION_TYPE
8001 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8005 /* Code to convert a decl node into text for a declaration in C. */
8007 static char tmpbuf[256];
8010 adorn_decl (tree decl, char *str)
8012 enum tree_code code = TREE_CODE (decl);
8014 if (code == ARRAY_REF)
8016 tree an_int_cst = TREE_OPERAND (decl, 1);
8018 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8019 sprintf (str + strlen (str), "[%ld]",
8020 (long) TREE_INT_CST_LOW (an_int_cst));
8025 else if (code == ARRAY_TYPE)
8027 tree an_int_cst = TYPE_SIZE (decl);
8028 tree array_of = TREE_TYPE (decl);
8030 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8031 sprintf (str + strlen (str), "[%ld]",
8032 (long) (TREE_INT_CST_LOW (an_int_cst)
8033 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8038 else if (code == CALL_EXPR)
8040 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8045 gen_declaration_1 (chain, str);
8046 chain = TREE_CHAIN (chain);
8053 else if (code == FUNCTION_TYPE)
8055 tree chain = TYPE_ARG_TYPES (decl);
8058 while (chain && TREE_VALUE (chain) != void_type_node)
8060 gen_declaration_1 (TREE_VALUE (chain), str);
8061 chain = TREE_CHAIN (chain);
8062 if (chain && TREE_VALUE (chain) != void_type_node)
8068 else if (code == INDIRECT_REF)
8070 strcpy (tmpbuf, "*");
8071 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8075 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8077 chain = TREE_CHAIN (chain))
8079 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8081 strcat (tmpbuf, " ");
8082 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8086 strcat (tmpbuf, " ");
8088 strcat (tmpbuf, str);
8089 strcpy (str, tmpbuf);
8092 else if (code == POINTER_TYPE)
8094 strcpy (tmpbuf, "*");
8095 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8097 if (TYPE_READONLY (decl))
8098 strcat (tmpbuf, " const");
8099 if (TYPE_VOLATILE (decl))
8100 strcat (tmpbuf, " volatile");
8102 strcat (tmpbuf, " ");
8104 strcat (tmpbuf, str);
8105 strcpy (str, tmpbuf);
8110 gen_declarator (tree decl, char *buf, const char *name)
8114 enum tree_code code = TREE_CODE (decl);
8124 op = TREE_OPERAND (decl, 0);
8126 /* We have a pointer to a function or array...(*)(), (*)[] */
8127 if ((code == ARRAY_REF || code == CALL_EXPR)
8128 && op && TREE_CODE (op) == INDIRECT_REF)
8131 str = gen_declarator (op, buf, name);
8135 strcpy (tmpbuf, "(");
8136 strcat (tmpbuf, str);
8137 strcat (tmpbuf, ")");
8138 strcpy (str, tmpbuf);
8141 adorn_decl (decl, str);
8150 /* This clause is done iteratively rather than recursively. */
8153 op = (is_complex_decl (TREE_TYPE (decl))
8154 ? TREE_TYPE (decl) : NULL_TREE);
8156 adorn_decl (decl, str);
8158 /* We have a pointer to a function or array...(*)(), (*)[] */
8159 if (code == POINTER_TYPE
8160 && op && (TREE_CODE (op) == FUNCTION_TYPE
8161 || TREE_CODE (op) == ARRAY_TYPE))
8163 strcpy (tmpbuf, "(");
8164 strcat (tmpbuf, str);
8165 strcat (tmpbuf, ")");
8166 strcpy (str, tmpbuf);
8169 decl = (is_complex_decl (TREE_TYPE (decl))
8170 ? TREE_TYPE (decl) : NULL_TREE);
8173 while (decl && (code = TREE_CODE (decl)))
8178 case IDENTIFIER_NODE:
8179 /* Will only happen if we are processing a "raw" expr-decl. */
8180 strcpy (buf, IDENTIFIER_POINTER (decl));
8191 /* We have an abstract declarator or a _DECL node. */
8199 gen_declspecs (tree declspecs, char *buf, int raw)
8205 for (chain = nreverse (copy_list (declspecs));
8206 chain; chain = TREE_CHAIN (chain))
8208 tree aspec = TREE_VALUE (chain);
8210 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8211 strcat (buf, IDENTIFIER_POINTER (aspec));
8212 else if (TREE_CODE (aspec) == RECORD_TYPE)
8214 if (OBJC_TYPE_NAME (aspec))
8216 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8218 if (! TREE_STATIC_TEMPLATE (aspec))
8219 strcat (buf, "struct ");
8220 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8225 tree chain = protocol_list;
8232 (PROTOCOL_NAME (TREE_VALUE (chain))));
8233 chain = TREE_CHAIN (chain);
8242 strcat (buf, "untagged struct");
8245 else if (TREE_CODE (aspec) == UNION_TYPE)
8247 if (OBJC_TYPE_NAME (aspec))
8249 if (! TREE_STATIC_TEMPLATE (aspec))
8250 strcat (buf, "union ");
8251 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8254 strcat (buf, "untagged union");
8257 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8259 if (OBJC_TYPE_NAME (aspec))
8261 if (! TREE_STATIC_TEMPLATE (aspec))
8262 strcat (buf, "enum ");
8263 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8266 strcat (buf, "untagged enum");
8269 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8270 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8272 else if (IS_ID (aspec))
8274 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8279 tree chain = protocol_list;
8286 (PROTOCOL_NAME (TREE_VALUE (chain))));
8287 chain = TREE_CHAIN (chain);
8294 if (TREE_CHAIN (chain))
8300 /* Type qualifiers. */
8301 if (TYPE_READONLY (declspecs))
8302 strcat (buf, "const ");
8303 if (TYPE_VOLATILE (declspecs))
8304 strcat (buf, "volatile ");
8306 switch (TREE_CODE (declspecs))
8308 /* Type specifiers. */
8311 declspecs = TYPE_MAIN_VARIANT (declspecs);
8313 /* Signed integer types. */
8315 if (declspecs == short_integer_type_node)
8316 strcat (buf, "short int ");
8317 else if (declspecs == integer_type_node)
8318 strcat (buf, "int ");
8319 else if (declspecs == long_integer_type_node)
8320 strcat (buf, "long int ");
8321 else if (declspecs == long_long_integer_type_node)
8322 strcat (buf, "long long int ");
8323 else if (declspecs == signed_char_type_node
8324 || declspecs == char_type_node)
8325 strcat (buf, "char ");
8327 /* Unsigned integer types. */
8329 else if (declspecs == short_unsigned_type_node)
8330 strcat (buf, "unsigned short ");
8331 else if (declspecs == unsigned_type_node)
8332 strcat (buf, "unsigned int ");
8333 else if (declspecs == long_unsigned_type_node)
8334 strcat (buf, "unsigned long ");
8335 else if (declspecs == long_long_unsigned_type_node)
8336 strcat (buf, "unsigned long long ");
8337 else if (declspecs == unsigned_char_type_node)
8338 strcat (buf, "unsigned char ");
8342 declspecs = TYPE_MAIN_VARIANT (declspecs);
8344 if (declspecs == float_type_node)
8345 strcat (buf, "float ");
8346 else if (declspecs == double_type_node)
8347 strcat (buf, "double ");
8348 else if (declspecs == long_double_type_node)
8349 strcat (buf, "long double ");
8353 if (OBJC_TYPE_NAME (declspecs)
8354 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8356 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8358 if (! TREE_STATIC_TEMPLATE (declspecs))
8359 strcat (buf, "struct ");
8360 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8364 tree chain = protocol_list;
8371 (PROTOCOL_NAME (TREE_VALUE (chain))));
8372 chain = TREE_CHAIN (chain);
8381 strcat (buf, "untagged struct");
8387 if (OBJC_TYPE_NAME (declspecs)
8388 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8390 strcat (buf, "union ");
8391 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8396 strcat (buf, "untagged union ");
8400 if (OBJC_TYPE_NAME (declspecs)
8401 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8403 strcat (buf, "enum ");
8404 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8409 strcat (buf, "untagged enum ");
8413 strcat (buf, "void ");
8418 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8423 tree chain = protocol_list;
8430 (PROTOCOL_NAME (TREE_VALUE (chain))));
8431 chain = TREE_CHAIN (chain);
8447 /* Given a tree node, produce a printable description of it in the given
8448 buffer, overwriting the buffer. */
8451 gen_declaration (tree atype_or_adecl, char *buf)
8454 gen_declaration_1 (atype_or_adecl, buf);
8458 /* Given a tree node, append a printable description to the end of the
8462 gen_declaration_1 (tree atype_or_adecl, char *buf)
8466 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8468 tree declspecs; /* "identifier_node", "record_type" */
8469 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8470 tree width = NULL_TREE; /* for bitfields */
8472 /* We have a "raw", abstract declarator (typename). */
8473 declarator = TREE_VALUE (atype_or_adecl);
8474 /* In the case of raw ivars, the declarator itself is a list,
8475 and contains bitfield widths. */
8476 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8478 width = TREE_VALUE (declarator);
8479 declarator = TREE_PURPOSE (declarator);
8481 declspecs = TREE_PURPOSE (atype_or_adecl);
8483 gen_declspecs (declspecs, buf, 1);
8487 strcat (buf, gen_declarator (declarator, declbuf, ""));
8490 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8491 TREE_INT_CST_LOW (width));
8497 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8498 tree declarator; /* "array_type", "function_type", "pointer_type". */
8500 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8501 || TREE_CODE (atype_or_adecl) == PARM_DECL
8502 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8503 atype = TREE_TYPE (atype_or_adecl);
8505 /* Assume we have a *_type node. */
8506 atype = atype_or_adecl;
8508 if (is_complex_decl (atype))
8512 /* Get the declaration specifier; it is at the end of the list. */
8513 declarator = chain = atype;
8515 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8516 while (is_complex_decl (chain));
8523 declarator = NULL_TREE;
8526 gen_declspecs (declspecs, buf, 0);
8528 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8529 || TREE_CODE (atype_or_adecl) == PARM_DECL
8530 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8532 const char *const decl_name =
8533 (DECL_NAME (atype_or_adecl)
8534 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8539 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8542 else if (decl_name[0])
8545 strcat (buf, decl_name);
8548 else if (declarator)
8551 strcat (buf, gen_declarator (declarator, declbuf, ""));
8556 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8558 /* Given a method tree, put a printable description into the given
8559 buffer (overwriting) and return a pointer to the buffer. */
8562 gen_method_decl (tree method, char *buf)
8567 if (RAW_TYPESPEC (method) != objc_object_reference)
8570 gen_declaration_1 (TREE_TYPE (method), buf);
8574 chain = METHOD_SEL_ARGS (method);
8577 /* We have a chain of keyword_decls. */
8580 if (KEYWORD_KEY_NAME (chain))
8581 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8584 if (RAW_TYPESPEC (chain) != objc_object_reference)
8587 gen_declaration_1 (TREE_TYPE (chain), buf);
8591 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8592 if ((chain = TREE_CHAIN (chain)))
8597 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8598 strcat (buf, ", ...");
8599 else if (METHOD_ADD_ARGS (method))
8601 /* We have a tree list node as generate by get_parm_info. */
8602 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8604 /* Know we have a chain of parm_decls. */
8608 gen_declaration_1 (chain, buf);
8609 chain = TREE_CHAIN (chain);
8615 /* We have a unary selector. */
8616 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8624 /* Dump an @interface declaration of the supplied class CHAIN to the
8625 supplied file FP. Used to implement the -gen-decls option (which
8626 prints out an @interface declaration of all classes compiled in
8627 this run); potentially useful for debugging the compiler too. */
8629 dump_interface (FILE *fp, tree chain)
8631 /* FIXME: A heap overflow here whenever a method (or ivar)
8632 declaration is so long that it doesn't fit in the buffer. The
8633 code and all the related functions should be rewritten to avoid
8634 using fixed size buffers. */
8635 char *buf = (char *) xmalloc (1024 * 10);
8636 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8637 tree ivar_decls = CLASS_RAW_IVARS (chain);
8638 tree nst_methods = CLASS_NST_METHODS (chain);
8639 tree cls_methods = CLASS_CLS_METHODS (chain);
8641 fprintf (fp, "\n@interface %s", my_name);
8643 /* CLASS_SUPER_NAME is used to store the superclass name for
8644 classes, and the category name for categories. */
8645 if (CLASS_SUPER_NAME (chain))
8647 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8649 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8650 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8652 fprintf (fp, " (%s)\n", name);
8656 fprintf (fp, " : %s\n", name);
8662 /* FIXME - the following doesn't seem to work at the moment. */
8665 fprintf (fp, "{\n");
8668 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8669 ivar_decls = TREE_CHAIN (ivar_decls);
8672 fprintf (fp, "}\n");
8677 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8678 nst_methods = TREE_CHAIN (nst_methods);
8683 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8684 cls_methods = TREE_CHAIN (cls_methods);
8687 fprintf (fp, "@end\n");
8690 /* Demangle function for Objective-C */
8692 objc_demangle (const char *mangled)
8694 char *demangled, *cp;
8696 if (mangled[0] == '_' &&
8697 (mangled[1] == 'i' || mangled[1] == 'c') &&
8700 cp = demangled = xmalloc(strlen(mangled) + 2);
8701 if (mangled[1] == 'i')
8702 *cp++ = '-'; /* for instance method */
8704 *cp++ = '+'; /* for class method */
8705 *cp++ = '['; /* opening left brace */
8706 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8707 while (*cp && *cp == '_')
8708 cp++; /* skip any initial underbars in class name */
8709 cp = strchr(cp, '_'); /* find first non-initial underbar */
8712 free(demangled); /* not mangled name */
8715 if (cp[1] == '_') /* easy case: no category name */
8717 *cp++ = ' '; /* replace two '_' with one ' ' */
8718 strcpy(cp, mangled + (cp - demangled) + 2);
8722 *cp++ = '('; /* less easy case: category name */
8723 cp = strchr(cp, '_');
8726 free(demangled); /* not mangled name */
8730 *cp++ = ' '; /* overwriting 1st char of method name... */
8731 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8733 while (*cp && *cp == '_')
8734 cp++; /* skip any initial underbars in method name */
8737 *cp = ':'; /* replace remaining '_' with ':' */
8738 *cp++ = ']'; /* closing right brace */
8739 *cp++ = 0; /* string terminator */
8743 return mangled; /* not an objc mangled name */
8747 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8749 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8755 gcc_obstack_init (&util_obstack);
8756 util_firstobj = (char *) obstack_finish (&util_obstack);
8758 errbuf = (char *) xmalloc (BUFSIZE);
8760 synth_module_prologue ();
8766 struct imp_entry *impent;
8768 /* The internally generated initializers appear to have missing braces.
8769 Don't warn about this. */
8770 int save_warn_missing_braces = warn_missing_braces;
8771 warn_missing_braces = 0;
8773 /* A missing @end may not be detected by the parser. */
8774 if (objc_implementation_context)
8776 warning ("`@end' missing in implementation context");
8777 finish_class (objc_implementation_context);
8778 objc_ivar_chain = NULL_TREE;
8779 objc_implementation_context = NULL_TREE;
8782 /* Process the static instances here because initialization of objc_symtab
8784 if (objc_static_instances)
8785 generate_static_references ();
8787 if (imp_list || class_names_chain
8788 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8789 generate_objc_symtab_decl ();
8791 for (impent = imp_list; impent; impent = impent->next)
8793 objc_implementation_context = impent->imp_context;
8794 implementation_template = impent->imp_template;
8796 UOBJC_CLASS_decl = impent->class_decl;
8797 UOBJC_METACLASS_decl = impent->meta_decl;
8799 /* Dump the @interface of each class as we compile it, if the
8800 -gen-decls option is in use. TODO: Dump the classes in the
8801 order they were found, rather than in reverse order as we
8803 if (flag_gen_declaration)
8805 dump_interface (gen_declaration_file, objc_implementation_context);
8808 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8810 /* all of the following reference the string pool... */
8811 generate_ivar_lists ();
8812 generate_dispatch_tables ();
8813 generate_shared_structures ();
8817 generate_dispatch_tables ();
8818 generate_category (objc_implementation_context);
8822 /* If we are using an array of selectors, we must always
8823 finish up the array decl even if no selectors were used. */
8824 if (! flag_next_runtime || sel_ref_chain)
8825 build_selector_translation_table ();
8828 generate_protocols ();
8830 if (flag_replace_objc_classes && imp_list)
8831 generate_objc_image_info ();
8833 if (objc_implementation_context || class_names_chain || objc_static_instances
8834 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8836 /* Arrange for ObjC data structures to be initialized at run time. */
8837 rtx init_sym = build_module_descriptor ();
8838 if (init_sym && targetm.have_ctors_dtors)
8839 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8842 /* Dump the class references. This forces the appropriate classes
8843 to be linked into the executable image, preserving unix archive
8844 semantics. This can be removed when we move to a more dynamically
8845 linked environment. */
8847 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8849 handle_class_ref (chain);
8850 if (TREE_PURPOSE (chain))
8851 generate_classref_translation_entry (chain);
8854 for (impent = imp_list; impent; impent = impent->next)
8855 handle_impent (impent);
8857 /* Dump the string table last. */
8859 generate_strings ();
8866 /* Run through the selector hash tables and print a warning for any
8867 selector which has multiple methods. */
8869 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8871 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8872 check_duplicates (hsh, 0, 1);
8873 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8874 check_duplicates (hsh, 0, 1);
8878 warn_missing_braces = save_warn_missing_braces;
8881 /* Subroutines of finish_objc. */
8884 generate_classref_translation_entry (tree chain)
8886 tree expr, name, decl_specs, decl, sc_spec;
8889 type = TREE_TYPE (TREE_PURPOSE (chain));
8891 expr = add_objc_string (TREE_VALUE (chain), class_names);
8892 expr = build_c_cast (type, expr); /* cast! */
8894 name = DECL_NAME (TREE_PURPOSE (chain));
8896 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8898 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8899 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8901 /* The decl that is returned from start_decl is the one that we
8902 forward declared in build_class_reference. */
8903 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8904 DECL_CONTEXT (decl) = NULL_TREE;
8905 finish_decl (decl, expr, NULL_TREE);
8910 handle_class_ref (tree chain)
8912 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8913 char *string = (char *) alloca (strlen (name) + 30);
8917 sprintf (string, "%sobjc_class_name_%s",
8918 (flag_next_runtime ? "." : "__"), name);
8920 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8921 if (flag_next_runtime)
8923 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8928 /* Make a decl for this name, so we can use its address in a tree. */
8929 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8930 DECL_EXTERNAL (decl) = 1;
8931 TREE_PUBLIC (decl) = 1;
8934 rest_of_decl_compilation (decl, 0, 0, 0);
8936 /* Make a decl for the address. */
8937 sprintf (string, "%sobjc_class_ref_%s",
8938 (flag_next_runtime ? "." : "__"), name);
8939 exp = build1 (ADDR_EXPR, string_type_node, decl);
8940 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8941 DECL_INITIAL (decl) = exp;
8942 TREE_STATIC (decl) = 1;
8943 TREE_USED (decl) = 1;
8946 rest_of_decl_compilation (decl, 0, 0, 0);
8950 handle_impent (struct imp_entry *impent)
8954 objc_implementation_context = impent->imp_context;
8955 implementation_template = impent->imp_template;
8957 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8959 const char *const class_name =
8960 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8962 string = (char *) alloca (strlen (class_name) + 30);
8964 sprintf (string, "%sobjc_class_name_%s",
8965 (flag_next_runtime ? "." : "__"), class_name);
8967 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8969 const char *const class_name =
8970 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8971 const char *const class_super_name =
8972 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8974 string = (char *) alloca (strlen (class_name)
8975 + strlen (class_super_name) + 30);
8977 /* Do the same for categories. Even though no references to
8978 these symbols are generated automatically by the compiler, it
8979 gives you a handle to pull them into an archive by hand. */
8980 sprintf (string, "*%sobjc_category_name_%s_%s",
8981 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8986 #ifdef ASM_DECLARE_CLASS_REFERENCE
8987 if (flag_next_runtime)
8989 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8997 init = build_int_2 (0, 0);
8998 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8999 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9000 TREE_PUBLIC (decl) = 1;
9001 TREE_READONLY (decl) = 1;
9002 TREE_USED (decl) = 1;
9003 TREE_CONSTANT (decl) = 1;
9004 DECL_CONTEXT (decl) = 0;
9005 DECL_ARTIFICIAL (decl) = 1;
9006 DECL_INITIAL (decl) = init;
9007 assemble_variable (decl, 1, 0, 0);
9011 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9012 later requires that ObjC translation units participating in F&C be
9013 specially marked. The following routine accomplishes this. */
9015 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9018 generate_objc_image_info (void)
9020 tree sc_spec, decl, initlist;
9022 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9024 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9025 tree_cons (NULL_TREE,
9028 build_index_type (build_int_2 (1, 0))),
9033 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9034 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9035 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9037 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9038 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9039 finish_decl (decl, initlist, NULL_TREE);
9042 /* Look up ID as an instance variable. */
9045 lookup_objc_ivar (tree id)
9049 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9050 /* We have a message to super. */
9051 return get_super_receiver ();
9052 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9054 if (is_private (decl))
9057 return build_ivar_reference (id);
9063 #include "gt-objc-objc-act.h"
9064 #include "gtype-objc.h"