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 ();
519 objc_finish_file (void)
521 mark_referenced_methods ();
523 /* Finalize Objective-C runtime data. No need to generate tables
524 and code if only checking syntax. */
525 if (!flag_syntax_only)
528 if (gen_declaration_file)
529 fclose (gen_declaration_file);
533 define_decl (tree declarator, tree declspecs)
535 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
536 finish_decl (decl, NULL_TREE, NULL_TREE);
540 /* Return the first occurrence of a method declaration corresponding
541 to sel_name in rproto_list. Search rproto_list recursively.
542 If is_class is 0, search for instance methods, otherwise for class
545 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
551 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
553 p = TREE_VALUE (rproto);
555 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
557 if ((fnd = lookup_method (is_class
558 ? PROTOCOL_CLS_METHODS (p)
559 : PROTOCOL_NST_METHODS (p), sel_name)))
561 else if (PROTOCOL_LIST (p))
562 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
567 ; /* An identifier...if we could not find a protocol. */
578 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
582 /* Make sure the protocol is supported by the object on the rhs. */
583 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
586 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
588 p = TREE_VALUE (rproto);
590 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
595 else if (PROTOCOL_LIST (p))
596 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
605 ; /* An identifier...if we could not find a protocol. */
611 /* Return true if TYPE is 'id'. */
614 objc_is_object_id (tree type)
616 return OBJC_TYPE_NAME (type) == objc_object_id;
620 objc_is_class_id (tree type)
622 return OBJC_TYPE_NAME (type) == objc_class_id;
625 /* Return 1 if LHS and RHS are compatible types for assignment or
626 various other operations. Return 0 if they are incompatible, and
627 return -1 if we choose to not decide (because the types are really
628 just C types, not ObjC specific ones). When the operation is
629 REFLEXIVE (typically comparisons), check for compatibility in
630 either direction; when it's not (typically assignments), don't.
632 This function is called in two cases: when both lhs and rhs are
633 pointers to records (in which case we check protocols too), and
634 when both lhs and rhs are records (in which case we check class
637 Warnings about classes/protocols not implementing a protocol are
638 emitted here (multiple of those warnings might be emitted for a
639 single line!); generic warnings about incompatible assignments and
640 lacks of casts in comparisons are/must be emitted by the caller if
645 objc_comptypes (tree lhs, tree rhs, int reflexive)
647 /* New clause for protocols. */
649 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
650 manage the ObjC ones, and leave the rest to the C code. */
651 if (TREE_CODE (lhs) == POINTER_TYPE
652 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
653 && TREE_CODE (rhs) == POINTER_TYPE
654 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
656 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
657 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
661 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
662 tree rproto, rproto_list;
665 /* <Protocol> = <Protocol> */
668 rproto_list = TYPE_PROTOCOL_LIST (rhs);
672 /* An assignment between objects of type 'id
673 <Protocol>'; make sure the protocol on the lhs is
674 supported by the object on the rhs. */
675 for (lproto = lproto_list; lproto;
676 lproto = TREE_CHAIN (lproto))
678 p = TREE_VALUE (lproto);
679 rproto = lookup_protocol_in_reflist (rproto_list, p);
683 ("object does not conform to the `%s' protocol",
684 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
690 /* Obscure case - a comparison between two objects
691 of type 'id <Protocol>'. Check that either the
692 protocol on the lhs is supported by the object on
693 the rhs, or viceversa. */
695 /* Check if the protocol on the lhs is supported by the
696 object on the rhs. */
697 for (lproto = lproto_list; lproto;
698 lproto = TREE_CHAIN (lproto))
700 p = TREE_VALUE (lproto);
701 rproto = lookup_protocol_in_reflist (rproto_list, p);
705 /* Check failed - check if the protocol on the rhs
706 is supported by the object on the lhs. */
707 for (rproto = rproto_list; rproto;
708 rproto = TREE_CHAIN (rproto))
710 p = TREE_VALUE (rproto);
711 lproto = lookup_protocol_in_reflist (lproto_list,
716 /* This check failed too: incompatible */
726 /* <Protocol> = <class> * */
727 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
729 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
732 /* Make sure the protocol is supported by the object on
734 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
736 p = TREE_VALUE (lproto);
738 rinter = lookup_interface (rname);
740 while (rinter && !rproto)
744 rproto_list = CLASS_PROTOCOL_LIST (rinter);
745 rproto = lookup_protocol_in_reflist (rproto_list, p);
746 /* If the underlying ObjC class does not have
747 the protocol we're looking for, check for "one-off"
748 protocols (e.g., `NSObject<MyProt> *foo;') attached
752 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
753 rproto = lookup_protocol_in_reflist (rproto_list, p);
756 /* Check for protocols adopted by categories. */
757 cat = CLASS_CATEGORY_LIST (rinter);
758 while (cat && !rproto)
760 rproto_list = CLASS_PROTOCOL_LIST (cat);
761 rproto = lookup_protocol_in_reflist (rproto_list, p);
762 cat = CLASS_CATEGORY_LIST (cat);
765 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
769 warning ("class `%s' does not implement the `%s' protocol",
770 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
771 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
775 /* <Protocol> = id */
776 else if (objc_is_object_id (TREE_TYPE (rhs)))
780 /* <Protocol> = Class */
781 else if (objc_is_class_id (TREE_TYPE (rhs)))
785 /* <Protocol> = ?? : let comptypes decide. */
788 else if (rhs_is_proto)
790 /* <class> * = <Protocol> */
791 if (TYPED_OBJECT (TREE_TYPE (lhs)))
795 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
797 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
799 /* Make sure the protocol is supported by the object on
801 for (rproto = rproto_list; rproto;
802 rproto = TREE_CHAIN (rproto))
804 tree p = TREE_VALUE (rproto);
806 rinter = lookup_interface (rname);
808 while (rinter && !lproto)
812 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
813 lproto = lookup_protocol_in_reflist (lproto_list, p);
814 /* If the underlying ObjC class does not
815 have the protocol we're looking for,
816 check for "one-off" protocols (e.g.,
817 `NSObject<MyProt> *foo;') attached to the
821 lproto_list = TYPE_PROTOCOL_LIST
823 lproto = lookup_protocol_in_reflist
827 /* Check for protocols adopted by categories. */
828 cat = CLASS_CATEGORY_LIST (rinter);
829 while (cat && !lproto)
831 lproto_list = CLASS_PROTOCOL_LIST (cat);
832 lproto = lookup_protocol_in_reflist (lproto_list,
834 cat = CLASS_CATEGORY_LIST (cat);
837 rinter = lookup_interface (CLASS_SUPER_NAME
842 warning ("class `%s' does not implement the `%s' protocol",
843 IDENTIFIER_POINTER (OBJC_TYPE_NAME
845 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
852 /* id = <Protocol> */
853 else if (objc_is_object_id (TREE_TYPE (lhs)))
857 /* Class = <Protocol> */
858 else if (objc_is_class_id (TREE_TYPE (lhs)))
862 /* ??? = <Protocol> : let comptypes decide */
870 /* Attention: we shouldn't defer to comptypes here. One bad
871 side effect would be that we might loose the REFLEXIVE
874 lhs = TREE_TYPE (lhs);
875 rhs = TREE_TYPE (rhs);
879 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
881 /* Nothing to do with ObjC - let immediately comptypes take
882 responsibility for checking. */
886 /* `id' = `<class> *' `<class> *' = `id': always allow it.
888 'Object *o = [[Object alloc] init]; falls
889 in the case <class> * = `id'.
891 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
892 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
895 /* `id' = `Class', `Class' = `id' */
897 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
898 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
901 /* `Class' != `<class> *' && `<class> *' != `Class'! */
902 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
903 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
906 /* `<class> *' = `<class> *' */
908 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
910 tree lname = OBJC_TYPE_NAME (lhs);
911 tree rname = OBJC_TYPE_NAME (rhs);
917 /* If the left hand side is a super class of the right hand side,
919 for (inter = lookup_interface (rname); inter;
920 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
921 if (lname == CLASS_SUPER_NAME (inter))
924 /* Allow the reverse when reflexive. */
926 for (inter = lookup_interface (lname); inter;
927 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
928 if (rname == CLASS_SUPER_NAME (inter))
934 /* Not an ObjC type - let comptypes do the check. */
938 /* Called from finish_decl. */
941 objc_check_decl (tree decl)
943 tree type = TREE_TYPE (decl);
945 if (TREE_CODE (type) != RECORD_TYPE)
947 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
948 error ("statically allocated instance of Objective-C class `%s'",
949 IDENTIFIER_POINTER (type));
952 /* Implement static typing. At this point, we know we have an interface. */
955 get_static_reference (tree interface, tree protocols)
957 tree type = xref_tag (RECORD_TYPE, interface);
961 tree t, m = TYPE_MAIN_VARIANT (type);
963 t = copy_node (type);
965 /* Add this type to the chain of variants of TYPE. */
966 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
967 TYPE_NEXT_VARIANT (m) = t;
969 /* Look up protocols and install in lang specific list. Note
970 that the protocol list can have a different lifetime than T! */
971 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
973 /* This forces a new pointer type to be created later
974 (in build_pointer_type)...so that the new template
975 we just created will actually be used...what a hack! */
976 if (TYPE_POINTER_TO (t))
977 TYPE_POINTER_TO (t) = NULL_TREE;
985 /* Return a declaration corresponding to a protocol list qualified 'id'. */
987 get_protocol_reference (tree protocols)
989 tree type_decl = lookup_name (objc_id_id);
992 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
994 type = TREE_TYPE (type_decl);
995 if (TYPE_MAIN_VARIANT (type) != objc_id_type)
996 warning ("unexpected type for `id' (%s)",
997 gen_declaration (type, errbuf));
1001 error ("undefined type `id', please import <objc/objc.h>");
1002 return error_mark_node;
1005 /* This clause creates a new pointer type that is qualified with
1006 the protocol specification...this info is used later to do more
1007 elaborate type checking. */
1011 tree t, m = TYPE_MAIN_VARIANT (type);
1013 t = copy_node (type);
1015 /* Add this type to the chain of variants of TYPE. */
1016 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1017 TYPE_NEXT_VARIANT (m) = t;
1019 /* Look up protocols...and install in lang specific list */
1020 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1022 /* This forces a new pointer type to be created later
1023 (in build_pointer_type)...so that the new template
1024 we just created will actually be used...what a hack! */
1025 if (TYPE_POINTER_TO (t))
1026 TYPE_POINTER_TO (t) = NULL_TREE;
1033 /* Check for circular dependencies in protocols. The arguments are
1034 PROTO, the protocol to check, and LIST, a list of protocol it
1038 check_protocol_recursively (tree proto, tree list)
1042 for (p = list; p; p = TREE_CHAIN (p))
1044 tree pp = TREE_VALUE (p);
1046 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1047 pp = lookup_protocol (pp);
1050 fatal_error ("protocol `%s' has circular dependency",
1051 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1053 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1057 /* Look up PROTOCOLS, and return a list of those that are found.
1058 If none are found, return NULL. */
1061 lookup_and_install_protocols (tree protocols)
1064 tree return_value = NULL_TREE;
1066 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1068 tree ident = TREE_VALUE (proto);
1069 tree p = lookup_protocol (ident);
1072 error ("cannot find protocol declaration for `%s'",
1073 IDENTIFIER_POINTER (ident));
1075 return_value = chainon (return_value,
1076 build_tree_list (NULL_TREE, p));
1079 return return_value;
1082 /* Create and push a decl for a built-in external variable or field NAME.
1084 TYPE is its data type. */
1087 create_builtin_decl (enum tree_code code, tree type, const char *name)
1089 tree decl = build_decl (code, get_identifier (name), type);
1091 if (code == VAR_DECL)
1093 TREE_STATIC (decl) = 1;
1094 make_decl_rtl (decl);
1096 DECL_ARTIFICIAL (decl) = 1;
1102 /* Find the decl for the constant string class. */
1105 setup_string_decl (void)
1107 if (!string_class_decl)
1109 if (!constant_string_global_id)
1113 /* %s in format will provide room for terminating null */
1114 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1115 + strlen (constant_string_class_name);
1116 name = xmalloc (length);
1117 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1118 constant_string_class_name);
1119 constant_string_global_id = get_identifier (name);
1121 string_class_decl = lookup_name (constant_string_global_id);
1125 /* Purpose: "play" parser, creating/installing representations
1126 of the declarations that are required by Objective-C.
1130 type_spec--------->sc_spec
1131 (tree_list) (tree_list)
1134 identifier_node identifier_node */
1137 synth_module_prologue (void)
1141 /* Defined in `objc.h' */
1142 objc_object_id = get_identifier (TAG_OBJECT);
1144 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1146 objc_id_type = build_pointer_type (objc_object_reference);
1148 objc_id_id = get_identifier (TYPE_ID);
1149 objc_class_id = get_identifier (TAG_CLASS);
1151 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1152 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1153 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1154 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, temp_type));
1156 /* Declare type of selector-objects that represent an operation name. */
1158 if (flag_next_runtime)
1159 /* `struct objc_selector *' */
1161 = build_pointer_type (xref_tag (RECORD_TYPE,
1162 get_identifier (TAG_SELECTOR)));
1164 /* `const struct objc_selector *' */
1166 = build_pointer_type
1167 (build_qualified_type (xref_tag (RECORD_TYPE,
1168 get_identifier (TAG_SELECTOR)),
1171 /* Declare receiver type used for dispatching messages to 'super'. */
1173 /* `struct objc_super *' */
1174 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1175 get_identifier (TAG_SUPER)));
1177 if (flag_next_runtime)
1179 /* NB: In order to call one of the ..._stret (struct-returning)
1180 functions, the function *MUST* first be cast to a signature that
1181 corresponds to the actual ObjC method being invoked. This is
1182 what is done by the build_objc_method_call() routine below. */
1184 /* id objc_msgSend (id, SEL, ...); */
1185 /* id objc_msgSendNonNil (id, SEL, ...); */
1186 /* id objc_msgSend_stret (id, SEL, ...); */
1187 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1189 = build_function_type (objc_id_type,
1190 tree_cons (NULL_TREE, objc_id_type,
1191 tree_cons (NULL_TREE,
1194 umsg_decl = builtin_function (TAG_MSGSEND,
1195 temp_type, 0, NOT_BUILT_IN,
1197 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1198 temp_type, 0, NOT_BUILT_IN,
1200 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1201 temp_type, 0, NOT_BUILT_IN,
1203 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1204 temp_type, 0, NOT_BUILT_IN,
1207 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1208 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1210 = build_function_type (objc_id_type,
1211 tree_cons (NULL_TREE, objc_super_type,
1212 tree_cons (NULL_TREE,
1215 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1216 temp_type, 0, NOT_BUILT_IN,
1218 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1219 temp_type, 0, NOT_BUILT_IN, 0,
1224 /* GNU runtime messenger entry points. */
1226 /* typedef id (*IMP)(id, SEL, ...); */
1228 = build_pointer_type
1229 (build_function_type (objc_id_type,
1230 tree_cons (NULL_TREE, objc_id_type,
1231 tree_cons (NULL_TREE,
1235 /* IMP objc_msg_lookup (id, SEL); */
1237 = build_function_type (IMP_type,
1238 tree_cons (NULL_TREE, objc_id_type,
1239 tree_cons (NULL_TREE,
1242 umsg_decl = builtin_function (TAG_MSGSEND,
1243 temp_type, 0, NOT_BUILT_IN,
1246 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1248 = build_function_type (IMP_type,
1249 tree_cons (NULL_TREE, objc_super_type,
1250 tree_cons (NULL_TREE,
1253 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1254 temp_type, 0, NOT_BUILT_IN,
1258 /* id objc_getClass (const char *); */
1260 temp_type = build_function_type (objc_id_type,
1261 tree_cons (NULL_TREE,
1262 const_string_type_node,
1266 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1269 /* id objc_getMetaClass (const char *); */
1271 objc_get_meta_class_decl
1272 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1274 build_super_template ();
1275 build_objc_exception_stuff ();
1276 if (flag_next_runtime)
1277 build_next_objc_exception_stuff ();
1279 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1281 if (! flag_next_runtime)
1283 if (flag_typed_selectors)
1285 /* Suppress outputting debug symbols, because
1286 dbxout_init hasn'r been called yet. */
1287 enum debug_info_type save_write_symbols = write_symbols;
1288 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1289 write_symbols = NO_DEBUG;
1290 debug_hooks = &do_nothing_debug_hooks;
1292 build_selector_template ();
1293 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1295 write_symbols = save_write_symbols;
1296 debug_hooks = save_hooks;
1299 temp_type = build_array_type (objc_selector_type, NULL_TREE);
1301 layout_type (temp_type);
1302 UOBJC_SELECTOR_TABLE_decl
1303 = create_builtin_decl (VAR_DECL, temp_type,
1304 "_OBJC_SELECTOR_TABLE");
1306 /* Avoid warning when not sending messages. */
1307 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1310 /* Forward declare constant_string_id and constant_string_type. */
1311 if (!constant_string_class_name)
1312 constant_string_class_name = default_constant_string_class_name;
1314 constant_string_id = get_identifier (constant_string_class_name);
1315 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1317 /* Pre-build the following entities - for speed/convenience. */
1318 self_id = get_identifier ("self");
1319 ucmd_id = get_identifier ("_cmd");
1321 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1322 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1326 /* Ensure that the ivar list for NSConstantString/NXConstantString
1327 (or whatever was specified via `-fconstant-string-class')
1328 contains fields at least as large as the following three, so that
1329 the runtime can stomp on them with confidence:
1331 struct STRING_OBJECT_CLASS_NAME
1335 unsigned int length;
1339 check_string_class_template (void)
1341 tree field_decl = TYPE_FIELDS (constant_string_type);
1343 #define AT_LEAST_AS_LARGE_AS(F, T) \
1344 (F && TREE_CODE (F) == FIELD_DECL \
1345 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1346 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1348 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1351 field_decl = TREE_CHAIN (field_decl);
1352 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1355 field_decl = TREE_CHAIN (field_decl);
1356 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1358 #undef AT_LEAST_AS_LARGE_AS
1361 /* Avoid calling `check_string_class_template ()' more than once. */
1362 static GTY(()) int string_layout_checked;
1364 /* Custom build_string which sets TREE_TYPE! */
1367 my_build_string (int len, const char *str)
1369 return fix_string_type (build_string (len, str));
1372 /* Given a chain of STRING_CST's, build a static instance of
1373 NXConstantString which points at the concatenation of those
1374 strings. We place the string object in the __string_objects
1375 section of the __OBJC segment. The Objective-C runtime will
1376 initialize the isa pointers of the string objects to point at the
1377 NXConstantString class object. */
1380 build_objc_string_object (tree string)
1382 tree initlist, constructor, constant_string_class;
1386 string = fix_string_type (string);
1388 constant_string_class = lookup_interface (constant_string_id);
1389 if (!constant_string_class
1390 || !(constant_string_type
1391 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1393 error ("cannot find interface declaration for `%s'",
1394 IDENTIFIER_POINTER (constant_string_id));
1395 return error_mark_node;
1398 /* Call to 'combine_strings' has been moved above. */
1399 TREE_SET_CODE (string, STRING_CST);
1400 length = TREE_STRING_LENGTH (string) - 1;
1402 if (!string_layout_checked)
1404 /* The NSConstantString/NXConstantString ivar layout is now
1406 if (!check_string_class_template ())
1408 error ("interface `%s' does not have valid constant string layout",
1409 IDENTIFIER_POINTER (constant_string_id));
1410 return error_mark_node;
1412 add_class_reference (constant_string_id);
1414 fields = TYPE_FIELDS (constant_string_type);
1416 /* & ((NXConstantString) { NULL, string, length }) */
1418 if (flag_next_runtime)
1420 /* For the NeXT runtime, we can generate a literal reference
1421 to the string class, don't need to run a constructor. */
1422 setup_string_decl ();
1423 if (string_class_decl == NULL_TREE)
1425 error ("cannot find reference tag for class `%s'",
1426 IDENTIFIER_POINTER (constant_string_id));
1427 return error_mark_node;
1429 initlist = build_tree_list
1431 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1435 initlist = build_tree_list (fields, build_int_cst (NULL_TREE, 0, 0));
1438 fields = TREE_CHAIN (fields);
1441 = tree_cons (fields, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1444 fields = TREE_CHAIN (fields);
1446 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length, 0), initlist);
1447 constructor = objc_build_constructor (constant_string_type,
1448 nreverse (initlist));
1450 if (!flag_next_runtime)
1453 = objc_add_static_instance (constructor, constant_string_type);
1456 constructor = build_unary_op (ADDR_EXPR, constructor, 1);
1457 TREE_CONSTANT (constructor) = true;
1461 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1463 static GTY(()) int num_static_inst;
1466 objc_add_static_instance (tree constructor, tree class_decl)
1471 /* Find the list of static instances for the CLASS_DECL. Create one if
1473 for (chain = &objc_static_instances;
1474 *chain && TREE_VALUE (*chain) != class_decl;
1475 chain = &TREE_CHAIN (*chain));
1478 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1479 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1482 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1483 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1484 DECL_COMMON (decl) = 1;
1485 TREE_STATIC (decl) = 1;
1486 DECL_ARTIFICIAL (decl) = 1;
1487 DECL_INITIAL (decl) = constructor;
1489 /* We may be writing something else just now.
1490 Postpone till end of input. */
1491 DECL_DEFER_OUTPUT (decl) = 1;
1492 pushdecl_top_level (decl);
1493 rest_of_decl_compilation (decl, 1, 0);
1495 /* Add the DECL to the head of this CLASS' list. */
1496 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1501 /* Build a static constant CONSTRUCTOR
1502 with type TYPE and elements ELTS. */
1505 objc_build_constructor (tree type, tree elts)
1507 tree constructor, f, e;
1509 /* ??? Most of the places that we build constructors, we don't fill in
1510 the type of integers properly. Convert them all en masse. */
1511 if (TREE_CODE (type) == ARRAY_TYPE)
1513 f = TREE_TYPE (type);
1514 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1515 for (e = elts; e ; e = TREE_CHAIN (e))
1516 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1520 f = TYPE_FIELDS (type);
1521 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1522 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1523 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1524 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1527 constructor = build_constructor (type, elts);
1528 TREE_CONSTANT (constructor) = 1;
1529 TREE_STATIC (constructor) = 1;
1530 TREE_READONLY (constructor) = 1;
1533 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1534 build_unary_op (wasn't true in 2.7.2.1 days) */
1535 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1540 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1542 /* Predefine the following data type:
1550 void *defs[cls_def_cnt + cat_def_cnt];
1554 build_objc_symtab_template (void)
1556 tree field_decl, field_decl_chain;
1558 objc_symtab_template
1559 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1561 /* long sel_ref_cnt; */
1563 field_decl = create_builtin_decl (FIELD_DECL,
1564 long_integer_type_node,
1566 field_decl_chain = field_decl;
1570 field_decl = create_builtin_decl (FIELD_DECL,
1571 build_pointer_type (objc_selector_type),
1573 chainon (field_decl_chain, field_decl);
1575 /* short cls_def_cnt; */
1577 field_decl = create_builtin_decl (FIELD_DECL,
1578 short_integer_type_node,
1580 chainon (field_decl_chain, field_decl);
1582 /* short cat_def_cnt; */
1584 field_decl = create_builtin_decl (FIELD_DECL,
1585 short_integer_type_node,
1587 chainon (field_decl_chain, field_decl);
1589 if (imp_count || cat_count || !flag_next_runtime)
1591 /* void *defs[imp_count + cat_count (+ 1)]; */
1592 /* NB: The index is one less than the size of the array. */
1593 int index = imp_count + cat_count
1594 + (flag_next_runtime? -1: 0);
1595 field_decl = create_builtin_decl
1599 build_index_type (build_int_cst (NULL_TREE, index, 0))),
1601 chainon (field_decl_chain, field_decl);
1604 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1607 /* Create the initial value for the `defs' field of _objc_symtab.
1608 This is a CONSTRUCTOR. */
1611 init_def_list (tree type)
1613 tree expr, initlist = NULL_TREE;
1614 struct imp_entry *impent;
1617 for (impent = imp_list; impent; impent = impent->next)
1619 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1621 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1622 initlist = tree_cons (NULL_TREE, expr, initlist);
1627 for (impent = imp_list; impent; impent = impent->next)
1629 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1631 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1632 initlist = tree_cons (NULL_TREE, expr, initlist);
1636 if (!flag_next_runtime)
1638 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1641 if (static_instances_decl)
1642 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1644 expr = build_int_cst (NULL_TREE, 0, 0);
1646 initlist = tree_cons (NULL_TREE, expr, initlist);
1649 return objc_build_constructor (type, nreverse (initlist));
1652 /* Construct the initial value for all of _objc_symtab. */
1655 init_objc_symtab (tree type)
1659 /* sel_ref_cnt = { ..., 5, ... } */
1661 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0, 0));
1663 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1665 if (flag_next_runtime || ! sel_ref_chain)
1666 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
1668 initlist = tree_cons (NULL_TREE,
1669 build_unary_op (ADDR_EXPR,
1670 UOBJC_SELECTOR_TABLE_decl, 1),
1673 /* cls_def_cnt = { ..., 5, ... } */
1675 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count, 0), initlist);
1677 /* cat_def_cnt = { ..., 5, ... } */
1679 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count, 0), initlist);
1681 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1683 if (imp_count || cat_count || !flag_next_runtime)
1686 tree field = TYPE_FIELDS (type);
1687 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1689 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1693 return objc_build_constructor (type, nreverse (initlist));
1696 /* Generate forward declarations for metadata such as
1697 'OBJC_CLASS_...'. */
1700 build_metadata_decl (const char *name, tree type)
1702 tree decl, decl_specs;
1703 /* extern struct TYPE NAME_<name>; */
1704 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1705 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1706 decl = define_decl (synth_id_with_class_suffix
1708 objc_implementation_context),
1710 TREE_USED (decl) = 1;
1711 DECL_ARTIFICIAL (decl) = 1;
1712 TREE_PUBLIC (decl) = 0;
1716 /* Push forward-declarations of all the categories so that
1717 init_def_list can use them in a CONSTRUCTOR. */
1720 forward_declare_categories (void)
1722 struct imp_entry *impent;
1723 tree sav = objc_implementation_context;
1725 for (impent = imp_list; impent; impent = impent->next)
1727 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1729 /* Set an invisible arg to synth_id_with_class_suffix. */
1730 objc_implementation_context = impent->imp_context;
1731 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1732 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1733 objc_category_template);
1736 objc_implementation_context = sav;
1739 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1740 and initialized appropriately. */
1743 generate_objc_symtab_decl (void)
1747 if (!objc_category_template)
1748 build_category_template ();
1750 /* forward declare categories */
1752 forward_declare_categories ();
1754 if (!objc_symtab_template)
1755 build_objc_symtab_template ();
1757 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1759 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1760 tree_cons (NULL_TREE,
1761 objc_symtab_template, sc_spec),
1765 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1766 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1767 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1768 finish_decl (UOBJC_SYMBOLS_decl,
1769 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1774 init_module_descriptor (tree type)
1776 tree initlist, expr;
1778 /* version = { 1, ... } */
1780 expr = build_int_cst (NULL_TREE, OBJC_VERSION, 0);
1781 initlist = build_tree_list (NULL_TREE, expr);
1783 /* size = { ..., sizeof (struct objc_module), ... } */
1785 expr = size_in_bytes (objc_module_template);
1786 initlist = tree_cons (NULL_TREE, expr, initlist);
1788 /* name = { ..., "foo.m", ... } */
1790 expr = add_objc_string (get_identifier (input_filename), class_names);
1791 initlist = tree_cons (NULL_TREE, expr, initlist);
1793 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1795 if (UOBJC_SYMBOLS_decl)
1796 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1798 expr = build_int_cst (NULL_TREE, 0, 0);
1799 initlist = tree_cons (NULL_TREE, expr, initlist);
1801 return objc_build_constructor (type, nreverse (initlist));
1804 /* Write out the data structures to describe Objective C classes defined.
1805 If appropriate, compile and output a setup function to initialize them.
1806 Return a symbol_ref to the function to call to initialize the Objective C
1807 data structures for this file (and perhaps for other files also).
1809 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1812 build_module_descriptor (void)
1814 tree decl_specs, field_decl, field_decl_chain;
1816 objc_module_template
1817 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1821 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1822 field_decl = get_identifier ("version");
1823 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1824 field_decl_chain = field_decl;
1828 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1829 field_decl = get_identifier ("size");
1830 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1831 chainon (field_decl_chain, field_decl);
1835 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1836 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1837 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1838 chainon (field_decl_chain, field_decl);
1840 /* struct objc_symtab *symtab; */
1842 decl_specs = get_identifier (UTAG_SYMTAB);
1843 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1844 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1845 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1846 chainon (field_decl_chain, field_decl);
1848 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1850 /* Create an instance of "objc_module". */
1852 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1853 build_tree_list (NULL_TREE,
1854 ridpointers[(int) RID_STATIC]));
1856 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1857 decl_specs, 1, NULL_TREE);
1859 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1860 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1861 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1863 finish_decl (UOBJC_MODULES_decl,
1864 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1867 /* Mark the decl to avoid "defined but not used" warning. */
1868 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1870 mark_decl_referenced (UOBJC_MODULES_decl);
1872 /* Generate a constructor call for the module descriptor.
1873 This code was generated by reading the grammar rules
1874 of c-parse.in; Therefore, it may not be the most efficient
1875 way of generating the requisite code. */
1877 if (flag_next_runtime)
1881 tree parms, execclass_decl, decelerator, void_list_node_1;
1882 tree init_function_name, init_function_decl, compound;
1884 /* Declare void __objc_execClass (void *); */
1886 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1887 execclass_decl = build_decl (FUNCTION_DECL,
1888 get_identifier (TAG_EXECCLASS),
1889 build_function_type (void_type_node,
1890 tree_cons (NULL_TREE, ptr_type_node,
1893 DECL_EXTERNAL (execclass_decl) = 1;
1894 DECL_ARTIFICIAL (execclass_decl) = 1;
1895 TREE_PUBLIC (execclass_decl) = 1;
1896 pushdecl (execclass_decl);
1897 rest_of_decl_compilation (execclass_decl, 0, 0);
1898 assemble_external (execclass_decl);
1900 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1902 init_function_name = get_file_function_name ('I');
1903 start_function (void_list_node_1,
1904 build_nt (CALL_EXPR, init_function_name,
1905 tree_cons (NULL_TREE, NULL_TREE,
1909 store_parm_decls ();
1910 compound = c_begin_compound_stmt (true);
1912 init_function_decl = current_function_decl;
1913 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1914 TREE_USED (init_function_decl) = 1;
1915 /* Don't let this one be deferred. */
1916 DECL_INLINE (init_function_decl) = 0;
1917 DECL_UNINLINABLE (init_function_decl) = 1;
1920 = build_tree_list (NULL_TREE,
1921 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1922 decelerator = build_function_call (execclass_decl, parms);
1924 add_stmt (decelerator);
1925 add_stmt (c_end_compound_stmt (compound, true));
1929 return XEXP (DECL_RTL (init_function_decl), 0);
1933 /* Return the DECL of the string IDENT in the SECTION. */
1936 get_objc_string_decl (tree ident, enum string_section section)
1940 if (section == class_names)
1941 chain = class_names_chain;
1942 else if (section == meth_var_names)
1943 chain = meth_var_names_chain;
1944 else if (section == meth_var_types)
1945 chain = meth_var_types_chain;
1949 for (; chain != 0; chain = TREE_CHAIN (chain))
1950 if (TREE_VALUE (chain) == ident)
1951 return (TREE_PURPOSE (chain));
1957 /* Output references to all statically allocated objects. Return the DECL
1958 for the array built. */
1961 generate_static_references (void)
1963 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1964 tree class_name, class, decl, initlist;
1965 tree cl_chain, in_chain;
1966 int num_inst, num_class;
1969 if (flag_next_runtime)
1972 for (cl_chain = objc_static_instances, num_class = 0;
1973 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1975 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1976 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1978 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1979 ident = get_identifier (buf);
1981 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
1982 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1983 build_tree_list (NULL_TREE,
1984 ridpointers[(int) RID_STATIC]));
1985 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1986 DECL_CONTEXT (decl) = 0;
1987 DECL_ARTIFICIAL (decl) = 1;
1988 TREE_USED (decl) = 1;
1990 /* Output {class_name, ...}. */
1991 class = TREE_VALUE (cl_chain);
1992 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
1993 initlist = build_tree_list (NULL_TREE,
1994 build_unary_op (ADDR_EXPR, class_name, 1));
1996 /* Output {..., instance, ...}. */
1997 for (in_chain = TREE_PURPOSE (cl_chain);
1998 in_chain; in_chain = TREE_CHAIN (in_chain))
2000 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2001 initlist = tree_cons (NULL_TREE, expr, initlist);
2004 /* Output {..., NULL}. */
2005 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
2007 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2008 finish_decl (decl, expr, NULL_TREE);
2010 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2013 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), decls);
2014 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2015 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
2016 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2017 build_tree_list (NULL_TREE,
2018 ridpointers[(int) RID_STATIC]));
2019 static_instances_decl
2020 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2021 TREE_USED (static_instances_decl) = 1;
2022 DECL_CONTEXT (static_instances_decl) = 0;
2023 DECL_ARTIFICIAL (static_instances_decl) = 1;
2024 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2026 finish_decl (static_instances_decl, expr, NULL_TREE);
2027 rest_of_decl_compilation (static_instances_decl, 0, 0);
2030 /* Output all strings. */
2033 generate_strings (void)
2035 tree sc_spec, decl_specs, expr_decl;
2036 tree chain, string_expr;
2039 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2041 string = TREE_VALUE (chain);
2042 decl = TREE_PURPOSE (chain);
2044 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2045 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2046 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2047 NULL_TREE, NULL_TREE);
2048 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2049 DECL_CONTEXT (decl) = NULL_TREE;
2050 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2051 IDENTIFIER_POINTER (string));
2052 finish_decl (decl, string_expr, NULL_TREE);
2055 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2057 string = TREE_VALUE (chain);
2058 decl = TREE_PURPOSE (chain);
2060 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2061 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2062 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2063 NULL_TREE, NULL_TREE);
2064 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2065 DECL_CONTEXT (decl) = NULL_TREE;
2066 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2067 IDENTIFIER_POINTER (string));
2068 finish_decl (decl, string_expr, NULL_TREE);
2071 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2073 string = TREE_VALUE (chain);
2074 decl = TREE_PURPOSE (chain);
2076 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2077 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2078 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
2079 NULL_TREE, NULL_TREE);
2080 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2081 DECL_CONTEXT (decl) = NULL_TREE;
2082 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2083 IDENTIFIER_POINTER (string));
2084 finish_decl (decl, string_expr, NULL_TREE);
2088 static GTY(()) int selector_reference_idx;
2091 build_selector_reference_decl (void)
2096 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2098 ident = get_identifier (buf);
2100 decl = build_decl (VAR_DECL, ident, objc_selector_type);
2101 DECL_EXTERNAL (decl) = 1;
2102 TREE_PUBLIC (decl) = 0;
2103 TREE_USED (decl) = 1;
2104 DECL_ARTIFICIAL (decl) = 1;
2105 DECL_CONTEXT (decl) = 0;
2107 make_decl_rtl (decl);
2108 pushdecl_top_level (decl);
2113 /* Just a handy wrapper for add_objc_string. */
2116 build_selector (tree ident)
2118 tree expr = add_objc_string (ident, meth_var_names);
2119 if (flag_typed_selectors)
2122 return build_c_cast (objc_selector_type, expr); /* cast! */
2126 build_selector_translation_table (void)
2128 tree sc_spec, decl_specs;
2129 tree chain, initlist = NULL_TREE;
2131 tree decl = NULL_TREE, var_decl, name;
2133 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2137 if (warn_selector && objc_implementation_context)
2141 for (method_chain = meth_var_names_chain;
2143 method_chain = TREE_CHAIN (method_chain))
2145 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2153 /* Adjust line number for warning message. */
2154 int save_lineno = input_line;
2155 if (flag_next_runtime && TREE_PURPOSE (chain))
2156 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2157 warning ("creating selector for non existant method %s",
2158 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2159 input_line = save_lineno;
2163 expr = build_selector (TREE_VALUE (chain));
2165 if (flag_next_runtime)
2167 name = DECL_NAME (TREE_PURPOSE (chain));
2169 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2171 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2172 decl_specs = tree_cons (NULL_TREE, objc_selector_type, sc_spec);
2176 /* The `decl' that is returned from start_decl is the one that we
2177 forward declared in `build_selector_reference' */
2178 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2181 /* add one for the '\0' character */
2182 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2184 if (flag_next_runtime)
2185 finish_decl (decl, expr, NULL_TREE);
2188 if (flag_typed_selectors)
2190 tree eltlist = NULL_TREE;
2191 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2192 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2193 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2194 expr = objc_build_constructor (objc_selector_template,
2195 nreverse (eltlist));
2197 initlist = tree_cons (NULL_TREE, expr, initlist);
2202 if (! flag_next_runtime)
2204 /* Cause the variable and its initial value to be actually output. */
2205 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2206 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2207 /* NULL terminate the list and fix the decl for output. */
2208 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
2209 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2210 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2211 nreverse (initlist));
2212 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2213 current_function_decl = NULL_TREE;
2218 get_proto_encoding (tree proto)
2223 if (! METHOD_ENCODING (proto))
2225 encoding = encode_method_prototype (proto);
2226 METHOD_ENCODING (proto) = encoding;
2229 encoding = METHOD_ENCODING (proto);
2231 return add_objc_string (encoding, meth_var_types);
2234 return build_int_cst (NULL_TREE, 0, 0);
2237 /* sel_ref_chain is a list whose "value" fields will be instances of
2238 identifier_node that represent the selector. */
2241 build_typed_selector_reference (tree ident, tree prototype)
2243 tree *chain = &sel_ref_chain;
2249 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2250 goto return_at_index;
2253 chain = &TREE_CHAIN (*chain);
2256 *chain = tree_cons (prototype, ident, NULL_TREE);
2259 expr = build_unary_op (ADDR_EXPR,
2260 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2261 build_int_cst (NULL_TREE, index, 0)),
2263 return build_c_cast (objc_selector_type, expr);
2267 build_selector_reference (tree ident)
2269 tree *chain = &sel_ref_chain;
2275 if (TREE_VALUE (*chain) == ident)
2276 return (flag_next_runtime
2277 ? TREE_PURPOSE (*chain)
2278 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2279 build_int_cst (NULL_TREE, index, 0)));
2282 chain = &TREE_CHAIN (*chain);
2285 expr = build_selector_reference_decl ();
2287 *chain = tree_cons (expr, ident, NULL_TREE);
2289 return (flag_next_runtime
2291 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2292 build_int_cst (NULL_TREE, index, 0)));
2295 static GTY(()) int class_reference_idx;
2298 build_class_reference_decl (void)
2303 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2305 ident = get_identifier (buf);
2307 decl = build_decl (VAR_DECL, ident, objc_class_type);
2308 DECL_EXTERNAL (decl) = 1;
2309 TREE_PUBLIC (decl) = 0;
2310 TREE_USED (decl) = 1;
2311 DECL_CONTEXT (decl) = 0;
2312 DECL_ARTIFICIAL (decl) = 1;
2314 make_decl_rtl (decl);
2315 pushdecl_top_level (decl);
2320 /* Create a class reference, but don't create a variable to reference
2324 add_class_reference (tree ident)
2328 if ((chain = cls_ref_chain))
2333 if (ident == TREE_VALUE (chain))
2337 chain = TREE_CHAIN (chain);
2341 /* Append to the end of the list */
2342 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2345 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2348 /* Get a class reference, creating it if necessary. Also create the
2349 reference variable. */
2352 get_class_reference (tree ident)
2357 if (processing_template_decl)
2358 /* Must wait until template instantiation time. */
2359 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2360 if (TREE_CODE (ident) == TYPE_DECL)
2361 ident = DECL_NAME (ident);
2365 if (!(ident = is_class_name (ident)))
2367 error ("`%s' is not an Objective-C class name or alias",
2368 IDENTIFIER_POINTER (orig_ident));
2369 return error_mark_node;
2372 if (flag_next_runtime && !flag_zero_link)
2377 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2378 if (TREE_VALUE (*chain) == ident)
2380 if (! TREE_PURPOSE (*chain))
2381 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2383 return TREE_PURPOSE (*chain);
2386 decl = build_class_reference_decl ();
2387 *chain = tree_cons (decl, ident, NULL_TREE);
2394 add_class_reference (ident);
2396 params = build_tree_list (NULL_TREE,
2397 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2398 IDENTIFIER_POINTER (ident)));
2400 assemble_external (objc_get_class_decl);
2401 return build_function_call (objc_get_class_decl, params);
2405 /* For each string section we have a chain which maps identifier nodes
2406 to decls for the strings. */
2409 add_objc_string (tree ident, enum string_section section)
2413 if (section == class_names)
2414 chain = &class_names_chain;
2415 else if (section == meth_var_names)
2416 chain = &meth_var_names_chain;
2417 else if (section == meth_var_types)
2418 chain = &meth_var_types_chain;
2424 if (TREE_VALUE (*chain) == ident)
2425 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2427 chain = &TREE_CHAIN (*chain);
2430 decl = build_objc_string_decl (section);
2432 *chain = tree_cons (decl, ident, NULL_TREE);
2434 return build_unary_op (ADDR_EXPR, decl, 1);
2437 static GTY(()) int class_names_idx;
2438 static GTY(()) int meth_var_names_idx;
2439 static GTY(()) int meth_var_types_idx;
2442 build_objc_string_decl (enum string_section section)
2447 if (section == class_names)
2448 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2449 else if (section == meth_var_names)
2450 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2451 else if (section == meth_var_types)
2452 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2454 ident = get_identifier (buf);
2456 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2457 DECL_EXTERNAL (decl) = 1;
2458 TREE_PUBLIC (decl) = 0;
2459 TREE_USED (decl) = 1;
2460 TREE_CONSTANT (decl) = 1;
2461 DECL_CONTEXT (decl) = 0;
2462 DECL_ARTIFICIAL (decl) = 1;
2464 make_decl_rtl (decl);
2465 pushdecl_top_level (decl);
2472 objc_declare_alias (tree alias_ident, tree class_ident)
2474 tree underlying_class;
2477 if (current_namespace != global_namespace) {
2478 error ("Objective-C declarations may only appear in global scope");
2480 #endif /* OBJCPLUS */
2482 if (!(underlying_class = is_class_name (class_ident)))
2483 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2484 else if (is_class_name (alias_ident))
2485 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2487 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2491 objc_declare_class (tree ident_list)
2495 if (current_namespace != global_namespace) {
2496 error ("Objective-C declarations may only appear in global scope");
2498 #endif /* OBJCPLUS */
2500 for (list = ident_list; list; list = TREE_CHAIN (list))
2502 tree ident = TREE_VALUE (list);
2504 if (! is_class_name (ident))
2506 tree record = lookup_name (ident);
2508 if (record && ! TREE_STATIC_TEMPLATE (record))
2510 error ("`%s' redeclared as different kind of symbol",
2511 IDENTIFIER_POINTER (ident));
2512 error ("%Jprevious declaration of '%D'",
2516 record = xref_tag (RECORD_TYPE, ident);
2517 TREE_STATIC_TEMPLATE (record) = 1;
2518 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2524 is_class_name (tree ident)
2528 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2529 && identifier_global_value (ident))
2530 ident = identifier_global_value (ident);
2531 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2532 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2535 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2536 ident = TYPE_NAME (ident);
2537 if (ident && TREE_CODE (ident) == TYPE_DECL)
2538 ident = DECL_NAME (ident);
2540 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2543 if (lookup_interface (ident))
2546 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2548 if (ident == TREE_VALUE (chain))
2552 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2554 if (ident == TREE_VALUE (chain))
2555 return TREE_PURPOSE (chain);
2561 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2562 class instance. This is needed by other parts of the compiler to
2563 handle ObjC types gracefully. */
2566 objc_is_object_ptr (tree type)
2568 type = TYPE_MAIN_VARIANT (type);
2569 if (!type || TREE_CODE (type) != POINTER_TYPE)
2571 /* NB: This function may be called before the ObjC front-end has
2572 been initialized, in which case OBJC_ID_TYPE will be NULL. */
2573 if (objc_id_type && type && TYPE_P (type)
2575 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2577 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2581 lookup_interface (tree ident)
2586 if (ident && TREE_CODE (ident) == TYPE_DECL)
2587 ident = DECL_NAME (ident);
2589 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2591 if (ident == CLASS_NAME (chain))
2597 /* Implement @defs (<classname>) within struct bodies. */
2600 get_class_ivars_from_name (tree class_name)
2602 tree interface = lookup_interface (class_name);
2603 tree field, fields = NULL_TREE;
2607 tree raw_ivar = get_class_ivars (interface, 1);
2609 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2610 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2612 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2613 TREE_PURPOSE (raw_ivar),
2614 TREE_VALUE (TREE_VALUE (raw_ivar)));
2616 finish_member_declaration (field);
2618 fields = chainon (fields, field);
2623 error ("cannot find interface declaration for `%s'",
2624 IDENTIFIER_POINTER (class_name));
2629 /* Used by: build_private_template, continue_class,
2630 and for @defs constructs. */
2633 get_class_ivars (tree interface, int raw)
2635 tree my_name, super_name, ivar_chain;
2637 my_name = CLASS_NAME (interface);
2638 super_name = CLASS_SUPER_NAME (interface);
2640 ivar_chain = CLASS_RAW_IVARS (interface);
2643 ivar_chain = CLASS_IVARS (interface);
2644 /* Save off a pristine copy of the leaf ivars (i.e, those not
2645 inherited from a super class). */
2646 if (!CLASS_OWN_IVARS (interface))
2647 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2653 tree super_interface = lookup_interface (super_name);
2655 if (!super_interface)
2657 /* fatal did not work with 2 args...should fix */
2658 error ("cannot find interface declaration for `%s', superclass of `%s'",
2659 IDENTIFIER_POINTER (super_name),
2660 IDENTIFIER_POINTER (my_name));
2661 exit (FATAL_EXIT_CODE);
2664 if (super_interface == interface)
2665 fatal_error ("circular inheritance in interface declaration for `%s'",
2666 IDENTIFIER_POINTER (super_name));
2668 interface = super_interface;
2669 my_name = CLASS_NAME (interface);
2670 super_name = CLASS_SUPER_NAME (interface);
2672 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2675 tree head = copy_list (op1);
2677 /* Prepend super class ivars...make a copy of the list, we
2678 do not want to alter the original. */
2679 chainon (head, ivar_chain);
2688 objc_create_temporary_var (tree type)
2692 decl = build_decl (VAR_DECL, NULL_TREE, type);
2693 TREE_USED (decl) = 1;
2694 DECL_ARTIFICIAL (decl) = 1;
2695 DECL_IGNORED_P (decl) = 1;
2696 DECL_CONTEXT (decl) = current_function_decl;
2701 /* Exception handling constructs. We begin by having the parser do most
2702 of the work and passing us blocks. What we do next depends on whether
2703 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2704 We abstract all of this in a handful of appropriately named routines. */
2706 /* Stack of open try blocks. */
2708 struct objc_try_context
2710 struct objc_try_context *outer;
2712 /* Statements (or statement lists) as processed by the parser. */
2716 /* Some file position locations. */
2717 location_t try_locus;
2718 location_t end_try_locus;
2719 location_t end_catch_locus;
2720 location_t finally_locus;
2721 location_t end_finally_locus;
2723 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2724 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2727 /* The CATCH_EXPR of an open @catch clause. */
2730 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2736 static struct objc_try_context *cur_try_context;
2738 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2739 that represents TYPE. For Objective-C, this is just the class name. */
2740 /* ??? Isn't there a class object or some such? Is it easy to get? */
2743 objc_eh_runtime_type (tree type)
2745 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2748 /* Initialize exception handling. */
2751 objc_init_exceptions (void)
2753 static bool done = false;
2759 if (!flag_objc_exceptions)
2760 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2761 "exception syntax");
2763 if (!flag_objc_sjlj_exceptions)
2765 c_eh_initialized_p = true;
2766 eh_personality_libfunc
2767 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2768 ? "__gnu_objc_personality_sj0"
2769 : "__gnu_objc_personality_v0");
2770 using_eh_for_cleanups ();
2771 lang_eh_runtime_type = objc_eh_runtime_type;
2775 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2776 we'll arrange for it to be initialized (and associated with a binding)
2780 objc_build_exc_ptr (void)
2782 if (flag_objc_sjlj_exceptions)
2784 tree var = cur_try_context->caught_decl;
2787 var = objc_create_temporary_var (objc_id_type);
2788 cur_try_context->caught_decl = var;
2793 return build (EXC_PTR_EXPR, objc_id_type);
2796 /* Build "objc_exception_try_exit(&_stack)". */
2799 next_sjlj_build_try_exit (void)
2802 t = build_fold_addr_expr (cur_try_context->stack_decl);
2803 t = tree_cons (NULL, t, NULL);
2804 t = build_function_call (objc_exception_try_exit_decl, t);
2809 objc_exception_try_enter (&_stack);
2810 if (_setjmp(&_stack.buf))
2814 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2815 empty, ready for the caller to fill them in. */
2818 next_sjlj_build_enter_and_setjmp (void)
2820 tree t, enter, sj, cond;
2822 t = build_fold_addr_expr (cur_try_context->stack_decl);
2823 t = tree_cons (NULL, t, NULL);
2824 enter = build_function_call (objc_exception_try_enter_decl, t);
2826 t = build_component_ref (cur_try_context->stack_decl,
2827 get_identifier ("buf"));
2828 t = build_fold_addr_expr (t);
2829 t = convert (ptr_type_node, t);
2830 t = tree_cons (NULL, t, NULL);
2831 sj = build_function_call (objc_setjmp_decl, t);
2833 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2834 cond = lang_hooks.truthvalue_conversion (cond);
2836 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2840 DECL = objc_exception_extract(&_stack);
2844 next_sjlj_build_exc_extract (tree decl)
2848 t = build_fold_addr_expr (cur_try_context->stack_decl);
2849 t = tree_cons (NULL, t, NULL);
2850 t = build_function_call (objc_exception_extract_decl, t);
2851 t = convert (TREE_TYPE (decl), t);
2852 t = build (MODIFY_EXPR, void_type_node, decl, t);
2858 if (objc_exception_match(obj_get_class(TYPE), _caught)
2865 objc_exception_try_exit(&_stack);
2867 from the sequence of CATCH_EXPRs in the current try context. */
2870 next_sjlj_build_catch_list (void)
2872 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
2874 tree *last = &catch_seq;
2875 bool saw_id = false;
2877 for (; !tsi_end_p (i); tsi_next (&i))
2879 tree stmt = tsi_stmt (i);
2880 tree type = CATCH_TYPES (stmt);
2881 tree body = CATCH_BODY (stmt);
2893 if (type == error_mark_node)
2894 cond = error_mark_node;
2897 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
2898 t = get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
2899 args = tree_cons (NULL, t, args);
2900 t = build_function_call (objc_exception_match_decl, args);
2901 cond = lang_hooks.truthvalue_conversion (t);
2903 t = build (COND_EXPR, void_type_node, cond, body, NULL);
2904 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
2907 last = &COND_EXPR_ELSE (t);
2913 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
2914 cur_try_context->caught_decl);
2915 annotate_with_locus (t, cur_try_context->end_catch_locus);
2916 append_to_statement_list (t, last);
2918 t = next_sjlj_build_try_exit ();
2919 annotate_with_locus (t, cur_try_context->end_catch_locus);
2920 append_to_statement_list (t, last);
2926 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
2927 exception handling. We aim to build:
2930 struct _objc_exception_data _stack;
2931 id volatile _rethrow = 0;
2934 objc_exception_try_enter (&_stack);
2935 if (_setjmp(&_stack.buf))
2937 id _caught = objc_exception_extract(&_stack);
2938 objc_exception_try_enter (&_stack);
2939 if (_setjmp(&_stack.buf))
2940 _rethrow = objc_exception_extract(&_stack);
2950 objc_exception_try_exit(&_stack);
2953 objc_exception_throw(_rethrow);
2957 If CATCH-LIST is empty, we can omit all of the block containing
2958 "_caught" except for the setting of _rethrow. Note the use of
2959 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
2960 but handles goto and other exits from the block. */
2963 next_sjlj_build_try_catch_finally (void)
2965 tree rethrow_decl, stack_decl, t;
2966 tree catch_seq, try_fin, bind;
2968 /* Create the declarations involved. */
2969 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
2970 stack_decl = objc_create_temporary_var (t);
2971 cur_try_context->stack_decl = stack_decl;
2973 rethrow_decl = objc_create_temporary_var (objc_id_type);
2974 cur_try_context->rethrow_decl = rethrow_decl;
2975 TREE_THIS_VOLATILE (rethrow_decl) = 1;
2976 TREE_CHAIN (rethrow_decl) = stack_decl;
2978 /* Build the outermost varible binding level. */
2979 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
2980 annotate_with_locus (bind, cur_try_context->try_locus);
2981 TREE_SIDE_EFFECTS (bind) = 1;
2983 /* Initialize rethrow_decl. */
2984 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
2985 convert (objc_id_type, null_pointer_node));
2986 annotate_with_locus (t, cur_try_context->try_locus);
2987 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
2989 /* Build the outermost TRY_FINALLY_EXPR. */
2990 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
2991 annotate_with_locus (try_fin, cur_try_context->try_locus);
2992 TREE_SIDE_EFFECTS (try_fin) = 1;
2993 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
2995 /* Create the complete catch sequence. */
2996 if (cur_try_context->catch_list)
2998 tree caught_decl = objc_build_exc_ptr ();
2999 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3001 t = next_sjlj_build_exc_extract (caught_decl);
3002 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3004 t = next_sjlj_build_enter_and_setjmp ();
3005 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3006 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3007 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3010 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3011 annotate_with_locus (catch_seq, cur_try_context->end_try_locus);
3013 /* Build the main register-and-try if statement. */
3014 t = next_sjlj_build_enter_and_setjmp ();
3015 annotate_with_locus (t, cur_try_context->try_locus);
3016 COND_EXPR_THEN (t) = catch_seq;
3017 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3018 TREE_OPERAND (try_fin, 0) = t;
3020 /* Build the complete FINALLY statement list. */
3021 t = next_sjlj_build_try_exit ();
3022 t = build_stmt (COND_EXPR,
3023 lang_hooks.truthvalue_conversion (rethrow_decl),
3025 annotate_with_locus (t, cur_try_context->finally_locus);
3026 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3028 append_to_statement_list (cur_try_context->finally_body,
3029 &TREE_OPERAND (try_fin, 1));
3031 t = tree_cons (NULL, rethrow_decl, NULL);
3032 t = build_function_call (objc_exception_throw_decl, t);
3033 t = build_stmt (COND_EXPR,
3034 lang_hooks.truthvalue_conversion (rethrow_decl),
3036 annotate_with_locus (t, cur_try_context->end_finally_locus);
3037 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3042 /* Called just after parsing the @try and its associated BODY. We now
3043 must prepare for the tricky bits -- handling the catches and finally. */
3046 objc_begin_try_stmt (location_t try_locus, tree body)
3048 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3049 c->outer = cur_try_context;
3051 c->try_locus = try_locus;
3052 c->end_try_locus = input_location;
3053 cur_try_context = c;
3055 objc_init_exceptions ();
3058 /* Called just after parsing "@catch (parm)". Open a binding level,
3059 enter PARM into the binding level, and initialize it. Leave the
3060 binding level open while the body of the compound statement is parsed. */
3063 objc_begin_catch_clause (tree parm)
3065 tree compound, decl, type, t;
3067 /* Begin a new scope that the entire catch clause will live in. */
3068 compound = c_begin_compound_stmt (1);
3070 /* Turn the raw declarator/declspecs into a decl in the current scope. */
3071 decl = define_decl (TREE_VALUE (TREE_PURPOSE (parm)),
3072 TREE_PURPOSE (TREE_PURPOSE (parm)));
3074 /* Since a decl is required here by syntax, don't warn if its unused. */
3075 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3076 be what the previous objc implementation did. */
3077 TREE_USED (decl) = 1;
3079 /* Verify that the type of the catch is valid. It must be a pointer
3080 to an Objective-C class, or "id" (which is catch-all). */
3081 type = TREE_TYPE (decl);
3082 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3084 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3086 error ("@catch parameter is not a known Objective-C class type");
3087 type = error_mark_node;
3089 else if (cur_try_context->catch_list)
3091 /* Examine previous @catch clauses and see if we've already
3092 caught the type in question. */
3093 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3094 for (; !tsi_end_p (i); tsi_next (&i))
3096 tree stmt = tsi_stmt (i);
3097 t = CATCH_TYPES (stmt);
3098 if (t == error_mark_node)
3100 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3102 warning ("exception of type %<%T%> will be caught",
3104 warning ("%H by earlier handler for %<%T%>",
3105 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_id_type));
3111 /* Record the data for the catch in the try context so that we can
3112 finalize it later. */
3113 t = build_stmt (CATCH_EXPR, type, compound);
3114 cur_try_context->current_catch = t;
3116 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3117 t = objc_build_exc_ptr ();
3118 t = convert (TREE_TYPE (decl), t);
3119 t = build (MODIFY_EXPR, void_type_node, decl, t);
3123 /* Called just after parsing the closing brace of a @catch clause. Close
3124 the open binding level, and record a CATCH_EXPR for it. */
3127 objc_finish_catch_clause (void)
3129 tree c = cur_try_context->current_catch;
3130 cur_try_context->current_catch = NULL;
3131 cur_try_context->end_catch_locus = input_location;
3133 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3134 append_to_statement_list (c, &cur_try_context->catch_list);
3137 /* Called after parsing a @finally clause and its associated BODY.
3138 Record the body for later placement. */
3141 objc_build_finally_clause (location_t finally_locus, tree body)
3143 cur_try_context->finally_body = body;
3144 cur_try_context->finally_locus = finally_locus;
3145 cur_try_context->end_finally_locus = input_location;
3148 /* Called to finalize a @try construct. */
3151 objc_finish_try_stmt (void)
3153 struct objc_try_context *c = cur_try_context;
3156 if (c->catch_list == NULL && c->finally_body == NULL)
3157 error ("`@try' without `@catch' or `@finally'");
3159 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3160 if (flag_objc_sjlj_exceptions)
3162 if (!cur_try_context->finally_body)
3164 cur_try_context->finally_locus = input_location;
3165 cur_try_context->end_finally_locus = input_location;
3167 stmt = next_sjlj_build_try_catch_finally ();
3171 /* Otherwise, nest the CATCH inside a FINALLY. */
3175 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3176 annotate_with_locus (stmt, cur_try_context->try_locus);
3178 if (c->finally_body)
3180 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3181 annotate_with_locus (stmt, cur_try_context->try_locus);
3186 cur_try_context = c->outer;
3191 objc_build_throw_stmt (tree throw_expr)
3195 objc_init_exceptions ();
3197 if (throw_expr == NULL)
3199 /* If we're not inside a @catch block, there is no "current
3200 exception" to be rethrown. */
3201 if (cur_try_context == NULL
3202 || cur_try_context->current_catch == NULL)
3204 error ("%<@throw%> (rethrow) used outside of a @catch block");
3208 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3209 value that we get from the runtime. */
3210 throw_expr = objc_build_exc_ptr ();
3213 /* A throw is just a call to the runtime throw function with the
3214 object as a parameter. */
3215 args = tree_cons (NULL, throw_expr, NULL);
3216 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3220 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3224 /* First lock the mutex. */
3225 mutex = save_expr (mutex);
3226 args = tree_cons (NULL, mutex, NULL);
3227 call = build_function_call (objc_sync_enter_decl, args);
3228 annotate_with_locus (call, start_locus);
3231 /* Build the mutex unlock. */
3232 args = tree_cons (NULL, mutex, NULL);
3233 call = build_function_call (objc_sync_exit_decl, args);
3234 annotate_with_locus (call, input_location);
3236 /* Put the that and the body in a TRY_FINALLY. */
3237 objc_begin_try_stmt (start_locus, body);
3238 objc_build_finally_clause (input_location, call);
3239 objc_finish_try_stmt ();
3243 /* Predefine the following data type:
3245 struct _objc_exception_data
3251 /* The following yuckiness should prevent users from having to #include
3252 <setjmp.h> in their code... */
3254 #ifdef TARGET_POWERPC
3255 /* snarfed from /usr/include/ppc/setjmp.h */
3256 #define _JBLEN (26 + 36 + 129 + 1)
3258 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3263 build_next_objc_exception_stuff (void)
3265 tree field_decl, field_decl_chain, index, temp_type;
3267 /* Suppress outputting debug symbols, because
3268 dbxout_init hasn't been called yet. */
3269 enum debug_info_type save_write_symbols = write_symbols;
3270 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3272 write_symbols = NO_DEBUG;
3273 debug_hooks = &do_nothing_debug_hooks;
3275 objc_exception_data_template
3276 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3278 /* int buf[_JBLEN]; */
3280 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1, 0));
3281 field_decl = create_builtin_decl (FIELD_DECL,
3282 build_array_type (integer_type_node, index),
3284 field_decl_chain = field_decl;
3286 /* void *pointers[4]; */
3288 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1, 0));
3289 field_decl = create_builtin_decl (FIELD_DECL,
3290 build_array_type (ptr_type_node, index),
3292 chainon (field_decl_chain, field_decl);
3294 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3296 /* int _setjmp(...); */
3297 /* If the user includes <setjmp.h>, this shall be superseded by
3298 'int _setjmp(jmp_buf);' */
3299 temp_type = build_function_type (integer_type_node, NULL_TREE);
3301 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3303 /* id objc_exception_extract(struct _objc_exception_data *); */
3305 = build_function_type (objc_id_type,
3306 tree_cons (NULL_TREE,
3307 build_pointer_type (objc_exception_data_template),
3309 objc_exception_extract_decl
3310 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3311 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3312 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3314 = build_function_type (void_type_node,
3315 tree_cons (NULL_TREE,
3316 build_pointer_type (objc_exception_data_template),
3318 objc_exception_try_enter_decl
3319 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3320 objc_exception_try_exit_decl
3321 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3323 /* int objc_exception_match(id, id); */
3325 = build_function_type (integer_type_node,
3326 tree_cons (NULL_TREE, objc_id_type,
3327 tree_cons (NULL_TREE, objc_id_type,
3329 objc_exception_match_decl
3330 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3332 write_symbols = save_write_symbols;
3333 debug_hooks = save_hooks;
3337 build_objc_exception_stuff (void)
3339 tree noreturn_list, nothrow_list, temp_type;
3341 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3342 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3344 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3345 /* void objc_sync_enter(id); */
3346 /* void objc_sync_exit(id); */
3347 temp_type = build_function_type (void_type_node,
3348 tree_cons (NULL_TREE, objc_id_type,
3350 objc_exception_throw_decl
3351 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3353 objc_sync_enter_decl
3354 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3355 NULL, nothrow_list);
3357 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3358 NULL, nothrow_list);
3362 /* struct <classname> {
3363 struct objc_class *isa;
3368 build_private_template (tree class)
3372 if (CLASS_STATIC_TEMPLATE (class))
3374 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3375 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3379 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3380 ivar_context = get_class_ivars (class, 0);
3382 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3384 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3386 /* mark this record as class template - for class type checking */
3387 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3391 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3393 build1 (INDIRECT_REF, NULL_TREE,
3396 return ivar_context;
3399 /* Begin code generation for protocols... */
3401 /* struct objc_protocol {
3402 char *protocol_name;
3403 struct objc_protocol **protocol_list;
3404 struct objc_method_desc *instance_methods;
3405 struct objc_method_desc *class_methods;
3409 build_protocol_template (void)
3411 tree decl_specs, field_decl, field_decl_chain;
3414 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3416 /* struct objc_class *isa; */
3418 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3419 get_identifier (UTAG_CLASS)));
3420 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3421 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3422 field_decl_chain = field_decl;
3424 /* char *protocol_name; */
3426 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3428 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3429 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3430 chainon (field_decl_chain, field_decl);
3432 /* struct objc_protocol **protocol_list; */
3434 decl_specs = build_tree_list (NULL_TREE, template);
3436 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3437 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3438 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3439 chainon (field_decl_chain, field_decl);
3441 /* struct objc_method_list *instance_methods; */
3444 = build_tree_list (NULL_TREE,
3445 xref_tag (RECORD_TYPE,
3446 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3448 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3449 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3450 chainon (field_decl_chain, field_decl);
3452 /* struct objc_method_list *class_methods; */
3455 = build_tree_list (NULL_TREE,
3456 xref_tag (RECORD_TYPE,
3457 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3459 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3460 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3461 chainon (field_decl_chain, field_decl);
3463 return finish_struct (template, field_decl_chain, NULL_TREE);
3467 build_descriptor_table_initializer (tree type, tree entries)
3469 tree initlist = NULL_TREE;
3473 tree eltlist = NULL_TREE;
3476 = tree_cons (NULL_TREE,
3477 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3479 = tree_cons (NULL_TREE,
3480 add_objc_string (METHOD_ENCODING (entries),
3485 = tree_cons (NULL_TREE,
3486 objc_build_constructor (type, nreverse (eltlist)),
3489 entries = TREE_CHAIN (entries);
3493 return objc_build_constructor (build_array_type (type, 0),
3494 nreverse (initlist));
3497 /* struct objc_method_prototype_list {
3499 struct objc_method_prototype {
3506 build_method_prototype_list_template (tree list_type, int size)
3508 tree objc_ivar_list_record;
3509 tree decl_specs, field_decl, field_decl_chain;
3511 /* Generate an unnamed struct definition. */
3513 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3515 /* int method_count; */
3517 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3518 field_decl = get_identifier ("method_count");
3519 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3520 field_decl_chain = field_decl;
3522 /* struct objc_method method_list[]; */
3524 decl_specs = build_tree_list (NULL_TREE, list_type);
3525 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3526 build_int_cst (NULL_TREE, size, 0), NULL_TREE, NULL_TREE);
3527 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3528 chainon (field_decl_chain, field_decl);
3530 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3532 return objc_ivar_list_record;
3536 build_method_prototype_template (void)
3539 tree decl_specs, field_decl, field_decl_chain;
3542 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3544 /* struct objc_selector *_cmd; */
3545 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3546 get_identifier (TAG_SELECTOR)), NULL_TREE);
3547 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3548 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3549 field_decl_chain = field_decl;
3551 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3553 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3554 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3555 chainon (field_decl_chain, field_decl);
3557 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3559 return proto_record;
3563 objc_method_parm_type (tree type)
3565 type = groktypename (TREE_TYPE (type));
3566 if (TREE_CODE (type) == TYPE_DECL)
3567 type = TREE_TYPE (type);
3568 return TYPE_MAIN_VARIANT (type);
3572 objc_encoded_type_size (tree type)
3574 int sz = int_size_in_bytes (type);
3576 /* Make all integer and enum types at least as large
3578 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3579 || TREE_CODE (type) == BOOLEAN_TYPE
3580 || TREE_CODE (type) == ENUMERAL_TYPE))
3581 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3582 /* Treat arrays as pointers, since that's how they're
3584 else if (TREE_CODE (type) == ARRAY_TYPE)
3585 sz = int_size_in_bytes (ptr_type_node);
3590 encode_method_prototype (tree method_decl)
3597 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3598 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3600 /* Encode return type. */
3601 encode_type (objc_method_parm_type (method_decl),
3602 obstack_object_size (&util_obstack),
3603 OBJC_ENCODE_INLINE_DEFS);
3606 /* The first two arguments (self and _cmd) are pointers; account for
3608 i = int_size_in_bytes (ptr_type_node);
3609 parm_offset = 2 * i;
3610 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3611 parms = TREE_CHAIN (parms))
3613 tree type = objc_method_parm_type (parms);
3614 int sz = objc_encoded_type_size (type);
3616 /* If a type size is not known, bail out. */
3619 error ("%Jtype '%D' does not have a known size",
3621 /* Pretend that the encoding succeeded; the compilation will
3622 fail nevertheless. */
3623 goto finish_encoding;
3628 sprintf (buf, "%d@0:%d", parm_offset, i);
3629 obstack_grow (&util_obstack, buf, strlen (buf));
3631 /* Argument types. */
3632 parm_offset = 2 * i;
3633 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3634 parms = TREE_CHAIN (parms))
3636 tree type = objc_method_parm_type (parms);
3638 /* Process argument qualifiers for user supplied arguments. */
3639 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3642 encode_type (type, obstack_object_size (&util_obstack),
3643 OBJC_ENCODE_INLINE_DEFS);
3645 /* Compute offset. */
3646 sprintf (buf, "%d", parm_offset);
3647 parm_offset += objc_encoded_type_size (type);
3649 obstack_grow (&util_obstack, buf, strlen (buf));
3653 obstack_1grow (&util_obstack, '\0');
3654 result = get_identifier (obstack_finish (&util_obstack));
3655 obstack_free (&util_obstack, util_firstobj);
3660 generate_descriptor_table (tree type, const char *name, int size, tree list,
3663 tree sc_spec, decl_specs, decl, initlist;
3665 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3666 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3668 decl = start_decl (synth_id_with_class_suffix (name, proto),
3669 decl_specs, 1, NULL_TREE);
3670 DECL_CONTEXT (decl) = NULL_TREE;
3672 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size, 0));
3673 initlist = tree_cons (NULL_TREE, list, initlist);
3675 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3682 generate_method_descriptors (tree protocol)
3684 tree initlist, chain, method_list_template;
3685 tree cast, variable_length_type;
3688 if (!objc_method_prototype_template)
3689 objc_method_prototype_template = build_method_prototype_template ();
3691 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3692 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3694 variable_length_type = groktypename (cast);
3696 chain = PROTOCOL_CLS_METHODS (protocol);
3699 size = list_length (chain);
3701 method_list_template
3702 = build_method_prototype_list_template (objc_method_prototype_template,
3706 = build_descriptor_table_initializer (objc_method_prototype_template,
3709 UOBJC_CLASS_METHODS_decl
3710 = generate_descriptor_table (method_list_template,
3711 "_OBJC_PROTOCOL_CLASS_METHODS",
3712 size, initlist, protocol);
3713 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3716 UOBJC_CLASS_METHODS_decl = 0;
3718 chain = PROTOCOL_NST_METHODS (protocol);
3721 size = list_length (chain);
3723 method_list_template
3724 = build_method_prototype_list_template (objc_method_prototype_template,
3727 = build_descriptor_table_initializer (objc_method_prototype_template,
3730 UOBJC_INSTANCE_METHODS_decl
3731 = generate_descriptor_table (method_list_template,
3732 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3733 size, initlist, protocol);
3734 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3737 UOBJC_INSTANCE_METHODS_decl = 0;
3741 generate_protocol_references (tree plist)
3745 /* Forward declare protocols referenced. */
3746 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3748 tree proto = TREE_VALUE (lproto);
3750 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3751 && PROTOCOL_NAME (proto))
3753 if (! PROTOCOL_FORWARD_DECL (proto))
3754 build_protocol_reference (proto);
3756 if (PROTOCOL_LIST (proto))
3757 generate_protocol_references (PROTOCOL_LIST (proto));
3762 /* For each protocol which was referenced either from a @protocol()
3763 expression, or because a class/category implements it (then a
3764 pointer to the protocol is stored in the struct describing the
3765 class/category), we create a statically allocated instance of the
3766 Protocol class. The code is written in such a way as to generate
3767 as few Protocol objects as possible; we generate a unique Protocol
3768 instance for each protocol, and we don't generate a Protocol
3769 instance if the protocol is never referenced (either from a
3770 @protocol() or from a class/category implementation). These
3771 statically allocated objects can be referred to via the static
3772 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3774 The statically allocated Protocol objects that we generate here
3775 need to be fixed up at runtime in order to be used: the 'isa'
3776 pointer of the objects need to be set up to point to the 'Protocol'
3777 class, as known at runtime.
3779 The NeXT runtime fixes up all protocols at program startup time,
3780 before main() is entered. It uses a low-level trick to look up all
3781 those symbols, then loops on them and fixes them up.
3783 The GNU runtime as well fixes up all protocols before user code
3784 from the module is executed; it requires pointers to those symbols
3785 to be put in the objc_symtab (which is then passed as argument to
3786 the function __objc_exec_class() which the compiler sets up to be
3787 executed automatically when the module is loaded); setup of those
3788 Protocol objects happen in two ways in the GNU runtime: all
3789 Protocol objects referred to by a class or category implementation
3790 are fixed up when the class/category is loaded; all Protocol
3791 objects referred to by a @protocol() expression are added by the
3792 compiler to the list of statically allocated instances to fixup
3793 (the same list holding the statically allocated constant string
3794 objects). Because, as explained above, the compiler generates as
3795 few Protocol objects as possible, some Protocol object might end up
3796 being referenced multiple times when compiled with the GNU runtime,
3797 and end up being fixed up multiple times at runtime inizialization.
3798 But that doesn't hurt, it's just a little inefficient. */
3801 generate_protocols (void)
3804 tree sc_spec, decl_specs, decl;
3805 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3808 if (! objc_protocol_template)
3809 objc_protocol_template = build_protocol_template ();
3811 /* If a protocol was directly referenced, pull in indirect references. */
3812 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3813 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3814 generate_protocol_references (PROTOCOL_LIST (p));
3816 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3818 tree nst_methods = PROTOCOL_NST_METHODS (p);
3819 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3821 /* If protocol wasn't referenced, don't generate any code. */
3822 if (! PROTOCOL_FORWARD_DECL (p))
3825 /* Make sure we link in the Protocol class. */
3826 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3830 if (! METHOD_ENCODING (nst_methods))
3832 encoding = encode_method_prototype (nst_methods);
3833 METHOD_ENCODING (nst_methods) = encoding;
3835 nst_methods = TREE_CHAIN (nst_methods);
3840 if (! METHOD_ENCODING (cls_methods))
3842 encoding = encode_method_prototype (cls_methods);
3843 METHOD_ENCODING (cls_methods) = encoding;
3846 cls_methods = TREE_CHAIN (cls_methods);
3848 generate_method_descriptors (p);
3850 if (PROTOCOL_LIST (p))
3851 refs_decl = generate_protocol_list (p);
3855 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3857 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3859 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3861 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3862 decl_specs, 1, NULL_TREE);
3864 DECL_CONTEXT (decl) = NULL_TREE;
3866 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3872 (build_tree_list (build_tree_list (NULL_TREE,
3873 objc_protocol_template),
3874 build1 (INDIRECT_REF, NULL_TREE,
3875 build1 (INDIRECT_REF, NULL_TREE,
3878 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3879 TREE_TYPE (refs_expr) = cast_type2;
3882 refs_expr = build_int_cst (NULL_TREE, 0, 0);
3884 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3885 by generate_method_descriptors, which is called above. */
3886 initlist = build_protocol_initializer (TREE_TYPE (decl),
3887 protocol_name_expr, refs_expr,
3888 UOBJC_INSTANCE_METHODS_decl,
3889 UOBJC_CLASS_METHODS_decl);
3890 finish_decl (decl, initlist, NULL_TREE);
3892 /* Mark the decl as used to avoid "defined but not used" warning. */
3893 TREE_USED (decl) = 1;
3898 build_protocol_initializer (tree type, tree protocol_name,
3899 tree protocol_list, tree instance_methods,
3902 tree initlist = NULL_TREE, expr;
3905 cast_type = groktypename
3907 (build_tree_list (NULL_TREE,
3908 xref_tag (RECORD_TYPE,
3909 get_identifier (UTAG_CLASS))),
3910 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3912 /* Filling the "isa" in with one allows the runtime system to
3913 detect that the version change...should remove before final release. */
3915 expr = build_int_cst (NULL_TREE, PROTOCOL_VERSION, 0);
3916 TREE_TYPE (expr) = cast_type;
3917 initlist = tree_cons (NULL_TREE, expr, initlist);
3918 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3919 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3921 if (!instance_methods)
3922 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
3925 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3926 initlist = tree_cons (NULL_TREE, expr, initlist);
3930 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
3933 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3934 initlist = tree_cons (NULL_TREE, expr, initlist);
3937 return objc_build_constructor (type, nreverse (initlist));
3940 /* struct objc_category {
3941 char *category_name;
3943 struct objc_method_list *instance_methods;
3944 struct objc_method_list *class_methods;
3945 struct objc_protocol_list *protocols;
3949 build_category_template (void)
3951 tree decl_specs, field_decl, field_decl_chain;
3953 objc_category_template = start_struct (RECORD_TYPE,
3954 get_identifier (UTAG_CATEGORY));
3955 /* char *category_name; */
3957 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3959 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3960 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3961 field_decl_chain = field_decl;
3963 /* char *class_name; */
3965 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3966 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3967 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3968 chainon (field_decl_chain, field_decl);
3970 /* struct objc_method_list *instance_methods; */
3972 decl_specs = build_tree_list (NULL_TREE,
3973 xref_tag (RECORD_TYPE,
3974 get_identifier (UTAG_METHOD_LIST)));
3976 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3977 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3978 chainon (field_decl_chain, field_decl);
3980 /* struct objc_method_list *class_methods; */
3982 decl_specs = build_tree_list (NULL_TREE,
3983 xref_tag (RECORD_TYPE,
3984 get_identifier (UTAG_METHOD_LIST)));
3986 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3987 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3988 chainon (field_decl_chain, field_decl);
3990 /* struct objc_protocol **protocol_list; */
3992 decl_specs = build_tree_list (NULL_TREE,
3993 xref_tag (RECORD_TYPE,
3994 get_identifier (UTAG_PROTOCOL)));
3996 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3997 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3998 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3999 chainon (field_decl_chain, field_decl);
4001 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4004 /* struct objc_selector {
4010 build_selector_template (void)
4013 tree decl_specs, field_decl, field_decl_chain;
4015 objc_selector_template
4016 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4020 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4021 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4022 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4023 field_decl_chain = field_decl;
4025 /* char *sel_type; */
4027 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4028 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4029 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4030 chainon (field_decl_chain, field_decl);
4032 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4035 /* struct objc_class {
4036 struct objc_class *isa;
4037 struct objc_class *super_class;
4042 struct objc_ivar_list *ivars;
4043 struct objc_method_list *methods;
4044 if (flag_next_runtime)
4045 struct objc_cache *cache;
4047 struct sarray *dtable;
4048 struct objc_class *subclass_list;
4049 struct objc_class *sibling_class;
4051 struct objc_protocol_list *protocols;
4052 if (flag_next_runtime)
4054 void *gc_object_type;
4057 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4058 the NeXT/Apple runtime; still, the compiler must generate them to
4059 maintain backward binary compatibility (and to allow for future
4063 build_class_template (void)
4065 tree decl_specs, field_decl, field_decl_chain;
4068 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4070 /* struct objc_class *isa; */
4072 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4073 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4074 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4075 field_decl_chain = field_decl;
4077 /* struct objc_class *super_class; */
4079 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4081 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4082 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4083 chainon (field_decl_chain, field_decl);
4087 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4088 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4089 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4090 chainon (field_decl_chain, field_decl);
4094 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4095 field_decl = get_identifier ("version");
4096 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4097 chainon (field_decl_chain, field_decl);
4101 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4102 field_decl = get_identifier ("info");
4103 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4104 chainon (field_decl_chain, field_decl);
4106 /* long instance_size; */
4108 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4109 field_decl = get_identifier ("instance_size");
4110 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4111 chainon (field_decl_chain, field_decl);
4113 /* struct objc_ivar_list *ivars; */
4115 decl_specs = build_tree_list (NULL_TREE,
4116 xref_tag (RECORD_TYPE,
4117 get_identifier (UTAG_IVAR_LIST)));
4118 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4119 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4120 chainon (field_decl_chain, field_decl);
4122 /* struct objc_method_list *methods; */
4124 decl_specs = build_tree_list (NULL_TREE,
4125 xref_tag (RECORD_TYPE,
4126 get_identifier (UTAG_METHOD_LIST)));
4127 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4128 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4129 chainon (field_decl_chain, field_decl);
4131 if (flag_next_runtime)
4133 /* struct objc_cache *cache; */
4135 decl_specs = build_tree_list (NULL_TREE,
4136 xref_tag (RECORD_TYPE,
4137 get_identifier ("objc_cache")));
4138 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4139 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4140 chainon (field_decl_chain, field_decl);
4144 /* struct sarray *dtable; */
4146 decl_specs = build_tree_list (NULL_TREE,
4147 xref_tag (RECORD_TYPE,
4148 get_identifier ("sarray")));
4149 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4150 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4151 chainon (field_decl_chain, field_decl);
4153 /* struct objc_class *subclass_list; */
4155 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4157 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4158 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4159 chainon (field_decl_chain, field_decl);
4161 /* struct objc_class *sibling_class; */
4163 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4165 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4166 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4167 chainon (field_decl_chain, field_decl);
4170 /* struct objc_protocol **protocol_list; */
4172 decl_specs = build_tree_list (NULL_TREE,
4173 xref_tag (RECORD_TYPE,
4174 get_identifier (UTAG_PROTOCOL)));
4176 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4178 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4179 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4180 chainon (field_decl_chain, field_decl);
4182 if (flag_next_runtime)
4186 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4187 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4189 = grokfield (field_decl, decl_specs, NULL_TREE);
4190 chainon (field_decl_chain, field_decl);
4193 /* void *gc_object_type; */
4195 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4196 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4197 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4198 chainon (field_decl_chain, field_decl);
4200 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4203 /* Generate appropriate forward declarations for an implementation. */
4206 synth_forward_declarations (void)
4210 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4211 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4212 objc_class_template);
4214 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4215 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4216 objc_class_template);
4218 mark_decl_referenced (UOBJC_CLASS_decl);
4219 mark_decl_referenced (UOBJC_METACLASS_decl);
4221 /* Pre-build the following entities - for speed/convenience. */
4223 an_id = get_identifier ("super_class");
4224 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4225 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4229 error_with_ivar (const char *message, tree decl, tree rawdecl)
4231 error ("%J%s `%s'", decl,
4232 message, gen_declaration (rawdecl, errbuf));
4237 check_ivars (tree inter, tree imp)
4239 tree intdecls = CLASS_IVARS (inter);
4240 tree impdecls = CLASS_IVARS (imp);
4241 tree rawintdecls = CLASS_RAW_IVARS (inter);
4242 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4249 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4250 intdecls = TREE_CHAIN (intdecls);
4252 if (intdecls == 0 && impdecls == 0)
4254 if (intdecls == 0 || impdecls == 0)
4256 error ("inconsistent instance variable specification");
4260 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4262 if (TREE_VALUE (TREE_VALUE (rawimpdecls)))
4264 /* t1 is the bit-field type, so t2 must be converted to the
4265 bit-field type for comparison as well. */
4266 unsigned HOST_WIDE_INT width
4267 = tree_low_cst (TREE_VALUE (TREE_VALUE (rawimpdecls)), 1);
4268 if (width != TYPE_PRECISION (t2))
4269 t2 = build_nonstandard_integer_type (width, TYPE_UNSIGNED (t2));
4272 if (!comptypes (t1, t2)
4273 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4274 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4276 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4278 error_with_ivar ("conflicting instance variable type",
4279 impdecls, rawimpdecls);
4280 error_with_ivar ("previous declaration of",
4281 intdecls, rawintdecls);
4283 else /* both the type and the name don't match */
4285 error ("inconsistent instance variable specification");
4290 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4292 error_with_ivar ("conflicting instance variable name",
4293 impdecls, rawimpdecls);
4294 error_with_ivar ("previous declaration of",
4295 intdecls, rawintdecls);
4298 intdecls = TREE_CHAIN (intdecls);
4299 impdecls = TREE_CHAIN (impdecls);
4300 rawintdecls = TREE_CHAIN (rawintdecls);
4301 rawimpdecls = TREE_CHAIN (rawimpdecls);
4305 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4306 This needs to be done just once per compilation. */
4309 build_super_template (void)
4311 tree decl_specs, field_decl, field_decl_chain;
4313 /* Suppress outputting debug symbols, because
4314 dbxout_init hasn't been called yet. */
4315 enum debug_info_type save_write_symbols = write_symbols;
4316 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4318 write_symbols = NO_DEBUG;
4319 debug_hooks = &do_nothing_debug_hooks;
4321 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4323 /* struct objc_object *self; */
4325 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4326 field_decl = get_identifier ("self");
4327 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4328 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4329 field_decl_chain = field_decl;
4332 /* struct objc_class *super_class; */
4334 /* struct objc_class *class; */
4337 decl_specs = get_identifier (UTAG_CLASS);
4338 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4340 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4342 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4345 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4346 chainon (field_decl_chain, field_decl);
4348 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4350 write_symbols = save_write_symbols;
4351 debug_hooks = save_hooks;
4354 /* struct objc_ivar {
4361 build_ivar_template (void)
4363 tree objc_ivar_id, objc_ivar_record;
4364 tree decl_specs, field_decl, field_decl_chain;
4366 objc_ivar_id = get_identifier (UTAG_IVAR);
4367 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4369 /* char *ivar_name; */
4371 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4372 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4374 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4375 field_decl_chain = field_decl;
4377 /* char *ivar_type; */
4379 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4380 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4382 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4383 chainon (field_decl_chain, field_decl);
4385 /* int ivar_offset; */
4387 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4388 field_decl = get_identifier ("ivar_offset");
4390 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4391 chainon (field_decl_chain, field_decl);
4393 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4395 return objc_ivar_record;
4400 struct objc_ivar ivar_list[ivar_count];
4404 build_ivar_list_template (tree list_type, int size)
4406 tree objc_ivar_list_record;
4407 tree decl_specs, field_decl, field_decl_chain;
4409 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4411 /* int ivar_count; */
4413 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4414 field_decl = get_identifier ("ivar_count");
4416 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4417 field_decl_chain = field_decl;
4419 /* struct objc_ivar ivar_list[]; */
4421 decl_specs = build_tree_list (NULL_TREE, list_type);
4422 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4423 build_int_cst (NULL_TREE, size, 0), NULL_TREE, NULL_TREE);
4425 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4426 chainon (field_decl_chain, field_decl);
4428 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4430 return objc_ivar_list_record;
4436 struct objc_method method_list[method_count];
4440 build_method_list_template (tree list_type, int size)
4442 tree objc_ivar_list_record;
4443 tree decl_specs, field_decl, field_decl_chain;
4445 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4447 /* int method_next; */
4452 xref_tag (RECORD_TYPE,
4453 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4455 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4456 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4457 field_decl_chain = field_decl;
4459 /* int method_count; */
4461 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4462 field_decl = get_identifier ("method_count");
4464 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4465 chainon (field_decl_chain, field_decl);
4467 /* struct objc_method method_list[]; */
4469 decl_specs = build_tree_list (NULL_TREE, list_type);
4470 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4471 build_int_cst (NULL_TREE, size, 0), NULL_TREE, NULL_TREE);
4473 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4474 chainon (field_decl_chain, field_decl);
4476 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4478 return objc_ivar_list_record;
4482 build_ivar_list_initializer (tree type, tree field_decl)
4484 tree initlist = NULL_TREE;
4488 tree ivar = NULL_TREE;
4491 if (DECL_NAME (field_decl))
4492 ivar = tree_cons (NULL_TREE,
4493 add_objc_string (DECL_NAME (field_decl),
4497 /* Unnamed bit-field ivar (yuck). */
4498 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), ivar);
4501 encode_field_decl (field_decl,
4502 obstack_object_size (&util_obstack),
4503 OBJC_ENCODE_DONT_INLINE_DEFS);
4505 /* Null terminate string. */
4506 obstack_1grow (&util_obstack, 0);
4510 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4513 obstack_free (&util_obstack, util_firstobj);
4516 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4517 initlist = tree_cons (NULL_TREE,
4518 objc_build_constructor (type, nreverse (ivar)),
4521 field_decl = TREE_CHAIN (field_decl);
4522 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4526 return objc_build_constructor (build_array_type (type, 0),
4527 nreverse (initlist));
4531 generate_ivars_list (tree type, const char *name, int size, tree list)
4533 tree sc_spec, decl_specs, decl, initlist;
4535 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4536 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4538 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4539 decl_specs, 1, NULL_TREE);
4541 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size, 0));
4542 initlist = tree_cons (NULL_TREE, list, initlist);
4545 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4551 /* Count only the fields occurring in T. */
4553 ivar_list_length (tree t)
4557 for (; t; t = TREE_CHAIN (t))
4558 if (TREE_CODE (t) == FIELD_DECL)
4565 generate_ivar_lists (void)
4567 tree initlist, ivar_list_template, chain;
4568 tree cast, variable_length_type;
4571 generating_instance_variables = 1;
4573 if (!objc_ivar_template)
4574 objc_ivar_template = build_ivar_template ();
4578 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4579 get_identifier (UTAG_IVAR_LIST))),
4581 variable_length_type = groktypename (cast);
4583 /* Only generate class variables for the root of the inheritance
4584 hierarchy since these will be the same for every class. */
4586 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4587 && (chain = TYPE_FIELDS (objc_class_template)))
4589 size = ivar_list_length (chain);
4591 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4592 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4594 UOBJC_CLASS_VARIABLES_decl
4595 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4597 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4600 UOBJC_CLASS_VARIABLES_decl = 0;
4602 chain = CLASS_IVARS (implementation_template);
4605 size = ivar_list_length (chain);
4606 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4607 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4609 UOBJC_INSTANCE_VARIABLES_decl
4610 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4612 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4615 UOBJC_INSTANCE_VARIABLES_decl = 0;
4617 generating_instance_variables = 0;
4621 build_dispatch_table_initializer (tree type, tree entries)
4623 tree initlist = NULL_TREE;
4627 tree elemlist = NULL_TREE;
4629 elemlist = tree_cons (NULL_TREE,
4630 build_selector (METHOD_SEL_NAME (entries)),
4633 /* Generate the method encoding if we don't have one already. */
4634 if (! METHOD_ENCODING (entries))
4635 METHOD_ENCODING (entries) =
4636 encode_method_prototype (entries);
4638 elemlist = tree_cons (NULL_TREE,
4639 add_objc_string (METHOD_ENCODING (entries),
4643 elemlist = tree_cons (NULL_TREE,
4644 build_unary_op (ADDR_EXPR,
4645 METHOD_DEFINITION (entries), 1),
4648 initlist = tree_cons (NULL_TREE,
4649 objc_build_constructor (type, nreverse (elemlist)),
4652 entries = TREE_CHAIN (entries);
4656 return objc_build_constructor (build_array_type (type, 0),
4657 nreverse (initlist));
4660 /* To accomplish method prototyping without generating all kinds of
4661 inane warnings, the definition of the dispatch table entries were
4664 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4666 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4669 build_method_template (void)
4672 tree decl_specs, field_decl, field_decl_chain;
4674 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4676 /* struct objc_selector *_cmd; */
4677 decl_specs = tree_cons (NULL_TREE,
4678 xref_tag (RECORD_TYPE,
4679 get_identifier (TAG_SELECTOR)),
4681 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4683 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4684 field_decl_chain = field_decl;
4686 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4687 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4688 get_identifier ("method_types"));
4689 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4690 chainon (field_decl_chain, field_decl);
4694 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4695 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4696 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4697 chainon (field_decl_chain, field_decl);
4699 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4706 generate_dispatch_table (tree type, const char *name, int size, tree list)
4708 tree sc_spec, decl_specs, decl, initlist;
4710 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4711 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4713 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4714 decl_specs, 1, NULL_TREE);
4716 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0, 0));
4717 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size, 0), initlist);
4718 initlist = tree_cons (NULL_TREE, list, initlist);
4721 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4728 mark_referenced_methods (void)
4730 struct imp_entry *impent;
4733 for (impent = imp_list; impent; impent = impent->next)
4735 chain = CLASS_CLS_METHODS (impent->imp_context);
4738 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4739 chain = TREE_CHAIN (chain);
4742 chain = CLASS_NST_METHODS (impent->imp_context);
4745 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4746 chain = TREE_CHAIN (chain);
4752 generate_dispatch_tables (void)
4754 tree initlist, chain, method_list_template;
4755 tree cast, variable_length_type;
4758 if (!objc_method_template)
4759 objc_method_template = build_method_template ();
4763 (build_tree_list (NULL_TREE,
4764 xref_tag (RECORD_TYPE,
4765 get_identifier (UTAG_METHOD_LIST))),
4768 variable_length_type = groktypename (cast);
4770 chain = CLASS_CLS_METHODS (objc_implementation_context);
4773 size = list_length (chain);
4775 method_list_template
4776 = build_method_list_template (objc_method_template, size);
4778 = build_dispatch_table_initializer (objc_method_template, chain);
4780 UOBJC_CLASS_METHODS_decl
4781 = generate_dispatch_table (method_list_template,
4782 ((TREE_CODE (objc_implementation_context)
4783 == CLASS_IMPLEMENTATION_TYPE)
4784 ? "_OBJC_CLASS_METHODS"
4785 : "_OBJC_CATEGORY_CLASS_METHODS"),
4787 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4790 UOBJC_CLASS_METHODS_decl = 0;
4792 chain = CLASS_NST_METHODS (objc_implementation_context);
4795 size = list_length (chain);
4797 method_list_template
4798 = build_method_list_template (objc_method_template, size);
4800 = build_dispatch_table_initializer (objc_method_template, chain);
4802 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4803 UOBJC_INSTANCE_METHODS_decl
4804 = generate_dispatch_table (method_list_template,
4805 "_OBJC_INSTANCE_METHODS",
4808 /* We have a category. */
4809 UOBJC_INSTANCE_METHODS_decl
4810 = generate_dispatch_table (method_list_template,
4811 "_OBJC_CATEGORY_INSTANCE_METHODS",
4813 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4816 UOBJC_INSTANCE_METHODS_decl = 0;
4820 generate_protocol_list (tree i_or_p)
4822 tree initlist, decl_specs, sc_spec;
4823 tree refs_decl, expr_decl, lproto, e, plist;
4827 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4828 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4829 plist = CLASS_PROTOCOL_LIST (i_or_p);
4830 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4831 plist = PROTOCOL_LIST (i_or_p);
4835 cast_type = groktypename
4837 (build_tree_list (NULL_TREE,
4838 xref_tag (RECORD_TYPE,
4839 get_identifier (UTAG_PROTOCOL))),
4840 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4843 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4844 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4845 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4848 /* Build initializer. */
4849 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), NULL_TREE);
4851 e = build_int_cst (NULL_TREE, size, 0);
4852 TREE_TYPE (e) = cast_type;
4853 initlist = tree_cons (NULL_TREE, e, initlist);
4855 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4857 tree pval = TREE_VALUE (lproto);
4859 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4860 && PROTOCOL_FORWARD_DECL (pval))
4862 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4863 initlist = tree_cons (NULL_TREE, e, initlist);
4867 /* static struct objc_protocol *refs[n]; */
4869 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4870 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4871 get_identifier (UTAG_PROTOCOL)),
4874 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4875 expr_decl = build_nt (ARRAY_REF,
4876 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4878 build_int_cst (NULL_TREE, size + 2, 0), NULL_TREE, NULL_TREE);
4879 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4880 expr_decl = build_nt (ARRAY_REF,
4881 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4883 build_int_cst (NULL_TREE, size + 2, 0), NULL_TREE, NULL_TREE);
4884 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4886 = build_nt (ARRAY_REF,
4887 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4889 build_int_cst (NULL_TREE, size + 2, 0), NULL_TREE, NULL_TREE);
4893 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4895 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4896 DECL_CONTEXT (refs_decl) = NULL_TREE;
4898 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4899 nreverse (initlist)),
4906 build_category_initializer (tree type, tree cat_name, tree class_name,
4907 tree instance_methods, tree class_methods,
4910 tree initlist = NULL_TREE, expr;
4912 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4913 initlist = tree_cons (NULL_TREE, class_name, initlist);
4915 if (!instance_methods)
4916 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
4919 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4920 initlist = tree_cons (NULL_TREE, expr, initlist);
4923 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
4926 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4927 initlist = tree_cons (NULL_TREE, expr, initlist);
4930 /* protocol_list = */
4932 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
4935 tree cast_type2 = groktypename
4937 (build_tree_list (NULL_TREE,
4938 xref_tag (RECORD_TYPE,
4939 get_identifier (UTAG_PROTOCOL))),
4940 build1 (INDIRECT_REF, NULL_TREE,
4941 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4943 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4944 TREE_TYPE (expr) = cast_type2;
4945 initlist = tree_cons (NULL_TREE, expr, initlist);
4948 return objc_build_constructor (type, nreverse (initlist));
4951 /* struct objc_class {
4952 struct objc_class *isa;
4953 struct objc_class *super_class;
4958 struct objc_ivar_list *ivars;
4959 struct objc_method_list *methods;
4960 if (flag_next_runtime)
4961 struct objc_cache *cache;
4963 struct sarray *dtable;
4964 struct objc_class *subclass_list;
4965 struct objc_class *sibling_class;
4967 struct objc_protocol_list *protocols;
4968 if (flag_next_runtime)
4970 void *gc_object_type;
4974 build_shared_structure_initializer (tree type, tree isa, tree super,
4975 tree name, tree size, int status,
4976 tree dispatch_table, tree ivar_list,
4979 tree initlist = NULL_TREE, expr;
4982 initlist = tree_cons (NULL_TREE, isa, initlist);
4985 initlist = tree_cons (NULL_TREE, super, initlist);
4988 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4991 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
4994 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, status, 0), initlist);
4996 /* instance_size = */
4997 initlist = tree_cons (NULL_TREE, size, initlist);
4999 /* objc_ivar_list = */
5001 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5004 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
5005 initlist = tree_cons (NULL_TREE, expr, initlist);
5008 /* objc_method_list = */
5009 if (!dispatch_table)
5010 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5013 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
5014 initlist = tree_cons (NULL_TREE, expr, initlist);
5017 if (flag_next_runtime)
5018 /* method_cache = */
5019 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5023 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5025 /* subclass_list = */
5026 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5028 /* sibling_class = */
5029 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5032 /* protocol_list = */
5033 if (! protocol_list)
5034 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5040 (build_tree_list (NULL_TREE,
5041 xref_tag (RECORD_TYPE,
5042 get_identifier (UTAG_PROTOCOL))),
5043 build1 (INDIRECT_REF, NULL_TREE,
5044 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5046 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5047 TREE_TYPE (expr) = cast_type2;
5048 initlist = tree_cons (NULL_TREE, expr, initlist);
5051 if (flag_next_runtime)
5053 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5055 /* gc_object_type = NULL */
5056 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), initlist);
5058 return objc_build_constructor (type, nreverse (initlist));
5061 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5064 lookup_category (tree class, tree cat_name)
5066 tree category = CLASS_CATEGORY_LIST (class);
5068 while (category && CLASS_SUPER_NAME (category) != cat_name)
5069 category = CLASS_CATEGORY_LIST (category);
5073 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5076 generate_category (tree cat)
5078 tree sc_spec, decl_specs, decl;
5079 tree initlist, cat_name_expr, class_name_expr;
5080 tree protocol_decl, category;
5082 add_class_reference (CLASS_NAME (cat));
5083 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5085 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5087 category = lookup_category (implementation_template,
5088 CLASS_SUPER_NAME (cat));
5090 if (category && CLASS_PROTOCOL_LIST (category))
5092 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5093 protocol_decl = generate_protocol_list (category);
5098 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5099 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5101 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5102 objc_implementation_context),
5103 decl_specs, 1, NULL_TREE);
5105 initlist = build_category_initializer (TREE_TYPE (decl),
5106 cat_name_expr, class_name_expr,
5107 UOBJC_INSTANCE_METHODS_decl,
5108 UOBJC_CLASS_METHODS_decl,
5111 finish_decl (decl, initlist, NULL_TREE);
5114 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5115 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5118 generate_shared_structures (void)
5120 tree sc_spec, decl_specs, decl;
5121 tree name_expr, super_expr, root_expr;
5122 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5123 tree cast_type, initlist, protocol_decl;
5125 my_super_id = CLASS_SUPER_NAME (implementation_template);
5128 add_class_reference (my_super_id);
5130 /* Compute "my_root_id" - this is required for code generation.
5131 the "isa" for all meta class structures points to the root of
5132 the inheritance hierarchy (e.g. "__Object")... */
5133 my_root_id = my_super_id;
5136 tree my_root_int = lookup_interface (my_root_id);
5138 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5139 my_root_id = CLASS_SUPER_NAME (my_root_int);
5146 /* No super class. */
5147 my_root_id = CLASS_NAME (implementation_template);
5150 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5151 objc_class_template),
5152 build1 (INDIRECT_REF,
5153 NULL_TREE, NULL_TREE)));
5155 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5158 /* Install class `isa' and `super' pointers at runtime. */
5161 super_expr = add_objc_string (my_super_id, class_names);
5162 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5165 super_expr = build_int_cst (NULL_TREE, 0, 0);
5167 root_expr = add_objc_string (my_root_id, class_names);
5168 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5170 if (CLASS_PROTOCOL_LIST (implementation_template))
5172 generate_protocol_references
5173 (CLASS_PROTOCOL_LIST (implementation_template));
5174 protocol_decl = generate_protocol_list (implementation_template);
5179 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5181 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5182 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5184 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5188 = build_shared_structure_initializer
5190 root_expr, super_expr, name_expr,
5191 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5193 UOBJC_CLASS_METHODS_decl,
5194 UOBJC_CLASS_VARIABLES_decl,
5197 finish_decl (decl, initlist, NULL_TREE);
5199 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5201 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5205 = build_shared_structure_initializer
5207 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5208 super_expr, name_expr,
5209 convert (integer_type_node,
5210 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5211 (implementation_template))),
5213 UOBJC_INSTANCE_METHODS_decl,
5214 UOBJC_INSTANCE_VARIABLES_decl,
5217 finish_decl (decl, initlist, NULL_TREE);
5221 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5224 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5225 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5227 const char *const class_name
5228 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5229 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5230 sprintf (string, "%s_%s", preamble,
5231 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5233 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5234 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5236 /* We have a category. */
5237 const char *const class_name
5238 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5239 const char *const class_super_name
5240 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5241 string = (char *) alloca (strlen (preamble)
5242 + strlen (class_name)
5243 + strlen (class_super_name)
5245 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5247 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5249 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5251 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5252 sprintf (string, "%s_%s", preamble, protocol_name);
5257 return get_identifier (string);
5261 is_objc_type_qualifier (tree node)
5263 return (TREE_CODE (node) == IDENTIFIER_NODE
5264 && (node == ridpointers [(int) RID_CONST]
5265 || node == ridpointers [(int) RID_VOLATILE]
5266 || node == ridpointers [(int) RID_IN]
5267 || node == ridpointers [(int) RID_OUT]
5268 || node == ridpointers [(int) RID_INOUT]
5269 || node == ridpointers [(int) RID_BYCOPY]
5270 || node == ridpointers [(int) RID_BYREF]
5271 || node == ridpointers [(int) RID_ONEWAY]));
5274 /* If type is empty or only type qualifiers are present, add default
5275 type of id (otherwise grokdeclarator will default to int). */
5278 adjust_type_for_id_default (tree type)
5280 tree declspecs, chain;
5283 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5284 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5286 declspecs = TREE_PURPOSE (type);
5288 /* Determine if a typespec is present. */
5289 for (chain = declspecs;
5291 chain = TREE_CHAIN (chain))
5293 if (TYPED_OBJECT (TREE_VALUE (chain))
5294 && !(TREE_VALUE (type)
5295 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5296 error ("can not use an object as parameter to a method\n");
5297 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5301 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5303 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5308 selector ':' '(' typename ')' identifier
5311 Transform an Objective-C keyword argument into
5312 the C equivalent parameter declarator.
5314 In: key_name, an "identifier_node" (optional).
5315 arg_type, a "tree_list" (optional).
5316 arg_name, an "identifier_node".
5318 Note: It would be really nice to strongly type the preceding
5319 arguments in the function prototype; however, then I
5320 could not use the "accessor" macros defined in "tree.h".
5322 Out: an instance of "keyword_decl". */
5325 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5329 /* If no type is specified, default to "id". */
5330 arg_type = adjust_type_for_id_default (arg_type);
5332 keyword_decl = make_node (KEYWORD_DECL);
5334 TREE_TYPE (keyword_decl) = arg_type;
5335 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5336 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5338 return keyword_decl;
5341 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5344 build_keyword_selector (tree selector)
5347 tree key_chain, key_name;
5350 /* Scan the selector to see how much space we'll need. */
5351 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5353 if (TREE_CODE (selector) == KEYWORD_DECL)
5354 key_name = KEYWORD_KEY_NAME (key_chain);
5355 else if (TREE_CODE (selector) == TREE_LIST)
5356 key_name = TREE_PURPOSE (key_chain);
5361 len += IDENTIFIER_LENGTH (key_name) + 1;
5363 /* Just a ':' arg. */
5367 buf = (char *) alloca (len + 1);
5368 /* Start the buffer out as an empty string. */
5371 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5373 if (TREE_CODE (selector) == KEYWORD_DECL)
5374 key_name = KEYWORD_KEY_NAME (key_chain);
5375 else if (TREE_CODE (selector) == TREE_LIST)
5377 key_name = TREE_PURPOSE (key_chain);
5378 /* The keyword decl chain will later be used as a function argument
5379 chain. Unhook the selector itself so as to not confuse other
5380 parts of the compiler. */
5381 TREE_PURPOSE (key_chain) = NULL_TREE;
5387 strcat (buf, IDENTIFIER_POINTER (key_name));
5391 return get_identifier (buf);
5394 /* Used for declarations and definitions. */
5397 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5402 /* If no type is specified, default to "id". */
5403 ret_type = adjust_type_for_id_default (ret_type);
5405 method_decl = make_node (code);
5406 TREE_TYPE (method_decl) = ret_type;
5408 /* If we have a keyword selector, create an identifier_node that
5409 represents the full selector name (`:' included)... */
5410 if (TREE_CODE (selector) == KEYWORD_DECL)
5412 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5413 METHOD_SEL_ARGS (method_decl) = selector;
5414 METHOD_ADD_ARGS (method_decl) = add_args;
5418 METHOD_SEL_NAME (method_decl) = selector;
5419 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5420 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5426 #define METHOD_DEF 0
5427 #define METHOD_REF 1
5429 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5430 an argument list for method METH. CONTEXT is either METHOD_DEF or
5431 METHOD_REF, saying whether we are trying to define a method or call
5432 one. SUPERFLAG says this is for a send to super; this makes a
5433 difference for the NeXT calling sequence in which the lookup and
5434 the method call are done together. If METH is null, user-defined
5435 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5438 get_arg_type_list (tree meth, int context, int superflag)
5442 /* Receiver type. */
5443 if (flag_next_runtime && superflag)
5444 arglist = build_tree_list (NULL_TREE, objc_super_type);
5445 else if (context == METHOD_DEF)
5446 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5448 arglist = build_tree_list (NULL_TREE, objc_id_type);
5450 /* Selector type - will eventually change to `int'. */
5451 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5453 /* No actual method prototype given -- assume that remaining arguments
5458 /* Build a list of argument types. */
5459 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5461 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5462 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5465 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5466 /* We have a `, ...' immediately following the selector,
5467 finalize the arglist...simulate get_parm_info (true). */
5469 else if (METHOD_ADD_ARGS (meth))
5471 /* we have a variable length selector */
5472 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5473 chainon (arglist, add_arg_list);
5476 /* finalize the arglist...simulate get_parm_info (false) */
5477 chainon (arglist, void_list_node);
5483 check_duplicates (hash hsh, int methods, int is_class)
5485 tree meth = NULL_TREE;
5493 /* We have two or more methods with the same name but
5497 warning ("multiple %s named `%c%s' found",
5498 methods ? "methods" : "selectors",
5499 (is_class ? '+' : '-'),
5500 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5502 warn_with_method (methods ? "using" : "found",
5503 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5507 for (loop = hsh->list; loop; loop = loop->next)
5508 warn_with_method ("also found",
5509 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5518 /* If RECEIVER is a class reference, return the identifier node for
5519 the referenced class. RECEIVER is created by get_class_reference,
5520 so we check the exact form created depending on which runtimes are
5524 receiver_is_class_object (tree receiver, int self, int super)
5526 tree chain, exp, arg;
5528 /* The receiver is 'self' or 'super' in the context of a class method. */
5529 if (objc_method_context
5530 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5533 ? CLASS_SUPER_NAME (implementation_template)
5534 : CLASS_NAME (implementation_template));
5536 if (flag_next_runtime)
5538 /* The receiver is a variable created by
5539 build_class_reference_decl. */
5540 if (TREE_CODE (receiver) == VAR_DECL
5541 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5542 /* Look up the identifier. */
5543 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5544 if (TREE_PURPOSE (chain) == receiver)
5545 return TREE_VALUE (chain);
5548 /* The receiver is a function call that returns an id. Check if
5549 it is a call to objc_getClass, if so, pick up the class name. */
5550 if (TREE_CODE (receiver) == CALL_EXPR
5551 && (exp = TREE_OPERAND (receiver, 0))
5552 && TREE_CODE (exp) == ADDR_EXPR
5553 && (exp = TREE_OPERAND (exp, 0))
5554 && TREE_CODE (exp) == FUNCTION_DECL
5555 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5556 prototypes for objc_get_class(). Thankfully, they seem to share the
5557 same function type. */
5558 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5559 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5560 /* We have a call to objc_get_class/objc_getClass! */
5561 && (arg = TREE_OPERAND (receiver, 1))
5562 && TREE_CODE (arg) == TREE_LIST
5563 && (arg = TREE_VALUE (arg)))
5566 if (TREE_CODE (arg) == ADDR_EXPR
5567 && (arg = TREE_OPERAND (arg, 0))
5568 && TREE_CODE (arg) == STRING_CST)
5569 /* Finally, we have the class name. */
5570 return get_identifier (TREE_STRING_POINTER (arg));
5575 /* If we are currently building a message expr, this holds
5576 the identifier of the selector of the message. This is
5577 used when printing warnings about argument mismatches. */
5579 static tree current_objc_message_selector = 0;
5582 objc_message_selector (void)
5584 return current_objc_message_selector;
5587 /* Construct an expression for sending a message.
5588 MESS has the object to send to in TREE_PURPOSE
5589 and the argument list (including selector) in TREE_VALUE.
5591 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5592 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5595 build_message_expr (tree mess)
5597 tree receiver = TREE_PURPOSE (mess);
5599 tree args = TREE_VALUE (mess);
5600 tree method_params = NULL_TREE;
5602 if (TREE_CODE (receiver) == ERROR_MARK)
5603 return error_mark_node;
5605 /* Obtain the full selector name. */
5606 if (TREE_CODE (args) == IDENTIFIER_NODE)
5607 /* A unary selector. */
5609 else if (TREE_CODE (args) == TREE_LIST)
5610 sel_name = build_keyword_selector (args);
5614 /* Build the parameter list to give to the method. */
5615 if (TREE_CODE (args) == TREE_LIST)
5617 tree chain = args, prev = NULL_TREE;
5619 /* We have a keyword selector--check for comma expressions. */
5622 tree element = TREE_VALUE (chain);
5624 /* We have a comma expression, must collapse... */
5625 if (TREE_CODE (element) == TREE_LIST)
5628 TREE_CHAIN (prev) = element;
5633 chain = TREE_CHAIN (chain);
5635 method_params = args;
5639 if (processing_template_decl)
5640 /* Must wait until template instantiation time. */
5641 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5645 return finish_message_expr (receiver, sel_name, method_params);
5648 /* Look up method SEL_NAME that would be suitable for receiver
5649 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5650 nonzero), and report on any duplicates. */
5653 lookup_method_in_hash_lists (tree sel_name, int is_class)
5655 hash method_prototype = NULL;
5658 method_prototype = hash_lookup (nst_method_hash_list,
5661 if (!method_prototype)
5663 method_prototype = hash_lookup (cls_method_hash_list,
5668 return check_duplicates (method_prototype, 1, is_class);
5671 /* The 'finish_message_expr' routine is called from within
5672 'build_message_expr' for non-template functions. In the case of
5673 C++ template functions, it is called from 'build_expr_from_tree'
5674 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5677 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5679 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5680 tree selector, retval, class_tree;
5681 int self, super, have_cast;
5683 /* Extract the receiver of the message, as well as its type
5684 (where the latter may take the form of a cast or be inferred
5685 from the implementation context). */
5687 while (TREE_CODE (rtype) == COMPOUND_EXPR
5688 || TREE_CODE (rtype) == MODIFY_EXPR
5689 || TREE_CODE (rtype) == NOP_EXPR
5690 || TREE_CODE (rtype) == COMPONENT_REF)
5691 rtype = TREE_OPERAND (rtype, 0);
5692 self = (rtype == self_decl);
5693 super = (rtype == UOBJC_SUPER_decl);
5694 rtype = TREE_TYPE (receiver);
5695 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5696 || (TREE_CODE (receiver) == COMPOUND_EXPR
5697 && !IS_SUPER (rtype)));
5699 /* If the receiver is a class object, retrieve the corresponding
5700 @interface, if one exists. */
5701 class_tree = receiver_is_class_object (receiver, self, super);
5703 /* Now determine the receiver type (if an explicit cast has not been
5708 rtype = lookup_interface (class_tree);
5709 /* Handle `self' and `super'. */
5712 if (!CLASS_SUPER_NAME (implementation_template))
5714 error ("no super class declared in @interface for `%s'",
5715 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5716 return error_mark_node;
5718 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5721 rtype = lookup_interface (CLASS_NAME (implementation_template));
5724 /* If receiver is of type `id' or `Class' (or if the @interface for a
5725 class is not visible), we shall be satisfied with the existence of
5726 any instance or class method. */
5727 if (!rtype || IS_ID (rtype)
5728 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5731 rtype = xref_tag (RECORD_TYPE, class_tree);
5732 else if (IS_ID (rtype))
5734 rprotos = TYPE_PROTOCOL_LIST (rtype);
5738 class_tree = TYPE_NAME (rtype) = get_identifier ("Class");
5742 = lookup_method_in_protocol_list (rprotos, sel_name,
5743 class_tree != NULL_TREE);
5744 if (!method_prototype && !rprotos)
5746 = lookup_method_in_hash_lists (sel_name,
5747 class_tree != NULL_TREE);
5751 tree orig_rtype = rtype, saved_rtype;
5753 if (TREE_CODE (rtype) == POINTER_TYPE)
5754 rtype = TREE_TYPE (rtype);
5755 /* Traverse typedef aliases */
5756 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5757 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5758 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5759 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5760 saved_rtype = rtype;
5761 if (TYPED_OBJECT (rtype))
5763 rprotos = TYPE_PROTOCOL_LIST (rtype);
5764 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5766 /* If we could not find an @interface declaration, we must have
5767 only seen a @class declaration; so, we cannot say anything
5768 more intelligent about which methods the receiver will
5771 rtype = saved_rtype;
5772 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5773 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5775 /* We have a valid ObjC class name. Look up the method name
5776 in the published @interface for the class (and its
5779 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5781 /* If the method was not found in the @interface, it may still
5782 exist locally as part of the @implementation. */
5783 if (!method_prototype && objc_implementation_context
5784 && CLASS_NAME (objc_implementation_context)
5785 == OBJC_TYPE_NAME (rtype))
5789 ? CLASS_CLS_METHODS (objc_implementation_context)
5790 : CLASS_NST_METHODS (objc_implementation_context)),
5793 /* If we haven't found a candidate method by now, try looking for
5794 it in the protocol list. */
5795 if (!method_prototype && rprotos)
5797 = lookup_method_in_protocol_list (rprotos, sel_name,
5798 class_tree != NULL_TREE);
5802 warning ("invalid receiver type `%s'",
5803 gen_declaration (orig_rtype, errbuf));
5804 rtype = rprotos = NULL_TREE;
5808 if (!method_prototype)
5810 static bool warn_missing_methods = false;
5813 warning ("`%s' may not respond to `%c%s'",
5814 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5815 (class_tree ? '+' : '-'),
5816 IDENTIFIER_POINTER (sel_name));
5818 warning ("`%c%s' not implemented by protocol(s)",
5819 (class_tree ? '+' : '-'),
5820 IDENTIFIER_POINTER (sel_name));
5821 if (!warn_missing_methods)
5823 warning ("(Messages without a matching method signature");
5824 warning ("will be assumed to return `id' and accept");
5825 warning ("`...' as arguments.)");
5826 warn_missing_methods = true;
5830 /* Save the selector name for printing error messages. */
5831 current_objc_message_selector = sel_name;
5833 /* Build the parameters list for looking up the method.
5834 These are the object itself and the selector. */
5836 if (flag_typed_selectors)
5837 selector = build_typed_selector_reference (sel_name, method_prototype);
5839 selector = build_selector_reference (sel_name);
5841 retval = build_objc_method_call (super, method_prototype,
5843 selector, method_params);
5845 current_objc_message_selector = 0;
5850 /* Build a tree expression to send OBJECT the operation SELECTOR,
5851 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5852 assuming the method has prototype METHOD_PROTOTYPE.
5853 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5854 Use METHOD_PARAMS as list of args to pass to the method.
5855 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5858 build_objc_method_call (int super_flag, tree method_prototype,
5859 tree lookup_object, tree selector,
5862 tree sender = (super_flag ? umsg_super_decl :
5863 (!flag_next_runtime || flag_nil_receivers
5865 : umsg_nonnil_decl));
5866 tree rcv_p = (super_flag ? objc_super_type : objc_id_type);
5868 /* If a prototype for the method to be called exists, then cast
5869 the sender's return type and arguments to match that of the method.
5870 Otherwise, leave sender as is. */
5873 ? groktypename (TREE_TYPE (method_prototype))
5876 = build_pointer_type
5877 (build_function_type
5880 (method_prototype, METHOD_REF, super_flag)));
5883 lookup_object = build_c_cast (rcv_p, lookup_object);
5885 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5886 lookup_object = save_expr (lookup_object);
5888 if (flag_next_runtime)
5890 /* If we are returning a struct in memory, and the address
5891 of that memory location is passed as a hidden first
5892 argument, then change which messenger entry point this
5893 expr will call. NB: Note that sender_cast remains
5894 unchanged (it already has a struct return type). */
5895 if (!targetm.calls.struct_value_rtx (0, 0)
5896 && (TREE_CODE (ret_type) == RECORD_TYPE
5897 || TREE_CODE (ret_type) == UNION_TYPE)
5898 && targetm.calls.return_in_memory (ret_type, 0))
5899 sender = (super_flag ? umsg_super_stret_decl :
5900 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5902 method_params = tree_cons (NULL_TREE, lookup_object,
5903 tree_cons (NULL_TREE, selector,
5905 method = build_fold_addr_expr (sender);
5909 /* This is the portable (GNU) way. */
5912 /* First, call the lookup function to get a pointer to the method,
5913 then cast the pointer, then call it with the method arguments. */
5915 object = (super_flag ? self_decl : lookup_object);
5917 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5918 t = tree_cons (NULL_TREE, lookup_object, t);
5919 method = build_function_call (sender, t);
5921 /* Pass the object to the method. */
5922 method_params = tree_cons (NULL_TREE, object,
5923 tree_cons (NULL_TREE, selector,
5927 /* ??? Selector is not at this point something we can use inside
5928 the compiler itself. Set it to garbage for the nonce. */
5929 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5930 return build_function_call (t, method_params);
5934 build_protocol_reference (tree p)
5936 tree decl, ident, ptype;
5938 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5940 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5942 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5943 objc_protocol_template),
5946 if (identifier_global_value (ident))
5947 decl = identifier_global_value (ident); /* Set by pushdecl. */
5950 decl = build_decl (VAR_DECL, ident, ptype);
5951 DECL_EXTERNAL (decl) = 1;
5952 TREE_PUBLIC (decl) = 0;
5953 TREE_USED (decl) = 1;
5954 DECL_ARTIFICIAL (decl) = 1;
5956 make_decl_rtl (decl);
5957 pushdecl_top_level (decl);
5960 PROTOCOL_FORWARD_DECL (p) = decl;
5963 /* This function is called by the parser when (and only when) a
5964 @protocol() expression is found, in order to compile it. */
5966 build_protocol_expr (tree protoname)
5969 tree p = lookup_protocol (protoname);
5973 error ("cannot find protocol declaration for `%s'",
5974 IDENTIFIER_POINTER (protoname));
5975 return error_mark_node;
5978 if (!PROTOCOL_FORWARD_DECL (p))
5979 build_protocol_reference (p);
5981 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5983 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5984 if we have it, rather than converting it here. */
5985 expr = convert (objc_protocol_type, expr);
5987 /* The @protocol() expression is being compiled into a pointer to a
5988 statically allocated instance of the Protocol class. To become
5989 usable at runtime, the 'isa' pointer of the instance need to be
5990 fixed up at runtime by the runtime library, to point to the
5991 actual 'Protocol' class. */
5993 /* For the GNU runtime, put the static Protocol instance in the list
5994 of statically allocated instances, so that we make sure that its
5995 'isa' pointer is fixed up at runtime by the GNU runtime library
5996 to point to the Protocol class (at runtime, when loading the
5997 module, the GNU runtime library loops on the statically allocated
5998 instances (as found in the defs field in objc_symtab) and fixups
5999 all the 'isa' pointers of those objects). */
6000 if (! flag_next_runtime)
6002 /* This type is a struct containing the fields of a Protocol
6003 object. (Cfr. objc_protocol_type instead is the type of a pointer
6004 to such a struct). */
6005 tree protocol_struct_type = xref_tag
6006 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6009 /* Look for the list of Protocol statically allocated instances
6010 to fixup at runtime. Create a new list to hold Protocol
6011 statically allocated instances, if the list is not found. At
6012 present there is only another list, holding NSConstantString
6013 static instances to be fixed up at runtime. */
6014 for (chain = &objc_static_instances;
6015 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6016 chain = &TREE_CHAIN (*chain));
6019 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6020 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6024 /* Add this statically allocated instance to the Protocol list. */
6025 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6026 PROTOCOL_FORWARD_DECL (p),
6027 TREE_PURPOSE (*chain));
6034 /* This function is called by the parser when a @selector() expression
6035 is found, in order to compile it. It is only called by the parser
6036 and only to compile a @selector(). */
6038 build_selector_expr (tree selnamelist)
6042 /* Obtain the full selector name. */
6043 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6044 /* A unary selector. */
6045 selname = selnamelist;
6046 else if (TREE_CODE (selnamelist) == TREE_LIST)
6047 selname = build_keyword_selector (selnamelist);
6051 /* If we are required to check @selector() expressions as they
6052 are found, check that the selector has been declared. */
6053 if (warn_undeclared_selector)
6055 /* Look the selector up in the list of all known class and
6056 instance methods (up to this line) to check that the selector
6060 /* First try with instance methods. */
6061 hsh = hash_lookup (nst_method_hash_list, selname);
6063 /* If not found, try with class methods. */
6066 hsh = hash_lookup (cls_method_hash_list, selname);
6069 /* If still not found, print out a warning. */
6072 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6077 if (flag_typed_selectors)
6078 return build_typed_selector_reference (selname, 0);
6080 return build_selector_reference (selname);
6084 build_encode_expr (tree type)
6089 encode_type (type, obstack_object_size (&util_obstack),
6090 OBJC_ENCODE_INLINE_DEFS);
6091 obstack_1grow (&util_obstack, 0); /* null terminate string */
6092 string = obstack_finish (&util_obstack);
6094 /* Synthesize a string that represents the encoded struct/union. */
6095 result = my_build_string (strlen (string) + 1, string);
6096 obstack_free (&util_obstack, util_firstobj);
6101 build_ivar_reference (tree id)
6103 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6105 /* Historically, a class method that produced objects (factory
6106 method) would assign `self' to the instance that it
6107 allocated. This would effectively turn the class method into
6108 an instance method. Following this assignment, the instance
6109 variables could be accessed. That practice, while safe,
6110 violates the simple rule that a class method should not refer
6111 to an instance variable. It's better to catch the cases
6112 where this is done unknowingly than to support the above
6114 warning ("instance variable `%s' accessed in class method",
6115 IDENTIFIER_POINTER (id));
6116 TREE_TYPE (self_decl) = objc_instance_type; /* cast */
6119 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6122 /* Compute a hash value for a given method SEL_NAME. */
6125 hash_func (tree sel_name)
6127 const unsigned char *s
6128 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6132 h = h * 67 + *s++ - 113;
6139 nst_method_hash_list
6140 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6141 cls_method_hash_list
6142 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6145 /* WARNING!!!! hash_enter is called with a method, and will peek
6146 inside to find its selector! But hash_lookup is given a selector
6147 directly, and looks for the selector that's inside the found
6148 entry's key (method) for comparison. */
6151 hash_enter (hash *hashlist, tree method)
6154 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6156 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6158 obj->next = hashlist[slot];
6161 hashlist[slot] = obj; /* append to front */
6165 hash_lookup (hash *hashlist, tree sel_name)
6169 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6173 if (sel_name == METHOD_SEL_NAME (target->key))
6176 target = target->next;
6182 hash_add_attr (hash entry, tree value)
6186 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6187 obj->next = entry->list;
6190 entry->list = obj; /* append to front */
6194 lookup_method (tree mchain, tree method)
6198 if (TREE_CODE (method) == IDENTIFIER_NODE)
6201 key = METHOD_SEL_NAME (method);
6205 if (METHOD_SEL_NAME (mchain) == key)
6208 mchain = TREE_CHAIN (mchain);
6214 lookup_method_static (tree interface, tree ident, int is_class)
6216 tree meth = NULL_TREE, root_inter = NULL_TREE;
6217 tree inter = interface;
6221 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6222 tree category = inter;
6224 /* First, look up the method in the class itself. */
6225 if ((meth = lookup_method (chain, ident)))
6228 /* Failing that, look for the method in each category of the class. */
6229 while ((category = CLASS_CATEGORY_LIST (category)))
6231 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6233 /* Check directly in each category. */
6234 if ((meth = lookup_method (chain, ident)))
6237 /* Failing that, check in each category's protocols. */
6238 if (CLASS_PROTOCOL_LIST (category))
6240 if ((meth = (lookup_method_in_protocol_list
6241 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6246 /* If not found in categories, check in protocols of the main class. */
6247 if (CLASS_PROTOCOL_LIST (inter))
6249 if ((meth = (lookup_method_in_protocol_list
6250 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6254 /* Failing that, climb up the inheritance hierarchy. */
6256 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6260 /* If no class (factory) method was found, check if an _instance_
6261 method of the same name exists in the root class. This is what
6262 the Objective-C runtime will do. If an instance method was not
6264 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6267 /* Add the method to the hash list if it doesn't contain an identical
6270 add_method_to_hash_list (hash *hash_list, tree method)
6274 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6276 /* Install on a global chain. */
6277 hash_enter (hash_list, method);
6281 /* Check types against those; if different, add to a list. */
6283 int already_there = comp_proto_with_proto (method, hsh->key);
6284 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6285 already_there |= comp_proto_with_proto (method, loop->value);
6287 hash_add_attr (hsh, method);
6292 objc_add_method (tree class, tree method, int is_class)
6296 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6298 /* put method on list in reverse order */
6301 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6302 CLASS_CLS_METHODS (class) = method;
6306 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6307 CLASS_NST_METHODS (class) = method;
6312 /* When processing an @interface for a class or category, give hard
6313 errors on methods with identical selectors but differing argument
6314 and/or return types. We do not do this for @implementations, because
6315 C/C++ will do it for us (i.e., there will be duplicate function
6316 definition errors). */
6317 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6318 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6319 && !comp_proto_with_proto (method, mth))
6320 error ("duplicate declaration of method `%c%s'",
6321 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6325 add_method_to_hash_list (cls_method_hash_list, method);
6328 add_method_to_hash_list (nst_method_hash_list, method);
6330 /* Instance methods in root classes (and categories thereof)
6331 may acts as class methods as a last resort. */
6332 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6333 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6334 class = lookup_interface (CLASS_NAME (class));
6336 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6337 && !CLASS_SUPER_NAME (class))
6338 add_method_to_hash_list (cls_method_hash_list, method);
6345 add_class (tree class)
6347 /* Put interfaces on list in reverse order. */
6348 TREE_CHAIN (class) = interface_chain;
6349 interface_chain = class;
6350 return interface_chain;
6354 add_category (tree class, tree category)
6356 /* Put categories on list in reverse order. */
6357 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6361 warning ("duplicate interface declaration for category `%s(%s)'",
6362 IDENTIFIER_POINTER (CLASS_NAME (class)),
6363 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6367 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6368 CLASS_CATEGORY_LIST (class) = category;
6372 /* Called after parsing each instance variable declaration. Necessary to
6373 preserve typedefs and implement public/private...
6375 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6378 add_instance_variable (tree class, int public, tree declarator,
6379 tree declspecs, tree width)
6381 tree field_decl = grokfield (declarator, declspecs, width);
6382 tree field_type = TREE_TYPE (field_decl);
6383 const char *ivar_name = DECL_NAME (field_decl)
6384 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6389 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6391 error ("illegal reference type specified for instance variable `%s'",
6393 /* Return class as is without adding this ivar. */
6398 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6399 || TYPE_SIZE (field_type) == error_mark_node
6400 /* 'type[0]' is allowed, but 'type[]' is not! */
6402 || (TYPE_SIZE (field_type) == bitsize_zero_node
6403 && !TREE_OPERAND (declarator, 1))
6407 error ("instance variable `%s' has unknown size", ivar_name);
6408 /* Return class as is without adding this ivar. */
6413 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6414 cannot be ivars; ditto for classes with vtables. */
6415 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6416 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6418 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6419 if(TYPE_POLYMORPHIC_P (field_type)) {
6420 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6421 error ("type `%s' has virtual member functions", type_name);
6422 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6423 type_name, ivar_name);
6424 /* Return class as is without adding this ivar. */
6427 /* user-defined constructors and destructors are not known to Obj-C and
6428 hence will not be called. This may or may not be a problem. */
6429 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6430 warning ("type `%s' has a user-defined constructor", type_name);
6431 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6432 warning ("type `%s' has a user-defined destructor", type_name);
6433 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6437 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6441 TREE_PUBLIC (field_decl) = 0;
6442 TREE_PRIVATE (field_decl) = 0;
6443 TREE_PROTECTED (field_decl) = 1;
6447 TREE_PUBLIC (field_decl) = 1;
6448 TREE_PRIVATE (field_decl) = 0;
6449 TREE_PROTECTED (field_decl) = 0;
6453 TREE_PUBLIC (field_decl) = 0;
6454 TREE_PRIVATE (field_decl) = 1;
6455 TREE_PROTECTED (field_decl) = 0;
6460 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6461 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6462 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6467 is_ivar (tree decl_chain, tree ident)
6469 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6470 if (DECL_NAME (decl_chain) == ident)
6475 /* True if the ivar is private and we are not in its implementation. */
6478 is_private (tree decl)
6480 return (TREE_PRIVATE (decl)
6481 && ! is_ivar (CLASS_IVARS (implementation_template),
6485 /* We have an instance variable reference;, check to see if it is public. */
6488 objc_is_public (tree expr, tree identifier)
6490 tree basetype = TREE_TYPE (expr);
6491 enum tree_code code = TREE_CODE (basetype);
6494 if (code == RECORD_TYPE)
6496 if (TREE_STATIC_TEMPLATE (basetype))
6498 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6500 error ("cannot find interface declaration for `%s'",
6501 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6505 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6507 if (TREE_PUBLIC (decl))
6510 /* Important difference between the Stepstone translator:
6511 all instance variables should be public within the context
6512 of the implementation. */
6513 if (objc_implementation_context
6514 && (((TREE_CODE (objc_implementation_context)
6515 == CLASS_IMPLEMENTATION_TYPE)
6516 || (TREE_CODE (objc_implementation_context)
6517 == CATEGORY_IMPLEMENTATION_TYPE))
6518 && (CLASS_NAME (objc_implementation_context)
6519 == OBJC_TYPE_NAME (basetype))))
6521 int private = is_private (decl);
6524 error ("instance variable `%s' is declared private",
6525 IDENTIFIER_POINTER (DECL_NAME (decl)));
6529 /* The 2.95.2 compiler sometimes allowed C functions to access
6530 non-@public ivars. We will let this slide for now... */
6531 if (!objc_method_context)
6533 warning ("instance variable `%s' is %s; "
6534 "this will be a hard error in the future",
6535 IDENTIFIER_POINTER (identifier),
6536 TREE_PRIVATE (decl) ? "@private" : "@protected");
6540 error ("instance variable `%s' is declared %s",
6541 IDENTIFIER_POINTER (identifier),
6542 TREE_PRIVATE (decl) ? "private" : "protected");
6547 else if (objc_implementation_context && (basetype == objc_object_reference))
6549 TREE_TYPE (expr) = uprivate_record;
6550 warning ("static access to object of type `id'");
6557 /* Make sure all entries in CHAIN are also in LIST. */
6560 check_methods (tree chain, tree list, int mtype)
6566 if (!lookup_method (list, chain))
6570 if (TREE_CODE (objc_implementation_context)
6571 == CLASS_IMPLEMENTATION_TYPE)
6572 warning ("incomplete implementation of class `%s'",
6573 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6574 else if (TREE_CODE (objc_implementation_context)
6575 == CATEGORY_IMPLEMENTATION_TYPE)
6576 warning ("incomplete implementation of category `%s'",
6577 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6581 warning ("method definition for `%c%s' not found",
6582 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6585 chain = TREE_CHAIN (chain);
6591 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6594 conforms_to_protocol (tree class, tree protocol)
6596 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6598 tree p = CLASS_PROTOCOL_LIST (class);
6599 while (p && TREE_VALUE (p) != protocol)
6604 tree super = (CLASS_SUPER_NAME (class)
6605 ? lookup_interface (CLASS_SUPER_NAME (class))
6607 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6616 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6617 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6620 check_methods_accessible (tree chain, tree context, int mtype)
6624 tree base_context = context;
6628 context = base_context;
6632 list = CLASS_CLS_METHODS (context);
6634 list = CLASS_NST_METHODS (context);
6636 if (lookup_method (list, chain))
6639 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6640 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6641 context = (CLASS_SUPER_NAME (context)
6642 ? lookup_interface (CLASS_SUPER_NAME (context))
6645 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6646 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6647 context = (CLASS_NAME (context)
6648 ? lookup_interface (CLASS_NAME (context))
6654 if (context == NULL_TREE)
6658 if (TREE_CODE (objc_implementation_context)
6659 == CLASS_IMPLEMENTATION_TYPE)
6660 warning ("incomplete implementation of class `%s'",
6662 (CLASS_NAME (objc_implementation_context)));
6663 else if (TREE_CODE (objc_implementation_context)
6664 == CATEGORY_IMPLEMENTATION_TYPE)
6665 warning ("incomplete implementation of category `%s'",
6667 (CLASS_SUPER_NAME (objc_implementation_context)));
6670 warning ("method definition for `%c%s' not found",
6671 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6674 chain = TREE_CHAIN (chain); /* next method... */
6679 /* Check whether the current interface (accessible via
6680 'objc_implementation_context') actually implements protocol P, along
6681 with any protocols that P inherits. */
6684 check_protocol (tree p, const char *type, const char *name)
6686 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6690 /* Ensure that all protocols have bodies! */
6693 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6694 CLASS_CLS_METHODS (objc_implementation_context),
6696 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6697 CLASS_NST_METHODS (objc_implementation_context),
6702 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6703 objc_implementation_context,
6705 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6706 objc_implementation_context,
6711 warning ("%s `%s' does not fully implement the `%s' protocol",
6712 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6715 /* Check protocols recursively. */
6716 if (PROTOCOL_LIST (p))
6718 tree subs = PROTOCOL_LIST (p);
6720 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6724 tree sub = TREE_VALUE (subs);
6726 /* If the superclass does not conform to the protocols
6727 inherited by P, then we must! */
6728 if (!super_class || !conforms_to_protocol (super_class, sub))
6729 check_protocol (sub, type, name);
6730 subs = TREE_CHAIN (subs);
6735 /* Check whether the current interface (accessible via
6736 'objc_implementation_context') actually implements the protocols listed
6740 check_protocols (tree proto_list, const char *type, const char *name)
6742 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6744 tree p = TREE_VALUE (proto_list);
6746 check_protocol (p, type, name);
6750 /* Make sure that the class CLASS_NAME is defined
6751 CODE says which kind of thing CLASS_NAME ought to be.
6752 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6753 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6756 start_class (enum tree_code code, tree class_name, tree super_name,
6762 if (current_namespace != global_namespace) {
6763 error ("Objective-C declarations may only appear in global scope");
6765 #endif /* OBJCPLUS */
6767 if (objc_implementation_context)
6769 warning ("`@end' missing in implementation context");
6770 finish_class (objc_implementation_context);
6771 objc_ivar_chain = NULL_TREE;
6772 objc_implementation_context = NULL_TREE;
6775 class = make_node (code);
6776 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6778 CLASS_NAME (class) = class_name;
6779 CLASS_SUPER_NAME (class) = super_name;
6780 CLASS_CLS_METHODS (class) = NULL_TREE;
6782 if (! is_class_name (class_name)
6783 && (decl = lookup_name (class_name)))
6785 error ("`%s' redeclared as different kind of symbol",
6786 IDENTIFIER_POINTER (class_name));
6787 error ("%Jprevious declaration of '%D'",
6791 if (code == CLASS_IMPLEMENTATION_TYPE)
6796 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6797 if (TREE_VALUE (chain) == class_name)
6799 error ("reimplementation of class `%s'",
6800 IDENTIFIER_POINTER (class_name));
6801 return error_mark_node;
6803 implemented_classes = tree_cons (NULL_TREE, class_name,
6804 implemented_classes);
6807 /* Reset for multiple classes per file. */
6810 objc_implementation_context = class;
6812 /* Lookup the interface for this implementation. */
6814 if (!(implementation_template = lookup_interface (class_name)))
6816 warning ("cannot find interface declaration for `%s'",
6817 IDENTIFIER_POINTER (class_name));
6818 add_class (implementation_template = objc_implementation_context);
6821 /* If a super class has been specified in the implementation,
6822 insure it conforms to the one specified in the interface. */
6825 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6827 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6828 const char *const name =
6829 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6830 error ("conflicting super class name `%s'",
6831 IDENTIFIER_POINTER (super_name));
6832 error ("previous declaration of `%s'", name);
6835 else if (! super_name)
6837 CLASS_SUPER_NAME (objc_implementation_context)
6838 = CLASS_SUPER_NAME (implementation_template);
6842 else if (code == CLASS_INTERFACE_TYPE)
6844 if (lookup_interface (class_name))
6846 error ("duplicate interface declaration for class `%s'",
6848 warning ("duplicate interface declaration for class `%s'",
6850 IDENTIFIER_POINTER (class_name));
6855 CLASS_PROTOCOL_LIST (class)
6856 = lookup_and_install_protocols (protocol_list);
6859 else if (code == CATEGORY_INTERFACE_TYPE)
6861 tree class_category_is_assoc_with;
6863 /* For a category, class_name is really the name of the class that
6864 the following set of methods will be associated with. We must
6865 find the interface so that can derive the objects template. */
6867 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6869 error ("cannot find interface declaration for `%s'",
6870 IDENTIFIER_POINTER (class_name));
6871 exit (FATAL_EXIT_CODE);
6874 add_category (class_category_is_assoc_with, class);
6877 CLASS_PROTOCOL_LIST (class)
6878 = lookup_and_install_protocols (protocol_list);
6881 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6883 /* Reset for multiple classes per file. */
6886 objc_implementation_context = class;
6888 /* For a category, class_name is really the name of the class that
6889 the following set of methods will be associated with. We must
6890 find the interface so that can derive the objects template. */
6892 if (!(implementation_template = lookup_interface (class_name)))
6894 error ("cannot find interface declaration for `%s'",
6895 IDENTIFIER_POINTER (class_name));
6896 exit (FATAL_EXIT_CODE);
6903 continue_class (tree class)
6905 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6906 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6908 struct imp_entry *imp_entry;
6911 /* Check consistency of the instance variables. */
6913 if (CLASS_IVARS (class))
6914 check_ivars (implementation_template, class);
6916 /* code generation */
6918 ivar_context = build_private_template (implementation_template);
6920 if (!objc_class_template)
6921 build_class_template ();
6923 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6925 imp_entry->next = imp_list;
6926 imp_entry->imp_context = class;
6927 imp_entry->imp_template = implementation_template;
6929 synth_forward_declarations ();
6930 imp_entry->class_decl = UOBJC_CLASS_decl;
6931 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6933 /* Append to front and increment count. */
6934 imp_list = imp_entry;
6935 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6940 return ivar_context;
6943 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6945 if (!CLASS_STATIC_TEMPLATE (class))
6947 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6948 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6949 CLASS_STATIC_TEMPLATE (class) = record;
6951 /* Mark this record as a class template for static typing. */
6952 TREE_STATIC_TEMPLATE (record) = 1;
6959 return error_mark_node;
6962 /* This is called once we see the "@end" in an interface/implementation. */
6965 finish_class (tree class)
6967 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6969 /* All code generation is done in finish_objc. */
6971 if (implementation_template != objc_implementation_context)
6973 /* Ensure that all method listed in the interface contain bodies. */
6974 check_methods (CLASS_CLS_METHODS (implementation_template),
6975 CLASS_CLS_METHODS (objc_implementation_context), '+');
6976 check_methods (CLASS_NST_METHODS (implementation_template),
6977 CLASS_NST_METHODS (objc_implementation_context), '-');
6979 if (CLASS_PROTOCOL_LIST (implementation_template))
6980 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6982 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6986 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6988 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6992 /* Ensure all method listed in the interface contain bodies. */
6993 check_methods (CLASS_CLS_METHODS (category),
6994 CLASS_CLS_METHODS (objc_implementation_context), '+');
6995 check_methods (CLASS_NST_METHODS (category),
6996 CLASS_NST_METHODS (objc_implementation_context), '-');
6998 if (CLASS_PROTOCOL_LIST (category))
6999 check_protocols (CLASS_PROTOCOL_LIST (category),
7001 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7005 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7008 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
7009 char *string = (char *) alloca (strlen (class_name) + 3);
7011 /* extern struct objc_object *_<my_name>; */
7013 sprintf (string, "_%s", class_name);
7015 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
7016 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
7017 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7023 add_protocol (tree protocol)
7025 /* Put protocol on list in reverse order. */
7026 TREE_CHAIN (protocol) = protocol_chain;
7027 protocol_chain = protocol;
7028 return protocol_chain;
7032 lookup_protocol (tree ident)
7036 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7037 if (ident == PROTOCOL_NAME (chain))
7043 /* This function forward declares the protocols named by NAMES. If
7044 they are already declared or defined, the function has no effect. */
7047 objc_declare_protocols (tree names)
7052 if (current_namespace != global_namespace) {
7053 error ("Objective-C declarations may only appear in global scope");
7055 #endif /* OBJCPLUS */
7057 for (list = names; list; list = TREE_CHAIN (list))
7059 tree name = TREE_VALUE (list);
7061 if (lookup_protocol (name) == NULL_TREE)
7063 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7065 TYPE_LANG_SLOT_1 (protocol)
7066 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7067 PROTOCOL_NAME (protocol) = name;
7068 PROTOCOL_LIST (protocol) = NULL_TREE;
7069 add_protocol (protocol);
7070 PROTOCOL_DEFINED (protocol) = 0;
7071 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7077 start_protocol (enum tree_code code, tree name, tree list)
7082 if (current_namespace != global_namespace) {
7083 error ("Objective-C declarations may only appear in global scope");
7085 #endif /* OBJCPLUS */
7087 /* This is as good a place as any. Need to invoke
7088 push_tag_toplevel. */
7089 if (!objc_protocol_template)
7090 objc_protocol_template = build_protocol_template ();
7092 protocol = lookup_protocol (name);
7096 protocol = make_node (code);
7097 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7099 PROTOCOL_NAME (protocol) = name;
7100 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7101 add_protocol (protocol);
7102 PROTOCOL_DEFINED (protocol) = 1;
7103 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7105 check_protocol_recursively (protocol, list);
7107 else if (! PROTOCOL_DEFINED (protocol))
7109 PROTOCOL_DEFINED (protocol) = 1;
7110 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7112 check_protocol_recursively (protocol, list);
7116 warning ("duplicate declaration for protocol `%s'",
7117 IDENTIFIER_POINTER (name));
7123 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7128 /* "Encode" a data type into a string, which grows in util_obstack.
7129 ??? What is the FORMAT? Someone please document this! */
7132 encode_type_qualifiers (tree declspecs)
7136 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7138 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7139 obstack_1grow (&util_obstack, 'r');
7140 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7141 obstack_1grow (&util_obstack, 'n');
7142 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7143 obstack_1grow (&util_obstack, 'N');
7144 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7145 obstack_1grow (&util_obstack, 'o');
7146 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7147 obstack_1grow (&util_obstack, 'O');
7148 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7149 obstack_1grow (&util_obstack, 'R');
7150 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7151 obstack_1grow (&util_obstack, 'V');
7155 /* Encode a pointer type. */
7158 encode_pointer (tree type, int curtype, int format)
7160 tree pointer_to = TREE_TYPE (type);
7162 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7164 if (OBJC_TYPE_NAME (pointer_to)
7165 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7167 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7169 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7171 obstack_1grow (&util_obstack, '@');
7174 else if (TREE_STATIC_TEMPLATE (pointer_to))
7176 if (generating_instance_variables)
7178 obstack_1grow (&util_obstack, '@');
7179 obstack_1grow (&util_obstack, '"');
7180 obstack_grow (&util_obstack, name, strlen (name));
7181 obstack_1grow (&util_obstack, '"');
7186 obstack_1grow (&util_obstack, '@');
7190 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7192 obstack_1grow (&util_obstack, '#');
7195 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7197 obstack_1grow (&util_obstack, ':');
7202 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7203 && TYPE_MODE (pointer_to) == QImode)
7205 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7206 ? OBJC_TYPE_NAME (pointer_to)
7207 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7209 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7211 obstack_1grow (&util_obstack, '*');
7216 /* We have a type that does not get special treatment. */
7218 /* NeXT extension */
7219 obstack_1grow (&util_obstack, '^');
7220 encode_type (pointer_to, curtype, format);
7224 encode_array (tree type, int curtype, int format)
7226 tree an_int_cst = TYPE_SIZE (type);
7227 tree array_of = TREE_TYPE (type);
7230 /* An incomplete array is treated like a pointer. */
7231 if (an_int_cst == NULL)
7233 encode_pointer (type, curtype, format);
7237 sprintf (buffer, "[%ld",
7238 (long) (TREE_INT_CST_LOW (an_int_cst)
7239 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7241 obstack_grow (&util_obstack, buffer, strlen (buffer));
7242 encode_type (array_of, curtype, format);
7243 obstack_1grow (&util_obstack, ']');
7248 encode_aggregate_within (tree type, int curtype, int format, int left,
7252 /* NB: aggregates that are pointed to have slightly different encoding
7253 rules in that you never encode the names of instance variables. */
7255 = (obstack_object_size (&util_obstack) > 0
7256 && *(obstack_next_free (&util_obstack) - 1) == '^');
7258 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7259 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7261 /* Traverse struct aliases; it is important to get the
7262 original struct and its tag name (if any). */
7263 type = TYPE_MAIN_VARIANT (type);
7264 name = OBJC_TYPE_NAME (type);
7265 /* Open parenth/bracket. */
7266 obstack_1grow (&util_obstack, left);
7268 /* Encode the struct/union tag name, or '?' if a tag was
7269 not provided. Typedef aliases do not qualify. */
7270 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7272 /* Did this struct have a tag? */
7273 && !TYPE_WAS_ANONYMOUS (type)
7276 obstack_grow (&util_obstack,
7277 IDENTIFIER_POINTER (name),
7278 strlen (IDENTIFIER_POINTER (name)));
7280 obstack_1grow (&util_obstack, '?');
7282 /* Encode the types (and possibly names) of the inner fields,
7284 if (inline_contents)
7286 tree fields = TYPE_FIELDS (type);
7288 obstack_1grow (&util_obstack, '=');
7289 for (; fields; fields = TREE_CHAIN (fields))
7292 /* C++ static members, and things that are not fields at all,
7293 should not appear in the encoding. */
7294 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7297 if (generating_instance_variables && !pointed_to)
7299 tree fname = DECL_NAME (fields);
7301 obstack_1grow (&util_obstack, '"');
7302 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7303 obstack_grow (&util_obstack,
7304 IDENTIFIER_POINTER (fname),
7305 strlen (IDENTIFIER_POINTER (fname)));
7306 obstack_1grow (&util_obstack, '"');
7308 encode_field_decl (fields, curtype, format);
7311 /* Close parenth/bracket. */
7312 obstack_1grow (&util_obstack, right);
7316 encode_aggregate (tree type, int curtype, int format)
7318 enum tree_code code = TREE_CODE (type);
7324 encode_aggregate_within (type, curtype, format, '{', '}');
7329 encode_aggregate_within (type, curtype, format, '(', ')');
7334 obstack_1grow (&util_obstack, 'i');
7342 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7346 encode_next_bitfield (int width)
7349 sprintf (buffer, "b%d", width);
7350 obstack_grow (&util_obstack, buffer, strlen (buffer));
7353 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7355 encode_type (tree type, int curtype, int format)
7357 enum tree_code code = TREE_CODE (type);
7360 if (code == INTEGER_TYPE)
7362 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7364 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7365 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7367 if (type == long_unsigned_type_node
7368 || type == long_integer_type_node)
7369 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7371 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7373 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7376 obstack_1grow (&util_obstack, c);
7379 else if (code == REAL_TYPE)
7381 /* Floating point types. */
7382 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7384 case 32: c = 'f'; break;
7386 case 128: c = 'd'; break;
7389 obstack_1grow (&util_obstack, c);
7392 else if (code == VOID_TYPE)
7393 obstack_1grow (&util_obstack, 'v');
7395 else if (code == BOOLEAN_TYPE)
7396 obstack_1grow (&util_obstack, 'B');
7398 else if (code == ARRAY_TYPE)
7399 encode_array (type, curtype, format);
7401 else if (code == POINTER_TYPE)
7402 encode_pointer (type, curtype, format);
7404 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7405 encode_aggregate (type, curtype, format);
7407 else if (code == FUNCTION_TYPE) /* '?' */
7408 obstack_1grow (&util_obstack, '?');
7412 encode_gnu_bitfield (int position, tree type, int size)
7414 enum tree_code code = TREE_CODE (type);
7416 char charType = '?';
7418 if (code == INTEGER_TYPE)
7420 if (integer_zerop (TYPE_MIN_VALUE (type)))
7422 /* Unsigned integer types. */
7424 if (TYPE_MODE (type) == QImode)
7426 else if (TYPE_MODE (type) == HImode)
7428 else if (TYPE_MODE (type) == SImode)
7430 if (type == long_unsigned_type_node)
7435 else if (TYPE_MODE (type) == DImode)
7440 /* Signed integer types. */
7442 if (TYPE_MODE (type) == QImode)
7444 else if (TYPE_MODE (type) == HImode)
7446 else if (TYPE_MODE (type) == SImode)
7448 if (type == long_integer_type_node)
7454 else if (TYPE_MODE (type) == DImode)
7458 else if (code == ENUMERAL_TYPE)
7463 sprintf (buffer, "b%d%c%d", position, charType, size);
7464 obstack_grow (&util_obstack, buffer, strlen (buffer));
7468 encode_field_decl (tree field_decl, int curtype, int format)
7473 /* C++ static members, and things that are not fields at all,
7474 should not appear in the encoding. */
7475 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7479 type = TREE_TYPE (field_decl);
7481 /* Generate the bitfield typing information, if needed. Note the difference
7482 between GNU and NeXT runtimes. */
7483 if (DECL_BIT_FIELD_TYPE (field_decl))
7485 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7487 if (flag_next_runtime)
7488 encode_next_bitfield (size);
7490 encode_gnu_bitfield (int_bit_position (field_decl),
7491 DECL_BIT_FIELD_TYPE (field_decl), size);
7494 encode_type (TREE_TYPE (field_decl), curtype, format);
7498 objc_expr_last (tree complex_expr)
7503 while ((next = TREE_OPERAND (complex_expr, 0)))
7504 complex_expr = next;
7506 return complex_expr;
7510 synth_self_and_ucmd_args (void)
7514 if (objc_method_context
7515 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7516 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7518 /* Really a `struct objc_class *'. However, we allow people to
7519 assign to self, which changes its type midstream. */
7520 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7522 push_parm_decl (build_tree_list
7523 (build_tree_list (decl_specs,
7524 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7527 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (objc_selector_type));
7528 push_parm_decl (build_tree_list
7529 (build_tree_list (decl_specs,
7530 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7534 /* Transform a method definition into a function definition as follows:
7535 - synthesize the first two arguments, "self" and "_cmd". */
7538 start_method_def (tree method)
7540 /* Required to implement _msgSuper. */
7541 objc_method_context = method;
7542 UOBJC_SUPER_decl = NULL_TREE;
7544 /* Must be called BEFORE start_function. */
7546 declare_parm_level ();
7548 /* Generate prototype declarations for arguments..."new-style". */
7549 synth_self_and_ucmd_args ();
7551 /* Generate argument declarations if a keyword_decl. */
7552 if (METHOD_SEL_ARGS (method))
7554 tree arglist = METHOD_SEL_ARGS (method);
7557 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7558 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7562 tree last_expr = objc_expr_last (arg_decl);
7564 /* Unite the abstract decl with its name. */
7565 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7566 push_parm_decl (build_tree_list
7567 (build_tree_list (arg_spec, arg_decl),
7571 /* Unhook: restore the abstract declarator. */
7572 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7577 push_parm_decl (build_tree_list
7578 (build_tree_list (arg_spec,
7579 KEYWORD_ARG_NAME (arglist)),
7582 arglist = TREE_CHAIN (arglist);
7587 if (METHOD_ADD_ARGS (method) != NULL_TREE
7588 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7590 /* We have a variable length selector - in "prototype" format. */
7591 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7594 /* This must be done prior to calling pushdecl. pushdecl is
7595 going to change our chain on us. */
7596 tree nextkey = TREE_CHAIN (akey);
7604 warn_with_method (const char *message, int mtype, tree method)
7606 /* Add a readable method name to the warning. */
7607 warning ("%J%s `%c%s'", method,
7608 message, mtype, gen_method_decl (method, errbuf));
7611 /* Return 1 if METHOD is consistent with PROTO. */
7614 comp_method_with_proto (tree method, tree proto)
7616 /* Create a function template node at most once. */
7617 if (!function1_template)
7618 function1_template = make_node (FUNCTION_TYPE);
7620 /* Install argument types - normally set by build_function_type. */
7621 TYPE_ARG_TYPES (function1_template)
7622 = get_arg_type_list (proto, METHOD_DEF, 0);
7624 /* install return type */
7625 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7627 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7630 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7633 objc_types_are_equivalent (tree type1, tree type2)
7637 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7639 type1 = TYPE_PROTOCOL_LIST (type1);
7640 type2 = TYPE_PROTOCOL_LIST (type2);
7641 if (list_length (type1) == list_length (type2))
7643 for (; type2; type2 = TREE_CHAIN (type2))
7644 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7651 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7654 comp_proto_with_proto (tree proto1, tree proto2)
7658 /* The following test is needed in case there are hashing
7660 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7663 /* Compare return types. */
7664 type1 = groktypename (TREE_TYPE (proto1));
7665 type2 = groktypename (TREE_TYPE (proto2));
7667 if (!objc_types_are_equivalent (type1, type2))
7670 /* Compare argument types. */
7671 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7672 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7674 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7676 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7680 return (!type1 && !type2);
7683 /* - Generate an identifier for the function. the format is "_n_cls",
7684 where 1 <= n <= nMethods, and cls is the name the implementation we
7686 - Install the return type from the method declaration.
7687 - If we have a prototype, check for type consistency. */
7690 really_start_method (tree method, tree parmlist)
7692 tree sc_spec, ret_spec, ret_decl, decl_specs;
7693 tree method_decl, method_id;
7694 const char *sel_name, *class_name, *cat_name;
7697 /* Synth the storage class & assemble the return type. */
7698 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7699 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7700 decl_specs = chainon (sc_spec, ret_spec);
7702 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7703 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7704 cat_name = ((TREE_CODE (objc_implementation_context)
7705 == CLASS_IMPLEMENTATION_TYPE)
7707 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7710 /* Make sure this is big enough for any plausible method label. */
7711 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7712 + (cat_name ? strlen (cat_name) : 0));
7714 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7715 class_name, cat_name, sel_name, method_slot);
7717 method_id = get_identifier (buf);
7720 /* Objective-C methods cannot be overloaded, so we don't need
7721 the type encoding appended. It looks bad anyway... */
7722 push_lang_context (lang_name_c);
7725 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7727 /* Check the declarator portion of the return type for the method. */
7728 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7730 /* Unite the complex decl (specified in the abstract decl) with the
7731 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7732 tree save_expr = objc_expr_last (ret_decl);
7734 TREE_OPERAND (save_expr, 0) = method_decl;
7735 method_decl = ret_decl;
7737 /* Fool the parser into thinking it is starting a function. */
7738 start_function (decl_specs, method_decl, NULL_TREE);
7740 /* Unhook: this has the effect of restoring the abstract declarator. */
7741 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7746 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7748 /* Fool the parser into thinking it is starting a function. */
7749 start_function (decl_specs, method_decl, NULL_TREE);
7751 /* Unhook: this has the effect of restoring the abstract declarator. */
7752 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7756 /* set self_decl from the first argument...this global is used by
7757 * build_ivar_reference().build_indirect_ref().
7759 self_decl = DECL_ARGUMENTS (current_function_decl);
7761 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7762 * the following: warning:unused parameter `struct objc_selector * _cmd'
7764 TREE_USED (self_decl) = 1;
7765 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7766 /* Ditto for the underlying (static) C function. */
7767 TREE_USED (current_function_decl) = 1;
7768 pop_lang_context ();
7771 METHOD_DEFINITION (method) = current_function_decl;
7773 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7775 if (implementation_template != objc_implementation_context)
7778 = lookup_method_static (implementation_template,
7779 METHOD_SEL_NAME (method),
7780 TREE_CODE (method) == CLASS_METHOD_DECL);
7784 if (!comp_method_with_proto (method, proto))
7786 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7788 warn_with_method ("conflicting types for", type, method);
7789 warn_with_method ("previous declaration of", type, proto);
7794 /* We have a method @implementation even though we did not
7795 see a corresponding @interface declaration (which is allowed
7796 by Objective-C rules). Go ahead and place the method in
7797 the @interface anyway, so that message dispatch lookups
7799 tree interface = implementation_template;
7801 if (TREE_CODE (objc_implementation_context)
7802 == CATEGORY_IMPLEMENTATION_TYPE)
7803 interface = lookup_category
7805 CLASS_SUPER_NAME (objc_implementation_context));
7808 objc_add_method (interface, copy_node (method),
7809 TREE_CODE (method) == CLASS_METHOD_DECL);
7814 /* The following routine is always called...this "architecture" is to
7815 accommodate "old-style" variable length selectors.
7817 - a:a b:b // prototype ; id c; id d; // old-style. */
7820 continue_method_def (void)
7824 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7825 /* We have a `, ...' immediately following the selector. */
7826 parmlist = get_parm_info (/*ellipsis=*/true);
7828 parmlist = get_parm_info (/*ellipsis=*/false);
7831 /* Set self_decl from the first argument...this global is used by
7832 build_ivar_reference calling build_indirect_ref. */
7833 self_decl = TREE_PURPOSE (parmlist);
7834 #endif /* !OBJCPLUS */
7837 really_start_method (objc_method_context, parmlist);
7838 store_parm_decls ();
7841 static void *UOBJC_SUPER_scope = 0;
7843 /* _n_Method (id self, SEL sel, ...)
7845 struct objc_super _S;
7846 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7850 get_super_receiver (void)
7852 if (objc_method_context)
7854 tree super_expr, super_expr_list;
7856 if (!UOBJC_SUPER_decl)
7858 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7859 build_tree_list (NULL_TREE,
7860 objc_super_template),
7863 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7865 /* This prevents `unused variable' warnings when compiling with -Wall. */
7866 TREE_USED (UOBJC_SUPER_decl) = 1;
7867 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7869 UOBJC_SUPER_scope = get_current_scope ();
7872 /* Set receiver to self. */
7873 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7874 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7875 super_expr_list = super_expr;
7877 /* Set class to begin searching. */
7879 super_expr = build_component_ref (UOBJC_SUPER_decl,
7880 get_identifier ("super_class"));
7882 super_expr = build_component_ref (UOBJC_SUPER_decl,
7883 get_identifier ("class"));
7886 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7888 /* [_cls, __cls]Super are "pre-built" in
7889 synth_forward_declarations. */
7891 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7892 ((TREE_CODE (objc_method_context)
7893 == INSTANCE_METHOD_DECL)
7895 : uucls_super_ref));
7899 /* We have a category. */
7901 tree super_name = CLASS_SUPER_NAME (implementation_template);
7904 /* Barf if super used in a category of Object. */
7907 error ("no super class declared in interface for `%s'",
7908 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7909 return error_mark_node;
7912 if (flag_next_runtime && !flag_zero_link)
7914 super_class = get_class_reference (super_name);
7915 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7916 /* If we are in a class method, we must retrieve the
7917 _metaclass_ for the current class, pointed at by
7918 the class's "isa" pointer. The following assumes that
7919 "isa" is the first ivar in a class (which it must be). */
7921 = build_indirect_ref
7922 (build_c_cast (build_pointer_type (objc_class_type),
7923 super_class), "unary *");
7927 add_class_reference (super_name);
7928 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7929 ? objc_get_class_decl : objc_get_meta_class_decl);
7930 assemble_external (super_class);
7932 = build_function_call
7936 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7937 IDENTIFIER_POINTER (super_name))));
7941 = build_modify_expr (super_expr, NOP_EXPR,
7942 build_c_cast (TREE_TYPE (super_expr),
7946 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7948 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7949 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7951 return super_expr_list;
7955 error ("[super ...] must appear in a method context");
7956 return error_mark_node;
7960 /* When exiting a scope, sever links to a 'super' declaration (if any)
7961 therein contained. */
7964 objc_clear_super_receiver (void)
7966 if (objc_method_context
7967 && UOBJC_SUPER_scope == get_current_scope ()) {
7968 UOBJC_SUPER_decl = 0;
7969 UOBJC_SUPER_scope = 0;
7974 objc_expand_function_end (void)
7976 /* This routine may also get called for C functions, including those
7977 nested within ObjC methods. In such cases, method encoding is
7979 if (objc_method_context == NULL_TREE
7980 || DECL_INITIAL (objc_method_context) != current_function_decl)
7983 METHOD_ENCODING (objc_method_context)
7984 = encode_method_prototype (objc_method_context);
7988 finish_method_def (void)
7990 lang_expand_function_end = objc_expand_function_end;
7991 /* We cannot validly inline ObjC methods, at least not without a language
7992 extension to declare that a method need not be dynamically
7993 dispatched, so suppress all thoughts of doing so. */
7994 DECL_INLINE (current_function_decl) = 0;
7995 DECL_UNINLINABLE (current_function_decl) = 1;
7998 lang_expand_function_end = NULL;
8000 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8001 since the optimizer may find "may be used before set" errors. */
8002 objc_method_context = NULL_TREE;
8007 lang_report_error_function (tree decl)
8009 if (objc_method_context)
8011 fprintf (stderr, "In method `%s'\n",
8012 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8022 is_complex_decl (tree type)
8024 return (TREE_CODE (type) == ARRAY_TYPE
8025 || TREE_CODE (type) == FUNCTION_TYPE
8026 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8030 /* Code to convert a decl node into text for a declaration in C. */
8032 static char tmpbuf[256];
8035 adorn_decl (tree decl, char *str)
8037 enum tree_code code = TREE_CODE (decl);
8039 if (code == ARRAY_REF)
8041 tree an_int_cst = TREE_OPERAND (decl, 1);
8043 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8044 sprintf (str + strlen (str), "[%ld]",
8045 (long) TREE_INT_CST_LOW (an_int_cst));
8050 else if (code == ARRAY_TYPE)
8052 tree an_int_cst = TYPE_SIZE (decl);
8053 tree array_of = TREE_TYPE (decl);
8055 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8056 sprintf (str + strlen (str), "[%ld]",
8057 (long) (TREE_INT_CST_LOW (an_int_cst)
8058 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8063 else if (code == CALL_EXPR)
8065 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8070 gen_declaration_1 (chain, str);
8071 chain = TREE_CHAIN (chain);
8078 else if (code == FUNCTION_TYPE)
8080 tree chain = TYPE_ARG_TYPES (decl);
8083 while (chain && TREE_VALUE (chain) != void_type_node)
8085 gen_declaration_1 (TREE_VALUE (chain), str);
8086 chain = TREE_CHAIN (chain);
8087 if (chain && TREE_VALUE (chain) != void_type_node)
8093 else if (code == INDIRECT_REF)
8095 strcpy (tmpbuf, "*");
8096 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8100 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8102 chain = TREE_CHAIN (chain))
8104 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8106 strcat (tmpbuf, " ");
8107 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8111 strcat (tmpbuf, " ");
8113 strcat (tmpbuf, str);
8114 strcpy (str, tmpbuf);
8117 else if (code == POINTER_TYPE)
8119 strcpy (tmpbuf, "*");
8120 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8122 if (TYPE_READONLY (decl))
8123 strcat (tmpbuf, " const");
8124 if (TYPE_VOLATILE (decl))
8125 strcat (tmpbuf, " volatile");
8127 strcat (tmpbuf, " ");
8129 strcat (tmpbuf, str);
8130 strcpy (str, tmpbuf);
8135 gen_declarator (tree decl, char *buf, const char *name)
8139 enum tree_code code = TREE_CODE (decl);
8149 op = TREE_OPERAND (decl, 0);
8151 /* We have a pointer to a function or array...(*)(), (*)[] */
8152 if ((code == ARRAY_REF || code == CALL_EXPR)
8153 && op && TREE_CODE (op) == INDIRECT_REF)
8156 str = gen_declarator (op, buf, name);
8160 strcpy (tmpbuf, "(");
8161 strcat (tmpbuf, str);
8162 strcat (tmpbuf, ")");
8163 strcpy (str, tmpbuf);
8166 adorn_decl (decl, str);
8175 /* This clause is done iteratively rather than recursively. */
8178 op = (is_complex_decl (TREE_TYPE (decl))
8179 ? TREE_TYPE (decl) : NULL_TREE);
8181 adorn_decl (decl, str);
8183 /* We have a pointer to a function or array...(*)(), (*)[] */
8184 if (code == POINTER_TYPE
8185 && op && (TREE_CODE (op) == FUNCTION_TYPE
8186 || TREE_CODE (op) == ARRAY_TYPE))
8188 strcpy (tmpbuf, "(");
8189 strcat (tmpbuf, str);
8190 strcat (tmpbuf, ")");
8191 strcpy (str, tmpbuf);
8194 decl = (is_complex_decl (TREE_TYPE (decl))
8195 ? TREE_TYPE (decl) : NULL_TREE);
8198 while (decl && (code = TREE_CODE (decl)))
8203 case IDENTIFIER_NODE:
8204 /* Will only happen if we are processing a "raw" expr-decl. */
8205 strcpy (buf, IDENTIFIER_POINTER (decl));
8216 /* We have an abstract declarator or a _DECL node. */
8224 gen_declspecs (tree declspecs, char *buf, int raw)
8230 for (chain = nreverse (copy_list (declspecs));
8231 chain; chain = TREE_CHAIN (chain))
8233 tree aspec = TREE_VALUE (chain);
8235 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8236 strcat (buf, IDENTIFIER_POINTER (aspec));
8237 else if (TREE_CODE (aspec) == RECORD_TYPE)
8239 if (OBJC_TYPE_NAME (aspec))
8241 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8243 if (! TREE_STATIC_TEMPLATE (aspec))
8244 strcat (buf, "struct ");
8245 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8250 tree chain = protocol_list;
8257 (PROTOCOL_NAME (TREE_VALUE (chain))));
8258 chain = TREE_CHAIN (chain);
8267 strcat (buf, "untagged struct");
8270 else if (TREE_CODE (aspec) == UNION_TYPE)
8272 if (OBJC_TYPE_NAME (aspec))
8274 if (! TREE_STATIC_TEMPLATE (aspec))
8275 strcat (buf, "union ");
8276 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8279 strcat (buf, "untagged union");
8282 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8284 if (OBJC_TYPE_NAME (aspec))
8286 if (! TREE_STATIC_TEMPLATE (aspec))
8287 strcat (buf, "enum ");
8288 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8291 strcat (buf, "untagged enum");
8294 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8295 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8297 else if (IS_ID (aspec))
8299 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8304 tree chain = protocol_list;
8311 (PROTOCOL_NAME (TREE_VALUE (chain))));
8312 chain = TREE_CHAIN (chain);
8319 if (TREE_CHAIN (chain))
8325 /* Type qualifiers. */
8326 if (TYPE_READONLY (declspecs))
8327 strcat (buf, "const ");
8328 if (TYPE_VOLATILE (declspecs))
8329 strcat (buf, "volatile ");
8331 switch (TREE_CODE (declspecs))
8333 /* Type specifiers. */
8336 declspecs = TYPE_MAIN_VARIANT (declspecs);
8338 /* Signed integer types. */
8340 if (declspecs == short_integer_type_node)
8341 strcat (buf, "short int ");
8342 else if (declspecs == integer_type_node)
8343 strcat (buf, "int ");
8344 else if (declspecs == long_integer_type_node)
8345 strcat (buf, "long int ");
8346 else if (declspecs == long_long_integer_type_node)
8347 strcat (buf, "long long int ");
8348 else if (declspecs == signed_char_type_node
8349 || declspecs == char_type_node)
8350 strcat (buf, "char ");
8352 /* Unsigned integer types. */
8354 else if (declspecs == short_unsigned_type_node)
8355 strcat (buf, "unsigned short ");
8356 else if (declspecs == unsigned_type_node)
8357 strcat (buf, "unsigned int ");
8358 else if (declspecs == long_unsigned_type_node)
8359 strcat (buf, "unsigned long ");
8360 else if (declspecs == long_long_unsigned_type_node)
8361 strcat (buf, "unsigned long long ");
8362 else if (declspecs == unsigned_char_type_node)
8363 strcat (buf, "unsigned char ");
8367 declspecs = TYPE_MAIN_VARIANT (declspecs);
8369 if (declspecs == float_type_node)
8370 strcat (buf, "float ");
8371 else if (declspecs == double_type_node)
8372 strcat (buf, "double ");
8373 else if (declspecs == long_double_type_node)
8374 strcat (buf, "long double ");
8378 if (OBJC_TYPE_NAME (declspecs)
8379 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8381 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8383 if (! TREE_STATIC_TEMPLATE (declspecs))
8384 strcat (buf, "struct ");
8385 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8389 tree chain = protocol_list;
8396 (PROTOCOL_NAME (TREE_VALUE (chain))));
8397 chain = TREE_CHAIN (chain);
8406 strcat (buf, "untagged struct");
8412 if (OBJC_TYPE_NAME (declspecs)
8413 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8415 strcat (buf, "union ");
8416 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8421 strcat (buf, "untagged union ");
8425 if (OBJC_TYPE_NAME (declspecs)
8426 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8428 strcat (buf, "enum ");
8429 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8434 strcat (buf, "untagged enum ");
8438 strcat (buf, "void ");
8443 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8448 tree chain = protocol_list;
8455 (PROTOCOL_NAME (TREE_VALUE (chain))));
8456 chain = TREE_CHAIN (chain);
8472 /* Given a tree node, produce a printable description of it in the given
8473 buffer, overwriting the buffer. */
8476 gen_declaration (tree atype_or_adecl, char *buf)
8479 gen_declaration_1 (atype_or_adecl, buf);
8483 /* Given a tree node, append a printable description to the end of the
8487 gen_declaration_1 (tree atype_or_adecl, char *buf)
8491 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8493 tree declspecs; /* "identifier_node", "record_type" */
8494 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8495 tree width = NULL_TREE; /* for bitfields */
8497 /* We have a "raw", abstract declarator (typename). */
8498 declarator = TREE_VALUE (atype_or_adecl);
8499 /* In the case of raw ivars, the declarator itself is a list,
8500 and contains bitfield widths. */
8501 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8503 width = TREE_VALUE (declarator);
8504 declarator = TREE_PURPOSE (declarator);
8506 declspecs = TREE_PURPOSE (atype_or_adecl);
8508 gen_declspecs (declspecs, buf, 1);
8512 strcat (buf, gen_declarator (declarator, declbuf, ""));
8515 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8516 TREE_INT_CST_LOW (width));
8522 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8523 tree declarator; /* "array_type", "function_type", "pointer_type". */
8525 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8526 || TREE_CODE (atype_or_adecl) == PARM_DECL
8527 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8528 atype = TREE_TYPE (atype_or_adecl);
8530 /* Assume we have a *_type node. */
8531 atype = atype_or_adecl;
8533 if (is_complex_decl (atype))
8537 /* Get the declaration specifier; it is at the end of the list. */
8538 declarator = chain = atype;
8540 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8541 while (is_complex_decl (chain));
8548 declarator = NULL_TREE;
8551 gen_declspecs (declspecs, buf, 0);
8553 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8554 || TREE_CODE (atype_or_adecl) == PARM_DECL
8555 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8557 const char *const decl_name =
8558 (DECL_NAME (atype_or_adecl)
8559 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8564 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8567 else if (decl_name[0])
8570 strcat (buf, decl_name);
8573 else if (declarator)
8576 strcat (buf, gen_declarator (declarator, declbuf, ""));
8581 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8583 /* Given a method tree, put a printable description into the given
8584 buffer (overwriting) and return a pointer to the buffer. */
8587 gen_method_decl (tree method, char *buf)
8592 if (RAW_TYPESPEC (method) != objc_object_reference)
8595 gen_declaration_1 (TREE_TYPE (method), buf);
8599 chain = METHOD_SEL_ARGS (method);
8602 /* We have a chain of keyword_decls. */
8605 if (KEYWORD_KEY_NAME (chain))
8606 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8609 if (RAW_TYPESPEC (chain) != objc_object_reference)
8612 gen_declaration_1 (TREE_TYPE (chain), buf);
8616 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8617 if ((chain = TREE_CHAIN (chain)))
8622 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8623 strcat (buf, ", ...");
8624 else if (METHOD_ADD_ARGS (method))
8626 /* We have a tree list node as generate by get_parm_info. */
8627 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8629 /* Know we have a chain of parm_decls. */
8633 gen_declaration_1 (chain, buf);
8634 chain = TREE_CHAIN (chain);
8640 /* We have a unary selector. */
8641 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8649 /* Dump an @interface declaration of the supplied class CHAIN to the
8650 supplied file FP. Used to implement the -gen-decls option (which
8651 prints out an @interface declaration of all classes compiled in
8652 this run); potentially useful for debugging the compiler too. */
8654 dump_interface (FILE *fp, tree chain)
8656 /* FIXME: A heap overflow here whenever a method (or ivar)
8657 declaration is so long that it doesn't fit in the buffer. The
8658 code and all the related functions should be rewritten to avoid
8659 using fixed size buffers. */
8660 char *buf = (char *) xmalloc (1024 * 10);
8661 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8662 tree ivar_decls = CLASS_RAW_IVARS (chain);
8663 tree nst_methods = CLASS_NST_METHODS (chain);
8664 tree cls_methods = CLASS_CLS_METHODS (chain);
8666 fprintf (fp, "\n@interface %s", my_name);
8668 /* CLASS_SUPER_NAME is used to store the superclass name for
8669 classes, and the category name for categories. */
8670 if (CLASS_SUPER_NAME (chain))
8672 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8674 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8675 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8677 fprintf (fp, " (%s)\n", name);
8681 fprintf (fp, " : %s\n", name);
8687 /* FIXME - the following doesn't seem to work at the moment. */
8690 fprintf (fp, "{\n");
8693 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8694 ivar_decls = TREE_CHAIN (ivar_decls);
8697 fprintf (fp, "}\n");
8702 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8703 nst_methods = TREE_CHAIN (nst_methods);
8708 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8709 cls_methods = TREE_CHAIN (cls_methods);
8712 fprintf (fp, "@end\n");
8715 /* Demangle function for Objective-C */
8717 objc_demangle (const char *mangled)
8719 char *demangled, *cp;
8721 if (mangled[0] == '_' &&
8722 (mangled[1] == 'i' || mangled[1] == 'c') &&
8725 cp = demangled = xmalloc(strlen(mangled) + 2);
8726 if (mangled[1] == 'i')
8727 *cp++ = '-'; /* for instance method */
8729 *cp++ = '+'; /* for class method */
8730 *cp++ = '['; /* opening left brace */
8731 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8732 while (*cp && *cp == '_')
8733 cp++; /* skip any initial underbars in class name */
8734 cp = strchr(cp, '_'); /* find first non-initial underbar */
8737 free(demangled); /* not mangled name */
8740 if (cp[1] == '_') /* easy case: no category name */
8742 *cp++ = ' '; /* replace two '_' with one ' ' */
8743 strcpy(cp, mangled + (cp - demangled) + 2);
8747 *cp++ = '('; /* less easy case: category name */
8748 cp = strchr(cp, '_');
8751 free(demangled); /* not mangled name */
8755 *cp++ = ' '; /* overwriting 1st char of method name... */
8756 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8758 while (*cp && *cp == '_')
8759 cp++; /* skip any initial underbars in method name */
8762 *cp = ':'; /* replace remaining '_' with ':' */
8763 *cp++ = ']'; /* closing right brace */
8764 *cp++ = 0; /* string terminator */
8768 return mangled; /* not an objc mangled name */
8772 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8774 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8780 gcc_obstack_init (&util_obstack);
8781 util_firstobj = (char *) obstack_finish (&util_obstack);
8783 errbuf = (char *) xmalloc (BUFSIZE);
8785 synth_module_prologue ();
8791 struct imp_entry *impent;
8793 /* The internally generated initializers appear to have missing braces.
8794 Don't warn about this. */
8795 int save_warn_missing_braces = warn_missing_braces;
8796 warn_missing_braces = 0;
8798 /* A missing @end may not be detected by the parser. */
8799 if (objc_implementation_context)
8801 warning ("`@end' missing in implementation context");
8802 finish_class (objc_implementation_context);
8803 objc_ivar_chain = NULL_TREE;
8804 objc_implementation_context = NULL_TREE;
8807 /* Process the static instances here because initialization of objc_symtab
8809 if (objc_static_instances)
8810 generate_static_references ();
8812 if (imp_list || class_names_chain
8813 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8814 generate_objc_symtab_decl ();
8816 for (impent = imp_list; impent; impent = impent->next)
8818 objc_implementation_context = impent->imp_context;
8819 implementation_template = impent->imp_template;
8821 UOBJC_CLASS_decl = impent->class_decl;
8822 UOBJC_METACLASS_decl = impent->meta_decl;
8824 /* Dump the @interface of each class as we compile it, if the
8825 -gen-decls option is in use. TODO: Dump the classes in the
8826 order they were found, rather than in reverse order as we
8828 if (flag_gen_declaration)
8830 dump_interface (gen_declaration_file, objc_implementation_context);
8833 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8835 /* all of the following reference the string pool... */
8836 generate_ivar_lists ();
8837 generate_dispatch_tables ();
8838 generate_shared_structures ();
8842 generate_dispatch_tables ();
8843 generate_category (objc_implementation_context);
8847 /* If we are using an array of selectors, we must always
8848 finish up the array decl even if no selectors were used. */
8849 if (! flag_next_runtime || sel_ref_chain)
8850 build_selector_translation_table ();
8853 generate_protocols ();
8855 if (flag_replace_objc_classes && imp_list)
8856 generate_objc_image_info ();
8858 if (objc_implementation_context || class_names_chain || objc_static_instances
8859 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8861 /* Arrange for ObjC data structures to be initialized at run time. */
8862 rtx init_sym = build_module_descriptor ();
8863 if (init_sym && targetm.have_ctors_dtors)
8864 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8867 /* Dump the class references. This forces the appropriate classes
8868 to be linked into the executable image, preserving unix archive
8869 semantics. This can be removed when we move to a more dynamically
8870 linked environment. */
8872 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8874 handle_class_ref (chain);
8875 if (TREE_PURPOSE (chain))
8876 generate_classref_translation_entry (chain);
8879 for (impent = imp_list; impent; impent = impent->next)
8880 handle_impent (impent);
8882 /* Dump the string table last. */
8884 generate_strings ();
8891 /* Run through the selector hash tables and print a warning for any
8892 selector which has multiple methods. */
8894 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8896 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8897 check_duplicates (hsh, 0, 1);
8898 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8899 check_duplicates (hsh, 0, 1);
8903 warn_missing_braces = save_warn_missing_braces;
8906 /* Subroutines of finish_objc. */
8909 generate_classref_translation_entry (tree chain)
8911 tree expr, name, decl_specs, decl, sc_spec;
8914 type = TREE_TYPE (TREE_PURPOSE (chain));
8916 expr = add_objc_string (TREE_VALUE (chain), class_names);
8917 expr = build_c_cast (type, expr); /* cast! */
8919 name = DECL_NAME (TREE_PURPOSE (chain));
8921 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8923 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8924 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8926 /* The decl that is returned from start_decl is the one that we
8927 forward declared in build_class_reference. */
8928 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8929 DECL_CONTEXT (decl) = NULL_TREE;
8930 finish_decl (decl, expr, NULL_TREE);
8935 handle_class_ref (tree chain)
8937 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8938 char *string = (char *) alloca (strlen (name) + 30);
8942 sprintf (string, "%sobjc_class_name_%s",
8943 (flag_next_runtime ? "." : "__"), name);
8945 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8946 if (flag_next_runtime)
8948 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8953 /* Make a decl for this name, so we can use its address in a tree. */
8954 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8955 DECL_EXTERNAL (decl) = 1;
8956 TREE_PUBLIC (decl) = 1;
8959 rest_of_decl_compilation (decl, 0, 0);
8961 /* Make a decl for the address. */
8962 sprintf (string, "%sobjc_class_ref_%s",
8963 (flag_next_runtime ? "." : "__"), name);
8964 exp = build1 (ADDR_EXPR, string_type_node, decl);
8965 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8966 DECL_INITIAL (decl) = exp;
8967 TREE_STATIC (decl) = 1;
8968 TREE_USED (decl) = 1;
8971 rest_of_decl_compilation (decl, 0, 0);
8975 handle_impent (struct imp_entry *impent)
8979 objc_implementation_context = impent->imp_context;
8980 implementation_template = impent->imp_template;
8982 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8984 const char *const class_name =
8985 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8987 string = (char *) alloca (strlen (class_name) + 30);
8989 sprintf (string, "%sobjc_class_name_%s",
8990 (flag_next_runtime ? "." : "__"), class_name);
8992 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8994 const char *const class_name =
8995 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8996 const char *const class_super_name =
8997 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8999 string = (char *) alloca (strlen (class_name)
9000 + strlen (class_super_name) + 30);
9002 /* Do the same for categories. Even though no references to
9003 these symbols are generated automatically by the compiler, it
9004 gives you a handle to pull them into an archive by hand. */
9005 sprintf (string, "*%sobjc_category_name_%s_%s",
9006 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9011 #ifdef ASM_DECLARE_CLASS_REFERENCE
9012 if (flag_next_runtime)
9014 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9022 init = build_int_cst (NULL_TREE, 0, 0);
9023 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
9024 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9025 TREE_PUBLIC (decl) = 1;
9026 TREE_READONLY (decl) = 1;
9027 TREE_USED (decl) = 1;
9028 TREE_CONSTANT (decl) = 1;
9029 DECL_CONTEXT (decl) = 0;
9030 DECL_ARTIFICIAL (decl) = 1;
9031 DECL_INITIAL (decl) = init;
9032 assemble_variable (decl, 1, 0, 0);
9036 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9037 later requires that ObjC translation units participating in F&C be
9038 specially marked. The following routine accomplishes this. */
9040 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9043 generate_objc_image_info (void)
9045 tree sc_spec, decl, initlist;
9047 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9049 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9050 tree_cons (NULL_TREE,
9053 build_index_type (build_int_cst (NULL_TREE, 1, 0))),
9058 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0, 0));
9059 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1, 0), initlist);
9060 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9062 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9063 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9064 finish_decl (decl, initlist, NULL_TREE);
9067 /* Look up ID as an instance variable. */
9070 lookup_objc_ivar (tree id)
9074 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9075 /* We have a message to super. */
9076 return get_super_receiver ();
9077 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9079 if (is_private (decl))
9082 return build_ivar_reference (id);
9088 #include "gt-objc-objc-act.h"