1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 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"
63 #include "diagnostic.h"
66 #define OBJC_VOID_AT_END build_tree_list (NULL_TREE, void_type_node)
68 /* This is the default way of generating a method name. */
69 /* I am not sure it is really correct.
70 Perhaps there's a danger that it will make name conflicts
71 if method names contain underscores. -- rms. */
72 #ifndef OBJC_GEN_METHOD_LABEL
73 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
76 sprintf ((BUF), "_%s_%s_%s_%s", \
77 ((IS_INST) ? "i" : "c"), \
79 ((CAT_NAME)? (CAT_NAME) : ""), \
81 for (temp = (BUF); *temp; temp++) \
82 if (*temp == ':') *temp = '_'; \
86 /* These need specifying. */
87 #ifndef OBJC_FORWARDING_STACK_OFFSET
88 #define OBJC_FORWARDING_STACK_OFFSET 0
91 #ifndef OBJC_FORWARDING_MIN_OFFSET
92 #define OBJC_FORWARDING_MIN_OFFSET 0
95 /* Set up for use of obstacks. */
99 /* This obstack is used to accumulate the encoding of a data type. */
100 static struct obstack util_obstack;
102 /* This points to the beginning of obstack contents, so we can free
103 the whole contents. */
106 /* The version identifies which language generation and runtime
107 the module (file) was compiled for, and is recorded in the
108 module descriptor. */
110 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
111 #define PROTOCOL_VERSION 2
113 /* (Decide if these can ever be validly changed.) */
114 #define OBJC_ENCODE_INLINE_DEFS 0
115 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
117 /*** Private Interface (procedures) ***/
119 /* Used by compile_file. */
121 static void init_objc (void);
122 static void finish_objc (void);
124 /* Code generation. */
126 static void synth_module_prologue (void);
127 static tree objc_build_constructor (tree, tree);
128 static rtx build_module_descriptor (void);
129 static tree init_module_descriptor (tree);
130 static tree build_objc_method_call (int, tree, tree, tree, tree);
131 static void generate_strings (void);
132 static tree get_proto_encoding (tree);
133 static void build_selector_translation_table (void);
135 static tree objc_add_static_instance (tree, tree);
137 static void build_objc_exception_stuff (void);
138 static tree objc_declare_variable (enum rid, tree, tree, tree);
139 static tree objc_enter_block (void);
140 static tree objc_exit_block (void);
141 static void objc_build_try_enter_fragment (void);
142 static void objc_build_try_exit_fragment (void);
143 static void objc_build_extract_fragment (void);
144 static tree objc_build_extract_expr (void);
146 static tree build_ivar_template (void);
147 static tree build_method_template (void);
148 static tree build_private_template (tree);
149 static void build_class_template (void);
150 static void build_selector_template (void);
151 static void build_category_template (void);
152 static tree lookup_method_in_hash_lists (tree, int);
153 static void build_super_template (void);
154 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
155 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
156 static void synth_forward_declarations (void);
157 static int ivar_list_length (tree);
158 static tree get_class_ivars (tree, int);
159 static void generate_ivar_lists (void);
160 static void generate_dispatch_tables (void);
161 static void generate_shared_structures (void);
162 static tree generate_protocol_list (tree);
163 static void generate_forward_declaration_to_string_table (void);
164 static void build_protocol_reference (tree);
166 static tree build_keyword_selector (tree);
167 static tree synth_id_with_class_suffix (const char *, tree);
169 static void generate_static_references (void);
170 static int check_methods_accessible (tree, tree, int);
171 static void encode_aggregate_within (tree, int, int, int, int);
172 static const char *objc_demangle (const char *);
173 static void objc_expand_function_end (void);
175 /* Hash tables to manage the global pool of method prototypes. */
177 hash *nst_method_hash_list = 0;
178 hash *cls_method_hash_list = 0;
180 static size_t hash_func (tree);
181 static void hash_init (void);
182 static void hash_enter (hash *, tree);
183 static hash hash_lookup (hash *, tree);
184 static void hash_add_attr (hash, tree);
185 static tree lookup_method (tree, tree);
186 static tree lookup_method_static (tree, tree, int);
187 static void add_method_to_hash_list (hash *, tree);
188 static tree add_class (tree);
189 static void add_category (tree, tree);
190 static inline tree lookup_category (tree, tree);
194 class_names, /* class, category, protocol, module names */
195 meth_var_names, /* method and variable names */
196 meth_var_types /* method and variable type descriptors */
199 static tree add_objc_string (tree, enum string_section);
200 static tree get_objc_string_decl (tree, enum string_section);
201 static tree build_objc_string_decl (enum string_section);
202 static tree build_selector_reference_decl (void);
204 /* Protocol additions. */
206 static tree add_protocol (tree);
207 static tree lookup_protocol (tree);
208 static void check_protocol_recursively (tree, tree);
209 static tree lookup_and_install_protocols (tree);
213 static void encode_type_qualifiers (tree);
214 static void encode_pointer (tree, int, int);
215 static void encode_array (tree, int, int);
216 static void encode_aggregate (tree, int, int);
217 static void encode_next_bitfield (int);
218 static void encode_gnu_bitfield (int, tree, int);
219 static void encode_type (tree, int, int);
220 static void encode_field_decl (tree, int, int);
222 static void really_start_method (tree, tree);
223 static int comp_method_with_proto (tree, tree);
224 static int objc_types_are_equivalent (tree, tree);
225 static int comp_proto_with_proto (tree, tree);
226 static tree get_arg_type_list (tree, int, int);
227 static tree objc_expr_last (tree);
228 static void synth_self_and_ucmd_args (void);
230 /* Utilities for debugging and error diagnostics. */
232 static void warn_with_method (const char *, int, tree);
233 static void error_with_ivar (const char *, tree, tree);
234 static char *gen_method_decl (tree, char *);
235 static char *gen_declaration (tree, char *);
236 static void gen_declaration_1 (tree, char *);
237 static char *gen_declarator (tree, char *, const char *);
238 static int is_complex_decl (tree);
239 static void adorn_decl (tree, char *);
240 static void dump_interface (FILE *, tree);
242 /* Everything else. */
244 static tree define_decl (tree, tree);
245 static tree lookup_method_in_protocol_list (tree, tree, int);
246 static tree lookup_protocol_in_reflist (tree, tree);
247 static tree create_builtin_decl (enum tree_code, tree, const char *);
248 static void setup_string_decl (void);
249 static int check_string_class_template (void);
250 static tree my_build_string (int, const char *);
251 static void build_objc_symtab_template (void);
252 static tree init_def_list (tree);
253 static tree init_objc_symtab (tree);
254 static tree build_metadata_decl (const char *, tree);
255 static void forward_declare_categories (void);
256 static void generate_objc_symtab_decl (void);
257 static tree build_selector (tree);
258 static tree build_typed_selector_reference (tree, tree);
259 static tree build_selector_reference (tree);
260 static tree build_class_reference_decl (void);
261 static void add_class_reference (tree);
262 static tree build_protocol_template (void);
263 static tree build_descriptor_table_initializer (tree, tree);
264 static tree build_method_prototype_list_template (tree, int);
265 static tree build_method_prototype_template (void);
266 static tree objc_method_parm_type (tree);
267 static int objc_encoded_type_size (tree);
268 static tree encode_method_prototype (tree);
269 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
270 static void generate_method_descriptors (tree);
271 static void generate_protocol_references (tree);
272 static void generate_protocols (void);
273 static void check_ivars (tree, tree);
274 static tree build_ivar_list_template (tree, int);
275 static tree build_method_list_template (tree, int);
276 static tree build_ivar_list_initializer (tree, tree);
277 static tree generate_ivars_list (tree, const char *, int, tree);
278 static tree build_dispatch_table_initializer (tree, tree);
279 static tree generate_dispatch_table (tree, const char *, int, tree);
280 static tree build_shared_structure_initializer (tree, tree, tree, tree,
281 tree, int, tree, tree, tree);
282 static void generate_category (tree);
283 static int is_objc_type_qualifier (tree);
284 static tree adjust_type_for_id_default (tree);
285 static tree check_duplicates (hash, int, int);
286 static tree receiver_is_class_object (tree, int, int);
287 static int check_methods (tree, tree, int);
288 static int conforms_to_protocol (tree, tree);
289 static void check_protocol (tree, const char *, const char *);
290 static void check_protocols (tree, const char *, const char *);
291 static void gen_declspecs (tree, char *, int);
292 static void generate_classref_translation_entry (tree);
293 static void handle_class_ref (tree);
294 static void generate_struct_by_value_array (void)
296 static void mark_referenced_methods (void);
297 static void generate_objc_image_info (void);
299 /*** Private Interface (data) ***/
301 /* Reserved tag definitions. */
304 #define TAG_OBJECT "objc_object"
305 #define TAG_CLASS "objc_class"
306 #define TAG_SUPER "objc_super"
307 #define TAG_SELECTOR "objc_selector"
309 #define UTAG_CLASS "_objc_class"
310 #define UTAG_IVAR "_objc_ivar"
311 #define UTAG_IVAR_LIST "_objc_ivar_list"
312 #define UTAG_METHOD "_objc_method"
313 #define UTAG_METHOD_LIST "_objc_method_list"
314 #define UTAG_CATEGORY "_objc_category"
315 #define UTAG_MODULE "_objc_module"
316 #define UTAG_SYMTAB "_objc_symtab"
317 #define UTAG_SUPER "_objc_super"
318 #define UTAG_SELECTOR "_objc_selector"
320 #define UTAG_PROTOCOL "_objc_protocol"
321 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
322 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
324 /* Note that the string object global name is only needed for the
326 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
328 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
330 static const char *TAG_GETCLASS;
331 static const char *TAG_GETMETACLASS;
332 static const char *TAG_MSGSEND;
333 static const char *TAG_MSGSENDSUPER;
334 /* The NeXT Objective-C messenger may have two extra entry points, for use
335 when returning a structure. */
336 static const char *TAG_MSGSEND_STRET;
337 static const char *TAG_MSGSENDSUPER_STRET;
338 static const char *TAG_EXECCLASS;
339 static const char *default_constant_string_class_name;
341 /* Runtime metadata flags. */
342 #define CLS_FACTORY 0x0001L
343 #define CLS_META 0x0002L
345 #define OBJC_MODIFIER_STATIC 0x00000001
346 #define OBJC_MODIFIER_FINAL 0x00000002
347 #define OBJC_MODIFIER_PUBLIC 0x00000004
348 #define OBJC_MODIFIER_PRIVATE 0x00000008
349 #define OBJC_MODIFIER_PROTECTED 0x00000010
350 #define OBJC_MODIFIER_NATIVE 0x00000020
351 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
352 #define OBJC_MODIFIER_ABSTRACT 0x00000080
353 #define OBJC_MODIFIER_VOLATILE 0x00000100
354 #define OBJC_MODIFIER_TRANSIENT 0x00000200
355 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
357 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
358 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
359 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
360 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
361 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
362 #define TAG_EXCEPTIONMATCH "objc_exception_match"
363 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
364 #define TAG_SYNCENTER "objc_sync_enter"
365 #define TAG_SYNCEXIT "objc_sync_exit"
366 #define TAG_SETJMP "_setjmp"
367 #define TAG_RETURN_STRUCT "objc_return_struct"
369 #define UTAG_EXCDATA "_objc_exception_data"
370 #define UTAG_EXCDATA_VAR "_stackExceptionData"
371 #define UTAG_CAUGHTEXC_VAR "_caughtException"
372 #define UTAG_RETHROWEXC_VAR "_rethrowException"
373 #define UTAG_EVALONCE_VAR "_eval_once"
377 struct val_stack *next;
379 static struct val_stack *catch_count_stack, *exc_binding_stack;
381 /* useful for debugging */
382 static int if_nesting_count;
383 static int blk_nesting_count;
385 static void val_stack_push (struct val_stack **, long);
386 static void val_stack_pop (struct val_stack **);
388 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
389 tree objc_global_trees[OCTI_MAX];
391 static void handle_impent (struct imp_entry *);
393 struct imp_entry *imp_list = 0;
394 int imp_count = 0; /* `@implementation' */
395 int cat_count = 0; /* `@category' */
397 /* Use to generate method labels. */
398 static int method_slot = 0;
402 static char *errbuf; /* Buffer for error diagnostics */
404 /* Data imported from tree.c. */
406 extern enum debug_info_type write_symbols;
408 /* Data imported from toplev.c. */
410 extern const char *dump_base_name;
412 static int flag_typed_selectors;
414 FILE *gen_declaration_file;
416 /* Tells "encode_pointer/encode_aggregate" whether we are generating
417 type descriptors for instance variables (as opposed to methods).
418 Type descriptors for instance variables contain more information
419 than methods (for static typing and embedded structures). */
421 static int generating_instance_variables = 0;
423 /* Some platforms pass small structures through registers versus
424 through an invisible pointer. Determine at what size structure is
425 the transition point between the two possibilities. */
428 generate_struct_by_value_array (void)
431 tree field_decl, field_decl_chain;
433 int aggregate_in_mem[32];
436 /* Presumably no platform passes 32 byte structures in a register. */
437 for (i = 1; i < 32; i++)
441 /* Create an unnamed struct that has `i' character components */
442 type = start_struct (RECORD_TYPE, NULL_TREE);
444 strcpy (buffer, "c1");
445 field_decl = create_builtin_decl (FIELD_DECL,
448 field_decl_chain = field_decl;
450 for (j = 1; j < i; j++)
452 sprintf (buffer, "c%d", j + 1);
453 field_decl = create_builtin_decl (FIELD_DECL,
456 chainon (field_decl_chain, field_decl);
458 finish_struct (type, field_decl_chain, NULL_TREE);
460 aggregate_in_mem[i] = aggregate_value_p (type, 0);
461 if (!aggregate_in_mem[i])
465 /* We found some structures that are returned in registers instead of memory
466 so output the necessary data. */
469 for (i = 31; i >= 0; i--)
470 if (!aggregate_in_mem[i])
472 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
474 /* The first member of the structure is always 0 because we don't handle
475 structures with 0 members */
476 printf ("static int struct_forward_array[] = {\n 0");
478 for (j = 1; j <= i; j++)
479 printf (", %d", aggregate_in_mem[j]);
489 if (c_objc_common_init () == false)
492 /* Force the line number back to 0; check_newline will have
493 raised it to 1, which will make the builtin functions appear
494 not to be built in. */
497 /* If gen_declaration desired, open the output file. */
498 if (flag_gen_declaration)
500 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
501 gen_declaration_file = fopen (dumpname, "w");
502 if (gen_declaration_file == 0)
503 fatal_error ("can't open %s: %m", dumpname);
507 if (flag_next_runtime)
509 TAG_GETCLASS = "objc_getClass";
510 TAG_GETMETACLASS = "objc_getMetaClass";
511 TAG_MSGSEND = "objc_msgSend";
512 TAG_MSGSENDSUPER = "objc_msgSendSuper";
513 TAG_MSGSEND_STRET = "objc_msgSend_stret";
514 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
515 TAG_EXECCLASS = "__objc_execClass";
516 default_constant_string_class_name = "NSConstantString";
520 TAG_GETCLASS = "objc_get_class";
521 TAG_GETMETACLASS = "objc_get_meta_class";
522 TAG_MSGSEND = "objc_msg_lookup";
523 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
524 /* GNU runtime does not provide special functions to support
525 structure-returning methods. */
526 TAG_EXECCLASS = "__objc_exec_class";
527 default_constant_string_class_name = "NXConstantString";
528 flag_typed_selectors = 1;
531 objc_ellipsis_node = make_node (ERROR_MARK);
535 if (print_struct_values)
536 generate_struct_by_value_array ();
544 mark_referenced_methods ();
545 c_objc_common_finish_file ();
547 /* Finalize Objective-C runtime data. No need to generate tables
548 and code if only checking syntax. */
549 if (!flag_syntax_only)
552 if (gen_declaration_file)
553 fclose (gen_declaration_file);
557 define_decl (tree declarator, tree declspecs)
559 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
560 finish_decl (decl, NULL_TREE, NULL_TREE);
565 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
571 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
573 p = TREE_VALUE (rproto);
575 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
577 if ((fnd = lookup_method (class_meth
578 ? PROTOCOL_CLS_METHODS (p)
579 : PROTOCOL_NST_METHODS (p), sel_name)))
581 else if (PROTOCOL_LIST (p))
582 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
583 sel_name, class_meth);
587 ; /* An identifier...if we could not find a protocol. */
598 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
602 /* Make sure the protocol is supported by the object on the rhs. */
603 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
606 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
608 p = TREE_VALUE (rproto);
610 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
615 else if (PROTOCOL_LIST (p))
616 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
625 ; /* An identifier...if we could not find a protocol. */
631 /* Return 1 if LHS and RHS are compatible types for assignment or
632 various other operations. Return 0 if they are incompatible, and
633 return -1 if we choose to not decide (because the types are really
634 just C types, not ObjC specific ones). When the operation is
635 REFLEXIVE (typically comparisons), check for compatibility in
636 either direction; when it's not (typically assignments), don't.
638 This function is called in two cases: when both lhs and rhs are
639 pointers to records (in which case we check protocols too), and
640 when both lhs and rhs are records (in which case we check class
643 Warnings about classes/protocols not implementing a protocol are
644 emitted here (multiple of those warnings might be emitted for a
645 single line!); generic warnings about incompatible assignments and
646 lacks of casts in comparisons are/must be emitted by the caller if
651 objc_comptypes (tree lhs, tree rhs, int reflexive)
653 /* New clause for protocols. */
655 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
656 manage the ObjC ones, and leave the rest to the C code. */
657 if (TREE_CODE (lhs) == POINTER_TYPE
658 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
659 && TREE_CODE (rhs) == POINTER_TYPE
660 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
662 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
663 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
667 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
668 tree rproto, rproto_list;
671 /* <Protocol> = <Protocol> */
674 rproto_list = TYPE_PROTOCOL_LIST (rhs);
678 /* An assignment between objects of type 'id
679 <Protocol>'; make sure the protocol on the lhs is
680 supported by the object on the rhs. */
681 for (lproto = lproto_list; lproto;
682 lproto = TREE_CHAIN (lproto))
684 p = TREE_VALUE (lproto);
685 rproto = lookup_protocol_in_reflist (rproto_list, p);
689 ("object does not conform to the `%s' protocol",
690 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
696 /* Obscure case - a comparison between two objects
697 of type 'id <Protocol>'. Check that either the
698 protocol on the lhs is supported by the object on
699 the rhs, or viceversa. */
701 /* Check if the protocol on the lhs is supported by the
702 object on the rhs. */
703 for (lproto = lproto_list; lproto;
704 lproto = TREE_CHAIN (lproto))
706 p = TREE_VALUE (lproto);
707 rproto = lookup_protocol_in_reflist (rproto_list, p);
711 /* Check failed - check if the protocol on the rhs
712 is supported by the object on the lhs. */
713 for (rproto = rproto_list; rproto;
714 rproto = TREE_CHAIN (rproto))
716 p = TREE_VALUE (rproto);
717 lproto = lookup_protocol_in_reflist (lproto_list,
722 /* This check failed too: incompatible */
732 /* <Protocol> = <class> * */
733 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
735 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
738 /* Make sure the protocol is supported by the object on
740 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
742 p = TREE_VALUE (lproto);
744 rinter = lookup_interface (rname);
746 while (rinter && !rproto)
750 rproto_list = CLASS_PROTOCOL_LIST (rinter);
751 rproto = lookup_protocol_in_reflist (rproto_list, p);
752 /* If the underlying ObjC class does not have
753 the protocol we're looking for, check for "one-off"
754 protocols (e.g., `NSObject<MyProt> *foo;') attached
758 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
759 rproto = lookup_protocol_in_reflist (rproto_list, p);
762 /* Check for protocols adopted by categories. */
763 cat = CLASS_CATEGORY_LIST (rinter);
764 while (cat && !rproto)
766 rproto_list = CLASS_PROTOCOL_LIST (cat);
767 rproto = lookup_protocol_in_reflist (rproto_list, p);
768 cat = CLASS_CATEGORY_LIST (cat);
771 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
775 warning ("class `%s' does not implement the `%s' protocol",
776 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
777 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
781 /* <Protocol> = id */
782 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
786 /* <Protocol> = Class */
787 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
791 /* <Protocol> = ?? : let comptypes decide. */
794 else if (rhs_is_proto)
796 /* <class> * = <Protocol> */
797 if (TYPED_OBJECT (TREE_TYPE (lhs)))
801 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
803 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
805 /* Make sure the protocol is supported by the object on
807 for (rproto = rproto_list; rproto;
808 rproto = TREE_CHAIN (rproto))
810 tree p = TREE_VALUE (rproto);
812 rinter = lookup_interface (rname);
814 while (rinter && !lproto)
818 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
819 lproto = lookup_protocol_in_reflist (lproto_list, p);
820 /* If the underlying ObjC class does not
821 have the protocol we're looking for,
822 check for "one-off" protocols (e.g.,
823 `NSObject<MyProt> *foo;') attached to the
827 lproto_list = TYPE_PROTOCOL_LIST
829 lproto = lookup_protocol_in_reflist
833 /* Check for protocols adopted by categories. */
834 cat = CLASS_CATEGORY_LIST (rinter);
835 while (cat && !lproto)
837 lproto_list = CLASS_PROTOCOL_LIST (cat);
838 lproto = lookup_protocol_in_reflist (lproto_list,
840 cat = CLASS_CATEGORY_LIST (cat);
843 rinter = lookup_interface (CLASS_SUPER_NAME
848 warning ("class `%s' does not implement the `%s' protocol",
849 IDENTIFIER_POINTER (OBJC_TYPE_NAME
851 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
858 /* id = <Protocol> */
859 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
863 /* Class = <Protocol> */
864 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
868 /* ??? = <Protocol> : let comptypes decide */
876 /* Attention: we shouldn't defer to comptypes here. One bad
877 side effect would be that we might loose the REFLEXIVE
880 lhs = TREE_TYPE (lhs);
881 rhs = TREE_TYPE (rhs);
885 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
887 /* Nothing to do with ObjC - let immediately comptypes take
888 responsibility for checking. */
892 /* `id' = `<class> *' `<class> *' = `id': always allow it.
894 'Object *o = [[Object alloc] init]; falls
895 in the case <class> * = `id'.
897 if ((OBJC_TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
898 || (OBJC_TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
901 /* `id' = `Class', `Class' = `id' */
903 else if ((OBJC_TYPE_NAME (lhs) == objc_object_id
904 && OBJC_TYPE_NAME (rhs) == objc_class_id)
905 || (OBJC_TYPE_NAME (lhs) == objc_class_id
906 && OBJC_TYPE_NAME (rhs) == objc_object_id))
909 /* `<class> *' = `<class> *' */
911 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
913 tree lname = OBJC_TYPE_NAME (lhs);
914 tree rname = OBJC_TYPE_NAME (rhs);
920 /* If the left hand side is a super class of the right hand side,
922 for (inter = lookup_interface (rname); inter;
923 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
924 if (lname == CLASS_SUPER_NAME (inter))
927 /* Allow the reverse when reflexive. */
929 for (inter = lookup_interface (lname); inter;
930 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
931 if (rname == CLASS_SUPER_NAME (inter))
937 /* Not an ObjC type - let comptypes do the check. */
941 /* Called from finish_decl. */
944 objc_check_decl (tree decl)
946 tree type = TREE_TYPE (decl);
948 if (TREE_CODE (type) != RECORD_TYPE)
950 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
951 error ("statically allocated instance of Objective-C class `%s'",
952 IDENTIFIER_POINTER (type));
955 /* Implement static typing. At this point, we know we have an interface. */
958 get_static_reference (tree interface, tree protocols)
960 tree type = xref_tag (RECORD_TYPE, interface);
964 tree t, m = TYPE_MAIN_VARIANT (type);
966 t = copy_node (type);
968 /* Add this type to the chain of variants of TYPE. */
969 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
970 TYPE_NEXT_VARIANT (m) = t;
972 /* Look up protocols and install in lang specific list. Note
973 that the protocol list can have a different lifetime than T! */
974 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
976 /* This forces a new pointer type to be created later
977 (in build_pointer_type)...so that the new template
978 we just created will actually be used...what a hack! */
979 if (TYPE_POINTER_TO (t))
980 TYPE_POINTER_TO (t) = NULL_TREE;
989 get_object_reference (tree protocols)
991 tree type_decl = lookup_name (objc_id_id);
994 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
996 type = TREE_TYPE (type_decl);
997 if (TYPE_MAIN_VARIANT (type) != id_type)
998 warning ("unexpected type for `id' (%s)",
999 gen_declaration (type, errbuf));
1003 error ("undefined type `id', please import <objc/objc.h>");
1004 return error_mark_node;
1007 /* This clause creates a new pointer type that is qualified with
1008 the protocol specification...this info is used later to do more
1009 elaborate type checking. */
1013 tree t, m = TYPE_MAIN_VARIANT (type);
1015 t = copy_node (type);
1017 /* Add this type to the chain of variants of TYPE. */
1018 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1019 TYPE_NEXT_VARIANT (m) = t;
1021 /* Look up protocols...and install in lang specific list */
1022 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1024 /* This forces a new pointer type to be created later
1025 (in build_pointer_type)...so that the new template
1026 we just created will actually be used...what a hack! */
1027 if (TYPE_POINTER_TO (t))
1028 TYPE_POINTER_TO (t) = NULL_TREE;
1035 /* Check for circular dependencies in protocols. The arguments are
1036 PROTO, the protocol to check, and LIST, a list of protocol it
1040 check_protocol_recursively (tree proto, tree list)
1044 for (p = list; p; p = TREE_CHAIN (p))
1046 tree pp = TREE_VALUE (p);
1048 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1049 pp = lookup_protocol (pp);
1052 fatal_error ("protocol `%s' has circular dependency",
1053 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1055 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1059 /* Look up PROTOCOLS, and return a list of those that are found.
1060 If none are found, return NULL. */
1063 lookup_and_install_protocols (tree protocols)
1066 tree return_value = NULL_TREE;
1068 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1070 tree ident = TREE_VALUE (proto);
1071 tree p = lookup_protocol (ident);
1074 error ("cannot find protocol declaration for `%s'",
1075 IDENTIFIER_POINTER (ident));
1077 return_value = chainon (return_value,
1078 build_tree_list (NULL_TREE, p));
1081 return return_value;
1084 /* Create and push a decl for a built-in external variable or field NAME.
1086 TYPE is its data type. */
1089 create_builtin_decl (enum tree_code code, tree type, const char *name)
1091 tree decl = build_decl (code, get_identifier (name), type);
1093 if (code == VAR_DECL)
1095 TREE_STATIC (decl) = 1;
1096 make_decl_rtl (decl, 0);
1098 DECL_ARTIFICIAL (decl) = 1;
1104 /* Find the decl for the constant string class. */
1107 setup_string_decl (void)
1109 if (!string_class_decl)
1111 if (!constant_string_global_id)
1115 /* %s in format will provide room for terminating null */
1116 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1117 + strlen (constant_string_class_name);
1118 name = xmalloc (length);
1119 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1120 constant_string_class_name);
1121 constant_string_global_id = get_identifier (name);
1123 string_class_decl = lookup_name (constant_string_global_id);
1127 /* Purpose: "play" parser, creating/installing representations
1128 of the declarations that are required by Objective-C.
1132 type_spec--------->sc_spec
1133 (tree_list) (tree_list)
1136 identifier_node identifier_node */
1139 synth_module_prologue (void)
1143 /* Defined in `objc.h' */
1144 objc_object_id = get_identifier (TAG_OBJECT);
1146 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1148 id_type = build_pointer_type (objc_object_reference);
1150 objc_id_id = get_identifier (TYPE_ID);
1151 objc_class_id = get_identifier (TAG_CLASS);
1153 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1154 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1155 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1156 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1159 /* Declare type of selector-objects that represent an operation name. */
1161 /* `struct objc_selector *' */
1163 = build_pointer_type (xref_tag (RECORD_TYPE,
1164 get_identifier (TAG_SELECTOR)));
1166 /* Forward declare type, or else the prototype for msgSendSuper will
1169 /* `struct objc_super *' */
1170 super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1171 get_identifier (TAG_SUPER)));
1174 /* id objc_msgSend (id, SEL, ...); */
1177 = build_function_type (id_type,
1178 tree_cons (NULL_TREE, id_type,
1179 tree_cons (NULL_TREE, selector_type,
1182 if (! flag_next_runtime)
1184 umsg_decl = build_decl (FUNCTION_DECL,
1185 get_identifier (TAG_MSGSEND), temp_type);
1186 DECL_EXTERNAL (umsg_decl) = 1;
1187 TREE_PUBLIC (umsg_decl) = 1;
1188 DECL_INLINE (umsg_decl) = 1;
1189 DECL_ARTIFICIAL (umsg_decl) = 1;
1191 make_decl_rtl (umsg_decl, NULL);
1192 pushdecl (umsg_decl);
1196 umsg_decl = builtin_function (TAG_MSGSEND,
1197 temp_type, 0, NOT_BUILT_IN,
1199 /* id objc_msgSendNonNil (id, SEL, ...); */
1200 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1201 temp_type, 0, NOT_BUILT_IN,
1205 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1208 = build_function_type (id_type,
1209 tree_cons (NULL_TREE, super_type,
1210 tree_cons (NULL_TREE, selector_type,
1213 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1214 temp_type, 0, NOT_BUILT_IN,
1217 /* The NeXT runtime defines the following additional entry points,
1218 used for dispatching calls to methods returning structs:
1220 #if defined(__cplusplus)
1221 id objc_msgSend_stret(id self, SEL op, ...);
1222 id objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...);
1224 void objc_msgSend_stret(void * stretAddr, id self, SEL op, ...);
1225 void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super,
1229 struct objc_return_struct objc_msgSendNonNil_stret(id self, SEL op, ...);
1231 These prototypes appear in <objc/objc-runtime.h>; however, they
1232 CANNOT BE USED DIRECTLY. In order to call one of the ..._stret
1233 functions, the function must first be cast to a signature that
1234 corresponds to the actual ObjC method being invoked. This is
1235 what is done by the build_objc_method_call() routine below. */
1237 if (flag_next_runtime)
1239 tree objc_return_struct_type
1240 = xref_tag (RECORD_TYPE,
1241 get_identifier (TAG_RETURN_STRUCT));
1243 tree stret_temp_type
1244 = build_function_type (id_type,
1245 tree_cons (NULL_TREE, id_type,
1246 tree_cons (NULL_TREE, selector_type,
1249 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1250 stret_temp_type, 0, NOT_BUILT_IN,
1253 = build_function_type (objc_return_struct_type,
1254 tree_cons (NULL_TREE, id_type,
1255 tree_cons (NULL_TREE, selector_type,
1258 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1259 stret_temp_type, 0, NOT_BUILT_IN,
1263 = build_function_type (id_type,
1264 tree_cons (NULL_TREE, super_type,
1265 tree_cons (NULL_TREE, selector_type,
1268 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1269 stret_temp_type, 0, NOT_BUILT_IN, 0,
1273 /* id objc_getClass (const char *); */
1275 temp_type = build_function_type (id_type,
1276 tree_cons (NULL_TREE,
1277 const_string_type_node,
1281 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1284 /* id objc_getMetaClass (const char *); */
1286 objc_get_meta_class_decl
1287 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1289 build_super_template ();
1290 if (flag_next_runtime)
1291 build_objc_exception_stuff ();
1293 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1295 if (! flag_next_runtime)
1297 if (flag_typed_selectors)
1299 /* Suppress outputting debug symbols, because
1300 dbxout_init hasn'r been called yet. */
1301 enum debug_info_type save_write_symbols = write_symbols;
1302 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1303 write_symbols = NO_DEBUG;
1304 debug_hooks = &do_nothing_debug_hooks;
1306 build_selector_template ();
1307 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1309 write_symbols = save_write_symbols;
1310 debug_hooks = save_hooks;
1313 temp_type = build_array_type (selector_type, NULL_TREE);
1315 layout_type (temp_type);
1316 UOBJC_SELECTOR_TABLE_decl
1317 = create_builtin_decl (VAR_DECL, temp_type,
1318 "_OBJC_SELECTOR_TABLE");
1320 /* Avoid warning when not sending messages. */
1321 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1324 generate_forward_declaration_to_string_table ();
1326 /* Forward declare constant_string_id and constant_string_type. */
1327 if (!constant_string_class_name)
1328 constant_string_class_name = default_constant_string_class_name;
1330 constant_string_id = get_identifier (constant_string_class_name);
1331 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1333 /* Pre-build the following entities - for speed/convenience. */
1334 self_id = get_identifier ("self");
1335 ucmd_id = get_identifier ("_cmd");
1337 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1338 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1342 /* Ensure that the ivar list for NSConstantString/NXConstantString
1343 (or whatever was specified via `-fconstant-string-class')
1344 contains fields at least as large as the following three, so that
1345 the runtime can stomp on them with confidence:
1347 struct STRING_OBJECT_CLASS_NAME
1351 unsigned int length;
1355 check_string_class_template (void)
1357 tree field_decl = TYPE_FIELDS (constant_string_type);
1359 #define AT_LEAST_AS_LARGE_AS(F, T) \
1360 (F && TREE_CODE (F) == FIELD_DECL \
1361 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1362 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1364 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1367 field_decl = TREE_CHAIN (field_decl);
1368 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1371 field_decl = TREE_CHAIN (field_decl);
1372 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1374 #undef AT_LEAST_AS_LARGE_AS
1377 /* Avoid calling `check_string_class_template ()' more than once. */
1378 static GTY(()) int string_layout_checked;
1380 /* Custom build_string which sets TREE_TYPE! */
1383 my_build_string (int len, const char *str)
1385 return fix_string_type (build_string (len, str));
1388 /* Given a chain of STRING_CST's, build a static instance of
1389 NXConstantString which points at the concatenation of those
1390 strings. We place the string object in the __string_objects
1391 section of the __OBJC segment. The Objective-C runtime will
1392 initialize the isa pointers of the string objects to point at the
1393 NXConstantString class object. */
1396 build_objc_string_object (tree string)
1398 tree initlist, constructor, constant_string_class;
1401 string = fix_string_type (string);
1403 constant_string_class = lookup_interface (constant_string_id);
1404 if (!constant_string_class
1405 || !(constant_string_type
1406 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1408 error ("cannot find interface declaration for `%s'",
1409 IDENTIFIER_POINTER (constant_string_id));
1410 return error_mark_node;
1413 /* Call to 'combine_strings' has been moved above. */
1414 TREE_SET_CODE (string, STRING_CST);
1415 length = TREE_STRING_LENGTH (string) - 1;
1417 if (!string_layout_checked)
1419 /* The NSConstantString/NXConstantString ivar layout is now
1421 if (!check_string_class_template ())
1423 error ("interface `%s' does not have valid constant string layout",
1424 IDENTIFIER_POINTER (constant_string_id));
1425 return error_mark_node;
1427 add_class_reference (constant_string_id);
1430 /* & ((NXConstantString) { NULL, string, length }) */
1432 if (flag_next_runtime)
1434 /* For the NeXT runtime, we can generate a literal reference
1435 to the string class, don't need to run a constructor. */
1436 setup_string_decl ();
1437 if (string_class_decl == NULL_TREE)
1439 error ("cannot find reference tag for class `%s'",
1440 IDENTIFIER_POINTER (constant_string_id));
1441 return error_mark_node;
1443 initlist = build_tree_list
1445 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1449 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1453 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1455 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1456 constructor = objc_build_constructor (constant_string_type,
1457 nreverse (initlist));
1459 if (!flag_next_runtime)
1462 = objc_add_static_instance (constructor, constant_string_type);
1465 return (build_unary_op (ADDR_EXPR, constructor, 1));
1468 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1470 static GTY(()) int num_static_inst;
1473 objc_add_static_instance (tree constructor, tree class_decl)
1478 /* Find the list of static instances for the CLASS_DECL. Create one if
1480 for (chain = &objc_static_instances;
1481 *chain && TREE_VALUE (*chain) != class_decl;
1482 chain = &TREE_CHAIN (*chain));
1485 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1486 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1489 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1490 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1491 DECL_COMMON (decl) = 1;
1492 TREE_STATIC (decl) = 1;
1493 DECL_ARTIFICIAL (decl) = 1;
1494 DECL_INITIAL (decl) = constructor;
1496 /* We may be writing something else just now.
1497 Postpone till end of input. */
1498 DECL_DEFER_OUTPUT (decl) = 1;
1499 pushdecl_top_level (decl);
1500 rest_of_decl_compilation (decl, 0, 1, 0);
1502 /* Add the DECL to the head of this CLASS' list. */
1503 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1508 /* Build a static constant CONSTRUCTOR
1509 with type TYPE and elements ELTS. */
1512 objc_build_constructor (tree type, tree elts)
1514 tree constructor, f, e;
1516 /* ??? Most of the places that we build constructors, we don't fill in
1517 the type of integers properly. Convert them all en masse. */
1518 if (TREE_CODE (type) == ARRAY_TYPE)
1520 f = TREE_TYPE (type);
1521 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1522 for (e = elts; e ; e = TREE_CHAIN (e))
1523 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1527 f = TYPE_FIELDS (type);
1528 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1529 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1530 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1531 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1534 constructor = build_constructor (type, elts);
1535 TREE_CONSTANT (constructor) = 1;
1536 TREE_STATIC (constructor) = 1;
1537 TREE_READONLY (constructor) = 1;
1540 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1541 build_unary_op (wasn't true in 2.7.2.1 days) */
1542 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1547 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1549 /* Predefine the following data type:
1557 void *defs[cls_def_cnt + cat_def_cnt];
1561 build_objc_symtab_template (void)
1563 tree field_decl, field_decl_chain;
1565 objc_symtab_template
1566 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1568 /* long sel_ref_cnt; */
1570 field_decl = create_builtin_decl (FIELD_DECL,
1571 long_integer_type_node,
1573 field_decl_chain = field_decl;
1577 field_decl = create_builtin_decl (FIELD_DECL,
1578 build_pointer_type (selector_type),
1580 chainon (field_decl_chain, field_decl);
1582 /* short cls_def_cnt; */
1584 field_decl = create_builtin_decl (FIELD_DECL,
1585 short_integer_type_node,
1587 chainon (field_decl_chain, field_decl);
1589 /* short cat_def_cnt; */
1591 field_decl = create_builtin_decl (FIELD_DECL,
1592 short_integer_type_node,
1594 chainon (field_decl_chain, field_decl);
1596 if (imp_count || cat_count || !flag_next_runtime)
1598 /* void *defs[imp_count + cat_count (+ 1)]; */
1599 /* NB: The index is one less than the size of the array. */
1600 int index = imp_count + cat_count
1601 + (flag_next_runtime? -1: 0);
1602 field_decl = create_builtin_decl
1606 build_index_type (build_int_2 (index, 0))),
1608 chainon (field_decl_chain, field_decl);
1611 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1614 /* Create the initial value for the `defs' field of _objc_symtab.
1615 This is a CONSTRUCTOR. */
1618 init_def_list (tree type)
1620 tree expr, initlist = NULL_TREE;
1621 struct imp_entry *impent;
1624 for (impent = imp_list; impent; impent = impent->next)
1626 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1628 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1629 initlist = tree_cons (NULL_TREE, expr, initlist);
1634 for (impent = imp_list; impent; impent = impent->next)
1636 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1638 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1639 initlist = tree_cons (NULL_TREE, expr, initlist);
1643 if (!flag_next_runtime)
1645 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1648 if (static_instances_decl)
1649 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1651 expr = build_int_2 (0, 0);
1653 initlist = tree_cons (NULL_TREE, expr, initlist);
1656 return objc_build_constructor (type, nreverse (initlist));
1659 /* Construct the initial value for all of _objc_symtab. */
1662 init_objc_symtab (tree type)
1666 /* sel_ref_cnt = { ..., 5, ... } */
1668 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1670 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1672 if (flag_next_runtime || ! sel_ref_chain)
1673 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1675 initlist = tree_cons (NULL_TREE,
1676 build_unary_op (ADDR_EXPR,
1677 UOBJC_SELECTOR_TABLE_decl, 1),
1680 /* cls_def_cnt = { ..., 5, ... } */
1682 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1684 /* cat_def_cnt = { ..., 5, ... } */
1686 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1688 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1690 if (imp_count || cat_count || !flag_next_runtime)
1693 tree field = TYPE_FIELDS (type);
1694 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1696 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1700 return objc_build_constructor (type, nreverse (initlist));
1703 /* Generate forward declarations for metadata such as
1704 'OBJC_CLASS_...'. */
1707 build_metadata_decl (const char *name, tree type)
1709 tree decl, decl_specs;
1710 /* extern struct TYPE NAME_<name>; */
1711 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1712 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1713 decl = define_decl (synth_id_with_class_suffix
1715 objc_implementation_context),
1717 TREE_USED (decl) = 1;
1718 DECL_ARTIFICIAL (decl) = 1;
1719 TREE_PUBLIC (decl) = 0;
1723 /* Push forward-declarations of all the categories so that
1724 init_def_list can use them in a CONSTRUCTOR. */
1727 forward_declare_categories (void)
1729 struct imp_entry *impent;
1730 tree sav = objc_implementation_context;
1732 for (impent = imp_list; impent; impent = impent->next)
1734 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1736 /* Set an invisible arg to synth_id_with_class_suffix. */
1737 objc_implementation_context = impent->imp_context;
1738 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1739 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1740 objc_category_template);
1743 objc_implementation_context = sav;
1746 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1747 and initialized appropriately. */
1750 generate_objc_symtab_decl (void)
1754 if (!objc_category_template)
1755 build_category_template ();
1757 /* forward declare categories */
1759 forward_declare_categories ();
1761 if (!objc_symtab_template)
1762 build_objc_symtab_template ();
1764 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1766 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1767 tree_cons (NULL_TREE,
1768 objc_symtab_template, sc_spec),
1772 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1773 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1774 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1775 finish_decl (UOBJC_SYMBOLS_decl,
1776 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1781 init_module_descriptor (tree type)
1783 tree initlist, expr;
1785 /* version = { 1, ... } */
1787 expr = build_int_2 (OBJC_VERSION, 0);
1788 initlist = build_tree_list (NULL_TREE, expr);
1790 /* size = { ..., sizeof (struct objc_module), ... } */
1792 expr = size_in_bytes (objc_module_template);
1793 initlist = tree_cons (NULL_TREE, expr, initlist);
1795 /* name = { ..., "foo.m", ... } */
1797 expr = add_objc_string (get_identifier (input_filename), class_names);
1798 initlist = tree_cons (NULL_TREE, expr, initlist);
1800 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1802 if (UOBJC_SYMBOLS_decl)
1803 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1805 expr = build_int_2 (0, 0);
1806 initlist = tree_cons (NULL_TREE, expr, initlist);
1808 return objc_build_constructor (type, nreverse (initlist));
1811 /* Write out the data structures to describe Objective C classes defined.
1812 If appropriate, compile and output a setup function to initialize them.
1813 Return a symbol_ref to the function to call to initialize the Objective C
1814 data structures for this file (and perhaps for other files also).
1816 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1819 build_module_descriptor (void)
1821 tree decl_specs, field_decl, field_decl_chain;
1823 objc_module_template
1824 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1828 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1829 field_decl = get_identifier ("version");
1830 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1831 field_decl_chain = field_decl;
1835 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1836 field_decl = get_identifier ("size");
1837 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1838 chainon (field_decl_chain, field_decl);
1842 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1843 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1844 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1845 chainon (field_decl_chain, field_decl);
1847 /* struct objc_symtab *symtab; */
1849 decl_specs = get_identifier (UTAG_SYMTAB);
1850 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1851 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1852 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1853 chainon (field_decl_chain, field_decl);
1855 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1857 /* Create an instance of "objc_module". */
1859 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1860 build_tree_list (NULL_TREE,
1861 ridpointers[(int) RID_STATIC]));
1863 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1864 decl_specs, 1, NULL_TREE);
1866 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1867 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1868 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1870 finish_decl (UOBJC_MODULES_decl,
1871 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1874 /* Mark the decl to avoid "defined but not used" warning. */
1875 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1877 /* Generate a constructor call for the module descriptor.
1878 This code was generated by reading the grammar rules
1879 of c-parse.in; Therefore, it may not be the most efficient
1880 way of generating the requisite code. */
1882 if (flag_next_runtime)
1886 tree parms, execclass_decl, decelerator, void_list_node_1;
1887 tree init_function_name, init_function_decl;
1889 /* Declare void __objc_execClass (void *); */
1891 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1892 execclass_decl = build_decl (FUNCTION_DECL,
1893 get_identifier (TAG_EXECCLASS),
1894 build_function_type (void_type_node,
1895 tree_cons (NULL_TREE, ptr_type_node,
1896 OBJC_VOID_AT_END)));
1898 DECL_EXTERNAL (execclass_decl) = 1;
1899 DECL_ARTIFICIAL (execclass_decl) = 1;
1900 TREE_PUBLIC (execclass_decl) = 1;
1901 pushdecl (execclass_decl);
1902 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1903 assemble_external (execclass_decl);
1905 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1907 init_function_name = get_file_function_name ('I');
1908 start_function (void_list_node_1,
1909 build_nt (CALL_EXPR, init_function_name,
1910 tree_cons (NULL_TREE, NULL_TREE,
1914 store_parm_decls ();
1916 init_function_decl = current_function_decl;
1917 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1918 TREE_USED (init_function_decl) = 1;
1919 /* Don't let this one be deferred. */
1920 DECL_INLINE (init_function_decl) = 0;
1921 DECL_UNINLINABLE (init_function_decl) = 1;
1922 current_function_cannot_inline
1923 = "static constructors and destructors cannot be inlined";
1926 = build_tree_list (NULL_TREE,
1927 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1928 decelerator = build_function_call (execclass_decl, parms);
1930 c_expand_expr_stmt (decelerator);
1934 return XEXP (DECL_RTL (init_function_decl), 0);
1938 /* extern const char _OBJC_STRINGS[]; */
1941 generate_forward_declaration_to_string_table (void)
1943 tree sc_spec, decl_specs, expr_decl;
1945 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1946 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1949 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1951 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1954 /* Return the DECL of the string IDENT in the SECTION. */
1957 get_objc_string_decl (tree ident, enum string_section section)
1961 if (section == class_names)
1962 chain = class_names_chain;
1963 else if (section == meth_var_names)
1964 chain = meth_var_names_chain;
1965 else if (section == meth_var_types)
1966 chain = meth_var_types_chain;
1970 for (; chain != 0; chain = TREE_CHAIN (chain))
1971 if (TREE_VALUE (chain) == ident)
1972 return (TREE_PURPOSE (chain));
1978 /* Output references to all statically allocated objects. Return the DECL
1979 for the array built. */
1982 generate_static_references (void)
1984 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1985 tree class_name, class, decl, initlist;
1986 tree cl_chain, in_chain, type;
1987 int num_inst, num_class;
1990 if (flag_next_runtime)
1993 for (cl_chain = objc_static_instances, num_class = 0;
1994 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1996 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1997 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1999 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2000 ident = get_identifier (buf);
2002 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2003 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2004 build_tree_list (NULL_TREE,
2005 ridpointers[(int) RID_STATIC]));
2006 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2007 DECL_CONTEXT (decl) = 0;
2008 DECL_ARTIFICIAL (decl) = 1;
2010 /* Output {class_name, ...}. */
2011 class = TREE_VALUE (cl_chain);
2012 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2013 initlist = build_tree_list (NULL_TREE,
2014 build_unary_op (ADDR_EXPR, class_name, 1));
2016 /* Output {..., instance, ...}. */
2017 for (in_chain = TREE_PURPOSE (cl_chain);
2018 in_chain; in_chain = TREE_CHAIN (in_chain))
2020 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2021 initlist = tree_cons (NULL_TREE, expr, initlist);
2024 /* Output {..., NULL}. */
2025 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2027 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2028 finish_decl (decl, expr, NULL_TREE);
2029 TREE_USED (decl) = 1;
2031 type = build_array_type (build_pointer_type (void_type_node), 0);
2032 decl = build_decl (VAR_DECL, ident, type);
2033 TREE_USED (decl) = 1;
2034 TREE_STATIC (decl) = 1;
2036 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2039 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2040 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2041 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2042 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2043 build_tree_list (NULL_TREE,
2044 ridpointers[(int) RID_STATIC]));
2045 static_instances_decl
2046 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2047 TREE_USED (static_instances_decl) = 1;
2048 DECL_CONTEXT (static_instances_decl) = 0;
2049 DECL_ARTIFICIAL (static_instances_decl) = 1;
2050 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2052 finish_decl (static_instances_decl, expr, NULL_TREE);
2055 /* Output all strings. */
2058 generate_strings (void)
2060 tree sc_spec, decl_specs, expr_decl;
2061 tree chain, string_expr;
2064 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2066 string = TREE_VALUE (chain);
2067 decl = TREE_PURPOSE (chain);
2069 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2070 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2071 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2072 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2073 DECL_CONTEXT (decl) = NULL_TREE;
2074 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2075 IDENTIFIER_POINTER (string));
2076 finish_decl (decl, string_expr, NULL_TREE);
2079 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2081 string = TREE_VALUE (chain);
2082 decl = TREE_PURPOSE (chain);
2084 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2085 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2086 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2087 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2088 DECL_CONTEXT (decl) = NULL_TREE;
2089 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2090 IDENTIFIER_POINTER (string));
2091 finish_decl (decl, string_expr, NULL_TREE);
2094 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2096 string = TREE_VALUE (chain);
2097 decl = TREE_PURPOSE (chain);
2099 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2100 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2101 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2102 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2103 DECL_CONTEXT (decl) = NULL_TREE;
2104 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2105 IDENTIFIER_POINTER (string));
2106 finish_decl (decl, string_expr, NULL_TREE);
2110 static GTY(()) int selector_reference_idx;
2113 build_selector_reference_decl (void)
2118 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2120 ident = get_identifier (buf);
2122 decl = build_decl (VAR_DECL, ident, selector_type);
2123 DECL_EXTERNAL (decl) = 1;
2124 TREE_PUBLIC (decl) = 0;
2125 TREE_USED (decl) = 1;
2126 DECL_ARTIFICIAL (decl) = 1;
2127 DECL_CONTEXT (decl) = 0;
2129 make_decl_rtl (decl, 0);
2130 pushdecl_top_level (decl);
2135 /* Just a handy wrapper for add_objc_string. */
2138 build_selector (tree ident)
2140 tree expr = add_objc_string (ident, meth_var_names);
2141 if (flag_typed_selectors)
2144 return build_c_cast (selector_type, expr); /* cast! */
2148 build_selector_translation_table (void)
2150 tree sc_spec, decl_specs;
2151 tree chain, initlist = NULL_TREE;
2153 tree decl = NULL_TREE, var_decl, name;
2155 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2159 if (warn_selector && objc_implementation_context)
2163 for (method_chain = meth_var_names_chain;
2165 method_chain = TREE_CHAIN (method_chain))
2167 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2175 /* Adjust line number for warning message. */
2176 int save_lineno = input_line;
2177 if (flag_next_runtime && TREE_PURPOSE (chain))
2178 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2179 warning ("creating selector for non existant method %s",
2180 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2181 input_line = save_lineno;
2185 expr = build_selector (TREE_VALUE (chain));
2187 if (flag_next_runtime)
2189 name = DECL_NAME (TREE_PURPOSE (chain));
2191 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2193 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2194 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2198 /* The `decl' that is returned from start_decl is the one that we
2199 forward declared in `build_selector_reference' */
2200 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2203 /* add one for the '\0' character */
2204 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2206 if (flag_next_runtime)
2207 finish_decl (decl, expr, NULL_TREE);
2210 if (flag_typed_selectors)
2212 tree eltlist = NULL_TREE;
2213 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2214 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2215 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2216 expr = objc_build_constructor (objc_selector_template,
2217 nreverse (eltlist));
2219 initlist = tree_cons (NULL_TREE, expr, initlist);
2224 if (! flag_next_runtime)
2226 /* Cause the variable and its initial value to be actually output. */
2227 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2228 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2229 /* NULL terminate the list and fix the decl for output. */
2230 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2231 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2232 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2233 nreverse (initlist));
2234 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2235 current_function_decl = NULL_TREE;
2240 get_proto_encoding (tree proto)
2245 if (! METHOD_ENCODING (proto))
2247 encoding = encode_method_prototype (proto);
2248 METHOD_ENCODING (proto) = encoding;
2251 encoding = METHOD_ENCODING (proto);
2253 return add_objc_string (encoding, meth_var_types);
2256 return build_int_2 (0, 0);
2259 /* sel_ref_chain is a list whose "value" fields will be instances of
2260 identifier_node that represent the selector. */
2263 build_typed_selector_reference (tree ident, tree prototype)
2265 tree *chain = &sel_ref_chain;
2271 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2272 goto return_at_index;
2275 chain = &TREE_CHAIN (*chain);
2278 *chain = tree_cons (prototype, ident, NULL_TREE);
2281 expr = build_unary_op (ADDR_EXPR,
2282 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2283 build_int_2 (index, 0)),
2285 return build_c_cast (selector_type, expr);
2289 build_selector_reference (tree ident)
2291 tree *chain = &sel_ref_chain;
2297 if (TREE_VALUE (*chain) == ident)
2298 return (flag_next_runtime
2299 ? TREE_PURPOSE (*chain)
2300 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2301 build_int_2 (index, 0)));
2304 chain = &TREE_CHAIN (*chain);
2307 expr = build_selector_reference_decl ();
2309 *chain = tree_cons (expr, ident, NULL_TREE);
2311 return (flag_next_runtime
2313 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2314 build_int_2 (index, 0)));
2317 static GTY(()) int class_reference_idx;
2320 build_class_reference_decl (void)
2325 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2327 ident = get_identifier (buf);
2329 decl = build_decl (VAR_DECL, ident, objc_class_type);
2330 DECL_EXTERNAL (decl) = 1;
2331 TREE_PUBLIC (decl) = 0;
2332 TREE_USED (decl) = 1;
2333 DECL_CONTEXT (decl) = 0;
2334 DECL_ARTIFICIAL (decl) = 1;
2336 make_decl_rtl (decl, 0);
2337 pushdecl_top_level (decl);
2342 /* Create a class reference, but don't create a variable to reference
2346 add_class_reference (tree ident)
2350 if ((chain = cls_ref_chain))
2355 if (ident == TREE_VALUE (chain))
2359 chain = TREE_CHAIN (chain);
2363 /* Append to the end of the list */
2364 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2367 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2370 /* Get a class reference, creating it if necessary. Also create the
2371 reference variable. */
2374 get_class_reference (tree ident)
2379 if (processing_template_decl)
2380 /* Must wait until template instantiation time. */
2381 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2382 if (TREE_CODE (ident) == TYPE_DECL)
2383 ident = DECL_NAME (ident);
2387 if (!(ident = is_class_name (ident)))
2389 error ("`%s' is not an Objective-C class name or alias",
2390 IDENTIFIER_POINTER (orig_ident));
2391 return error_mark_node;
2394 if (flag_next_runtime && !flag_zero_link)
2399 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2400 if (TREE_VALUE (*chain) == ident)
2402 if (! TREE_PURPOSE (*chain))
2403 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2405 return TREE_PURPOSE (*chain);
2408 decl = build_class_reference_decl ();
2409 *chain = tree_cons (decl, ident, NULL_TREE);
2416 add_class_reference (ident);
2418 params = build_tree_list (NULL_TREE,
2419 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2420 IDENTIFIER_POINTER (ident)));
2422 assemble_external (objc_get_class_decl);
2423 return build_function_call (objc_get_class_decl, params);
2427 /* For each string section we have a chain which maps identifier nodes
2428 to decls for the strings. */
2431 add_objc_string (tree ident, enum string_section section)
2435 if (section == class_names)
2436 chain = &class_names_chain;
2437 else if (section == meth_var_names)
2438 chain = &meth_var_names_chain;
2439 else if (section == meth_var_types)
2440 chain = &meth_var_types_chain;
2446 if (TREE_VALUE (*chain) == ident)
2447 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2449 chain = &TREE_CHAIN (*chain);
2452 decl = build_objc_string_decl (section);
2454 *chain = tree_cons (decl, ident, NULL_TREE);
2456 return build_unary_op (ADDR_EXPR, decl, 1);
2459 static GTY(()) int class_names_idx;
2460 static GTY(()) int meth_var_names_idx;
2461 static GTY(()) int meth_var_types_idx;
2464 build_objc_string_decl (enum string_section section)
2469 if (section == class_names)
2470 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2471 else if (section == meth_var_names)
2472 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2473 else if (section == meth_var_types)
2474 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2476 ident = get_identifier (buf);
2478 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2479 DECL_EXTERNAL (decl) = 1;
2480 TREE_PUBLIC (decl) = 0;
2481 TREE_USED (decl) = 1;
2482 TREE_CONSTANT (decl) = 1;
2483 DECL_CONTEXT (decl) = 0;
2484 DECL_ARTIFICIAL (decl) = 1;
2486 make_decl_rtl (decl, 0);
2487 pushdecl_top_level (decl);
2494 objc_declare_alias (tree alias_ident, tree class_ident)
2496 tree underlying_class;
2499 if (current_namespace != global_namespace) {
2500 error ("Objective-C declarations may only appear in global scope");
2502 #endif /* OBJCPLUS */
2504 if (!(underlying_class = is_class_name (class_ident)))
2505 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2506 else if (is_class_name (alias_ident))
2507 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2509 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2513 objc_declare_class (tree ident_list)
2517 if (current_namespace != global_namespace) {
2518 error ("Objective-C declarations may only appear in global scope");
2520 #endif /* OBJCPLUS */
2522 for (list = ident_list; list; list = TREE_CHAIN (list))
2524 tree ident = TREE_VALUE (list);
2526 if (! is_class_name (ident))
2528 tree record = lookup_name (ident);
2530 if (record && ! TREE_STATIC_TEMPLATE (record))
2532 error ("`%s' redeclared as different kind of symbol",
2533 IDENTIFIER_POINTER (ident));
2534 error ("%Jprevious declaration of '%D'",
2538 record = xref_tag (RECORD_TYPE, ident);
2539 TREE_STATIC_TEMPLATE (record) = 1;
2540 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2546 is_class_name (tree ident)
2550 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2551 && identifier_global_value (ident))
2552 ident = identifier_global_value (ident);
2553 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2554 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2557 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2558 ident = TYPE_NAME (ident);
2559 if (ident && TREE_CODE (ident) == TYPE_DECL)
2560 ident = DECL_NAME (ident);
2562 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2565 if (lookup_interface (ident))
2568 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2570 if (ident == TREE_VALUE (chain))
2574 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2576 if (ident == TREE_VALUE (chain))
2577 return TREE_PURPOSE (chain);
2583 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2584 class instance. This is needed by other parts of the compiler to
2585 handle ObjC types gracefully. */
2588 objc_is_object_ptr (tree type)
2590 type = TYPE_MAIN_VARIANT (type);
2591 if (!type || TREE_CODE (type) != POINTER_TYPE)
2593 /* NB: This function may be called before the ObjC front-end has
2594 been initialized, in which case ID_TYPE will be NULL. */
2595 if (id_type && type && TYPE_P (type)
2597 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2599 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2603 lookup_interface (tree ident)
2608 if (ident && TREE_CODE (ident) == TYPE_DECL)
2609 ident = DECL_NAME (ident);
2611 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2613 if (ident == CLASS_NAME (chain))
2619 /* Implement @defs (<classname>) within struct bodies. */
2622 get_class_ivars_from_name (tree class_name)
2624 tree interface = lookup_interface (class_name);
2625 tree field, fields = NULL_TREE;
2629 tree raw_ivar = get_class_ivars (interface, 1);
2631 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2632 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2634 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2635 TREE_PURPOSE (raw_ivar),
2636 TREE_VALUE (TREE_VALUE (raw_ivar)));
2638 finish_member_declaration (field);
2640 fields = chainon (fields, field);
2645 error ("cannot find interface declaration for `%s'",
2646 IDENTIFIER_POINTER (class_name));
2651 /* Used by: build_private_template, continue_class,
2652 and for @defs constructs. */
2655 get_class_ivars (tree interface, int raw)
2657 tree my_name, super_name, ivar_chain;
2659 my_name = CLASS_NAME (interface);
2660 super_name = CLASS_SUPER_NAME (interface);
2662 ivar_chain = CLASS_RAW_IVARS (interface);
2665 ivar_chain = CLASS_IVARS (interface);
2666 /* Save off a pristine copy of the leaf ivars (i.e, those not
2667 inherited from a super class). */
2668 if (!CLASS_OWN_IVARS (interface))
2669 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2675 tree super_interface = lookup_interface (super_name);
2677 if (!super_interface)
2679 /* fatal did not work with 2 args...should fix */
2680 error ("cannot find interface declaration for `%s', superclass of `%s'",
2681 IDENTIFIER_POINTER (super_name),
2682 IDENTIFIER_POINTER (my_name));
2683 exit (FATAL_EXIT_CODE);
2686 if (super_interface == interface)
2687 fatal_error ("circular inheritance in interface declaration for `%s'",
2688 IDENTIFIER_POINTER (super_name));
2690 interface = super_interface;
2691 my_name = CLASS_NAME (interface);
2692 super_name = CLASS_SUPER_NAME (interface);
2694 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2697 tree head = copy_list (op1);
2699 /* Prepend super class ivars...make a copy of the list, we
2700 do not want to alter the original. */
2701 chainon (head, ivar_chain);
2710 objc_enter_block (void)
2715 block = begin_compound_stmt (0);
2717 block = c_begin_compound_stmt ();
2720 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
2723 objc_exception_block_stack = tree_cons (NULL_TREE, block,
2724 objc_exception_block_stack);
2726 blk_nesting_count++;
2731 objc_exit_block (void)
2733 tree block = TREE_VALUE (objc_exception_block_stack);
2735 tree scope_stmt, inner;
2738 objc_clear_super_receiver ();
2740 finish_compound_stmt (0, block);
2742 scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
2743 inner = poplevel (KEEP_MAYBE, 1, 0);
2745 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
2746 = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
2748 RECHAIN_STMTS (block, COMPOUND_BODY (block));
2750 last_expr_type = NULL_TREE;
2751 objc_exception_block_stack = TREE_CHAIN (objc_exception_block_stack);
2753 blk_nesting_count--;
2758 objc_declare_variable (enum rid scspec, tree name, tree type, tree init)
2762 type = tree_cons (NULL_TREE, type,
2763 tree_cons (NULL_TREE, ridpointers[(int) scspec],
2765 TREE_STATIC (type) = 1;
2766 decl = start_decl (name, type, (init != NULL_TREE), NULL_TREE);
2767 finish_decl (decl, init, NULL_TREE);
2768 /* This prevents `unused variable' warnings when compiling with -Wall. */
2769 TREE_USED (decl) = 1;
2770 DECL_ARTIFICIAL (decl) = 1;
2775 objc_build_throw_stmt (tree throw_expr)
2779 if (!flag_objc_exceptions)
2780 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2782 if (!throw_expr && objc_caught_exception)
2783 throw_expr = TREE_VALUE (objc_caught_exception);
2787 error ("`@throw;' (rethrow) used outside of a `@catch' block");
2788 return error_mark_node;
2791 func_params = tree_cons (NULL_TREE, throw_expr, NULL_TREE);
2793 assemble_external (objc_exception_throw_decl);
2794 return c_expand_expr_stmt (build_function_call (objc_exception_throw_decl,
2799 val_stack_push (struct val_stack **nc, long val)
2801 struct val_stack *new_elem = xmalloc (sizeof (struct val_stack));
2802 new_elem->val = val;
2803 new_elem->next = *nc;
2808 val_stack_pop (struct val_stack **nc)
2810 struct val_stack *old_elem = *nc;
2811 *nc = old_elem->next;
2816 objc_build_try_enter_fragment (void)
2818 /* objc_exception_try_enter(&_stackExceptionData);
2819 if (!_setjmp(&_stackExceptionData.buf)) { */
2821 tree func_params, if_stmt, cond;
2824 = tree_cons (NULL_TREE,
2825 build_unary_op (ADDR_EXPR,
2826 TREE_VALUE (objc_stack_exception_data),
2830 assemble_external (objc_exception_try_enter_decl);
2831 c_expand_expr_stmt (build_function_call
2832 (objc_exception_try_enter_decl, func_params));
2834 if_stmt = c_begin_if_stmt ();
2836 /* If <setjmp.h> has been included, the _setjmp prototype has
2837 acquired a real, breathing type for its parameter. Cast our
2838 argument to that type. */
2840 = tree_cons (NULL_TREE,
2841 build_c_cast (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))
2842 ? TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
2846 build_component_ref (TREE_VALUE (objc_stack_exception_data),
2847 get_identifier ("buf")), 0)),
2849 assemble_external (objc_setjmp_decl);
2850 cond = build_unary_op (TRUTH_NOT_EXPR,
2851 build_function_call (objc_setjmp_decl, func_params),
2853 c_expand_start_cond (c_common_truthvalue_conversion (cond),
2855 objc_enter_block ();
2859 objc_build_extract_expr (void)
2861 /* ... = objc_exception_extract(&_stackExceptionData); */
2864 = tree_cons (NULL_TREE,
2865 build_unary_op (ADDR_EXPR,
2866 TREE_VALUE (objc_stack_exception_data), 0),
2869 assemble_external (objc_exception_extract_decl);
2870 return build_function_call (objc_exception_extract_decl, func_params);
2874 objc_build_try_exit_fragment (void)
2876 /* objc_exception_try_exit(&_stackExceptionData); */
2879 = tree_cons (NULL_TREE,
2880 build_unary_op (ADDR_EXPR,
2881 TREE_VALUE (objc_stack_exception_data), 0),
2884 assemble_external (objc_exception_try_exit_decl);
2885 c_expand_expr_stmt (build_function_call (objc_exception_try_exit_decl,
2890 objc_build_extract_fragment (void)
2893 _rethrowException = objc_exception_extract(&_stackExceptionData);
2899 c_expand_start_else ();
2900 objc_enter_block ();
2901 c_expand_expr_stmt (build_modify_expr
2902 (TREE_VALUE (objc_rethrow_exception),
2904 objc_build_extract_expr ()));
2907 c_expand_end_cond ();
2912 objc_build_try_prologue (void)
2915 struct _objc_exception_data _stackExceptionData;
2916 volatile id _rethrowException = nil;
2917 { // begin TRY-CATCH scope
2918 objc_exception_try_enter(&_stackExceptionData);
2919 if (!_setjmp(&_stackExceptionData.buf)) { */
2921 tree try_catch_block;
2923 if (!flag_objc_exceptions)
2924 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2926 objc_mark_locals_volatile ((void *)(exc_binding_stack
2927 ? exc_binding_stack->val
2929 objc_enter_block ();
2930 objc_stack_exception_data
2931 = tree_cons (NULL_TREE,
2932 objc_declare_variable (RID_AUTO,
2933 get_identifier (UTAG_EXCDATA_VAR),
2934 xref_tag (RECORD_TYPE,
2935 get_identifier (UTAG_EXCDATA)),
2937 objc_stack_exception_data);
2938 objc_rethrow_exception = tree_cons (NULL_TREE,
2939 objc_declare_variable (RID_VOLATILE,
2940 get_identifier (UTAG_RETHROWEXC_VAR),
2942 build_int_2 (0, 0)),
2943 objc_rethrow_exception);
2945 try_catch_block = objc_enter_block ();
2946 val_stack_push (&exc_binding_stack, (long) get_current_scope ());
2947 objc_build_try_enter_fragment ();
2949 return try_catch_block;
2953 objc_build_try_epilogue (int also_catch_prologue)
2955 if (also_catch_prologue)
2958 register id _caughtException = objc_exception_extract( &_stackExceptionData);
2959 objc_exception_try_enter(&_stackExceptionData);
2960 if(!_setjmp(&_stackExceptionData.buf)) {
2968 c_expand_start_else ();
2969 objc_enter_block ();
2970 objc_caught_exception
2971 = tree_cons (NULL_TREE,
2972 objc_declare_variable (RID_REGISTER,
2973 get_identifier (UTAG_CAUGHTEXC_VAR),
2975 objc_build_extract_expr ()),
2976 objc_caught_exception);
2977 objc_build_try_enter_fragment ();
2978 val_stack_push (&catch_count_stack, 1);
2979 if_stmt = c_begin_if_stmt ();
2981 c_expand_start_cond (c_common_truthvalue_conversion (boolean_false_node),
2983 objc_enter_block ();
2985 /* Start a new chain of @catch statements for this @try. */
2986 objc_catch_type = tree_cons (objc_catch_type, NULL_TREE, NULL_TREE);
2989 { /* !also_catch_prologue */
2992 _rethrowException = objc_exception_extract( &_stackExceptionData);
2995 objc_build_extract_fragment ();
3001 objc_build_catch_stmt (tree catch_expr)
3003 /* } else if (objc_exception_match(objc_get_class("SomeClass"), _caughtException)) {
3004 register SomeClass *e = _caughtException; */
3006 tree if_stmt, cond, func_params, prev_catch, var_name, var_type;
3010 /* Yet another C/C++ impedance mismatch. */
3011 catch_expr = TREE_PURPOSE (catch_expr);
3014 var_name = TREE_VALUE (catch_expr);
3015 var_type = TREE_VALUE (TREE_PURPOSE (catch_expr));
3016 if (TREE_CODE (var_name) == INDIRECT_REF)
3017 var_name = TREE_OPERAND (var_name, 0);
3018 if (TREE_CODE (var_type) == TYPE_DECL
3019 || TREE_CODE (var_type) == POINTER_TYPE)
3020 var_type = TREE_TYPE (var_type);
3021 catch_id = (var_type == TREE_TYPE (id_type));
3023 if (!flag_objc_exceptions)
3024 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3026 if (!(catch_id || TYPED_OBJECT (var_type)))
3027 fatal_error ("`@catch' parameter is not a known Objective-C class type");
3029 /* Examine previous @catch clauses for the current @try block for
3030 superclasses of the 'var_type' class. */
3031 for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch);
3032 prev_catch = TREE_CHAIN (prev_catch))
3034 if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
3036 warning ("Exception already handled by preceding `@catch(id)'");
3040 && objc_comptypes (TREE_VALUE (prev_catch), var_type, 0) == 1)
3041 warning ("Exception of type `%s *' already handled by `@catch (%s *)'",
3042 IDENTIFIER_POINTER (OBJC_TYPE_NAME (var_type)),
3043 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_VALUE (prev_catch))));
3046 objc_catch_type = tree_cons (NULL_TREE, var_type, objc_catch_type);
3051 c_expand_start_else ();
3052 catch_count_stack->val++;
3053 if_stmt = c_begin_if_stmt ();
3057 cond = integer_one_node;
3060 cond = get_class_reference (OBJC_TYPE_NAME (var_type));
3063 = tree_cons (NULL_TREE, cond,
3064 tree_cons (NULL_TREE,
3065 TREE_VALUE (objc_caught_exception),
3067 assemble_external (objc_exception_match_decl);
3068 cond = build_function_call (objc_exception_match_decl, func_params);
3071 c_expand_start_cond (c_common_truthvalue_conversion (cond),
3073 objc_enter_block ();
3074 objc_declare_variable (RID_REGISTER, var_name,
3075 build_pointer_type (var_type),
3076 TREE_VALUE (objc_caught_exception));
3080 objc_build_catch_epilogue (void)
3083 _rethrowException = _caughtException;
3084 objc_exception_try_exit(&_stackExceptionData);
3087 _rethrowException = objc_exception_extract(&_stackExceptionData);
3090 } // end TRY-CATCH scope
3096 c_expand_start_else ();
3097 objc_enter_block ();
3100 (TREE_VALUE (objc_rethrow_exception),
3102 TREE_VALUE (objc_caught_exception)));
3103 objc_build_try_exit_fragment ();
3105 while (catch_count_stack->val--)
3107 c_finish_else (); /* close off all the nested ifs ! */
3108 c_expand_end_cond ();
3111 val_stack_pop (&catch_count_stack);
3112 objc_caught_exception = TREE_CHAIN (objc_caught_exception);
3114 objc_build_extract_fragment ();
3118 c_expand_end_cond ();
3122 /* Return to enclosing chain of @catch statements (if any). */
3123 while (TREE_VALUE (objc_catch_type))
3124 objc_catch_type = TREE_CHAIN (objc_catch_type);
3125 objc_catch_type = TREE_PURPOSE (objc_catch_type);
3129 objc_build_finally_prologue (void)
3131 /* { // begin FINALLY scope
3132 if (!_rethrowException) {
3133 objc_exception_try_exit(&_stackExceptionData);
3136 tree blk = objc_enter_block ();
3138 tree if_stmt = c_begin_if_stmt ();
3141 c_expand_start_cond (c_common_truthvalue_conversion
3144 TREE_VALUE (objc_rethrow_exception), 0)),
3146 objc_enter_block ();
3147 objc_build_try_exit_fragment ();
3150 c_expand_end_cond ();
3157 objc_build_finally_epilogue (void)
3159 /* if (_rethrowException) {
3160 objc_exception_throw(_rethrowException);
3162 } // end FINALLY scope
3165 tree if_stmt = c_begin_if_stmt ();
3169 (c_common_truthvalue_conversion (TREE_VALUE (objc_rethrow_exception)),
3171 objc_enter_block ();
3172 objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception));
3175 c_expand_end_cond ();
3179 objc_rethrow_exception = TREE_CHAIN (objc_rethrow_exception);
3180 objc_stack_exception_data = TREE_CHAIN (objc_stack_exception_data);
3182 val_stack_pop (&exc_binding_stack);
3183 return objc_exit_block ();
3187 objc_build_try_catch_finally_stmt (int has_catch, int has_finally)
3189 /* NB: The operative assumption here is that TRY_FINALLY_EXPR will
3190 deal with all exits from 'try_catch_blk' and route them through
3192 tree outer_blk = objc_build_finally_epilogue ();
3193 tree prec_stmt = TREE_CHAIN (TREE_CHAIN (COMPOUND_BODY (outer_blk)));
3194 tree try_catch_blk = TREE_CHAIN (prec_stmt), try_catch_expr;
3195 tree finally_blk = TREE_CHAIN (try_catch_blk), finally_expr;
3196 tree succ_stmt = TREE_CHAIN (finally_blk);
3197 tree try_finally_stmt, try_finally_expr;
3199 if (!flag_objc_exceptions)
3200 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3202 /* It is an error to have a @try block without a @catch and/or @finally
3203 (even though sensible code can be generated nonetheless). */
3205 if (!has_catch && !has_finally)
3206 error ("`@try' without `@catch' or `@finally'");
3208 /* We shall now do something truly disgusting. We shall remove the
3209 'try_catch_blk' and 'finally_blk' from the 'outer_blk' statement
3210 chain, and replace them with a TRY_FINALLY_EXPR statement! If
3211 this doesn't work, we will have to learn (from Per/gcj) how to
3212 construct the 'outer_blk' lazily. */
3214 TREE_CHAIN (try_catch_blk) = TREE_CHAIN (finally_blk) = NULL_TREE;
3215 try_catch_expr = build1 (STMT_EXPR, void_type_node, try_catch_blk);
3216 TREE_SIDE_EFFECTS (try_catch_expr) = 1;
3217 finally_expr = build1 (STMT_EXPR, void_type_node, finally_blk);
3218 TREE_SIDE_EFFECTS (finally_expr) = 1;
3219 try_finally_expr = build (TRY_FINALLY_EXPR, void_type_node, try_catch_expr,
3221 TREE_SIDE_EFFECTS (try_finally_expr) = 1;
3222 try_finally_stmt = build_stmt (EXPR_STMT, try_finally_expr);
3223 TREE_CHAIN (prec_stmt) = try_finally_stmt;
3224 TREE_CHAIN (try_finally_stmt) = succ_stmt;
3226 return outer_blk; /* the whole enchilada */
3230 objc_build_synchronized_prologue (tree sync_expr)
3233 id _eval_once = <sync_expr>;
3235 objc_sync_enter( _eval_once ); */
3239 if (!flag_objc_exceptions)
3240 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3242 objc_enter_block ();
3244 = tree_cons (NULL_TREE,
3245 objc_declare_variable (RID_AUTO,
3246 get_identifier (UTAG_EVALONCE_VAR),
3250 objc_build_try_prologue ();
3251 objc_enter_block ();
3252 func_params = tree_cons (NULL_TREE,
3253 TREE_VALUE (objc_eval_once),
3256 assemble_external (objc_sync_enter_decl);
3257 c_expand_expr_stmt (build_function_call
3258 (objc_sync_enter_decl, func_params));
3262 objc_build_synchronized_epilogue (void)
3266 objc_sync_exit( _eval_once );
3273 objc_build_try_epilogue (0);
3274 objc_build_finally_prologue ();
3275 func_params = tree_cons (NULL_TREE, TREE_VALUE (objc_eval_once),
3278 assemble_external (objc_sync_exit_decl);
3279 c_expand_expr_stmt (build_function_call (objc_sync_exit_decl,
3281 objc_build_try_catch_finally_stmt (0, 1);
3283 return objc_exit_block ();
3286 /* Predefine the following data type:
3288 struct _objc_exception_data
3294 /* The following yuckiness should prevent users from having to #include
3295 <setjmp.h> in their code... */
3297 #ifdef TARGET_POWERPC
3298 /* snarfed from /usr/include/ppc/setjmp.h */
3299 #define _JBLEN (26 + 36 + 129 + 1)
3301 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3306 build_objc_exception_stuff (void)
3308 tree field_decl, field_decl_chain, index, temp_type;
3310 /* Suppress outputting debug symbols, because
3311 dbxout_init hasn't been called yet. */
3312 enum debug_info_type save_write_symbols = write_symbols;
3313 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3315 write_symbols = NO_DEBUG;
3316 debug_hooks = &do_nothing_debug_hooks;
3317 objc_exception_data_template
3318 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3320 /* int buf[_JBLEN]; */
3322 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3323 field_decl = create_builtin_decl (FIELD_DECL,
3324 build_array_type (integer_type_node, index),
3326 field_decl_chain = field_decl;
3328 /* void *pointers[4]; */
3330 index = build_index_type (build_int_2 (4 - 1, 0));
3331 field_decl = create_builtin_decl (FIELD_DECL,
3332 build_array_type (ptr_type_node, index),
3334 chainon (field_decl_chain, field_decl);
3336 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3338 /* int _setjmp(...); */
3339 /* If the user includes <setjmp.h>, this shall be superceded by
3340 'int _setjmp(jmp_buf);' */
3341 temp_type = build_function_type (integer_type_node, NULL_TREE);
3343 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3345 /* id objc_exception_extract(struct _objc_exception_data *); */
3347 = build_function_type (id_type,
3348 tree_cons (NULL_TREE,
3349 build_pointer_type (objc_exception_data_template),
3351 objc_exception_extract_decl
3352 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3353 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3354 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3356 = build_function_type (void_type_node,
3357 tree_cons (NULL_TREE,
3358 build_pointer_type (objc_exception_data_template),
3360 objc_exception_try_enter_decl
3361 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3362 objc_exception_try_exit_decl
3363 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3364 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3365 /* void objc_sync_enter(id); */
3366 /* void objc_sync_exit(id); */
3367 temp_type = build_function_type (void_type_node,
3368 tree_cons (NULL_TREE, id_type,
3370 objc_exception_throw_decl
3371 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3372 DECL_ATTRIBUTES (objc_exception_throw_decl)
3373 = tree_cons (get_identifier ("noreturn"), NULL_TREE, NULL_TREE);
3374 objc_sync_enter_decl
3375 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3377 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3378 /* int objc_exception_match(id, id); */
3379 temp_type = build_function_type (integer_type_node,
3380 tree_cons (NULL_TREE, id_type,
3381 tree_cons (NULL_TREE, id_type,
3382 OBJC_VOID_AT_END)));
3383 objc_exception_match_decl
3384 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3386 write_symbols = save_write_symbols;
3387 debug_hooks = save_hooks;
3390 /* struct <classname> {
3391 struct objc_class *isa;
3396 build_private_template (tree class)
3400 if (CLASS_STATIC_TEMPLATE (class))
3402 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3403 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3407 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3408 ivar_context = get_class_ivars (class, 0);
3410 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3412 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3414 /* mark this record as class template - for class type checking */
3415 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3419 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3421 build1 (INDIRECT_REF, NULL_TREE,
3424 return ivar_context;
3427 /* Begin code generation for protocols... */
3429 /* struct objc_protocol {
3430 char *protocol_name;
3431 struct objc_protocol **protocol_list;
3432 struct objc_method_desc *instance_methods;
3433 struct objc_method_desc *class_methods;
3437 build_protocol_template (void)
3439 tree decl_specs, field_decl, field_decl_chain;
3442 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3444 /* struct objc_class *isa; */
3446 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3447 get_identifier (UTAG_CLASS)));
3448 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3449 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3450 field_decl_chain = field_decl;
3452 /* char *protocol_name; */
3454 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3456 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3457 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3458 chainon (field_decl_chain, field_decl);
3460 /* struct objc_protocol **protocol_list; */
3462 decl_specs = build_tree_list (NULL_TREE, template);
3464 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3465 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3466 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3467 chainon (field_decl_chain, field_decl);
3469 /* struct objc_method_list *instance_methods; */
3472 = build_tree_list (NULL_TREE,
3473 xref_tag (RECORD_TYPE,
3474 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3476 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3477 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3478 chainon (field_decl_chain, field_decl);
3480 /* struct objc_method_list *class_methods; */
3483 = build_tree_list (NULL_TREE,
3484 xref_tag (RECORD_TYPE,
3485 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3487 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3488 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3489 chainon (field_decl_chain, field_decl);
3491 return finish_struct (template, field_decl_chain, NULL_TREE);
3495 build_descriptor_table_initializer (tree type, tree entries)
3497 tree initlist = NULL_TREE;
3501 tree eltlist = NULL_TREE;
3504 = tree_cons (NULL_TREE,
3505 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3507 = tree_cons (NULL_TREE,
3508 add_objc_string (METHOD_ENCODING (entries),
3513 = tree_cons (NULL_TREE,
3514 objc_build_constructor (type, nreverse (eltlist)),
3517 entries = TREE_CHAIN (entries);
3521 return objc_build_constructor (build_array_type (type, 0),
3522 nreverse (initlist));
3525 /* struct objc_method_prototype_list {
3527 struct objc_method_prototype {
3534 build_method_prototype_list_template (tree list_type, int size)
3536 tree objc_ivar_list_record;
3537 tree decl_specs, field_decl, field_decl_chain;
3539 /* Generate an unnamed struct definition. */
3541 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3543 /* int method_count; */
3545 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3546 field_decl = get_identifier ("method_count");
3547 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3548 field_decl_chain = field_decl;
3550 /* struct objc_method method_list[]; */
3552 decl_specs = build_tree_list (NULL_TREE, list_type);
3553 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3554 build_int_2 (size, 0));
3555 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3556 chainon (field_decl_chain, field_decl);
3558 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3560 return objc_ivar_list_record;
3564 build_method_prototype_template (void)
3567 tree decl_specs, field_decl, field_decl_chain;
3570 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3572 /* struct objc_selector *_cmd; */
3573 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3574 get_identifier (TAG_SELECTOR)), NULL_TREE);
3575 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3576 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3577 field_decl_chain = field_decl;
3579 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3581 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3582 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3583 chainon (field_decl_chain, field_decl);
3585 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3587 return proto_record;
3591 objc_method_parm_type (tree type)
3593 type = groktypename (TREE_TYPE (type));
3594 if (TREE_CODE (type) == TYPE_DECL)
3595 type = TREE_TYPE (type);
3596 return TYPE_MAIN_VARIANT (type);
3600 objc_encoded_type_size (tree type)
3602 int sz = int_size_in_bytes (type);
3604 /* Make all integer and enum types at least as large
3606 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3607 || TREE_CODE (type) == BOOLEAN_TYPE
3608 || TREE_CODE (type) == ENUMERAL_TYPE))
3609 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3610 /* Treat arrays as pointers, since that's how they're
3612 else if (TREE_CODE (type) == ARRAY_TYPE)
3613 sz = int_size_in_bytes (ptr_type_node);
3618 encode_method_prototype (tree method_decl)
3625 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3626 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3628 /* Encode return type. */
3629 encode_type (objc_method_parm_type (method_decl),
3630 obstack_object_size (&util_obstack),
3631 OBJC_ENCODE_INLINE_DEFS);
3634 /* The first two arguments (self and _cmd) are pointers; account for
3636 i = int_size_in_bytes (ptr_type_node);
3637 parm_offset = 2 * i;
3638 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3639 parms = TREE_CHAIN (parms))
3641 tree type = objc_method_parm_type (parms);
3642 int sz = objc_encoded_type_size (type);
3644 /* If a type size is not known, bail out. */
3647 error ("%Jtype '%D' does not have a known size",
3649 /* Pretend that the encoding succeeded; the compilation will
3650 fail nevertheless. */
3651 goto finish_encoding;
3656 sprintf (buf, "%d@0:%d", parm_offset, i);
3657 obstack_grow (&util_obstack, buf, strlen (buf));
3659 /* Argument types. */
3660 parm_offset = 2 * i;
3661 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3662 parms = TREE_CHAIN (parms))
3664 tree type = objc_method_parm_type (parms);
3666 /* Process argument qualifiers for user supplied arguments. */
3667 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3670 encode_type (type, obstack_object_size (&util_obstack),
3671 OBJC_ENCODE_INLINE_DEFS);
3673 /* Compute offset. */
3674 sprintf (buf, "%d", parm_offset);
3675 parm_offset += objc_encoded_type_size (type);
3677 obstack_grow (&util_obstack, buf, strlen (buf));
3681 obstack_1grow (&util_obstack, '\0');
3682 result = get_identifier (obstack_finish (&util_obstack));
3683 obstack_free (&util_obstack, util_firstobj);
3688 generate_descriptor_table (tree type, const char *name, int size, tree list,
3691 tree sc_spec, decl_specs, decl, initlist;
3693 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3694 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3696 decl = start_decl (synth_id_with_class_suffix (name, proto),
3697 decl_specs, 1, NULL_TREE);
3698 DECL_CONTEXT (decl) = NULL_TREE;
3700 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3701 initlist = tree_cons (NULL_TREE, list, initlist);
3703 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3710 generate_method_descriptors (tree protocol)
3712 tree initlist, chain, method_list_template;
3713 tree cast, variable_length_type;
3716 if (!objc_method_prototype_template)
3717 objc_method_prototype_template = build_method_prototype_template ();
3719 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3720 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3722 variable_length_type = groktypename (cast);
3724 chain = PROTOCOL_CLS_METHODS (protocol);
3727 size = list_length (chain);
3729 method_list_template
3730 = build_method_prototype_list_template (objc_method_prototype_template,
3734 = build_descriptor_table_initializer (objc_method_prototype_template,
3737 UOBJC_CLASS_METHODS_decl
3738 = generate_descriptor_table (method_list_template,
3739 "_OBJC_PROTOCOL_CLASS_METHODS",
3740 size, initlist, protocol);
3741 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3744 UOBJC_CLASS_METHODS_decl = 0;
3746 chain = PROTOCOL_NST_METHODS (protocol);
3749 size = list_length (chain);
3751 method_list_template
3752 = build_method_prototype_list_template (objc_method_prototype_template,
3755 = build_descriptor_table_initializer (objc_method_prototype_template,
3758 UOBJC_INSTANCE_METHODS_decl
3759 = generate_descriptor_table (method_list_template,
3760 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3761 size, initlist, protocol);
3762 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3765 UOBJC_INSTANCE_METHODS_decl = 0;
3769 generate_protocol_references (tree plist)
3773 /* Forward declare protocols referenced. */
3774 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3776 tree proto = TREE_VALUE (lproto);
3778 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3779 && PROTOCOL_NAME (proto))
3781 if (! PROTOCOL_FORWARD_DECL (proto))
3782 build_protocol_reference (proto);
3784 if (PROTOCOL_LIST (proto))
3785 generate_protocol_references (PROTOCOL_LIST (proto));
3790 /* For each protocol which was referenced either from a @protocol()
3791 expression, or because a class/category implements it (then a
3792 pointer to the protocol is stored in the struct describing the
3793 class/category), we create a statically allocated instance of the
3794 Protocol class. The code is written in such a way as to generate
3795 as few Protocol objects as possible; we generate a unique Protocol
3796 instance for each protocol, and we don't generate a Protocol
3797 instance if the protocol is never referenced (either from a
3798 @protocol() or from a class/category implementation). These
3799 statically allocated objects can be referred to via the static
3800 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3802 The statically allocated Protocol objects that we generate here
3803 need to be fixed up at runtime in order to be used: the 'isa'
3804 pointer of the objects need to be set up to point to the 'Protocol'
3805 class, as known at runtime.
3807 The NeXT runtime fixes up all protocols at program startup time,
3808 before main() is entered. It uses a low-level trick to look up all
3809 those symbols, then loops on them and fixes them up.
3811 The GNU runtime as well fixes up all protocols before user code
3812 from the module is executed; it requires pointers to those symbols
3813 to be put in the objc_symtab (which is then passed as argument to
3814 the function __objc_exec_class() which the compiler sets up to be
3815 executed automatically when the module is loaded); setup of those
3816 Protocol objects happen in two ways in the GNU runtime: all
3817 Protocol objects referred to by a class or category implementation
3818 are fixed up when the class/category is loaded; all Protocol
3819 objects referred to by a @protocol() expression are added by the
3820 compiler to the list of statically allocated instances to fixup
3821 (the same list holding the statically allocated constant string
3822 objects). Because, as explained above, the compiler generates as
3823 few Protocol objects as possible, some Protocol object might end up
3824 being referenced multiple times when compiled with the GNU runtime,
3825 and end up being fixed up multiple times at runtime inizialization.
3826 But that doesn't hurt, it's just a little inefficient. */
3829 generate_protocols (void)
3832 tree sc_spec, decl_specs, decl;
3833 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3836 if (! objc_protocol_template)
3837 objc_protocol_template = build_protocol_template ();
3839 /* If a protocol was directly referenced, pull in indirect references. */
3840 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3841 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3842 generate_protocol_references (PROTOCOL_LIST (p));
3844 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3846 tree nst_methods = PROTOCOL_NST_METHODS (p);
3847 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3849 /* If protocol wasn't referenced, don't generate any code. */
3850 if (! PROTOCOL_FORWARD_DECL (p))
3853 /* Make sure we link in the Protocol class. */
3854 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3858 if (! METHOD_ENCODING (nst_methods))
3860 encoding = encode_method_prototype (nst_methods);
3861 METHOD_ENCODING (nst_methods) = encoding;
3863 nst_methods = TREE_CHAIN (nst_methods);
3868 if (! METHOD_ENCODING (cls_methods))
3870 encoding = encode_method_prototype (cls_methods);
3871 METHOD_ENCODING (cls_methods) = encoding;
3874 cls_methods = TREE_CHAIN (cls_methods);
3876 generate_method_descriptors (p);
3878 if (PROTOCOL_LIST (p))
3879 refs_decl = generate_protocol_list (p);
3883 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3885 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3887 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3889 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3890 decl_specs, 1, NULL_TREE);
3892 DECL_CONTEXT (decl) = NULL_TREE;
3894 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3900 (build_tree_list (build_tree_list (NULL_TREE,
3901 objc_protocol_template),
3902 build1 (INDIRECT_REF, NULL_TREE,
3903 build1 (INDIRECT_REF, NULL_TREE,
3906 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3907 TREE_TYPE (refs_expr) = cast_type2;
3910 refs_expr = build_int_2 (0, 0);
3912 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3913 by generate_method_descriptors, which is called above. */
3914 initlist = build_protocol_initializer (TREE_TYPE (decl),
3915 protocol_name_expr, refs_expr,
3916 UOBJC_INSTANCE_METHODS_decl,
3917 UOBJC_CLASS_METHODS_decl);
3918 finish_decl (decl, initlist, NULL_TREE);
3920 /* Mark the decl as used to avoid "defined but not used" warning. */
3921 TREE_USED (decl) = 1;
3926 build_protocol_initializer (tree type, tree protocol_name,
3927 tree protocol_list, tree instance_methods,
3930 tree initlist = NULL_TREE, expr;
3933 cast_type = groktypename
3935 (build_tree_list (NULL_TREE,
3936 xref_tag (RECORD_TYPE,
3937 get_identifier (UTAG_CLASS))),
3938 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3940 /* Filling the "isa" in with one allows the runtime system to
3941 detect that the version change...should remove before final release. */
3943 expr = build_int_2 (PROTOCOL_VERSION, 0);
3944 TREE_TYPE (expr) = cast_type;
3945 initlist = tree_cons (NULL_TREE, expr, initlist);
3946 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3947 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3949 if (!instance_methods)
3950 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3953 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3954 initlist = tree_cons (NULL_TREE, expr, initlist);
3958 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3961 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3962 initlist = tree_cons (NULL_TREE, expr, initlist);
3965 return objc_build_constructor (type, nreverse (initlist));
3968 /* struct objc_category {
3969 char *category_name;
3971 struct objc_method_list *instance_methods;
3972 struct objc_method_list *class_methods;
3973 struct objc_protocol_list *protocols;
3977 build_category_template (void)
3979 tree decl_specs, field_decl, field_decl_chain;
3981 objc_category_template = start_struct (RECORD_TYPE,
3982 get_identifier (UTAG_CATEGORY));
3983 /* char *category_name; */
3985 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3987 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3988 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3989 field_decl_chain = field_decl;
3991 /* char *class_name; */
3993 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3994 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3995 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3996 chainon (field_decl_chain, field_decl);
3998 /* struct objc_method_list *instance_methods; */
4000 decl_specs = build_tree_list (NULL_TREE,
4001 xref_tag (RECORD_TYPE,
4002 get_identifier (UTAG_METHOD_LIST)));
4004 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
4005 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4006 chainon (field_decl_chain, field_decl);
4008 /* struct objc_method_list *class_methods; */
4010 decl_specs = build_tree_list (NULL_TREE,
4011 xref_tag (RECORD_TYPE,
4012 get_identifier (UTAG_METHOD_LIST)));
4014 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
4015 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4016 chainon (field_decl_chain, field_decl);
4018 /* struct objc_protocol **protocol_list; */
4020 decl_specs = build_tree_list (NULL_TREE,
4021 xref_tag (RECORD_TYPE,
4022 get_identifier (UTAG_PROTOCOL)));
4024 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4025 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4026 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4027 chainon (field_decl_chain, field_decl);
4029 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4032 /* struct objc_selector {
4038 build_selector_template (void)
4041 tree decl_specs, field_decl, field_decl_chain;
4043 objc_selector_template
4044 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4048 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4049 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4050 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4051 field_decl_chain = field_decl;
4053 /* char *sel_type; */
4055 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4056 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4057 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4058 chainon (field_decl_chain, field_decl);
4060 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4063 /* struct objc_class {
4064 struct objc_class *isa;
4065 struct objc_class *super_class;
4070 struct objc_ivar_list *ivars;
4071 struct objc_method_list *methods;
4072 if (flag_next_runtime)
4073 struct objc_cache *cache;
4075 struct sarray *dtable;
4076 struct objc_class *subclass_list;
4077 struct objc_class *sibling_class;
4079 struct objc_protocol_list *protocols;
4080 if (flag_next_runtime)
4082 void *gc_object_type;
4085 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4086 the NeXT/Apple runtime; still, the compiler must generate them to
4087 maintain backward binary compatibility (and to allow for future
4091 build_class_template (void)
4093 tree decl_specs, field_decl, field_decl_chain;
4096 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4098 /* struct objc_class *isa; */
4100 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4101 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4102 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4103 field_decl_chain = field_decl;
4105 /* struct objc_class *super_class; */
4107 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4109 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4110 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4111 chainon (field_decl_chain, field_decl);
4115 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4116 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4117 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4118 chainon (field_decl_chain, field_decl);
4122 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4123 field_decl = get_identifier ("version");
4124 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4125 chainon (field_decl_chain, field_decl);
4129 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4130 field_decl = get_identifier ("info");
4131 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4132 chainon (field_decl_chain, field_decl);
4134 /* long instance_size; */
4136 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4137 field_decl = get_identifier ("instance_size");
4138 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4139 chainon (field_decl_chain, field_decl);
4141 /* struct objc_ivar_list *ivars; */
4143 decl_specs = build_tree_list (NULL_TREE,
4144 xref_tag (RECORD_TYPE,
4145 get_identifier (UTAG_IVAR_LIST)));
4146 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4147 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4148 chainon (field_decl_chain, field_decl);
4150 /* struct objc_method_list *methods; */
4152 decl_specs = build_tree_list (NULL_TREE,
4153 xref_tag (RECORD_TYPE,
4154 get_identifier (UTAG_METHOD_LIST)));
4155 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4156 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4157 chainon (field_decl_chain, field_decl);
4159 if (flag_next_runtime)
4161 /* struct objc_cache *cache; */
4163 decl_specs = build_tree_list (NULL_TREE,
4164 xref_tag (RECORD_TYPE,
4165 get_identifier ("objc_cache")));
4166 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4167 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4168 chainon (field_decl_chain, field_decl);
4172 /* struct sarray *dtable; */
4174 decl_specs = build_tree_list (NULL_TREE,
4175 xref_tag (RECORD_TYPE,
4176 get_identifier ("sarray")));
4177 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4178 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4179 chainon (field_decl_chain, field_decl);
4181 /* struct objc_class *subclass_list; */
4183 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4185 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4186 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4187 chainon (field_decl_chain, field_decl);
4189 /* struct objc_class *sibling_class; */
4191 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4193 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4194 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4195 chainon (field_decl_chain, field_decl);
4198 /* struct objc_protocol **protocol_list; */
4200 decl_specs = build_tree_list (NULL_TREE,
4201 xref_tag (RECORD_TYPE,
4202 get_identifier (UTAG_PROTOCOL)));
4204 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4206 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4207 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4208 chainon (field_decl_chain, field_decl);
4210 if (flag_next_runtime)
4214 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4215 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4217 = grokfield (field_decl, decl_specs, NULL_TREE);
4218 chainon (field_decl_chain, field_decl);
4221 /* void *gc_object_type; */
4223 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4224 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4225 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4226 chainon (field_decl_chain, field_decl);
4228 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4231 /* Generate appropriate forward declarations for an implementation. */
4234 synth_forward_declarations (void)
4238 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4239 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4240 objc_class_template);
4242 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4243 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4244 objc_class_template);
4246 /* Pre-build the following entities - for speed/convenience. */
4248 an_id = get_identifier ("super_class");
4249 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4250 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4254 error_with_ivar (const char *message, tree decl, tree rawdecl)
4256 error ("%J%s `%s'", decl,
4257 message, gen_declaration (rawdecl, errbuf));
4262 check_ivars (tree inter, tree imp)
4264 tree intdecls = CLASS_IVARS (inter);
4265 tree impdecls = CLASS_IVARS (imp);
4266 tree rawintdecls = CLASS_RAW_IVARS (inter);
4267 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4274 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4275 intdecls = TREE_CHAIN (intdecls);
4277 if (intdecls == 0 && impdecls == 0)
4279 if (intdecls == 0 || impdecls == 0)
4281 error ("inconsistent instance variable specification");
4285 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4287 if (!comptypes (t1, t2, false)
4288 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4289 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4291 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4293 error_with_ivar ("conflicting instance variable type",
4294 impdecls, rawimpdecls);
4295 error_with_ivar ("previous declaration of",
4296 intdecls, rawintdecls);
4298 else /* both the type and the name don't match */
4300 error ("inconsistent instance variable specification");
4305 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4307 error_with_ivar ("conflicting instance variable name",
4308 impdecls, rawimpdecls);
4309 error_with_ivar ("previous declaration of",
4310 intdecls, rawintdecls);
4313 intdecls = TREE_CHAIN (intdecls);
4314 impdecls = TREE_CHAIN (impdecls);
4315 rawintdecls = TREE_CHAIN (rawintdecls);
4316 rawimpdecls = TREE_CHAIN (rawimpdecls);
4320 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4321 This needs to be done just once per compilation. */
4324 build_super_template (void)
4326 tree decl_specs, field_decl, field_decl_chain;
4328 /* Suppress outputting debug symbols, because
4329 dbxout_init hasn't been called yet. */
4330 enum debug_info_type save_write_symbols = write_symbols;
4331 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4333 write_symbols = NO_DEBUG;
4334 debug_hooks = &do_nothing_debug_hooks;
4336 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4338 /* struct objc_object *self; */
4340 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4341 field_decl = get_identifier ("self");
4342 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4343 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4344 field_decl_chain = field_decl;
4346 /* struct objc_class *class; */
4348 decl_specs = get_identifier (UTAG_CLASS);
4349 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4350 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4352 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4353 chainon (field_decl_chain, field_decl);
4355 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4357 write_symbols = save_write_symbols;
4358 debug_hooks = save_hooks;
4361 /* struct objc_ivar {
4368 build_ivar_template (void)
4370 tree objc_ivar_id, objc_ivar_record;
4371 tree decl_specs, field_decl, field_decl_chain;
4373 objc_ivar_id = get_identifier (UTAG_IVAR);
4374 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4376 /* char *ivar_name; */
4378 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4379 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4381 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4382 field_decl_chain = field_decl;
4384 /* char *ivar_type; */
4386 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4387 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4389 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4390 chainon (field_decl_chain, field_decl);
4392 /* int ivar_offset; */
4394 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4395 field_decl = get_identifier ("ivar_offset");
4397 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4398 chainon (field_decl_chain, field_decl);
4400 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4402 return objc_ivar_record;
4407 struct objc_ivar ivar_list[ivar_count];
4411 build_ivar_list_template (tree list_type, int size)
4413 tree objc_ivar_list_record;
4414 tree decl_specs, field_decl, field_decl_chain;
4416 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4418 /* int ivar_count; */
4420 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4421 field_decl = get_identifier ("ivar_count");
4423 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4424 field_decl_chain = field_decl;
4426 /* struct objc_ivar ivar_list[]; */
4428 decl_specs = build_tree_list (NULL_TREE, list_type);
4429 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4430 build_int_2 (size, 0));
4432 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4433 chainon (field_decl_chain, field_decl);
4435 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4437 return objc_ivar_list_record;
4443 struct objc_method method_list[method_count];
4447 build_method_list_template (tree list_type, int size)
4449 tree objc_ivar_list_record;
4450 tree decl_specs, field_decl, field_decl_chain;
4452 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4454 /* int method_next; */
4459 xref_tag (RECORD_TYPE,
4460 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4462 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4463 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4464 field_decl_chain = field_decl;
4466 /* int method_count; */
4468 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4469 field_decl = get_identifier ("method_count");
4471 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4472 chainon (field_decl_chain, field_decl);
4474 /* struct objc_method method_list[]; */
4476 decl_specs = build_tree_list (NULL_TREE, list_type);
4477 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4478 build_int_2 (size, 0));
4480 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4481 chainon (field_decl_chain, field_decl);
4483 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4485 return objc_ivar_list_record;
4489 build_ivar_list_initializer (tree type, tree field_decl)
4491 tree initlist = NULL_TREE;
4495 tree ivar = NULL_TREE;
4498 if (DECL_NAME (field_decl))
4499 ivar = tree_cons (NULL_TREE,
4500 add_objc_string (DECL_NAME (field_decl),
4504 /* Unnamed bit-field ivar (yuck). */
4505 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4508 encode_field_decl (field_decl,
4509 obstack_object_size (&util_obstack),
4510 OBJC_ENCODE_DONT_INLINE_DEFS);
4512 /* Null terminate string. */
4513 obstack_1grow (&util_obstack, 0);
4517 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4520 obstack_free (&util_obstack, util_firstobj);
4523 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4524 initlist = tree_cons (NULL_TREE,
4525 objc_build_constructor (type, nreverse (ivar)),
4528 field_decl = TREE_CHAIN (field_decl);
4529 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4533 return objc_build_constructor (build_array_type (type, 0),
4534 nreverse (initlist));
4538 generate_ivars_list (tree type, const char *name, int size, tree list)
4540 tree sc_spec, decl_specs, decl, initlist;
4542 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4543 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4545 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4546 decl_specs, 1, NULL_TREE);
4548 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4549 initlist = tree_cons (NULL_TREE, list, initlist);
4552 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4558 /* Count only the fields occurring in T. */
4560 ivar_list_length (tree t)
4564 for (; t; t = TREE_CHAIN (t))
4565 if (TREE_CODE (t) == FIELD_DECL)
4572 generate_ivar_lists (void)
4574 tree initlist, ivar_list_template, chain;
4575 tree cast, variable_length_type;
4578 generating_instance_variables = 1;
4580 if (!objc_ivar_template)
4581 objc_ivar_template = build_ivar_template ();
4585 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4586 get_identifier (UTAG_IVAR_LIST))),
4588 variable_length_type = groktypename (cast);
4590 /* Only generate class variables for the root of the inheritance
4591 hierarchy since these will be the same for every class. */
4593 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4594 && (chain = TYPE_FIELDS (objc_class_template)))
4596 size = ivar_list_length (chain);
4598 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4599 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4601 UOBJC_CLASS_VARIABLES_decl
4602 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4604 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4607 UOBJC_CLASS_VARIABLES_decl = 0;
4609 chain = CLASS_IVARS (implementation_template);
4612 size = ivar_list_length (chain);
4613 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4614 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4616 UOBJC_INSTANCE_VARIABLES_decl
4617 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4619 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4622 UOBJC_INSTANCE_VARIABLES_decl = 0;
4624 generating_instance_variables = 0;
4628 build_dispatch_table_initializer (tree type, tree entries)
4630 tree initlist = NULL_TREE;
4634 tree elemlist = NULL_TREE;
4636 elemlist = tree_cons (NULL_TREE,
4637 build_selector (METHOD_SEL_NAME (entries)),
4640 /* Generate the method encoding if we don't have one already. */
4641 if (! METHOD_ENCODING (entries))
4642 METHOD_ENCODING (entries) =
4643 encode_method_prototype (entries);
4645 elemlist = tree_cons (NULL_TREE,
4646 add_objc_string (METHOD_ENCODING (entries),
4650 elemlist = tree_cons (NULL_TREE,
4651 build_unary_op (ADDR_EXPR,
4652 METHOD_DEFINITION (entries), 1),
4655 initlist = tree_cons (NULL_TREE,
4656 objc_build_constructor (type, nreverse (elemlist)),
4659 entries = TREE_CHAIN (entries);
4663 return objc_build_constructor (build_array_type (type, 0),
4664 nreverse (initlist));
4667 /* To accomplish method prototyping without generating all kinds of
4668 inane warnings, the definition of the dispatch table entries were
4671 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4673 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4676 build_method_template (void)
4679 tree decl_specs, field_decl, field_decl_chain;
4681 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4683 /* struct objc_selector *_cmd; */
4684 decl_specs = tree_cons (NULL_TREE,
4685 xref_tag (RECORD_TYPE,
4686 get_identifier (TAG_SELECTOR)),
4688 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4690 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4691 field_decl_chain = field_decl;
4693 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4694 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4695 get_identifier ("method_types"));
4696 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4697 chainon (field_decl_chain, field_decl);
4701 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4702 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4703 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4704 chainon (field_decl_chain, field_decl);
4706 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4713 generate_dispatch_table (tree type, const char *name, int size, tree list)
4715 tree sc_spec, decl_specs, decl, initlist;
4717 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4718 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4720 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4721 decl_specs, 1, NULL_TREE);
4723 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4724 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4725 initlist = tree_cons (NULL_TREE, list, initlist);
4728 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4735 mark_referenced_methods (void)
4737 struct imp_entry *impent;
4740 for (impent = imp_list; impent; impent = impent->next)
4742 chain = CLASS_CLS_METHODS (impent->imp_context);
4745 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4746 chain = TREE_CHAIN (chain);
4749 chain = CLASS_NST_METHODS (impent->imp_context);
4752 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4753 chain = TREE_CHAIN (chain);
4759 generate_dispatch_tables (void)
4761 tree initlist, chain, method_list_template;
4762 tree cast, variable_length_type;
4765 if (!objc_method_template)
4766 objc_method_template = build_method_template ();
4770 (build_tree_list (NULL_TREE,
4771 xref_tag (RECORD_TYPE,
4772 get_identifier (UTAG_METHOD_LIST))),
4775 variable_length_type = groktypename (cast);
4777 chain = CLASS_CLS_METHODS (objc_implementation_context);
4780 size = list_length (chain);
4782 method_list_template
4783 = build_method_list_template (objc_method_template, size);
4785 = build_dispatch_table_initializer (objc_method_template, chain);
4787 UOBJC_CLASS_METHODS_decl
4788 = generate_dispatch_table (method_list_template,
4789 ((TREE_CODE (objc_implementation_context)
4790 == CLASS_IMPLEMENTATION_TYPE)
4791 ? "_OBJC_CLASS_METHODS"
4792 : "_OBJC_CATEGORY_CLASS_METHODS"),
4794 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4797 UOBJC_CLASS_METHODS_decl = 0;
4799 chain = CLASS_NST_METHODS (objc_implementation_context);
4802 size = list_length (chain);
4804 method_list_template
4805 = build_method_list_template (objc_method_template, size);
4807 = build_dispatch_table_initializer (objc_method_template, chain);
4809 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4810 UOBJC_INSTANCE_METHODS_decl
4811 = generate_dispatch_table (method_list_template,
4812 "_OBJC_INSTANCE_METHODS",
4815 /* We have a category. */
4816 UOBJC_INSTANCE_METHODS_decl
4817 = generate_dispatch_table (method_list_template,
4818 "_OBJC_CATEGORY_INSTANCE_METHODS",
4820 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4823 UOBJC_INSTANCE_METHODS_decl = 0;
4827 generate_protocol_list (tree i_or_p)
4829 tree initlist, decl_specs, sc_spec;
4830 tree refs_decl, expr_decl, lproto, e, plist;
4834 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4835 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4836 plist = CLASS_PROTOCOL_LIST (i_or_p);
4837 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4838 plist = PROTOCOL_LIST (i_or_p);
4842 cast_type = groktypename
4844 (build_tree_list (NULL_TREE,
4845 xref_tag (RECORD_TYPE,
4846 get_identifier (UTAG_PROTOCOL))),
4847 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4850 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4851 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4852 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4855 /* Build initializer. */
4856 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4858 e = build_int_2 (size, 0);
4859 TREE_TYPE (e) = cast_type;
4860 initlist = tree_cons (NULL_TREE, e, initlist);
4862 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4864 tree pval = TREE_VALUE (lproto);
4866 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4867 && PROTOCOL_FORWARD_DECL (pval))
4869 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4870 initlist = tree_cons (NULL_TREE, e, initlist);
4874 /* static struct objc_protocol *refs[n]; */
4876 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4877 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4878 get_identifier (UTAG_PROTOCOL)),
4881 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4882 expr_decl = build_nt (ARRAY_REF,
4883 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4885 build_int_2 (size + 2, 0));
4886 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4887 expr_decl = build_nt (ARRAY_REF,
4888 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4890 build_int_2 (size + 2, 0));
4891 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4893 = build_nt (ARRAY_REF,
4894 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4896 build_int_2 (size + 2, 0));
4900 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4902 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4903 DECL_CONTEXT (refs_decl) = NULL_TREE;
4905 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4906 nreverse (initlist)),
4913 build_category_initializer (tree type, tree cat_name, tree class_name,
4914 tree instance_methods, tree class_methods,
4917 tree initlist = NULL_TREE, expr;
4919 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4920 initlist = tree_cons (NULL_TREE, class_name, initlist);
4922 if (!instance_methods)
4923 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4926 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4927 initlist = tree_cons (NULL_TREE, expr, initlist);
4930 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4933 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4934 initlist = tree_cons (NULL_TREE, expr, initlist);
4937 /* protocol_list = */
4939 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4942 tree cast_type2 = groktypename
4944 (build_tree_list (NULL_TREE,
4945 xref_tag (RECORD_TYPE,
4946 get_identifier (UTAG_PROTOCOL))),
4947 build1 (INDIRECT_REF, NULL_TREE,
4948 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4950 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4951 TREE_TYPE (expr) = cast_type2;
4952 initlist = tree_cons (NULL_TREE, expr, initlist);
4955 return objc_build_constructor (type, nreverse (initlist));
4958 /* struct objc_class {
4959 struct objc_class *isa;
4960 struct objc_class *super_class;
4965 struct objc_ivar_list *ivars;
4966 struct objc_method_list *methods;
4967 if (flag_next_runtime)
4968 struct objc_cache *cache;
4970 struct sarray *dtable;
4971 struct objc_class *subclass_list;
4972 struct objc_class *sibling_class;
4974 struct objc_protocol_list *protocols;
4975 if (flag_next_runtime)
4977 void *gc_object_type;
4981 build_shared_structure_initializer (tree type, tree isa, tree super,
4982 tree name, tree size, int status,
4983 tree dispatch_table, tree ivar_list,
4986 tree initlist = NULL_TREE, expr;
4989 initlist = tree_cons (NULL_TREE, isa, initlist);
4992 initlist = tree_cons (NULL_TREE, super, initlist);
4995 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4998 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5001 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
5003 /* instance_size = */
5004 initlist = tree_cons (NULL_TREE, size, initlist);
5006 /* objc_ivar_list = */
5008 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5011 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
5012 initlist = tree_cons (NULL_TREE, expr, initlist);
5015 /* objc_method_list = */
5016 if (!dispatch_table)
5017 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5020 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
5021 initlist = tree_cons (NULL_TREE, expr, initlist);
5024 if (flag_next_runtime)
5025 /* method_cache = */
5026 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5030 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5032 /* subclass_list = */
5033 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5035 /* sibling_class = */
5036 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5039 /* protocol_list = */
5040 if (! protocol_list)
5041 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5047 (build_tree_list (NULL_TREE,
5048 xref_tag (RECORD_TYPE,
5049 get_identifier (UTAG_PROTOCOL))),
5050 build1 (INDIRECT_REF, NULL_TREE,
5051 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5053 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5054 TREE_TYPE (expr) = cast_type2;
5055 initlist = tree_cons (NULL_TREE, expr, initlist);
5058 if (flag_next_runtime)
5060 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5062 /* gc_object_type = NULL */
5063 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5065 return objc_build_constructor (type, nreverse (initlist));
5068 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5071 lookup_category (tree class, tree cat_name)
5073 tree category = CLASS_CATEGORY_LIST (class);
5075 while (category && CLASS_SUPER_NAME (category) != cat_name)
5076 category = CLASS_CATEGORY_LIST (category);
5080 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5083 generate_category (tree cat)
5085 tree sc_spec, decl_specs, decl;
5086 tree initlist, cat_name_expr, class_name_expr;
5087 tree protocol_decl, category;
5089 add_class_reference (CLASS_NAME (cat));
5090 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5092 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5094 category = lookup_category (implementation_template,
5095 CLASS_SUPER_NAME (cat));
5097 if (category && CLASS_PROTOCOL_LIST (category))
5099 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5100 protocol_decl = generate_protocol_list (category);
5105 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5106 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5108 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5109 objc_implementation_context),
5110 decl_specs, 1, NULL_TREE);
5112 initlist = build_category_initializer (TREE_TYPE (decl),
5113 cat_name_expr, class_name_expr,
5114 UOBJC_INSTANCE_METHODS_decl,
5115 UOBJC_CLASS_METHODS_decl,
5118 finish_decl (decl, initlist, NULL_TREE);
5121 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5122 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5125 generate_shared_structures (void)
5127 tree sc_spec, decl_specs, decl;
5128 tree name_expr, super_expr, root_expr;
5129 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5130 tree cast_type, initlist, protocol_decl;
5132 my_super_id = CLASS_SUPER_NAME (implementation_template);
5135 add_class_reference (my_super_id);
5137 /* Compute "my_root_id" - this is required for code generation.
5138 the "isa" for all meta class structures points to the root of
5139 the inheritance hierarchy (e.g. "__Object")... */
5140 my_root_id = my_super_id;
5143 tree my_root_int = lookup_interface (my_root_id);
5145 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5146 my_root_id = CLASS_SUPER_NAME (my_root_int);
5153 /* No super class. */
5154 my_root_id = CLASS_NAME (implementation_template);
5157 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5158 objc_class_template),
5159 build1 (INDIRECT_REF,
5160 NULL_TREE, NULL_TREE)));
5162 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5165 /* Install class `isa' and `super' pointers at runtime. */
5168 super_expr = add_objc_string (my_super_id, class_names);
5169 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5172 super_expr = build_int_2 (0, 0);
5174 root_expr = add_objc_string (my_root_id, class_names);
5175 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5177 if (CLASS_PROTOCOL_LIST (implementation_template))
5179 generate_protocol_references
5180 (CLASS_PROTOCOL_LIST (implementation_template));
5181 protocol_decl = generate_protocol_list (implementation_template);
5186 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5188 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5189 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5191 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5195 = build_shared_structure_initializer
5197 root_expr, super_expr, name_expr,
5198 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5200 UOBJC_CLASS_METHODS_decl,
5201 UOBJC_CLASS_VARIABLES_decl,
5204 finish_decl (decl, initlist, NULL_TREE);
5206 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5208 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5212 = build_shared_structure_initializer
5214 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5215 super_expr, name_expr,
5216 convert (integer_type_node,
5217 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5218 (implementation_template))),
5220 UOBJC_INSTANCE_METHODS_decl,
5221 UOBJC_INSTANCE_VARIABLES_decl,
5224 finish_decl (decl, initlist, NULL_TREE);
5228 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5231 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5232 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5234 const char *const class_name
5235 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5236 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5237 sprintf (string, "%s_%s", preamble,
5238 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5240 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5241 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5243 /* We have a category. */
5244 const char *const class_name
5245 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5246 const char *const class_super_name
5247 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5248 string = (char *) alloca (strlen (preamble)
5249 + strlen (class_name)
5250 + strlen (class_super_name)
5252 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5254 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5256 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5258 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5259 sprintf (string, "%s_%s", preamble, protocol_name);
5264 return get_identifier (string);
5268 is_objc_type_qualifier (tree node)
5270 return (TREE_CODE (node) == IDENTIFIER_NODE
5271 && (node == ridpointers [(int) RID_CONST]
5272 || node == ridpointers [(int) RID_VOLATILE]
5273 || node == ridpointers [(int) RID_IN]
5274 || node == ridpointers [(int) RID_OUT]
5275 || node == ridpointers [(int) RID_INOUT]
5276 || node == ridpointers [(int) RID_BYCOPY]
5277 || node == ridpointers [(int) RID_BYREF]
5278 || node == ridpointers [(int) RID_ONEWAY]));
5281 /* If type is empty or only type qualifiers are present, add default
5282 type of id (otherwise grokdeclarator will default to int). */
5285 adjust_type_for_id_default (tree type)
5287 tree declspecs, chain;
5290 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5291 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5293 declspecs = TREE_PURPOSE (type);
5295 /* Determine if a typespec is present. */
5296 for (chain = declspecs;
5298 chain = TREE_CHAIN (chain))
5300 if (TYPED_OBJECT (TREE_VALUE (chain))
5301 && !(TREE_VALUE (type)
5302 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5303 error ("can not use an object as parameter to a method\n");
5304 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5308 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5310 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5315 selector ':' '(' typename ')' identifier
5318 Transform an Objective-C keyword argument into
5319 the C equivalent parameter declarator.
5321 In: key_name, an "identifier_node" (optional).
5322 arg_type, a "tree_list" (optional).
5323 arg_name, an "identifier_node".
5325 Note: It would be really nice to strongly type the preceding
5326 arguments in the function prototype; however, then I
5327 could not use the "accessor" macros defined in "tree.h".
5329 Out: an instance of "keyword_decl". */
5332 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5336 /* If no type is specified, default to "id". */
5337 arg_type = adjust_type_for_id_default (arg_type);
5339 keyword_decl = make_node (KEYWORD_DECL);
5341 TREE_TYPE (keyword_decl) = arg_type;
5342 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5343 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5345 return keyword_decl;
5348 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5351 build_keyword_selector (tree selector)
5354 tree key_chain, key_name;
5357 /* Scan the selector to see how much space we'll need. */
5358 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5360 if (TREE_CODE (selector) == KEYWORD_DECL)
5361 key_name = KEYWORD_KEY_NAME (key_chain);
5362 else if (TREE_CODE (selector) == TREE_LIST)
5363 key_name = TREE_PURPOSE (key_chain);
5368 len += IDENTIFIER_LENGTH (key_name) + 1;
5370 /* Just a ':' arg. */
5374 buf = (char *) alloca (len + 1);
5375 /* Start the buffer out as an empty string. */
5378 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5380 if (TREE_CODE (selector) == KEYWORD_DECL)
5381 key_name = KEYWORD_KEY_NAME (key_chain);
5382 else if (TREE_CODE (selector) == TREE_LIST)
5384 key_name = TREE_PURPOSE (key_chain);
5385 /* The keyword decl chain will later be used as a function argument
5386 chain. Unhook the selector itself so as to not confuse other
5387 parts of the compiler. */
5388 TREE_PURPOSE (key_chain) = NULL_TREE;
5394 strcat (buf, IDENTIFIER_POINTER (key_name));
5398 return get_identifier (buf);
5401 /* Used for declarations and definitions. */
5404 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5409 /* If no type is specified, default to "id". */
5410 ret_type = adjust_type_for_id_default (ret_type);
5412 method_decl = make_node (code);
5413 TREE_TYPE (method_decl) = ret_type;
5415 /* If we have a keyword selector, create an identifier_node that
5416 represents the full selector name (`:' included)... */
5417 if (TREE_CODE (selector) == KEYWORD_DECL)
5419 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5420 METHOD_SEL_ARGS (method_decl) = selector;
5421 METHOD_ADD_ARGS (method_decl) = add_args;
5425 METHOD_SEL_NAME (method_decl) = selector;
5426 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5427 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5433 #define METHOD_DEF 0
5434 #define METHOD_REF 1
5436 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5437 an argument list for method METH. CONTEXT is either METHOD_DEF or
5438 METHOD_REF, saying whether we are trying to define a method or call
5439 one. SUPERFLAG says this is for a send to super; this makes a
5440 difference for the NeXT calling sequence in which the lookup and
5441 the method call are done together. If METH is null, user-defined
5442 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5445 get_arg_type_list (tree meth, int context, int superflag)
5449 /* Receiver type. */
5450 if (flag_next_runtime && superflag)
5451 arglist = build_tree_list (NULL_TREE, super_type);
5452 else if (context == METHOD_DEF)
5453 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5455 arglist = build_tree_list (NULL_TREE, id_type);
5457 /* Selector type - will eventually change to `int'. */
5458 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
5460 /* No actual method prototype given -- assume that remaining arguments
5465 /* Build a list of argument types. */
5466 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5468 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5469 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5472 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5473 /* We have a `, ...' immediately following the selector,
5474 finalize the arglist...simulate get_parm_info (0). */
5476 else if (METHOD_ADD_ARGS (meth))
5478 /* we have a variable length selector */
5479 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5480 chainon (arglist, add_arg_list);
5483 /* finalize the arglist...simulate get_parm_info (1) */
5484 chainon (arglist, OBJC_VOID_AT_END);
5490 check_duplicates (hash hsh, int methods, int is_class)
5492 tree meth = NULL_TREE;
5500 /* We have two or more methods with the same name but
5504 warning ("multiple %s named `%c%s' found",
5505 methods ? "methods" : "selectors",
5506 (is_class ? '+' : '-'),
5507 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5509 warn_with_method (methods ? "using" : "found",
5510 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5514 for (loop = hsh->list; loop; loop = loop->next)
5515 warn_with_method ("also found",
5516 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5525 /* If RECEIVER is a class reference, return the identifier node for
5526 the referenced class. RECEIVER is created by get_class_reference,
5527 so we check the exact form created depending on which runtimes are
5531 receiver_is_class_object (tree receiver, int self, int super)
5533 tree chain, exp, arg;
5535 /* The receiver is 'self' or 'super' in the context of a class method. */
5536 if (objc_method_context
5537 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5540 ? CLASS_SUPER_NAME (implementation_template)
5541 : CLASS_NAME (implementation_template));
5543 if (flag_next_runtime)
5545 /* The receiver is a variable created by
5546 build_class_reference_decl. */
5547 if (TREE_CODE (receiver) == VAR_DECL
5548 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5549 /* Look up the identifier. */
5550 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5551 if (TREE_PURPOSE (chain) == receiver)
5552 return TREE_VALUE (chain);
5555 /* The receiver is a function call that returns an id. Check if
5556 it is a call to objc_getClass, if so, pick up the class name. */
5557 if (TREE_CODE (receiver) == CALL_EXPR
5558 && (exp = TREE_OPERAND (receiver, 0))
5559 && TREE_CODE (exp) == ADDR_EXPR
5560 && (exp = TREE_OPERAND (exp, 0))
5561 && TREE_CODE (exp) == FUNCTION_DECL
5562 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5563 prototypes for objc_get_class(). Thankfuly, they seem to share the
5564 same function type. */
5565 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5566 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5567 /* We have a call to objc_get_class/objc_getClass! */
5568 && (arg = TREE_OPERAND (receiver, 1))
5569 && TREE_CODE (arg) == TREE_LIST
5570 && (arg = TREE_VALUE (arg)))
5573 if (TREE_CODE (arg) == ADDR_EXPR
5574 && (arg = TREE_OPERAND (arg, 0))
5575 && TREE_CODE (arg) == STRING_CST)
5576 /* Finally, we have the class name. */
5577 return get_identifier (TREE_STRING_POINTER (arg));
5582 /* If we are currently building a message expr, this holds
5583 the identifier of the selector of the message. This is
5584 used when printing warnings about argument mismatches. */
5586 static tree current_objc_message_selector = 0;
5589 objc_message_selector (void)
5591 return current_objc_message_selector;
5594 /* Construct an expression for sending a message.
5595 MESS has the object to send to in TREE_PURPOSE
5596 and the argument list (including selector) in TREE_VALUE.
5598 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5599 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5602 build_message_expr (tree mess)
5604 tree receiver = TREE_PURPOSE (mess);
5606 tree args = TREE_VALUE (mess);
5607 tree method_params = NULL_TREE;
5609 if (TREE_CODE (receiver) == ERROR_MARK)
5610 return error_mark_node;
5612 /* Obtain the full selector name. */
5613 if (TREE_CODE (args) == IDENTIFIER_NODE)
5614 /* A unary selector. */
5616 else if (TREE_CODE (args) == TREE_LIST)
5617 sel_name = build_keyword_selector (args);
5621 /* Build the parameter list to give to the method. */
5622 if (TREE_CODE (args) == TREE_LIST)
5624 tree chain = args, prev = NULL_TREE;
5626 /* We have a keyword selector--check for comma expressions. */
5629 tree element = TREE_VALUE (chain);
5631 /* We have a comma expression, must collapse... */
5632 if (TREE_CODE (element) == TREE_LIST)
5635 TREE_CHAIN (prev) = element;
5640 chain = TREE_CHAIN (chain);
5642 method_params = args;
5646 if (processing_template_decl)
5647 /* Must wait until template instantiation time. */
5648 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5652 return finish_message_expr (receiver, sel_name, method_params);
5655 /* Look up method SEL_NAME that would be suitable for receiver
5656 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5657 nonzero), and report on any duplicates. */
5660 lookup_method_in_hash_lists (tree sel_name, int is_class)
5662 hash method_prototype = NULL;
5665 method_prototype = hash_lookup (nst_method_hash_list,
5668 if (!method_prototype)
5670 method_prototype = hash_lookup (cls_method_hash_list,
5675 return check_duplicates (method_prototype, 1, is_class);
5678 /* The 'finish_message_expr' routine is called from within
5679 'build_message_expr' for non-template functions. In the case of
5680 C++ template functions, it is called from 'build_expr_from_tree'
5681 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5684 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5686 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5687 tree selector, retval, is_class;
5688 int self, super, have_cast;
5690 /* Extract the receiver of the message, as well as its type
5691 (where the latter may take the form of a cast or be inferred
5692 from the implementation context). */
5694 while (TREE_CODE (rtype) == COMPOUND_EXPR
5695 || TREE_CODE (rtype) == MODIFY_EXPR
5696 || TREE_CODE (rtype) == NOP_EXPR
5697 || TREE_CODE (rtype) == COMPONENT_REF)
5698 rtype = TREE_OPERAND (rtype, 0);
5699 self = (rtype == self_decl);
5700 super = (rtype == UOBJC_SUPER_decl);
5701 rtype = TREE_TYPE (receiver);
5702 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5703 || (TREE_CODE (receiver) == COMPOUND_EXPR
5704 && !IS_SUPER (rtype)));
5706 /* If the receiver is a class object, retrieve the corresponding
5707 @interface, if one exists. */
5708 is_class = receiver_is_class_object (receiver, self, super);
5710 /* Now determine the receiver type (if an explicit cast has not been
5715 rtype = lookup_interface (is_class);
5716 /* Handle `self' and `super'. */
5719 if (!CLASS_SUPER_NAME (implementation_template))
5721 error ("no super class declared in @interface for `%s'",
5722 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5723 return error_mark_node;
5725 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5728 rtype = lookup_interface (CLASS_NAME (implementation_template));
5731 /* If receiver is of type `id' or `Class' (or if the @interface for a
5732 class is not visible), we shall be satisfied with the existence of
5733 any instance or class method. */
5734 if (!rtype || IS_ID (rtype)
5735 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5738 rtype = xref_tag (RECORD_TYPE, is_class);
5739 else if (IS_ID (rtype))
5741 rprotos = TYPE_PROTOCOL_LIST (rtype);
5745 is_class = TYPE_NAME (rtype) = get_identifier ("Class");
5749 = lookup_method_in_protocol_list (rprotos, sel_name,
5750 is_class != NULL_TREE);
5751 if (!method_prototype && !rprotos)
5753 = lookup_method_in_hash_lists (sel_name,
5754 is_class != NULL_TREE);
5758 tree orig_rtype = rtype, saved_rtype;
5760 if (TREE_CODE (rtype) == POINTER_TYPE)
5761 rtype = TREE_TYPE (rtype);
5762 /* Traverse typedef aliases */
5763 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5764 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5765 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5766 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5767 saved_rtype = rtype;
5768 if (TYPED_OBJECT (rtype))
5770 rprotos = TYPE_PROTOCOL_LIST (rtype);
5771 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5773 /* If we could not find an @interface declaration, we must have
5774 only seen a @class declaration; so, we cannot say anything
5775 more intelligent about which methods the receiver will
5778 rtype = saved_rtype;
5779 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5780 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5782 /* We have a valid ObjC class name. Look up the method name
5783 in the published @interface for the class (and its
5786 = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
5788 /* If the method was not found in the @interface, it may still
5789 exist locally as part of the @implementation. */
5790 if (!method_prototype && objc_implementation_context
5791 && CLASS_NAME (objc_implementation_context)
5792 == OBJC_TYPE_NAME (rtype))
5796 ? CLASS_CLS_METHODS (objc_implementation_context)
5797 : CLASS_NST_METHODS (objc_implementation_context)),
5800 /* If we haven't found a candidate method by now, try looking for
5801 it in the protocol list. */
5802 if (!method_prototype && rprotos)
5804 = lookup_method_in_protocol_list (rprotos, sel_name,
5805 is_class != NULL_TREE);
5809 warning ("invalid receiver type `%s'",
5810 gen_declaration (orig_rtype, errbuf));
5811 rtype = rprotos = NULL_TREE;
5815 if (!method_prototype)
5817 static bool warn_missing_methods = false;
5820 warning ("`%s' may not respond to `%c%s'",
5821 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5822 (is_class ? '+' : '-'),
5823 IDENTIFIER_POINTER (sel_name));
5825 warning ("`%c%s' not implemented by protocol(s)",
5826 (is_class ? '+' : '-'),
5827 IDENTIFIER_POINTER (sel_name));
5828 if (!warn_missing_methods)
5830 warning ("(Messages without a matching method signature");
5831 warning ("will be assumed to return `id' and accept");
5832 warning ("`...' as arguments.)");
5833 warn_missing_methods = true;
5837 /* Save the selector name for printing error messages. */
5838 current_objc_message_selector = sel_name;
5840 /* Build the parameters list for looking up the method.
5841 These are the object itself and the selector. */
5843 if (flag_typed_selectors)
5844 selector = build_typed_selector_reference (sel_name, method_prototype);
5846 selector = build_selector_reference (sel_name);
5848 retval = build_objc_method_call (super, method_prototype,
5850 selector, method_params);
5852 current_objc_message_selector = 0;
5857 /* Build a tree expression to send OBJECT the operation SELECTOR,
5858 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5859 assuming the method has prototype METHOD_PROTOTYPE.
5860 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5861 Use METHOD_PARAMS as list of args to pass to the method.
5862 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5865 build_objc_method_call (int super_flag, tree method_prototype,
5866 tree lookup_object, tree selector,
5869 tree sender = (super_flag ? umsg_super_decl :
5870 (!flag_next_runtime || flag_nil_receivers
5872 : umsg_nonnil_decl));
5873 tree rcv_p = (super_flag ? super_type : id_type);
5875 /* If a prototype for the method to be called exists, then cast
5876 the sender's return type and arguments to match that of the method.
5877 Otherwise, leave sender as is. */
5880 ? groktypename (TREE_TYPE (method_prototype))
5883 = build_pointer_type
5884 (build_function_type
5887 (method_prototype, METHOD_REF, super_flag)));
5889 lookup_object = build_c_cast (rcv_p, lookup_object);
5891 if (flag_next_runtime)
5893 /* If we are returning a struct in memory, and the address
5894 of that memory location is passed as a hidden first
5895 argument, then change which messenger entry point this
5896 expr will call. NB: Note that sender_cast remains
5897 unchanged (it already has a struct return type). */
5898 if (!targetm.calls.struct_value_rtx (0, 0)
5899 && (TREE_CODE (ret_type) == RECORD_TYPE
5900 || TREE_CODE (ret_type) == UNION_TYPE)
5901 && targetm.calls.return_in_memory (ret_type, 0))
5902 sender = (super_flag ? umsg_super_stret_decl :
5903 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5905 method_params = tree_cons (NULL_TREE, lookup_object,
5906 tree_cons (NULL_TREE, selector,
5908 TREE_USED (sender) = 1;
5909 assemble_external (sender);
5910 /* We want to cast the sender, not convert it. */
5911 return build_function_call (build_c_cast (sender_cast, sender),
5916 /* This is the portable (GNU) way. */
5917 tree method, object;
5919 /* First, call the lookup function to get a pointer to the method,
5920 then cast the pointer, then call it with the method arguments.
5921 Use SAVE_EXPR to avoid evaluating the receiver twice. */
5922 lookup_object = save_expr (lookup_object);
5923 object = (super_flag ? self_decl : lookup_object);
5924 TREE_USED (sender) = 1;
5925 assemble_external (sender);
5927 = build_function_call (sender,
5928 tree_cons (NULL_TREE, lookup_object,
5929 tree_cons (NULL_TREE, selector,
5932 /* Pass the object to the method. */
5933 TREE_USED (method) = 1;
5934 assemble_external (method);
5935 return build_function_call
5936 (build_c_cast (sender_cast, method),
5937 tree_cons (NULL_TREE, object,
5938 tree_cons (NULL_TREE, selector, method_params)));
5943 build_protocol_reference (tree p)
5945 tree decl, ident, ptype;
5947 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5949 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5951 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5952 objc_protocol_template),
5955 if (identifier_global_value (ident))
5956 decl = identifier_global_value (ident); /* Set by pushdecl. */
5959 decl = build_decl (VAR_DECL, ident, ptype);
5960 DECL_EXTERNAL (decl) = 1;
5961 TREE_PUBLIC (decl) = 0;
5962 TREE_USED (decl) = 1;
5963 DECL_ARTIFICIAL (decl) = 1;
5965 make_decl_rtl (decl, 0);
5966 pushdecl_top_level (decl);
5969 PROTOCOL_FORWARD_DECL (p) = decl;
5972 /* This function is called by the parser when (and only when) a
5973 @protocol() expression is found, in order to compile it. */
5975 build_protocol_expr (tree protoname)
5978 tree p = lookup_protocol (protoname);
5982 error ("cannot find protocol declaration for `%s'",
5983 IDENTIFIER_POINTER (protoname));
5984 return error_mark_node;
5987 if (!PROTOCOL_FORWARD_DECL (p))
5988 build_protocol_reference (p);
5990 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5992 TREE_TYPE (expr) = protocol_type;
5994 /* The @protocol() expression is being compiled into a pointer to a
5995 statically allocated instance of the Protocol class. To become
5996 usable at runtime, the 'isa' pointer of the instance need to be
5997 fixed up at runtime by the runtime library, to point to the
5998 actual 'Protocol' class. */
6000 /* For the GNU runtime, put the static Protocol instance in the list
6001 of statically allocated instances, so that we make sure that its
6002 'isa' pointer is fixed up at runtime by the GNU runtime library
6003 to point to the Protocol class (at runtime, when loading the
6004 module, the GNU runtime library loops on the statically allocated
6005 instances (as found in the defs field in objc_symtab) and fixups
6006 all the 'isa' pointers of those objects). */
6007 if (! flag_next_runtime)
6009 /* This type is a struct containing the fields of a Protocol
6010 object. (Cfr. protocol_type instead is the type of a pointer
6011 to such a struct). */
6012 tree protocol_struct_type = xref_tag
6013 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6016 /* Look for the list of Protocol statically allocated instances
6017 to fixup at runtime. Create a new list to hold Protocol
6018 statically allocated instances, if the list is not found. At
6019 present there is only another list, holding NSConstantString
6020 static instances to be fixed up at runtime. */
6021 for (chain = &objc_static_instances;
6022 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6023 chain = &TREE_CHAIN (*chain));
6026 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6027 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6031 /* Add this statically allocated instance to the Protocol list. */
6032 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6033 PROTOCOL_FORWARD_DECL (p),
6034 TREE_PURPOSE (*chain));
6041 /* This function is called by the parser when a @selector() expression
6042 is found, in order to compile it. It is only called by the parser
6043 and only to compile a @selector(). */
6045 build_selector_expr (tree selnamelist)
6049 /* Obtain the full selector name. */
6050 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6051 /* A unary selector. */
6052 selname = selnamelist;
6053 else if (TREE_CODE (selnamelist) == TREE_LIST)
6054 selname = build_keyword_selector (selnamelist);
6058 /* If we are required to check @selector() expressions as they
6059 are found, check that the selector has been declared. */
6060 if (warn_undeclared_selector)
6062 /* Look the selector up in the list of all known class and
6063 instance methods (up to this line) to check that the selector
6067 /* First try with instance methods. */
6068 hsh = hash_lookup (nst_method_hash_list, selname);
6070 /* If not found, try with class methods. */
6073 hsh = hash_lookup (cls_method_hash_list, selname);
6076 /* If still not found, print out a warning. */
6079 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6084 if (flag_typed_selectors)
6085 return build_typed_selector_reference (selname, 0);
6087 return build_selector_reference (selname);
6091 build_encode_expr (tree type)
6096 encode_type (type, obstack_object_size (&util_obstack),
6097 OBJC_ENCODE_INLINE_DEFS);
6098 obstack_1grow (&util_obstack, 0); /* null terminate string */
6099 string = obstack_finish (&util_obstack);
6101 /* Synthesize a string that represents the encoded struct/union. */
6102 result = my_build_string (strlen (string) + 1, string);
6103 obstack_free (&util_obstack, util_firstobj);
6108 build_ivar_reference (tree id)
6110 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6112 /* Historically, a class method that produced objects (factory
6113 method) would assign `self' to the instance that it
6114 allocated. This would effectively turn the class method into
6115 an instance method. Following this assignment, the instance
6116 variables could be accessed. That practice, while safe,
6117 violates the simple rule that a class method should not refer
6118 to an instance variable. It's better to catch the cases
6119 where this is done unknowingly than to support the above
6121 warning ("instance variable `%s' accessed in class method",
6122 IDENTIFIER_POINTER (id));
6123 TREE_TYPE (self_decl) = instance_type; /* cast */
6126 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6129 /* Compute a hash value for a given method SEL_NAME. */
6132 hash_func (tree sel_name)
6134 const unsigned char *s
6135 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6139 h = h * 67 + *s++ - 113;
6146 nst_method_hash_list
6147 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6148 cls_method_hash_list
6149 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6152 /* WARNING!!!! hash_enter is called with a method, and will peek
6153 inside to find its selector! But hash_lookup is given a selector
6154 directly, and looks for the selector that's inside the found
6155 entry's key (method) for comparison. */
6158 hash_enter (hash *hashlist, tree method)
6161 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6163 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6165 obj->next = hashlist[slot];
6168 hashlist[slot] = obj; /* append to front */
6172 hash_lookup (hash *hashlist, tree sel_name)
6176 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6180 if (sel_name == METHOD_SEL_NAME (target->key))
6183 target = target->next;
6189 hash_add_attr (hash entry, tree value)
6193 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6194 obj->next = entry->list;
6197 entry->list = obj; /* append to front */
6201 lookup_method (tree mchain, tree method)
6205 if (TREE_CODE (method) == IDENTIFIER_NODE)
6208 key = METHOD_SEL_NAME (method);
6212 if (METHOD_SEL_NAME (mchain) == key)
6215 mchain = TREE_CHAIN (mchain);
6221 lookup_method_static (tree interface, tree ident, int is_class)
6223 tree meth = NULL_TREE, root_inter = NULL_TREE;
6224 tree inter = interface;
6228 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6229 tree category = inter;
6231 /* First, look up the method in the class itself. */
6232 if ((meth = lookup_method (chain, ident)))
6235 /* Failing that, look for the method in each category of the class. */
6236 while ((category = CLASS_CATEGORY_LIST (category)))
6238 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6240 /* Check directly in each category. */
6241 if ((meth = lookup_method (chain, ident)))
6244 /* Failing that, check in each category's protocols. */
6245 if (CLASS_PROTOCOL_LIST (category))
6247 if ((meth = (lookup_method_in_protocol_list
6248 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6253 /* If not found in categories, check in protocols of the main class. */
6254 if (CLASS_PROTOCOL_LIST (inter))
6256 if ((meth = (lookup_method_in_protocol_list
6257 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6261 /* Failing that, climb up the inheritance hierarchy. */
6263 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6267 /* If no class (factory) method was found, check if an _instance_
6268 method of the same name exists in the root class. This is what
6269 the Objective-C runtime will do. If an instance method was not
6271 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6274 /* Add the method to the hash list if it doesn't contain an identical
6277 add_method_to_hash_list (hash *hash_list, tree method)
6281 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6283 /* Install on a global chain. */
6284 hash_enter (hash_list, method);
6288 /* Check types against those; if different, add to a list. */
6290 int already_there = comp_proto_with_proto (method, hsh->key);
6291 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6292 already_there |= comp_proto_with_proto (method, loop->value);
6294 hash_add_attr (hsh, method);
6299 objc_add_method (tree class, tree method, int is_class)
6303 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6305 /* put method on list in reverse order */
6308 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6309 CLASS_CLS_METHODS (class) = method;
6313 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6314 CLASS_NST_METHODS (class) = method;
6319 /* When processing an @interface for a class or category, give hard
6320 errors on methods with identical selectors but differing argument
6321 and/or return types. We do not do this for @implementations, because
6322 C/C++ will do it for us (i.e., there will be duplicate function
6323 definition errors). */
6324 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6325 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6326 && !comp_proto_with_proto (method, mth))
6327 error ("duplicate declaration of method `%c%s'",
6328 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6332 add_method_to_hash_list (cls_method_hash_list, method);
6335 add_method_to_hash_list (nst_method_hash_list, method);
6337 /* Instance methods in root classes (and categories thereof)
6338 may acts as class methods as a last resort. */
6339 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6340 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6341 class = lookup_interface (CLASS_NAME (class));
6343 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6344 && !CLASS_SUPER_NAME (class))
6345 add_method_to_hash_list (cls_method_hash_list, method);
6352 add_class (tree class)
6354 /* Put interfaces on list in reverse order. */
6355 TREE_CHAIN (class) = interface_chain;
6356 interface_chain = class;
6357 return interface_chain;
6361 add_category (tree class, tree category)
6363 /* Put categories on list in reverse order. */
6364 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6368 warning ("duplicate interface declaration for category `%s(%s)'",
6369 IDENTIFIER_POINTER (CLASS_NAME (class)),
6370 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6374 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6375 CLASS_CATEGORY_LIST (class) = category;
6379 /* Called after parsing each instance variable declaration. Necessary to
6380 preserve typedefs and implement public/private...
6382 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6385 add_instance_variable (tree class, int public, tree declarator,
6386 tree declspecs, tree width)
6388 tree field_decl = grokfield (declarator, declspecs, width);
6389 tree field_type = TREE_TYPE (field_decl);
6390 const char *ivar_name = DECL_NAME (field_decl)
6391 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6396 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6398 error ("illegal reference type specified for instance variable `%s'",
6400 /* Return class as is without adding this ivar. */
6405 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6406 || TYPE_SIZE (field_type) == error_mark_node
6407 /* 'type[0]' is allowed, but 'type[]' is not! */
6409 || (TYPE_SIZE (field_type) == bitsize_zero_node
6410 && !TREE_OPERAND (declarator, 1))
6414 error ("instance variable `%s' has unknown size", ivar_name);
6415 /* Return class as is without adding this ivar. */
6420 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6421 cannot be ivars; ditto for classes with vtables. */
6422 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6423 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6425 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6426 if(TYPE_POLYMORPHIC_P (field_type)) {
6427 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6428 error ("type `%s' has virtual member functions", type_name);
6429 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6430 type_name, ivar_name);
6431 /* Return class as is without adding this ivar. */
6434 /* user-defined constructors and destructors are not known to Obj-C and
6435 hence will not be called. This may or may not be a problem. */
6436 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6437 warning ("type `%s' has a user-defined constructor", type_name);
6438 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6439 warning ("type `%s' has a user-defined destructor", type_name);
6440 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6444 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6448 TREE_PUBLIC (field_decl) = 0;
6449 TREE_PRIVATE (field_decl) = 0;
6450 TREE_PROTECTED (field_decl) = 1;
6454 TREE_PUBLIC (field_decl) = 1;
6455 TREE_PRIVATE (field_decl) = 0;
6456 TREE_PROTECTED (field_decl) = 0;
6460 TREE_PUBLIC (field_decl) = 0;
6461 TREE_PRIVATE (field_decl) = 1;
6462 TREE_PROTECTED (field_decl) = 0;
6467 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6468 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6469 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6474 is_ivar (tree decl_chain, tree ident)
6476 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6477 if (DECL_NAME (decl_chain) == ident)
6482 /* True if the ivar is private and we are not in its implementation. */
6485 is_private (tree decl)
6487 return (TREE_PRIVATE (decl)
6488 && ! is_ivar (CLASS_IVARS (implementation_template),
6492 /* We have an instance variable reference;, check to see if it is public. */
6495 is_public (tree expr, tree identifier)
6497 tree basetype = TREE_TYPE (expr);
6498 enum tree_code code = TREE_CODE (basetype);
6501 if (code == RECORD_TYPE)
6503 if (TREE_STATIC_TEMPLATE (basetype))
6505 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6507 error ("cannot find interface declaration for `%s'",
6508 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6512 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6514 if (TREE_PUBLIC (decl))
6517 /* Important difference between the Stepstone translator:
6518 all instance variables should be public within the context
6519 of the implementation. */
6520 if (objc_implementation_context
6521 && (((TREE_CODE (objc_implementation_context)
6522 == CLASS_IMPLEMENTATION_TYPE)
6523 || (TREE_CODE (objc_implementation_context)
6524 == CATEGORY_IMPLEMENTATION_TYPE))
6525 && (CLASS_NAME (objc_implementation_context)
6526 == OBJC_TYPE_NAME (basetype))))
6528 int private = is_private (decl);
6531 error ("instance variable `%s' is declared private",
6532 IDENTIFIER_POINTER (DECL_NAME (decl)));
6536 /* The 2.95.2 compiler sometimes allowed C functions to access
6537 non-@public ivars. We will let this slide for now... */
6538 if (!objc_method_context)
6540 warning ("instance variable `%s' is %s; "
6541 "this will be a hard error in the future",
6542 IDENTIFIER_POINTER (identifier),
6543 TREE_PRIVATE (decl) ? "@private" : "@protected");
6547 error ("instance variable `%s' is declared %s",
6548 IDENTIFIER_POINTER (identifier),
6549 TREE_PRIVATE (decl) ? "private" : "protected");
6554 else if (objc_implementation_context && (basetype == objc_object_reference))
6556 TREE_TYPE (expr) = uprivate_record;
6557 warning ("static access to object of type `id'");
6564 /* Make sure all entries in CHAIN are also in LIST. */
6567 check_methods (tree chain, tree list, int mtype)
6573 if (!lookup_method (list, chain))
6577 if (TREE_CODE (objc_implementation_context)
6578 == CLASS_IMPLEMENTATION_TYPE)
6579 warning ("incomplete implementation of class `%s'",
6580 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6581 else if (TREE_CODE (objc_implementation_context)
6582 == CATEGORY_IMPLEMENTATION_TYPE)
6583 warning ("incomplete implementation of category `%s'",
6584 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6588 warning ("method definition for `%c%s' not found",
6589 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6592 chain = TREE_CHAIN (chain);
6598 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6601 conforms_to_protocol (tree class, tree protocol)
6603 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6605 tree p = CLASS_PROTOCOL_LIST (class);
6606 while (p && TREE_VALUE (p) != protocol)
6611 tree super = (CLASS_SUPER_NAME (class)
6612 ? lookup_interface (CLASS_SUPER_NAME (class))
6614 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6623 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6624 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6627 check_methods_accessible (tree chain, tree context, int mtype)
6631 tree base_context = context;
6635 context = base_context;
6639 list = CLASS_CLS_METHODS (context);
6641 list = CLASS_NST_METHODS (context);
6643 if (lookup_method (list, chain))
6646 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6647 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6648 context = (CLASS_SUPER_NAME (context)
6649 ? lookup_interface (CLASS_SUPER_NAME (context))
6652 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6653 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6654 context = (CLASS_NAME (context)
6655 ? lookup_interface (CLASS_NAME (context))
6661 if (context == NULL_TREE)
6665 if (TREE_CODE (objc_implementation_context)
6666 == CLASS_IMPLEMENTATION_TYPE)
6667 warning ("incomplete implementation of class `%s'",
6669 (CLASS_NAME (objc_implementation_context)));
6670 else if (TREE_CODE (objc_implementation_context)
6671 == CATEGORY_IMPLEMENTATION_TYPE)
6672 warning ("incomplete implementation of category `%s'",
6674 (CLASS_SUPER_NAME (objc_implementation_context)));
6677 warning ("method definition for `%c%s' not found",
6678 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6681 chain = TREE_CHAIN (chain); /* next method... */
6686 /* Check whether the current interface (accessible via
6687 'objc_implementation_context') actually implements protocol P, along
6688 with any protocols that P inherits. */
6691 check_protocol (tree p, const char *type, const char *name)
6693 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6697 /* Ensure that all protocols have bodies! */
6700 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6701 CLASS_CLS_METHODS (objc_implementation_context),
6703 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6704 CLASS_NST_METHODS (objc_implementation_context),
6709 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6710 objc_implementation_context,
6712 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6713 objc_implementation_context,
6718 warning ("%s `%s' does not fully implement the `%s' protocol",
6719 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6722 /* Check protocols recursively. */
6723 if (PROTOCOL_LIST (p))
6725 tree subs = PROTOCOL_LIST (p);
6727 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6731 tree sub = TREE_VALUE (subs);
6733 /* If the superclass does not conform to the protocols
6734 inherited by P, then we must! */
6735 if (!super_class || !conforms_to_protocol (super_class, sub))
6736 check_protocol (sub, type, name);
6737 subs = TREE_CHAIN (subs);
6742 /* Check whether the current interface (accessible via
6743 'objc_implementation_context') actually implements the protocols listed
6747 check_protocols (tree proto_list, const char *type, const char *name)
6749 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6751 tree p = TREE_VALUE (proto_list);
6753 check_protocol (p, type, name);
6757 /* Make sure that the class CLASS_NAME is defined
6758 CODE says which kind of thing CLASS_NAME ought to be.
6759 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6760 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6763 start_class (enum tree_code code, tree class_name, tree super_name,
6769 if (current_namespace != global_namespace) {
6770 error ("Objective-C declarations may only appear in global scope");
6772 #endif /* OBJCPLUS */
6774 if (objc_implementation_context)
6776 warning ("`@end' missing in implementation context");
6777 finish_class (objc_implementation_context);
6778 objc_ivar_chain = NULL_TREE;
6779 objc_implementation_context = NULL_TREE;
6782 class = make_node (code);
6783 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6785 CLASS_NAME (class) = class_name;
6786 CLASS_SUPER_NAME (class) = super_name;
6787 CLASS_CLS_METHODS (class) = NULL_TREE;
6789 if (! is_class_name (class_name)
6790 && (decl = lookup_name (class_name)))
6792 error ("`%s' redeclared as different kind of symbol",
6793 IDENTIFIER_POINTER (class_name));
6794 error ("%Jprevious declaration of '%D'",
6798 if (code == CLASS_IMPLEMENTATION_TYPE)
6803 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6804 if (TREE_VALUE (chain) == class_name)
6806 error ("reimplementation of class `%s'",
6807 IDENTIFIER_POINTER (class_name));
6808 return error_mark_node;
6810 implemented_classes = tree_cons (NULL_TREE, class_name,
6811 implemented_classes);
6814 /* Reset for multiple classes per file. */
6817 objc_implementation_context = class;
6819 /* Lookup the interface for this implementation. */
6821 if (!(implementation_template = lookup_interface (class_name)))
6823 warning ("cannot find interface declaration for `%s'",
6824 IDENTIFIER_POINTER (class_name));
6825 add_class (implementation_template = objc_implementation_context);
6828 /* If a super class has been specified in the implementation,
6829 insure it conforms to the one specified in the interface. */
6832 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6834 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6835 const char *const name =
6836 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6837 error ("conflicting super class name `%s'",
6838 IDENTIFIER_POINTER (super_name));
6839 error ("previous declaration of `%s'", name);
6842 else if (! super_name)
6844 CLASS_SUPER_NAME (objc_implementation_context)
6845 = CLASS_SUPER_NAME (implementation_template);
6849 else if (code == CLASS_INTERFACE_TYPE)
6851 if (lookup_interface (class_name))
6853 error ("duplicate interface declaration for class `%s'",
6855 warning ("duplicate interface declaration for class `%s'",
6857 IDENTIFIER_POINTER (class_name));
6862 CLASS_PROTOCOL_LIST (class)
6863 = lookup_and_install_protocols (protocol_list);
6866 else if (code == CATEGORY_INTERFACE_TYPE)
6868 tree class_category_is_assoc_with;
6870 /* For a category, class_name is really the name of the class that
6871 the following set of methods will be associated with. We must
6872 find the interface so that can derive the objects template. */
6874 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6876 error ("cannot find interface declaration for `%s'",
6877 IDENTIFIER_POINTER (class_name));
6878 exit (FATAL_EXIT_CODE);
6881 add_category (class_category_is_assoc_with, class);
6884 CLASS_PROTOCOL_LIST (class)
6885 = lookup_and_install_protocols (protocol_list);
6888 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6890 /* Reset for multiple classes per file. */
6893 objc_implementation_context = class;
6895 /* For a category, class_name is really the name of the class that
6896 the following set of methods will be associated with. We must
6897 find the interface so that can derive the objects template. */
6899 if (!(implementation_template = lookup_interface (class_name)))
6901 error ("cannot find interface declaration for `%s'",
6902 IDENTIFIER_POINTER (class_name));
6903 exit (FATAL_EXIT_CODE);
6910 continue_class (tree class)
6912 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6913 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6915 struct imp_entry *imp_entry;
6918 /* Check consistency of the instance variables. */
6920 if (CLASS_IVARS (class))
6921 check_ivars (implementation_template, class);
6923 /* code generation */
6925 ivar_context = build_private_template (implementation_template);
6927 if (!objc_class_template)
6928 build_class_template ();
6930 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6932 imp_entry->next = imp_list;
6933 imp_entry->imp_context = class;
6934 imp_entry->imp_template = implementation_template;
6936 synth_forward_declarations ();
6937 imp_entry->class_decl = UOBJC_CLASS_decl;
6938 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6940 /* Append to front and increment count. */
6941 imp_list = imp_entry;
6942 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6947 return ivar_context;
6950 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6952 if (!CLASS_STATIC_TEMPLATE (class))
6954 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6955 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6956 CLASS_STATIC_TEMPLATE (class) = record;
6958 /* Mark this record as a class template for static typing. */
6959 TREE_STATIC_TEMPLATE (record) = 1;
6966 return error_mark_node;
6969 /* This is called once we see the "@end" in an interface/implementation. */
6972 finish_class (tree class)
6974 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6976 /* All code generation is done in finish_objc. */
6978 if (implementation_template != objc_implementation_context)
6980 /* Ensure that all method listed in the interface contain bodies. */
6981 check_methods (CLASS_CLS_METHODS (implementation_template),
6982 CLASS_CLS_METHODS (objc_implementation_context), '+');
6983 check_methods (CLASS_NST_METHODS (implementation_template),
6984 CLASS_NST_METHODS (objc_implementation_context), '-');
6986 if (CLASS_PROTOCOL_LIST (implementation_template))
6987 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6989 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6993 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6995 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6999 /* Ensure all method listed in the interface contain bodies. */
7000 check_methods (CLASS_CLS_METHODS (category),
7001 CLASS_CLS_METHODS (objc_implementation_context), '+');
7002 check_methods (CLASS_NST_METHODS (category),
7003 CLASS_NST_METHODS (objc_implementation_context), '-');
7005 if (CLASS_PROTOCOL_LIST (category))
7006 check_protocols (CLASS_PROTOCOL_LIST (category),
7008 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7012 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7015 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
7016 char *string = (char *) alloca (strlen (class_name) + 3);
7018 /* extern struct objc_object *_<my_name>; */
7020 sprintf (string, "_%s", class_name);
7022 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
7023 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
7024 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7030 add_protocol (tree protocol)
7032 /* Put protocol on list in reverse order. */
7033 TREE_CHAIN (protocol) = protocol_chain;
7034 protocol_chain = protocol;
7035 return protocol_chain;
7039 lookup_protocol (tree ident)
7043 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7044 if (ident == PROTOCOL_NAME (chain))
7050 /* This function forward declares the protocols named by NAMES. If
7051 they are already declared or defined, the function has no effect. */
7054 objc_declare_protocols (tree names)
7059 if (current_namespace != global_namespace) {
7060 error ("Objective-C declarations may only appear in global scope");
7062 #endif /* OBJCPLUS */
7064 for (list = names; list; list = TREE_CHAIN (list))
7066 tree name = TREE_VALUE (list);
7068 if (lookup_protocol (name) == NULL_TREE)
7070 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7072 TYPE_BINFO (protocol) = make_tree_vec (2);
7073 PROTOCOL_NAME (protocol) = name;
7074 PROTOCOL_LIST (protocol) = NULL_TREE;
7075 add_protocol (protocol);
7076 PROTOCOL_DEFINED (protocol) = 0;
7077 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7083 start_protocol (enum tree_code code, tree name, tree list)
7088 if (current_namespace != global_namespace) {
7089 error ("Objective-C declarations may only appear in global scope");
7091 #endif /* OBJCPLUS */
7093 /* This is as good a place as any. Need to invoke
7094 push_tag_toplevel. */
7095 if (!objc_protocol_template)
7096 objc_protocol_template = build_protocol_template ();
7098 protocol = lookup_protocol (name);
7102 protocol = make_node (code);
7103 TYPE_BINFO (protocol) = make_tree_vec (2);
7105 PROTOCOL_NAME (protocol) = name;
7106 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7107 add_protocol (protocol);
7108 PROTOCOL_DEFINED (protocol) = 1;
7109 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7111 check_protocol_recursively (protocol, list);
7113 else if (! PROTOCOL_DEFINED (protocol))
7115 PROTOCOL_DEFINED (protocol) = 1;
7116 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7118 check_protocol_recursively (protocol, list);
7122 warning ("duplicate declaration for protocol `%s'",
7123 IDENTIFIER_POINTER (name));
7129 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7134 /* "Encode" a data type into a string, which grows in util_obstack.
7135 ??? What is the FORMAT? Someone please document this! */
7138 encode_type_qualifiers (tree declspecs)
7142 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7144 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7145 obstack_1grow (&util_obstack, 'r');
7146 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7147 obstack_1grow (&util_obstack, 'n');
7148 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7149 obstack_1grow (&util_obstack, 'N');
7150 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7151 obstack_1grow (&util_obstack, 'o');
7152 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7153 obstack_1grow (&util_obstack, 'O');
7154 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7155 obstack_1grow (&util_obstack, 'R');
7156 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7157 obstack_1grow (&util_obstack, 'V');
7161 /* Encode a pointer type. */
7164 encode_pointer (tree type, int curtype, int format)
7166 tree pointer_to = TREE_TYPE (type);
7168 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7170 if (OBJC_TYPE_NAME (pointer_to)
7171 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7173 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7175 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7177 obstack_1grow (&util_obstack, '@');
7180 else if (TREE_STATIC_TEMPLATE (pointer_to))
7182 if (generating_instance_variables)
7184 obstack_1grow (&util_obstack, '@');
7185 obstack_1grow (&util_obstack, '"');
7186 obstack_grow (&util_obstack, name, strlen (name));
7187 obstack_1grow (&util_obstack, '"');
7192 obstack_1grow (&util_obstack, '@');
7196 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7198 obstack_1grow (&util_obstack, '#');
7201 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7203 obstack_1grow (&util_obstack, ':');
7208 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7209 && TYPE_MODE (pointer_to) == QImode)
7211 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7212 ? OBJC_TYPE_NAME (pointer_to)
7213 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7215 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7217 obstack_1grow (&util_obstack, '*');
7222 /* We have a type that does not get special treatment. */
7224 /* NeXT extension */
7225 obstack_1grow (&util_obstack, '^');
7226 encode_type (pointer_to, curtype, format);
7230 encode_array (tree type, int curtype, int format)
7232 tree an_int_cst = TYPE_SIZE (type);
7233 tree array_of = TREE_TYPE (type);
7236 /* An incomplete array is treated like a pointer. */
7237 if (an_int_cst == NULL)
7239 encode_pointer (type, curtype, format);
7243 sprintf (buffer, "[%ld",
7244 (long) (TREE_INT_CST_LOW (an_int_cst)
7245 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7247 obstack_grow (&util_obstack, buffer, strlen (buffer));
7248 encode_type (array_of, curtype, format);
7249 obstack_1grow (&util_obstack, ']');
7254 encode_aggregate_within (tree type, int curtype, int format, int left,
7258 /* NB: aggregates that are pointed to have slightly different encoding
7259 rules in that you never encode the names of instance variables. */
7261 = (obstack_object_size (&util_obstack) > 0
7262 && *(obstack_next_free (&util_obstack) - 1) == '^');
7264 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7265 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7267 /* Traverse struct aliases; it is important to get the
7268 original struct and its tag name (if any). */
7269 type = TYPE_MAIN_VARIANT (type);
7270 name = OBJC_TYPE_NAME (type);
7271 /* Open parenth/bracket. */
7272 obstack_1grow (&util_obstack, left);
7274 /* Encode the struct/union tag name, or '?' if a tag was
7275 not provided. Typedef aliases do not qualify. */
7276 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7278 /* Did this struct have a tag? */
7279 && !TYPE_WAS_ANONYMOUS (type)
7282 obstack_grow (&util_obstack,
7283 IDENTIFIER_POINTER (name),
7284 strlen (IDENTIFIER_POINTER (name)));
7286 obstack_1grow (&util_obstack, '?');
7288 /* Encode the types (and possibly names) of the inner fields,
7290 if (inline_contents)
7292 tree fields = TYPE_FIELDS (type);
7294 obstack_1grow (&util_obstack, '=');
7295 for (; fields; fields = TREE_CHAIN (fields))
7298 /* C++ static members, and things that are not fields at all,
7299 should not appear in the encoding. */
7300 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7303 if (generating_instance_variables && !pointed_to)
7305 tree fname = DECL_NAME (fields);
7307 obstack_1grow (&util_obstack, '"');
7308 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7309 obstack_grow (&util_obstack,
7310 IDENTIFIER_POINTER (fname),
7311 strlen (IDENTIFIER_POINTER (fname)));
7312 obstack_1grow (&util_obstack, '"');
7314 encode_field_decl (fields, curtype, format);
7317 /* Close parenth/bracket. */
7318 obstack_1grow (&util_obstack, right);
7322 encode_aggregate (tree type, int curtype, int format)
7324 enum tree_code code = TREE_CODE (type);
7330 encode_aggregate_within (type, curtype, format, '{', '}');
7335 encode_aggregate_within (type, curtype, format, '(', ')');
7340 obstack_1grow (&util_obstack, 'i');
7348 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7352 encode_next_bitfield (int width)
7355 sprintf (buffer, "b%d", width);
7356 obstack_grow (&util_obstack, buffer, strlen (buffer));
7359 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7361 encode_type (tree type, int curtype, int format)
7363 enum tree_code code = TREE_CODE (type);
7366 if (code == INTEGER_TYPE)
7368 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7370 case 8: c = TREE_UNSIGNED (type) ? 'C' : 'c'; break;
7371 case 16: c = TREE_UNSIGNED (type) ? 'S' : 's'; break;
7373 if (type == long_unsigned_type_node
7374 || type == long_integer_type_node)
7375 c = TREE_UNSIGNED (type) ? 'L' : 'l';
7377 c = TREE_UNSIGNED (type) ? 'I' : 'i';
7379 case 64: c = TREE_UNSIGNED (type) ? 'Q' : 'q'; break;
7382 obstack_1grow (&util_obstack, c);
7385 else if (code == REAL_TYPE)
7387 /* Floating point types. */
7388 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7390 case 32: c = 'f'; break;
7392 case 128: c = 'd'; break;
7395 obstack_1grow (&util_obstack, c);
7398 else if (code == VOID_TYPE)
7399 obstack_1grow (&util_obstack, 'v');
7401 else if (code == BOOLEAN_TYPE)
7402 obstack_1grow (&util_obstack, 'B');
7404 else if (code == ARRAY_TYPE)
7405 encode_array (type, curtype, format);
7407 else if (code == POINTER_TYPE)
7408 encode_pointer (type, curtype, format);
7410 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7411 encode_aggregate (type, curtype, format);
7413 else if (code == FUNCTION_TYPE) /* '?' */
7414 obstack_1grow (&util_obstack, '?');
7418 encode_gnu_bitfield (int position, tree type, int size)
7420 enum tree_code code = TREE_CODE (type);
7422 char charType = '?';
7424 if (code == INTEGER_TYPE)
7426 if (integer_zerop (TYPE_MIN_VALUE (type)))
7428 /* Unsigned integer types. */
7430 if (TYPE_MODE (type) == QImode)
7432 else if (TYPE_MODE (type) == HImode)
7434 else if (TYPE_MODE (type) == SImode)
7436 if (type == long_unsigned_type_node)
7441 else if (TYPE_MODE (type) == DImode)
7446 /* Signed integer types. */
7448 if (TYPE_MODE (type) == QImode)
7450 else if (TYPE_MODE (type) == HImode)
7452 else if (TYPE_MODE (type) == SImode)
7454 if (type == long_integer_type_node)
7460 else if (TYPE_MODE (type) == DImode)
7464 else if (code == ENUMERAL_TYPE)
7469 sprintf (buffer, "b%d%c%d", position, charType, size);
7470 obstack_grow (&util_obstack, buffer, strlen (buffer));
7474 encode_field_decl (tree field_decl, int curtype, int format)
7479 /* C++ static members, and things that are not fields at all,
7480 should not appear in the encoding. */
7481 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7485 type = TREE_TYPE (field_decl);
7487 /* Generate the bitfield typing information, if needed. Note the difference
7488 between GNU and NeXT runtimes. */
7489 if (DECL_BIT_FIELD_TYPE (field_decl))
7491 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7493 if (flag_next_runtime)
7494 encode_next_bitfield (size);
7496 encode_gnu_bitfield (int_bit_position (field_decl),
7497 DECL_BIT_FIELD_TYPE (field_decl), size);
7500 encode_type (TREE_TYPE (field_decl), curtype, format);
7504 objc_expr_last (tree complex_expr)
7509 while ((next = TREE_OPERAND (complex_expr, 0)))
7510 complex_expr = next;
7512 return complex_expr;
7516 synth_self_and_ucmd_args (void)
7520 if (objc_method_context
7521 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7522 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7524 /* Really a `struct objc_class *'. However, we allow people to
7525 assign to self, which changes its type midstream. */
7526 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7528 push_parm_decl (build_tree_list
7529 (build_tree_list (decl_specs,
7530 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7533 decl_specs = build_tree_list (NULL_TREE,
7534 xref_tag (RECORD_TYPE,
7535 get_identifier (TAG_SELECTOR)));
7536 push_parm_decl (build_tree_list
7537 (build_tree_list (decl_specs,
7538 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7542 /* Transform a method definition into a function definition as follows:
7543 - synthesize the first two arguments, "self" and "_cmd". */
7546 start_method_def (tree method)
7548 /* Required to implement _msgSuper. */
7549 objc_method_context = method;
7550 UOBJC_SUPER_decl = NULL_TREE;
7552 /* Must be called BEFORE start_function. */
7555 /* Generate prototype declarations for arguments..."new-style". */
7556 synth_self_and_ucmd_args ();
7558 /* Generate argument declarations if a keyword_decl. */
7559 if (METHOD_SEL_ARGS (method))
7561 tree arglist = METHOD_SEL_ARGS (method);
7564 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7565 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7569 tree last_expr = objc_expr_last (arg_decl);
7571 /* Unite the abstract decl with its name. */
7572 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7573 push_parm_decl (build_tree_list
7574 (build_tree_list (arg_spec, arg_decl),
7578 /* Unhook: restore the abstract declarator. */
7579 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7584 push_parm_decl (build_tree_list
7585 (build_tree_list (arg_spec,
7586 KEYWORD_ARG_NAME (arglist)),
7589 arglist = TREE_CHAIN (arglist);
7594 if (METHOD_ADD_ARGS (method) != NULL_TREE
7595 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7597 /* We have a variable length selector - in "prototype" format. */
7598 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7601 /* This must be done prior to calling pushdecl. pushdecl is
7602 going to change our chain on us. */
7603 tree nextkey = TREE_CHAIN (akey);
7611 warn_with_method (const char *message, int mtype, tree method)
7613 /* Add a readable method name to the warning. */
7614 warning ("%J%s `%c%s'", method,
7615 message, mtype, gen_method_decl (method, errbuf));
7618 /* Return 1 if METHOD is consistent with PROTO. */
7621 comp_method_with_proto (tree method, tree proto)
7623 /* Create a function template node at most once. */
7624 if (!function1_template)
7625 function1_template = make_node (FUNCTION_TYPE);
7627 /* Install argument types - normally set by build_function_type. */
7628 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7630 /* install return type */
7631 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7633 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
7637 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7640 objc_types_are_equivalent (tree type1, tree type2)
7644 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7646 type1 = TYPE_PROTOCOL_LIST (type1);
7647 type2 = TYPE_PROTOCOL_LIST (type2);
7648 if (list_length (type1) == list_length (type2))
7650 for (; type2; type2 = TREE_CHAIN (type2))
7651 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7658 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7661 comp_proto_with_proto (tree proto1, tree proto2)
7665 /* The following test is needed in case there are hashing
7667 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7670 /* Compare return types. */
7671 type1 = groktypename (TREE_TYPE (proto1));
7672 type2 = groktypename (TREE_TYPE (proto2));
7674 if (!objc_types_are_equivalent (type1, type2))
7677 /* Compare argument types. */
7678 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7679 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7681 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7683 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7687 return (!type1 && !type2);
7690 /* - Generate an identifier for the function. the format is "_n_cls",
7691 where 1 <= n <= nMethods, and cls is the name the implementation we
7693 - Install the return type from the method declaration.
7694 - If we have a prototype, check for type consistency. */
7697 really_start_method (tree method, tree parmlist)
7699 tree sc_spec, ret_spec, ret_decl, decl_specs;
7700 tree method_decl, method_id;
7701 const char *sel_name, *class_name, *cat_name;
7704 /* Synth the storage class & assemble the return type. */
7705 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7706 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7707 decl_specs = chainon (sc_spec, ret_spec);
7709 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7710 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7711 cat_name = ((TREE_CODE (objc_implementation_context)
7712 == CLASS_IMPLEMENTATION_TYPE)
7714 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7717 /* Make sure this is big enough for any plausible method label. */
7718 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7719 + (cat_name ? strlen (cat_name) : 0));
7721 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7722 class_name, cat_name, sel_name, method_slot);
7724 method_id = get_identifier (buf);
7727 /* Objective-C methods cannot be overloaded, so we don't need
7728 the type encoding appended. It looks bad anyway... */
7729 push_lang_context (lang_name_c);
7732 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7734 /* Check the declarator portion of the return type for the method. */
7735 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7737 /* Unite the complex decl (specified in the abstract decl) with the
7738 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7739 tree save_expr = objc_expr_last (ret_decl);
7741 TREE_OPERAND (save_expr, 0) = method_decl;
7742 method_decl = ret_decl;
7744 /* Fool the parser into thinking it is starting a function. */
7745 start_function (decl_specs, method_decl, NULL_TREE);
7747 /* Unhook: this has the effect of restoring the abstract declarator. */
7748 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7753 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7755 /* Fool the parser into thinking it is starting a function. */
7756 start_function (decl_specs, method_decl, NULL_TREE);
7758 /* Unhook: this has the effect of restoring the abstract declarator. */
7759 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7763 /* set self_decl from the first argument...this global is used by
7764 * build_ivar_reference().build_indirect_ref().
7766 self_decl = DECL_ARGUMENTS (current_function_decl);
7768 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7769 * the following: warning:unused parameter `struct objc_selector * _cmd'
7771 TREE_USED (self_decl) = 1;
7772 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7773 /* Ditto for the underlying (static) C function. */
7774 TREE_USED (current_function_decl) = 1;
7775 pop_lang_context ();
7778 METHOD_DEFINITION (method) = current_function_decl;
7780 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7782 if (implementation_template != objc_implementation_context)
7785 = lookup_method_static (implementation_template,
7786 METHOD_SEL_NAME (method),
7787 TREE_CODE (method) == CLASS_METHOD_DECL);
7791 if (!comp_method_with_proto (method, proto))
7793 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7795 warn_with_method ("conflicting types for", type, method);
7796 warn_with_method ("previous declaration of", type, proto);
7801 /* We have a method @implementation even though we did not
7802 see a corresponding @interface declaration (which is allowed
7803 by Objective-C rules). Go ahead and place the method in
7804 the @interface anyway, so that message dispatch lookups
7806 tree interface = implementation_template;
7808 if (TREE_CODE (objc_implementation_context)
7809 == CATEGORY_IMPLEMENTATION_TYPE)
7810 interface = lookup_category
7812 CLASS_SUPER_NAME (objc_implementation_context));
7815 objc_add_method (interface, copy_node (method),
7816 TREE_CODE (method) == CLASS_METHOD_DECL);
7821 /* The following routine is always called...this "architecture" is to
7822 accommodate "old-style" variable length selectors.
7824 - a:a b:b // prototype ; id c; id d; // old-style. */
7827 continue_method_def (void)
7831 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7832 /* We have a `, ...' immediately following the selector. */
7833 parmlist = get_parm_info (0);
7835 parmlist = get_parm_info (1); /* place a `void_at_end' */
7838 /* Set self_decl from the first argument...this global is used by
7839 build_ivar_reference calling build_indirect_ref. */
7840 self_decl = TREE_PURPOSE (parmlist);
7841 #endif /* !OBJCPLUS */
7844 really_start_method (objc_method_context, parmlist);
7845 store_parm_decls ();
7848 static void *UOBJC_SUPER_scope = 0;
7850 /* _n_Method (id self, SEL sel, ...)
7852 struct objc_super _S;
7853 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7857 get_super_receiver (void)
7859 if (objc_method_context)
7861 tree super_expr, super_expr_list;
7863 if (!UOBJC_SUPER_decl)
7865 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7866 build_tree_list (NULL_TREE,
7867 objc_super_template),
7870 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7872 /* This prevents `unused variable' warnings when compiling with -Wall. */
7873 TREE_USED (UOBJC_SUPER_decl) = 1;
7874 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7876 UOBJC_SUPER_scope = get_current_scope ();
7879 /* Set receiver to self. */
7880 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7881 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7882 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7884 /* Set class to begin searching. */
7885 super_expr = build_component_ref (UOBJC_SUPER_decl,
7886 get_identifier ("class"));
7888 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7890 /* [_cls, __cls]Super are "pre-built" in
7891 synth_forward_declarations. */
7893 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7894 ((TREE_CODE (objc_method_context)
7895 == INSTANCE_METHOD_DECL)
7897 : uucls_super_ref));
7901 /* We have a category. */
7903 tree super_name = CLASS_SUPER_NAME (implementation_template);
7906 /* Barf if super used in a category of Object. */
7909 error ("no super class declared in interface for `%s'",
7910 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7911 return error_mark_node;
7914 if (flag_next_runtime && !flag_zero_link)
7916 super_class = get_class_reference (super_name);
7917 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7918 /* If we are in a class method, we must retrieve the
7919 _metaclass_ for the current class, pointed at by
7920 the class's "isa" pointer. The following assumes that
7921 "isa" is the first ivar in a class (which it must be). */
7923 = build_indirect_ref
7924 (build_c_cast (build_pointer_type (objc_class_type),
7925 super_class), "unary *");
7929 add_class_reference (super_name);
7930 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7931 ? objc_get_class_decl : objc_get_meta_class_decl);
7932 assemble_external (super_class);
7934 = build_function_call
7938 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7939 IDENTIFIER_POINTER (super_name))));
7943 = build_modify_expr (super_expr, NOP_EXPR,
7944 build_c_cast (TREE_TYPE (super_expr),
7948 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7950 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7951 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7953 return build_compound_expr (super_expr_list);
7957 error ("[super ...] must appear in a method context");
7958 return error_mark_node;
7962 /* When exiting a scope, sever links to a 'super' declaration (if any)
7963 therein contained. */
7966 objc_clear_super_receiver (void)
7968 if (objc_method_context
7969 && UOBJC_SUPER_scope == get_current_scope ()) {
7970 UOBJC_SUPER_decl = 0;
7971 UOBJC_SUPER_scope = 0;
7976 objc_expand_function_end (void)
7978 /* This routine may also get called for C functions, including those
7979 nested within ObjC methods. In such cases, method encoding is
7981 if (objc_method_context == NULL_TREE
7982 || DECL_INITIAL (objc_method_context) != current_function_decl)
7985 METHOD_ENCODING (objc_method_context)
7986 = encode_method_prototype (objc_method_context);
7990 finish_method_def (void)
7992 lang_expand_function_end = objc_expand_function_end;
7993 /* We cannot validly inline ObjC methods, at least not without a language
7994 extension to declare that a method need not be dynamically
7995 dispatched, so suppress all thoughts of doing so. */
7996 DECL_INLINE (current_function_decl) = 0;
7997 DECL_UNINLINABLE (current_function_decl) = 1;
7998 current_function_cannot_inline = "methods cannot be inlined";
8001 lang_expand_function_end = NULL;
8003 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8004 since the optimizer may find "may be used before set" errors. */
8005 objc_method_context = NULL_TREE;
8010 lang_report_error_function (tree decl)
8012 if (objc_method_context)
8014 fprintf (stderr, "In method `%s'\n",
8015 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8025 is_complex_decl (tree type)
8027 return (TREE_CODE (type) == ARRAY_TYPE
8028 || TREE_CODE (type) == FUNCTION_TYPE
8029 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8033 /* Code to convert a decl node into text for a declaration in C. */
8035 static char tmpbuf[256];
8038 adorn_decl (tree decl, char *str)
8040 enum tree_code code = TREE_CODE (decl);
8042 if (code == ARRAY_REF)
8044 tree an_int_cst = TREE_OPERAND (decl, 1);
8046 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8047 sprintf (str + strlen (str), "[%ld]",
8048 (long) TREE_INT_CST_LOW (an_int_cst));
8053 else if (code == ARRAY_TYPE)
8055 tree an_int_cst = TYPE_SIZE (decl);
8056 tree array_of = TREE_TYPE (decl);
8058 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8059 sprintf (str + strlen (str), "[%ld]",
8060 (long) (TREE_INT_CST_LOW (an_int_cst)
8061 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8066 else if (code == CALL_EXPR)
8068 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8073 gen_declaration_1 (chain, str);
8074 chain = TREE_CHAIN (chain);
8081 else if (code == FUNCTION_TYPE)
8083 tree chain = TYPE_ARG_TYPES (decl);
8086 while (chain && TREE_VALUE (chain) != void_type_node)
8088 gen_declaration_1 (TREE_VALUE (chain), str);
8089 chain = TREE_CHAIN (chain);
8090 if (chain && TREE_VALUE (chain) != void_type_node)
8096 else if (code == INDIRECT_REF)
8098 strcpy (tmpbuf, "*");
8099 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8103 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8105 chain = TREE_CHAIN (chain))
8107 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8109 strcat (tmpbuf, " ");
8110 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8114 strcat (tmpbuf, " ");
8116 strcat (tmpbuf, str);
8117 strcpy (str, tmpbuf);
8120 else if (code == POINTER_TYPE)
8122 strcpy (tmpbuf, "*");
8123 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
8125 if (TREE_READONLY (decl))
8126 strcat (tmpbuf, " const");
8127 if (TYPE_VOLATILE (decl))
8128 strcat (tmpbuf, " volatile");
8130 strcat (tmpbuf, " ");
8132 strcat (tmpbuf, str);
8133 strcpy (str, tmpbuf);
8138 gen_declarator (tree decl, char *buf, const char *name)
8142 enum tree_code code = TREE_CODE (decl);
8152 op = TREE_OPERAND (decl, 0);
8154 /* We have a pointer to a function or array...(*)(), (*)[] */
8155 if ((code == ARRAY_REF || code == CALL_EXPR)
8156 && op && TREE_CODE (op) == INDIRECT_REF)
8159 str = gen_declarator (op, buf, name);
8163 strcpy (tmpbuf, "(");
8164 strcat (tmpbuf, str);
8165 strcat (tmpbuf, ")");
8166 strcpy (str, tmpbuf);
8169 adorn_decl (decl, str);
8178 /* This clause is done iteratively rather than recursively. */
8181 op = (is_complex_decl (TREE_TYPE (decl))
8182 ? TREE_TYPE (decl) : NULL_TREE);
8184 adorn_decl (decl, str);
8186 /* We have a pointer to a function or array...(*)(), (*)[] */
8187 if (code == POINTER_TYPE
8188 && op && (TREE_CODE (op) == FUNCTION_TYPE
8189 || TREE_CODE (op) == ARRAY_TYPE))
8191 strcpy (tmpbuf, "(");
8192 strcat (tmpbuf, str);
8193 strcat (tmpbuf, ")");
8194 strcpy (str, tmpbuf);
8197 decl = (is_complex_decl (TREE_TYPE (decl))
8198 ? TREE_TYPE (decl) : NULL_TREE);
8201 while (decl && (code = TREE_CODE (decl)))
8206 case IDENTIFIER_NODE:
8207 /* Will only happen if we are processing a "raw" expr-decl. */
8208 strcpy (buf, IDENTIFIER_POINTER (decl));
8219 /* We have an abstract declarator or a _DECL node. */
8227 gen_declspecs (tree declspecs, char *buf, int raw)
8233 for (chain = nreverse (copy_list (declspecs));
8234 chain; chain = TREE_CHAIN (chain))
8236 tree aspec = TREE_VALUE (chain);
8238 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8239 strcat (buf, IDENTIFIER_POINTER (aspec));
8240 else if (TREE_CODE (aspec) == RECORD_TYPE)
8242 if (OBJC_TYPE_NAME (aspec))
8244 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8246 if (! TREE_STATIC_TEMPLATE (aspec))
8247 strcat (buf, "struct ");
8248 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8253 tree chain = protocol_list;
8260 (PROTOCOL_NAME (TREE_VALUE (chain))));
8261 chain = TREE_CHAIN (chain);
8270 strcat (buf, "untagged struct");
8273 else if (TREE_CODE (aspec) == UNION_TYPE)
8275 if (OBJC_TYPE_NAME (aspec))
8277 if (! TREE_STATIC_TEMPLATE (aspec))
8278 strcat (buf, "union ");
8279 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8282 strcat (buf, "untagged union");
8285 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8287 if (OBJC_TYPE_NAME (aspec))
8289 if (! TREE_STATIC_TEMPLATE (aspec))
8290 strcat (buf, "enum ");
8291 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8294 strcat (buf, "untagged enum");
8297 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8298 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8300 else if (IS_ID (aspec))
8302 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8307 tree chain = protocol_list;
8314 (PROTOCOL_NAME (TREE_VALUE (chain))));
8315 chain = TREE_CHAIN (chain);
8322 if (TREE_CHAIN (chain))
8328 /* Type qualifiers. */
8329 if (TREE_READONLY (declspecs))
8330 strcat (buf, "const ");
8331 if (TYPE_VOLATILE (declspecs))
8332 strcat (buf, "volatile ");
8334 switch (TREE_CODE (declspecs))
8336 /* Type specifiers. */
8339 declspecs = TYPE_MAIN_VARIANT (declspecs);
8341 /* Signed integer types. */
8343 if (declspecs == short_integer_type_node)
8344 strcat (buf, "short int ");
8345 else if (declspecs == integer_type_node)
8346 strcat (buf, "int ");
8347 else if (declspecs == long_integer_type_node)
8348 strcat (buf, "long int ");
8349 else if (declspecs == long_long_integer_type_node)
8350 strcat (buf, "long long int ");
8351 else if (declspecs == signed_char_type_node
8352 || declspecs == char_type_node)
8353 strcat (buf, "char ");
8355 /* Unsigned integer types. */
8357 else if (declspecs == short_unsigned_type_node)
8358 strcat (buf, "unsigned short ");
8359 else if (declspecs == unsigned_type_node)
8360 strcat (buf, "unsigned int ");
8361 else if (declspecs == long_unsigned_type_node)
8362 strcat (buf, "unsigned long ");
8363 else if (declspecs == long_long_unsigned_type_node)
8364 strcat (buf, "unsigned long long ");
8365 else if (declspecs == unsigned_char_type_node)
8366 strcat (buf, "unsigned char ");
8370 declspecs = TYPE_MAIN_VARIANT (declspecs);
8372 if (declspecs == float_type_node)
8373 strcat (buf, "float ");
8374 else if (declspecs == double_type_node)
8375 strcat (buf, "double ");
8376 else if (declspecs == long_double_type_node)
8377 strcat (buf, "long double ");
8381 if (OBJC_TYPE_NAME (declspecs)
8382 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8384 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8386 if (! TREE_STATIC_TEMPLATE (declspecs))
8387 strcat (buf, "struct ");
8388 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8392 tree chain = protocol_list;
8399 (PROTOCOL_NAME (TREE_VALUE (chain))));
8400 chain = TREE_CHAIN (chain);
8409 strcat (buf, "untagged struct");
8415 if (OBJC_TYPE_NAME (declspecs)
8416 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8418 strcat (buf, "union ");
8419 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8424 strcat (buf, "untagged union ");
8428 if (OBJC_TYPE_NAME (declspecs)
8429 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8431 strcat (buf, "enum ");
8432 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8437 strcat (buf, "untagged enum ");
8441 strcat (buf, "void ");
8446 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8451 tree chain = protocol_list;
8458 (PROTOCOL_NAME (TREE_VALUE (chain))));
8459 chain = TREE_CHAIN (chain);
8475 /* Given a tree node, produce a printable description of it in the given
8476 buffer, overwriting the buffer. */
8479 gen_declaration (tree atype_or_adecl, char *buf)
8482 gen_declaration_1 (atype_or_adecl, buf);
8486 /* Given a tree node, append a printable description to the end of the
8490 gen_declaration_1 (tree atype_or_adecl, char *buf)
8494 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8496 tree declspecs; /* "identifier_node", "record_type" */
8497 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8498 tree width = NULL_TREE; /* for bitfields */
8500 /* We have a "raw", abstract declarator (typename). */
8501 declarator = TREE_VALUE (atype_or_adecl);
8502 /* In the case of raw ivars, the declarator itself is a list,
8503 and contains bitfield widths. */
8504 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8506 width = TREE_VALUE (declarator);
8507 declarator = TREE_PURPOSE (declarator);
8509 declspecs = TREE_PURPOSE (atype_or_adecl);
8511 gen_declspecs (declspecs, buf, 1);
8515 strcat (buf, gen_declarator (declarator, declbuf, ""));
8518 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8519 TREE_INT_CST_LOW (width));
8525 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8526 tree declarator; /* "array_type", "function_type", "pointer_type". */
8528 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8529 || TREE_CODE (atype_or_adecl) == PARM_DECL
8530 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8531 atype = TREE_TYPE (atype_or_adecl);
8533 /* Assume we have a *_type node. */
8534 atype = atype_or_adecl;
8536 if (is_complex_decl (atype))
8540 /* Get the declaration specifier; it is at the end of the list. */
8541 declarator = chain = atype;
8543 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8544 while (is_complex_decl (chain));
8551 declarator = NULL_TREE;
8554 gen_declspecs (declspecs, buf, 0);
8556 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8557 || TREE_CODE (atype_or_adecl) == PARM_DECL
8558 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8560 const char *const decl_name =
8561 (DECL_NAME (atype_or_adecl)
8562 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8567 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8570 else if (decl_name[0])
8573 strcat (buf, decl_name);
8576 else if (declarator)
8579 strcat (buf, gen_declarator (declarator, declbuf, ""));
8584 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8586 /* Given a method tree, put a printable description into the given
8587 buffer (overwriting) and return a pointer to the buffer. */
8590 gen_method_decl (tree method, char *buf)
8595 if (RAW_TYPESPEC (method) != objc_object_reference)
8598 gen_declaration_1 (TREE_TYPE (method), buf);
8602 chain = METHOD_SEL_ARGS (method);
8605 /* We have a chain of keyword_decls. */
8608 if (KEYWORD_KEY_NAME (chain))
8609 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8612 if (RAW_TYPESPEC (chain) != objc_object_reference)
8615 gen_declaration_1 (TREE_TYPE (chain), buf);
8619 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8620 if ((chain = TREE_CHAIN (chain)))
8625 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8626 strcat (buf, ", ...");
8627 else if (METHOD_ADD_ARGS (method))
8629 /* We have a tree list node as generate by get_parm_info. */
8630 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8632 /* Know we have a chain of parm_decls. */
8636 gen_declaration_1 (chain, buf);
8637 chain = TREE_CHAIN (chain);
8643 /* We have a unary selector. */
8644 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8652 /* Dump an @interface declaration of the supplied class CHAIN to the
8653 supplied file FP. Used to implement the -gen-decls option (which
8654 prints out an @interface declaration of all classes compiled in
8655 this run); potentially useful for debugging the compiler too. */
8657 dump_interface (FILE *fp, tree chain)
8659 /* FIXME: A heap overflow here whenever a method (or ivar)
8660 declaration is so long that it doesn't fit in the buffer. The
8661 code and all the related functions should be rewritten to avoid
8662 using fixed size buffers. */
8663 char *buf = (char *) xmalloc (1024 * 10);
8664 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8665 tree ivar_decls = CLASS_RAW_IVARS (chain);
8666 tree nst_methods = CLASS_NST_METHODS (chain);
8667 tree cls_methods = CLASS_CLS_METHODS (chain);
8669 fprintf (fp, "\n@interface %s", my_name);
8671 /* CLASS_SUPER_NAME is used to store the superclass name for
8672 classes, and the category name for categories. */
8673 if (CLASS_SUPER_NAME (chain))
8675 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8677 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8678 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8680 fprintf (fp, " (%s)\n", name);
8684 fprintf (fp, " : %s\n", name);
8690 /* FIXME - the following doesn't seem to work at the moment. */
8693 fprintf (fp, "{\n");
8696 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8697 ivar_decls = TREE_CHAIN (ivar_decls);
8700 fprintf (fp, "}\n");
8705 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8706 nst_methods = TREE_CHAIN (nst_methods);
8711 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8712 cls_methods = TREE_CHAIN (cls_methods);
8715 fprintf (fp, "@end\n");
8718 /* Demangle function for Objective-C */
8720 objc_demangle (const char *mangled)
8722 char *demangled, *cp;
8724 if (mangled[0] == '_' &&
8725 (mangled[1] == 'i' || mangled[1] == 'c') &&
8728 cp = demangled = xmalloc(strlen(mangled) + 2);
8729 if (mangled[1] == 'i')
8730 *cp++ = '-'; /* for instance method */
8732 *cp++ = '+'; /* for class method */
8733 *cp++ = '['; /* opening left brace */
8734 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8735 while (*cp && *cp == '_')
8736 cp++; /* skip any initial underbars in class name */
8737 cp = strchr(cp, '_'); /* find first non-initial underbar */
8740 free(demangled); /* not mangled name */
8743 if (cp[1] == '_') /* easy case: no category name */
8745 *cp++ = ' '; /* replace two '_' with one ' ' */
8746 strcpy(cp, mangled + (cp - demangled) + 2);
8750 *cp++ = '('; /* less easy case: category name */
8751 cp = strchr(cp, '_');
8754 free(demangled); /* not mangled name */
8758 *cp++ = ' '; /* overwriting 1st char of method name... */
8759 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8761 while (*cp && *cp == '_')
8762 cp++; /* skip any initial underbars in method name */
8765 *cp = ':'; /* replace remaining '_' with ':' */
8766 *cp++ = ']'; /* closing right brace */
8767 *cp++ = 0; /* string terminator */
8771 return mangled; /* not an objc mangled name */
8775 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8777 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8783 gcc_obstack_init (&util_obstack);
8784 util_firstobj = (char *) obstack_finish (&util_obstack);
8786 errbuf = (char *) xmalloc (BUFSIZE);
8788 synth_module_prologue ();
8794 struct imp_entry *impent;
8796 /* The internally generated initializers appear to have missing braces.
8797 Don't warn about this. */
8798 int save_warn_missing_braces = warn_missing_braces;
8799 warn_missing_braces = 0;
8801 /* A missing @end may not be detected by the parser. */
8802 if (objc_implementation_context)
8804 warning ("`@end' missing in implementation context");
8805 finish_class (objc_implementation_context);
8806 objc_ivar_chain = NULL_TREE;
8807 objc_implementation_context = NULL_TREE;
8810 generate_forward_declaration_to_string_table ();
8812 /* Process the static instances here because initialization of objc_symtab
8814 if (objc_static_instances)
8815 generate_static_references ();
8817 if (imp_list || class_names_chain
8818 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8819 generate_objc_symtab_decl ();
8821 for (impent = imp_list; impent; impent = impent->next)
8823 objc_implementation_context = impent->imp_context;
8824 implementation_template = impent->imp_template;
8826 UOBJC_CLASS_decl = impent->class_decl;
8827 UOBJC_METACLASS_decl = impent->meta_decl;
8829 /* Dump the @interface of each class as we compile it, if the
8830 -gen-decls option is in use. TODO: Dump the classes in the
8831 order they were found, rather than in reverse order as we
8833 if (flag_gen_declaration)
8835 dump_interface (gen_declaration_file, objc_implementation_context);
8838 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8840 /* all of the following reference the string pool... */
8841 generate_ivar_lists ();
8842 generate_dispatch_tables ();
8843 generate_shared_structures ();
8847 generate_dispatch_tables ();
8848 generate_category (objc_implementation_context);
8852 /* If we are using an array of selectors, we must always
8853 finish up the array decl even if no selectors were used. */
8854 if (! flag_next_runtime || sel_ref_chain)
8855 build_selector_translation_table ();
8858 generate_protocols ();
8860 if (flag_replace_objc_classes && imp_list)
8861 generate_objc_image_info ();
8863 if (objc_implementation_context || class_names_chain || objc_static_instances
8864 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8866 /* Arrange for ObjC data structures to be initialized at run time. */
8867 rtx init_sym = build_module_descriptor ();
8868 if (init_sym && targetm.have_ctors_dtors)
8869 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8872 /* Dump the class references. This forces the appropriate classes
8873 to be linked into the executable image, preserving unix archive
8874 semantics. This can be removed when we move to a more dynamically
8875 linked environment. */
8877 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8879 handle_class_ref (chain);
8880 if (TREE_PURPOSE (chain))
8881 generate_classref_translation_entry (chain);
8884 for (impent = imp_list; impent; impent = impent->next)
8885 handle_impent (impent);
8887 /* Dump the string table last. */
8889 generate_strings ();
8896 /* Run through the selector hash tables and print a warning for any
8897 selector which has multiple methods. */
8899 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8901 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8902 check_duplicates (hsh, 0, 1);
8903 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8904 check_duplicates (hsh, 0, 1);
8908 warn_missing_braces = save_warn_missing_braces;
8911 /* Subroutines of finish_objc. */
8914 generate_classref_translation_entry (tree chain)
8916 tree expr, name, decl_specs, decl, sc_spec;
8919 type = TREE_TYPE (TREE_PURPOSE (chain));
8921 expr = add_objc_string (TREE_VALUE (chain), class_names);
8922 expr = build_c_cast (type, expr); /* cast! */
8924 name = DECL_NAME (TREE_PURPOSE (chain));
8926 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8928 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8929 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8931 /* The decl that is returned from start_decl is the one that we
8932 forward declared in build_class_reference. */
8933 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8934 DECL_CONTEXT (decl) = NULL_TREE;
8935 finish_decl (decl, expr, NULL_TREE);
8940 handle_class_ref (tree chain)
8942 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8943 char *string = (char *) alloca (strlen (name) + 30);
8947 sprintf (string, "%sobjc_class_name_%s",
8948 (flag_next_runtime ? "." : "__"), name);
8950 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8951 if (flag_next_runtime)
8953 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8958 /* Make a decl for this name, so we can use its address in a tree. */
8959 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8960 DECL_EXTERNAL (decl) = 1;
8961 TREE_PUBLIC (decl) = 1;
8964 rest_of_decl_compilation (decl, 0, 0, 0);
8966 /* Make a decl for the address. */
8967 sprintf (string, "%sobjc_class_ref_%s",
8968 (flag_next_runtime ? "." : "__"), name);
8969 exp = build1 (ADDR_EXPR, string_type_node, decl);
8970 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8971 DECL_INITIAL (decl) = exp;
8972 TREE_STATIC (decl) = 1;
8973 TREE_USED (decl) = 1;
8976 rest_of_decl_compilation (decl, 0, 0, 0);
8980 handle_impent (struct imp_entry *impent)
8984 objc_implementation_context = impent->imp_context;
8985 implementation_template = impent->imp_template;
8987 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8989 const char *const class_name =
8990 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8992 string = (char *) alloca (strlen (class_name) + 30);
8994 sprintf (string, "%sobjc_class_name_%s",
8995 (flag_next_runtime ? "." : "__"), class_name);
8997 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8999 const char *const class_name =
9000 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9001 const char *const class_super_name =
9002 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9004 string = (char *) alloca (strlen (class_name)
9005 + strlen (class_super_name) + 30);
9007 /* Do the same for categories. Even though no references to
9008 these symbols are generated automatically by the compiler, it
9009 gives you a handle to pull them into an archive by hand. */
9010 sprintf (string, "*%sobjc_category_name_%s_%s",
9011 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9016 #ifdef ASM_DECLARE_CLASS_REFERENCE
9017 if (flag_next_runtime)
9019 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9027 init = build_int_2 (0, 0);
9028 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
9029 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9030 TREE_PUBLIC (decl) = 1;
9031 TREE_READONLY (decl) = 1;
9032 TREE_USED (decl) = 1;
9033 TREE_CONSTANT (decl) = 1;
9034 DECL_CONTEXT (decl) = 0;
9035 DECL_ARTIFICIAL (decl) = 1;
9036 DECL_INITIAL (decl) = init;
9037 assemble_variable (decl, 1, 0, 0);
9041 /* The Fix-and-Countinue functionality available in Mac OS X 10.3 and
9042 later requires that ObjC translation units participating in F&C be
9043 specially marked. The following routine accomplishes this. */
9045 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9048 generate_objc_image_info (void)
9050 tree sc_spec, decl, initlist;
9052 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9054 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9055 tree_cons (NULL_TREE,
9058 build_index_type (build_int_2 (1, 0))),
9063 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9064 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9065 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9067 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9068 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9069 finish_decl (decl, initlist, NULL_TREE);
9072 /* Look up ID as an instance variable. */
9075 lookup_objc_ivar (tree id)
9079 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9080 /* We have a message to super. */
9081 return get_super_receiver ();
9082 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9084 if (is_private (decl))
9087 return build_ivar_reference (id);
9093 #include "gt-objc-objc-act.h"
9094 #include "gtype-objc.h"