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);
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 tree add_class (tree);
188 static void add_category (tree, tree);
192 class_names, /* class, category, protocol, module names */
193 meth_var_names, /* method and variable names */
194 meth_var_types /* method and variable type descriptors */
197 static tree add_objc_string (tree, enum string_section);
198 static tree get_objc_string_decl (tree, enum string_section);
199 static tree build_objc_string_decl (enum string_section);
200 static tree build_selector_reference_decl (void);
202 /* Protocol additions. */
204 static tree add_protocol (tree);
205 static tree lookup_protocol (tree);
206 static void check_protocol_recursively (tree, tree);
207 static tree lookup_and_install_protocols (tree);
211 static void encode_type_qualifiers (tree);
212 static void encode_pointer (tree, int, int);
213 static void encode_array (tree, int, int);
214 static void encode_aggregate (tree, int, int);
215 static void encode_next_bitfield (int);
216 static void encode_gnu_bitfield (int, tree, int);
217 static void encode_type (tree, int, int);
218 static void encode_field_decl (tree, int, int);
220 static void really_start_method (tree, tree);
221 static int comp_method_with_proto (tree, tree);
222 static int objc_types_are_equivalent (tree, tree);
223 static int comp_proto_with_proto (tree, tree);
224 static tree get_arg_type_list (tree, int, int);
225 static tree objc_expr_last (tree);
226 static void synth_self_and_ucmd_args (void);
228 /* Utilities for debugging and error diagnostics. */
230 static void warn_with_method (const char *, int, tree);
231 static void error_with_ivar (const char *, tree, tree);
232 static char *gen_method_decl (tree, char *);
233 static char *gen_declaration (tree, char *);
234 static void gen_declaration_1 (tree, char *);
235 static char *gen_declarator (tree, char *, const char *);
236 static int is_complex_decl (tree);
237 static void adorn_decl (tree, char *);
238 static void dump_interface (FILE *, tree);
240 /* Everything else. */
242 static tree define_decl (tree, tree);
243 static tree lookup_method_in_protocol_list (tree, tree, int);
244 static tree lookup_protocol_in_reflist (tree, tree);
245 static tree create_builtin_decl (enum tree_code, tree, const char *);
246 static void setup_string_decl (void);
247 static int check_string_class_template (void);
248 static tree my_build_string (int, const char *);
249 static void build_objc_symtab_template (void);
250 static tree init_def_list (tree);
251 static tree init_objc_symtab (tree);
252 static tree build_metadata_decl (const char *, tree);
253 static void forward_declare_categories (void);
254 static void generate_objc_symtab_decl (void);
255 static tree build_selector (tree);
256 static tree build_typed_selector_reference (tree, tree);
257 static tree build_selector_reference (tree);
258 static tree build_class_reference_decl (void);
259 static void add_class_reference (tree);
260 static tree build_protocol_template (void);
261 static tree build_descriptor_table_initializer (tree, tree);
262 static tree build_method_prototype_list_template (tree, int);
263 static tree build_method_prototype_template (void);
264 static tree objc_method_parm_type (tree);
265 static int objc_encoded_type_size (tree);
266 static tree encode_method_prototype (tree);
267 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
268 static void generate_method_descriptors (tree);
269 static void generate_protocol_references (tree);
270 static void generate_protocols (void);
271 static void check_ivars (tree, tree);
272 static tree build_ivar_list_template (tree, int);
273 static tree build_method_list_template (tree, int);
274 static tree build_ivar_list_initializer (tree, tree);
275 static tree generate_ivars_list (tree, const char *, int, tree);
276 static tree build_dispatch_table_initializer (tree, tree);
277 static tree generate_dispatch_table (tree, const char *, int, tree);
278 static tree build_shared_structure_initializer (tree, tree, tree, tree,
279 tree, int, tree, tree, tree);
280 static void generate_category (tree);
281 static int is_objc_type_qualifier (tree);
282 static tree adjust_type_for_id_default (tree);
283 static tree check_duplicates (hash, int);
284 static tree receiver_is_class_object (tree, int, int);
285 static int check_methods (tree, tree, int);
286 static int conforms_to_protocol (tree, tree);
287 static void check_protocol (tree, const char *, const char *);
288 static void check_protocols (tree, const char *, const char *);
289 static void gen_declspecs (tree, char *, int);
290 static void generate_classref_translation_entry (tree);
291 static void handle_class_ref (tree);
292 static void generate_struct_by_value_array (void)
294 static void mark_referenced_methods (void);
295 static void generate_objc_image_info (void);
297 /*** Private Interface (data) ***/
299 /* Reserved tag definitions. */
302 #define TAG_OBJECT "objc_object"
303 #define TAG_CLASS "objc_class"
304 #define TAG_SUPER "objc_super"
305 #define TAG_SELECTOR "objc_selector"
307 #define UTAG_CLASS "_objc_class"
308 #define UTAG_IVAR "_objc_ivar"
309 #define UTAG_IVAR_LIST "_objc_ivar_list"
310 #define UTAG_METHOD "_objc_method"
311 #define UTAG_METHOD_LIST "_objc_method_list"
312 #define UTAG_CATEGORY "_objc_category"
313 #define UTAG_MODULE "_objc_module"
314 #define UTAG_SYMTAB "_objc_symtab"
315 #define UTAG_SUPER "_objc_super"
316 #define UTAG_SELECTOR "_objc_selector"
318 #define UTAG_PROTOCOL "_objc_protocol"
319 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
320 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
322 /* Note that the string object global name is only needed for the
324 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
326 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
328 static const char *TAG_GETCLASS;
329 static const char *TAG_GETMETACLASS;
330 static const char *TAG_MSGSEND;
331 static const char *TAG_MSGSENDSUPER;
332 /* The NeXT Objective-C messenger may have two extra entry points, for use
333 when returning a structure. */
334 static const char *TAG_MSGSEND_STRET;
335 static const char *TAG_MSGSENDSUPER_STRET;
336 static const char *TAG_EXECCLASS;
337 static const char *default_constant_string_class_name;
339 /* Runtime metadata flags. */
340 #define CLS_FACTORY 0x0001L
341 #define CLS_META 0x0002L
343 #define OBJC_MODIFIER_STATIC 0x00000001
344 #define OBJC_MODIFIER_FINAL 0x00000002
345 #define OBJC_MODIFIER_PUBLIC 0x00000004
346 #define OBJC_MODIFIER_PRIVATE 0x00000008
347 #define OBJC_MODIFIER_PROTECTED 0x00000010
348 #define OBJC_MODIFIER_NATIVE 0x00000020
349 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
350 #define OBJC_MODIFIER_ABSTRACT 0x00000080
351 #define OBJC_MODIFIER_VOLATILE 0x00000100
352 #define OBJC_MODIFIER_TRANSIENT 0x00000200
353 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
355 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
356 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
357 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
358 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
359 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
360 #define TAG_EXCEPTIONMATCH "objc_exception_match"
361 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
362 #define TAG_SYNCENTER "objc_sync_enter"
363 #define TAG_SYNCEXIT "objc_sync_exit"
364 #define TAG_SETJMP "_setjmp"
365 #define TAG_RETURN_STRUCT "objc_return_struct"
367 #define UTAG_EXCDATA "_objc_exception_data"
368 #define UTAG_EXCDATA_VAR "_stackExceptionData"
369 #define UTAG_CAUGHTEXC_VAR "_caughtException"
370 #define UTAG_RETHROWEXC_VAR "_rethrowException"
371 #define UTAG_EVALONCE_VAR "_eval_once"
375 struct val_stack *next;
377 static struct val_stack *catch_count_stack, *exc_binding_stack;
379 /* useful for debugging */
380 static int if_nesting_count;
381 static int blk_nesting_count;
383 static void val_stack_push (struct val_stack **, long);
384 static void val_stack_pop (struct val_stack **);
386 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
387 tree objc_global_trees[OCTI_MAX];
389 static void handle_impent (struct imp_entry *);
391 struct imp_entry *imp_list = 0;
392 int imp_count = 0; /* `@implementation' */
393 int cat_count = 0; /* `@category' */
395 /* Use to generate method labels. */
396 static int method_slot = 0;
400 static char *errbuf; /* Buffer for error diagnostics */
402 /* Data imported from tree.c. */
404 extern enum debug_info_type write_symbols;
406 /* Data imported from toplev.c. */
408 extern const char *dump_base_name;
410 static int flag_typed_selectors;
412 FILE *gen_declaration_file;
414 /* Tells "encode_pointer/encode_aggregate" whether we are generating
415 type descriptors for instance variables (as opposed to methods).
416 Type descriptors for instance variables contain more information
417 than methods (for static typing and embedded structures). */
419 static int generating_instance_variables = 0;
421 /* Some platforms pass small structures through registers versus
422 through an invisible pointer. Determine at what size structure is
423 the transition point between the two possibilities. */
426 generate_struct_by_value_array (void)
429 tree field_decl, field_decl_chain;
431 int aggregate_in_mem[32];
434 /* Presumably no platform passes 32 byte structures in a register. */
435 for (i = 1; i < 32; i++)
439 /* Create an unnamed struct that has `i' character components */
440 type = start_struct (RECORD_TYPE, NULL_TREE);
442 strcpy (buffer, "c1");
443 field_decl = create_builtin_decl (FIELD_DECL,
446 field_decl_chain = field_decl;
448 for (j = 1; j < i; j++)
450 sprintf (buffer, "c%d", j + 1);
451 field_decl = create_builtin_decl (FIELD_DECL,
454 chainon (field_decl_chain, field_decl);
456 finish_struct (type, field_decl_chain, NULL_TREE);
458 aggregate_in_mem[i] = aggregate_value_p (type, 0);
459 if (!aggregate_in_mem[i])
463 /* We found some structures that are returned in registers instead of memory
464 so output the necessary data. */
467 for (i = 31; i >= 0; i--)
468 if (!aggregate_in_mem[i])
470 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
472 /* The first member of the structure is always 0 because we don't handle
473 structures with 0 members */
474 printf ("static int struct_forward_array[] = {\n 0");
476 for (j = 1; j <= i; j++)
477 printf (", %d", aggregate_in_mem[j]);
487 if (c_objc_common_init () == false)
490 /* Force the line number back to 0; check_newline will have
491 raised it to 1, which will make the builtin functions appear
492 not to be built in. */
495 /* If gen_declaration desired, open the output file. */
496 if (flag_gen_declaration)
498 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
499 gen_declaration_file = fopen (dumpname, "w");
500 if (gen_declaration_file == 0)
501 fatal_error ("can't open %s: %m", dumpname);
505 if (flag_next_runtime)
507 TAG_GETCLASS = "objc_getClass";
508 TAG_GETMETACLASS = "objc_getMetaClass";
509 TAG_MSGSEND = "objc_msgSend";
510 TAG_MSGSENDSUPER = "objc_msgSendSuper";
511 TAG_MSGSEND_STRET = "objc_msgSend_stret";
512 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
513 TAG_EXECCLASS = "__objc_execClass";
514 default_constant_string_class_name = "NSConstantString";
518 TAG_GETCLASS = "objc_get_class";
519 TAG_GETMETACLASS = "objc_get_meta_class";
520 TAG_MSGSEND = "objc_msg_lookup";
521 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
522 /* GNU runtime does not provide special functions to support
523 structure-returning methods. */
524 TAG_EXECCLASS = "__objc_exec_class";
525 default_constant_string_class_name = "NXConstantString";
526 flag_typed_selectors = 1;
529 objc_ellipsis_node = make_node (ERROR_MARK);
533 if (print_struct_values)
534 generate_struct_by_value_array ();
542 mark_referenced_methods ();
543 c_objc_common_finish_file ();
545 /* Finalize Objective-C runtime data. No need to generate tables
546 and code if only checking syntax. */
547 if (!flag_syntax_only)
550 if (gen_declaration_file)
551 fclose (gen_declaration_file);
555 define_decl (tree declarator, tree declspecs)
557 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
558 finish_decl (decl, NULL_TREE, NULL_TREE);
563 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
569 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
571 p = TREE_VALUE (rproto);
573 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
575 if ((fnd = lookup_method (class_meth
576 ? PROTOCOL_CLS_METHODS (p)
577 : PROTOCOL_NST_METHODS (p), sel_name)))
579 else if (PROTOCOL_LIST (p))
580 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
581 sel_name, class_meth);
585 ; /* An identifier...if we could not find a protocol. */
596 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
600 /* Make sure the protocol is supported by the object on the rhs. */
601 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
604 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
606 p = TREE_VALUE (rproto);
608 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
613 else if (PROTOCOL_LIST (p))
614 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
623 ; /* An identifier...if we could not find a protocol. */
629 /* Return 1 if LHS and RHS are compatible types for assignment or
630 various other operations. Return 0 if they are incompatible, and
631 return -1 if we choose to not decide (because the types are really
632 just C types, not ObjC specific ones). When the operation is
633 REFLEXIVE (typically comparisons), check for compatibility in
634 either direction; when it's not (typically assignments), don't.
636 This function is called in two cases: when both lhs and rhs are
637 pointers to records (in which case we check protocols too), and
638 when both lhs and rhs are records (in which case we check class
641 Warnings about classes/protocols not implementing a protocol are
642 emitted here (multiple of those warnings might be emitted for a
643 single line!); generic warnings about incompatible assignments and
644 lacks of casts in comparisons are/must be emitted by the caller if
649 objc_comptypes (tree lhs, tree rhs, int reflexive)
651 /* New clause for protocols. */
653 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
654 manage the ObjC ones, and leave the rest to the C code. */
655 if (TREE_CODE (lhs) == POINTER_TYPE
656 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
657 && TREE_CODE (rhs) == POINTER_TYPE
658 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
660 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
661 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
665 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
666 tree rproto, rproto_list;
669 /* <Protocol> = <Protocol> */
672 rproto_list = TYPE_PROTOCOL_LIST (rhs);
676 /* An assignment between objects of type 'id
677 <Protocol>'; make sure the protocol on the lhs is
678 supported by the object on the rhs. */
679 for (lproto = lproto_list; lproto;
680 lproto = TREE_CHAIN (lproto))
682 p = TREE_VALUE (lproto);
683 rproto = lookup_protocol_in_reflist (rproto_list, p);
687 ("object does not conform to the `%s' protocol",
688 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
694 /* Obscure case - a comparison between two objects
695 of type 'id <Protocol>'. Check that either the
696 protocol on the lhs is supported by the object on
697 the rhs, or viceversa. */
699 /* Check if the protocol on the lhs is supported by the
700 object on the rhs. */
701 for (lproto = lproto_list; lproto;
702 lproto = TREE_CHAIN (lproto))
704 p = TREE_VALUE (lproto);
705 rproto = lookup_protocol_in_reflist (rproto_list, p);
709 /* Check failed - check if the protocol on the rhs
710 is supported by the object on the lhs. */
711 for (rproto = rproto_list; rproto;
712 rproto = TREE_CHAIN (rproto))
714 p = TREE_VALUE (rproto);
715 lproto = lookup_protocol_in_reflist (lproto_list,
720 /* This check failed too: incompatible */
730 /* <Protocol> = <class> * */
731 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
733 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
736 /* Make sure the protocol is supported by the object on
738 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
740 p = TREE_VALUE (lproto);
742 rinter = lookup_interface (rname);
744 while (rinter && !rproto)
748 rproto_list = CLASS_PROTOCOL_LIST (rinter);
749 rproto = lookup_protocol_in_reflist (rproto_list, p);
750 /* If the underlying ObjC class does not have
751 the protocol we're looking for, check for "one-off"
752 protocols (e.g., `NSObject<MyProt> *foo;') attached
756 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
757 rproto = lookup_protocol_in_reflist (rproto_list, p);
760 /* Check for protocols adopted by categories. */
761 cat = CLASS_CATEGORY_LIST (rinter);
762 while (cat && !rproto)
764 rproto_list = CLASS_PROTOCOL_LIST (cat);
765 rproto = lookup_protocol_in_reflist (rproto_list, p);
766 cat = CLASS_CATEGORY_LIST (cat);
769 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
773 warning ("class `%s' does not implement the `%s' protocol",
774 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
775 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
779 /* <Protocol> = id */
780 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
784 /* <Protocol> = Class */
785 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
789 /* <Protocol> = ?? : let comptypes decide. */
792 else if (rhs_is_proto)
794 /* <class> * = <Protocol> */
795 if (TYPED_OBJECT (TREE_TYPE (lhs)))
799 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
801 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
803 /* Make sure the protocol is supported by the object on
805 for (rproto = rproto_list; rproto;
806 rproto = TREE_CHAIN (rproto))
808 tree p = TREE_VALUE (rproto);
810 rinter = lookup_interface (rname);
812 while (rinter && !lproto)
816 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
817 lproto = lookup_protocol_in_reflist (lproto_list, p);
818 /* If the underlying ObjC class does not
819 have the protocol we're looking for,
820 check for "one-off" protocols (e.g.,
821 `NSObject<MyProt> *foo;') attached to the
825 lproto_list = TYPE_PROTOCOL_LIST
827 lproto = lookup_protocol_in_reflist
831 /* Check for protocols adopted by categories. */
832 cat = CLASS_CATEGORY_LIST (rinter);
833 while (cat && !lproto)
835 lproto_list = CLASS_PROTOCOL_LIST (cat);
836 lproto = lookup_protocol_in_reflist (lproto_list,
838 cat = CLASS_CATEGORY_LIST (cat);
841 rinter = lookup_interface (CLASS_SUPER_NAME
846 warning ("class `%s' does not implement the `%s' protocol",
847 IDENTIFIER_POINTER (OBJC_TYPE_NAME
849 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
856 /* id = <Protocol> */
857 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
861 /* Class = <Protocol> */
862 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
866 /* ??? = <Protocol> : let comptypes decide */
874 /* Attention: we shouldn't defer to comptypes here. One bad
875 side effect would be that we might loose the REFLEXIVE
878 lhs = TREE_TYPE (lhs);
879 rhs = TREE_TYPE (rhs);
883 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
885 /* Nothing to do with ObjC - let immediately comptypes take
886 responsibility for checking. */
890 /* `id' = `<class> *' `<class> *' = `id': always allow it.
892 'Object *o = [[Object alloc] init]; falls
893 in the case <class> * = `id'.
895 if ((OBJC_TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
896 || (OBJC_TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
899 /* `id' = `Class', `Class' = `id' */
901 else if ((OBJC_TYPE_NAME (lhs) == objc_object_id
902 && OBJC_TYPE_NAME (rhs) == objc_class_id)
903 || (OBJC_TYPE_NAME (lhs) == objc_class_id
904 && OBJC_TYPE_NAME (rhs) == objc_object_id))
907 /* `<class> *' = `<class> *' */
909 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
911 tree lname = OBJC_TYPE_NAME (lhs);
912 tree rname = OBJC_TYPE_NAME (rhs);
918 /* If the left hand side is a super class of the right hand side,
920 for (inter = lookup_interface (rname); inter;
921 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
922 if (lname == CLASS_SUPER_NAME (inter))
925 /* Allow the reverse when reflexive. */
927 for (inter = lookup_interface (lname); inter;
928 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
929 if (rname == CLASS_SUPER_NAME (inter))
935 /* Not an ObjC type - let comptypes do the check. */
939 /* Called from finish_decl. */
942 objc_check_decl (tree decl)
944 tree type = TREE_TYPE (decl);
946 if (TREE_CODE (type) != RECORD_TYPE)
948 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type)))
949 && type != constant_string_type)
950 error ("statically allocated instance of Objective-C class `%s'",
951 IDENTIFIER_POINTER (type));
954 /* Implement static typing. At this point, we know we have an interface. */
957 get_static_reference (tree interface, tree protocols)
959 tree type = xref_tag (RECORD_TYPE, interface);
963 tree t, m = TYPE_MAIN_VARIANT (type);
965 t = copy_node (type);
967 /* Add this type to the chain of variants of TYPE. */
968 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
969 TYPE_NEXT_VARIANT (m) = t;
971 /* Look up protocols and install in lang specific list. Note
972 that the protocol list can have a different lifetime than T! */
973 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
975 /* This forces a new pointer type to be created later
976 (in build_pointer_type)...so that the new template
977 we just created will actually be used...what a hack! */
978 if (TYPE_POINTER_TO (t))
979 TYPE_POINTER_TO (t) = NULL_TREE;
988 get_object_reference (tree protocols)
990 tree type_decl = lookup_name (objc_id_id);
993 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
995 type = TREE_TYPE (type_decl);
996 if (TYPE_MAIN_VARIANT (type) != id_type)
997 warning ("unexpected type for `id' (%s)",
998 gen_declaration (type, errbuf));
1002 error ("undefined type `id', please import <objc/objc.h>");
1003 return error_mark_node;
1006 /* This clause creates a new pointer type that is qualified with
1007 the protocol specification...this info is used later to do more
1008 elaborate type checking. */
1012 tree t, m = TYPE_MAIN_VARIANT (type);
1014 t = copy_node (type);
1016 /* Add this type to the chain of variants of TYPE. */
1017 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1018 TYPE_NEXT_VARIANT (m) = t;
1020 /* Look up protocols...and install in lang specific list */
1021 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1023 /* This forces a new pointer type to be created later
1024 (in build_pointer_type)...so that the new template
1025 we just created will actually be used...what a hack! */
1026 if (TYPE_POINTER_TO (t))
1027 TYPE_POINTER_TO (t) = NULL_TREE;
1034 /* Check for circular dependencies in protocols. The arguments are
1035 PROTO, the protocol to check, and LIST, a list of protocol it
1039 check_protocol_recursively (tree proto, tree list)
1043 for (p = list; p; p = TREE_CHAIN (p))
1045 tree pp = TREE_VALUE (p);
1047 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1048 pp = lookup_protocol (pp);
1051 fatal_error ("protocol `%s' has circular dependency",
1052 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1054 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1058 /* Look up PROTOCOLS, and return a list of those that are found.
1059 If none are found, return NULL. */
1062 lookup_and_install_protocols (tree protocols)
1065 tree return_value = NULL_TREE;
1067 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1069 tree ident = TREE_VALUE (proto);
1070 tree p = lookup_protocol (ident);
1073 error ("cannot find protocol declaration for `%s'",
1074 IDENTIFIER_POINTER (ident));
1076 return_value = chainon (return_value,
1077 build_tree_list (NULL_TREE, p));
1080 return return_value;
1083 /* Create and push a decl for a built-in external variable or field NAME.
1085 TYPE is its data type. */
1088 create_builtin_decl (enum tree_code code, tree type, const char *name)
1090 tree decl = build_decl (code, get_identifier (name), type);
1092 if (code == VAR_DECL)
1094 TREE_STATIC (decl) = 1;
1095 make_decl_rtl (decl, 0);
1097 DECL_ARTIFICIAL (decl) = 1;
1103 /* Find the decl for the constant string class. */
1106 setup_string_decl (void)
1108 if (!string_class_decl)
1110 if (!constant_string_global_id)
1114 /* %s in format will provide room for terminating null */
1115 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1116 + strlen (constant_string_class_name);
1117 name = xmalloc (length);
1118 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1119 constant_string_class_name);
1120 constant_string_global_id = get_identifier (name);
1122 string_class_decl = lookup_name (constant_string_global_id);
1126 /* Purpose: "play" parser, creating/installing representations
1127 of the declarations that are required by Objective-C.
1131 type_spec--------->sc_spec
1132 (tree_list) (tree_list)
1135 identifier_node identifier_node */
1138 synth_module_prologue (void)
1142 /* Defined in `objc.h' */
1143 objc_object_id = get_identifier (TAG_OBJECT);
1145 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1147 id_type = build_pointer_type (objc_object_reference);
1149 objc_id_id = get_identifier (TYPE_ID);
1150 objc_class_id = get_identifier (TAG_CLASS);
1152 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1153 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1154 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1155 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1158 /* Declare type of selector-objects that represent an operation name. */
1160 /* `struct objc_selector *' */
1162 = build_pointer_type (xref_tag (RECORD_TYPE,
1163 get_identifier (TAG_SELECTOR)));
1165 /* Forward declare type, or else the prototype for msgSendSuper will
1168 /* `struct objc_super *' */
1169 super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1170 get_identifier (TAG_SUPER)));
1173 /* id objc_msgSend (id, SEL, ...); */
1176 = build_function_type (id_type,
1177 tree_cons (NULL_TREE, id_type,
1178 tree_cons (NULL_TREE, selector_type,
1181 if (! flag_next_runtime)
1183 umsg_decl = build_decl (FUNCTION_DECL,
1184 get_identifier (TAG_MSGSEND), temp_type);
1185 DECL_EXTERNAL (umsg_decl) = 1;
1186 TREE_PUBLIC (umsg_decl) = 1;
1187 DECL_INLINE (umsg_decl) = 1;
1188 DECL_ARTIFICIAL (umsg_decl) = 1;
1190 make_decl_rtl (umsg_decl, NULL);
1191 pushdecl (umsg_decl);
1195 umsg_decl = builtin_function (TAG_MSGSEND,
1196 temp_type, 0, NOT_BUILT_IN,
1198 /* id objc_msgSendNonNil (id, SEL, ...); */
1199 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1200 temp_type, 0, NOT_BUILT_IN,
1204 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1207 = build_function_type (id_type,
1208 tree_cons (NULL_TREE, super_type,
1209 tree_cons (NULL_TREE, selector_type,
1212 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1213 temp_type, 0, NOT_BUILT_IN,
1216 /* The NeXT runtime defines the following additional entry points,
1217 used for dispatching calls to methods returning structs:
1219 #if defined(__cplusplus)
1220 id objc_msgSend_stret(id self, SEL op, ...);
1221 id objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...);
1223 void objc_msgSend_stret(void * stretAddr, id self, SEL op, ...);
1224 void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super,
1228 struct objc_return_struct objc_msgSendNonNil_stret(id self, SEL op, ...);
1230 These prototypes appear in <objc/objc-runtime.h>; however, they
1231 CANNOT BE USED DIRECTLY. In order to call one of the ..._stret
1232 functions, the function must first be cast to a signature that
1233 corresponds to the actual ObjC method being invoked. This is
1234 what is done by the build_objc_method_call() routine below. */
1236 if (flag_next_runtime)
1238 tree objc_return_struct_type
1239 = xref_tag (RECORD_TYPE,
1240 get_identifier (TAG_RETURN_STRUCT));
1242 tree stret_temp_type
1243 = build_function_type (id_type,
1244 tree_cons (NULL_TREE, id_type,
1245 tree_cons (NULL_TREE, selector_type,
1248 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1249 stret_temp_type, 0, NOT_BUILT_IN,
1252 = build_function_type (objc_return_struct_type,
1253 tree_cons (NULL_TREE, id_type,
1254 tree_cons (NULL_TREE, selector_type,
1257 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1258 stret_temp_type, 0, NOT_BUILT_IN,
1262 = build_function_type (id_type,
1263 tree_cons (NULL_TREE, super_type,
1264 tree_cons (NULL_TREE, selector_type,
1267 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1268 stret_temp_type, 0, NOT_BUILT_IN, 0,
1272 /* id objc_getClass (const char *); */
1274 temp_type = build_function_type (id_type,
1275 tree_cons (NULL_TREE,
1276 const_string_type_node,
1280 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1283 /* id objc_getMetaClass (const char *); */
1285 objc_get_meta_class_decl
1286 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1288 build_super_template ();
1289 if (flag_next_runtime)
1290 build_objc_exception_stuff ();
1292 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1294 if (! flag_next_runtime)
1296 if (flag_typed_selectors)
1298 /* Suppress outputting debug symbols, because
1299 dbxout_init hasn'r been called yet. */
1300 enum debug_info_type save_write_symbols = write_symbols;
1301 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1302 write_symbols = NO_DEBUG;
1303 debug_hooks = &do_nothing_debug_hooks;
1305 build_selector_template ();
1306 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1308 write_symbols = save_write_symbols;
1309 debug_hooks = save_hooks;
1312 temp_type = build_array_type (selector_type, NULL_TREE);
1314 layout_type (temp_type);
1315 UOBJC_SELECTOR_TABLE_decl
1316 = create_builtin_decl (VAR_DECL, temp_type,
1317 "_OBJC_SELECTOR_TABLE");
1319 /* Avoid warning when not sending messages. */
1320 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1323 generate_forward_declaration_to_string_table ();
1325 /* Forward declare constant_string_id and constant_string_type. */
1326 if (!constant_string_class_name)
1327 constant_string_class_name = default_constant_string_class_name;
1329 constant_string_id = get_identifier (constant_string_class_name);
1330 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1332 /* Pre-build the following entities - for speed/convenience. */
1333 self_id = get_identifier ("self");
1334 ucmd_id = get_identifier ("_cmd");
1336 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1337 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1341 /* Ensure that the ivar list for NSConstantString/NXConstantString
1342 (or whatever was specified via `-fconstant-string-class')
1343 contains fields at least as large as the following three, so that
1344 the runtime can stomp on them with confidence:
1346 struct STRING_OBJECT_CLASS_NAME
1350 unsigned int length;
1354 check_string_class_template (void)
1356 tree field_decl = TYPE_FIELDS (constant_string_type);
1358 #define AT_LEAST_AS_LARGE_AS(F, T) \
1359 (F && TREE_CODE (F) == FIELD_DECL \
1360 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1361 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1363 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1366 field_decl = TREE_CHAIN (field_decl);
1367 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1370 field_decl = TREE_CHAIN (field_decl);
1371 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1373 #undef AT_LEAST_AS_LARGE_AS
1376 /* Avoid calling `check_string_class_template ()' more than once. */
1377 static GTY(()) int string_layout_checked;
1379 /* Custom build_string which sets TREE_TYPE! */
1382 my_build_string (int len, const char *str)
1384 return fix_string_type (build_string (len, str));
1387 /* Given a chain of STRING_CST's, build a static instance of
1388 NXConstantString which points at the concatenation of those
1389 strings. We place the string object in the __string_objects
1390 section of the __OBJC segment. The Objective-C runtime will
1391 initialize the isa pointers of the string objects to point at the
1392 NXConstantString class object. */
1395 build_objc_string_object (tree string)
1397 tree initlist, constructor, constant_string_class;
1400 string = fix_string_type (string);
1402 constant_string_class = lookup_interface (constant_string_id);
1403 if (!constant_string_class
1404 || !(constant_string_type
1405 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1407 error ("cannot find interface declaration for `%s'",
1408 IDENTIFIER_POINTER (constant_string_id));
1409 return error_mark_node;
1412 /* Call to 'combine_strings' has been moved above. */
1413 TREE_SET_CODE (string, STRING_CST);
1414 length = TREE_STRING_LENGTH (string) - 1;
1416 if (!string_layout_checked)
1418 /* The NSConstantString/NXConstantString ivar layout is now
1420 if (!check_string_class_template ())
1422 error ("interface `%s' does not have valid constant string layout",
1423 IDENTIFIER_POINTER (constant_string_id));
1424 return error_mark_node;
1426 add_class_reference (constant_string_id);
1429 /* & ((NXConstantString) { NULL, string, length }) */
1431 if (flag_next_runtime)
1433 /* For the NeXT runtime, we can generate a literal reference
1434 to the string class, don't need to run a constructor. */
1435 setup_string_decl ();
1436 if (string_class_decl == NULL_TREE)
1438 error ("cannot find reference tag for class `%s'",
1439 IDENTIFIER_POINTER (constant_string_id));
1440 return error_mark_node;
1442 initlist = build_tree_list
1444 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1448 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1452 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1454 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1455 constructor = objc_build_constructor (constant_string_type,
1456 nreverse (initlist));
1458 if (!flag_next_runtime)
1461 = objc_add_static_instance (constructor, constant_string_type);
1464 return (build_unary_op (ADDR_EXPR, constructor, 1));
1467 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1469 static GTY(()) int num_static_inst;
1472 objc_add_static_instance (tree constructor, tree class_decl)
1477 /* Find the list of static instances for the CLASS_DECL. Create one if
1479 for (chain = &objc_static_instances;
1480 *chain && TREE_VALUE (*chain) != class_decl;
1481 chain = &TREE_CHAIN (*chain));
1484 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1485 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1488 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1489 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1490 DECL_COMMON (decl) = 1;
1491 TREE_STATIC (decl) = 1;
1492 DECL_ARTIFICIAL (decl) = 1;
1493 DECL_INITIAL (decl) = constructor;
1495 /* We may be writing something else just now.
1496 Postpone till end of input. */
1497 DECL_DEFER_OUTPUT (decl) = 1;
1498 pushdecl_top_level (decl);
1499 rest_of_decl_compilation (decl, 0, 1, 0);
1501 /* Add the DECL to the head of this CLASS' list. */
1502 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1507 /* Build a static constant CONSTRUCTOR
1508 with type TYPE and elements ELTS. */
1511 objc_build_constructor (tree type, tree elts)
1513 tree constructor, f, e;
1515 /* ??? Most of the places that we build constructors, we don't fill in
1516 the type of integers properly. Convert them all en masse. */
1517 if (TREE_CODE (type) == ARRAY_TYPE)
1519 f = TREE_TYPE (type);
1520 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1521 for (e = elts; e ; e = TREE_CHAIN (e))
1522 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1526 f = TYPE_FIELDS (type);
1527 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1528 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1529 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1530 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1533 constructor = build_constructor (type, elts);
1534 TREE_CONSTANT (constructor) = 1;
1535 TREE_STATIC (constructor) = 1;
1536 TREE_READONLY (constructor) = 1;
1539 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1540 build_unary_op (wasn't true in 2.7.2.1 days) */
1541 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1546 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1548 /* Predefine the following data type:
1556 void *defs[cls_def_cnt + cat_def_cnt];
1560 build_objc_symtab_template (void)
1562 tree field_decl, field_decl_chain;
1564 objc_symtab_template
1565 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1567 /* long sel_ref_cnt; */
1569 field_decl = create_builtin_decl (FIELD_DECL,
1570 long_integer_type_node,
1572 field_decl_chain = field_decl;
1576 field_decl = create_builtin_decl (FIELD_DECL,
1577 build_pointer_type (selector_type),
1579 chainon (field_decl_chain, field_decl);
1581 /* short cls_def_cnt; */
1583 field_decl = create_builtin_decl (FIELD_DECL,
1584 short_integer_type_node,
1586 chainon (field_decl_chain, field_decl);
1588 /* short cat_def_cnt; */
1590 field_decl = create_builtin_decl (FIELD_DECL,
1591 short_integer_type_node,
1593 chainon (field_decl_chain, field_decl);
1595 if (imp_count || cat_count || !flag_next_runtime)
1597 /* void *defs[imp_count + cat_count (+ 1)]; */
1598 /* NB: The index is one less than the size of the array. */
1599 int index = imp_count + cat_count
1600 + (flag_next_runtime? -1: 0);
1601 field_decl = create_builtin_decl
1605 build_index_type (build_int_2 (index, 0))),
1607 chainon (field_decl_chain, field_decl);
1610 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1613 /* Create the initial value for the `defs' field of _objc_symtab.
1614 This is a CONSTRUCTOR. */
1617 init_def_list (tree type)
1619 tree expr, initlist = NULL_TREE;
1620 struct imp_entry *impent;
1623 for (impent = imp_list; impent; impent = impent->next)
1625 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1627 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1628 initlist = tree_cons (NULL_TREE, expr, initlist);
1633 for (impent = imp_list; impent; impent = impent->next)
1635 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1637 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1638 initlist = tree_cons (NULL_TREE, expr, initlist);
1642 if (!flag_next_runtime)
1644 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1647 if (static_instances_decl)
1648 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1650 expr = build_int_2 (0, 0);
1652 initlist = tree_cons (NULL_TREE, expr, initlist);
1655 return objc_build_constructor (type, nreverse (initlist));
1658 /* Construct the initial value for all of _objc_symtab. */
1661 init_objc_symtab (tree type)
1665 /* sel_ref_cnt = { ..., 5, ... } */
1667 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1669 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1671 if (flag_next_runtime || ! sel_ref_chain)
1672 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1674 initlist = tree_cons (NULL_TREE,
1675 build_unary_op (ADDR_EXPR,
1676 UOBJC_SELECTOR_TABLE_decl, 1),
1679 /* cls_def_cnt = { ..., 5, ... } */
1681 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1683 /* cat_def_cnt = { ..., 5, ... } */
1685 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1687 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1689 if (imp_count || cat_count || !flag_next_runtime)
1692 tree field = TYPE_FIELDS (type);
1693 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1695 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1699 return objc_build_constructor (type, nreverse (initlist));
1702 /* Generate forward declarations for metadata such as
1703 'OBJC_CLASS_...'. */
1706 build_metadata_decl (const char *name, tree type)
1708 tree decl, decl_specs;
1709 /* extern struct TYPE NAME_<name>; */
1710 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1711 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1712 decl = define_decl (synth_id_with_class_suffix
1714 objc_implementation_context),
1716 TREE_USED (decl) = 1;
1717 DECL_ARTIFICIAL (decl) = 1;
1718 TREE_PUBLIC (decl) = 0;
1722 /* Push forward-declarations of all the categories so that
1723 init_def_list can use them in a CONSTRUCTOR. */
1726 forward_declare_categories (void)
1728 struct imp_entry *impent;
1729 tree sav = objc_implementation_context;
1731 for (impent = imp_list; impent; impent = impent->next)
1733 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1735 /* Set an invisible arg to synth_id_with_class_suffix. */
1736 objc_implementation_context = impent->imp_context;
1737 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1738 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1739 objc_category_template);
1742 objc_implementation_context = sav;
1745 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1746 and initialized appropriately. */
1749 generate_objc_symtab_decl (void)
1753 if (!objc_category_template)
1754 build_category_template ();
1756 /* forward declare categories */
1758 forward_declare_categories ();
1760 if (!objc_symtab_template)
1761 build_objc_symtab_template ();
1763 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1765 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1766 tree_cons (NULL_TREE,
1767 objc_symtab_template, sc_spec),
1771 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1772 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1773 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1774 finish_decl (UOBJC_SYMBOLS_decl,
1775 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1780 init_module_descriptor (tree type)
1782 tree initlist, expr;
1784 /* version = { 1, ... } */
1786 expr = build_int_2 (OBJC_VERSION, 0);
1787 initlist = build_tree_list (NULL_TREE, expr);
1789 /* size = { ..., sizeof (struct objc_module), ... } */
1791 expr = size_in_bytes (objc_module_template);
1792 initlist = tree_cons (NULL_TREE, expr, initlist);
1794 /* name = { ..., "foo.m", ... } */
1796 expr = add_objc_string (get_identifier (input_filename), class_names);
1797 initlist = tree_cons (NULL_TREE, expr, initlist);
1799 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1801 if (UOBJC_SYMBOLS_decl)
1802 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1804 expr = build_int_2 (0, 0);
1805 initlist = tree_cons (NULL_TREE, expr, initlist);
1807 return objc_build_constructor (type, nreverse (initlist));
1810 /* Write out the data structures to describe Objective C classes defined.
1811 If appropriate, compile and output a setup function to initialize them.
1812 Return a symbol_ref to the function to call to initialize the Objective C
1813 data structures for this file (and perhaps for other files also).
1815 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1818 build_module_descriptor (void)
1820 tree decl_specs, field_decl, field_decl_chain;
1822 objc_module_template
1823 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1827 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1828 field_decl = get_identifier ("version");
1829 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1830 field_decl_chain = field_decl;
1834 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1835 field_decl = get_identifier ("size");
1836 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1837 chainon (field_decl_chain, field_decl);
1841 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1842 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1843 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1844 chainon (field_decl_chain, field_decl);
1846 /* struct objc_symtab *symtab; */
1848 decl_specs = get_identifier (UTAG_SYMTAB);
1849 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1850 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1851 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1852 chainon (field_decl_chain, field_decl);
1854 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1856 /* Create an instance of "objc_module". */
1858 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1859 build_tree_list (NULL_TREE,
1860 ridpointers[(int) RID_STATIC]));
1862 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1863 decl_specs, 1, NULL_TREE);
1865 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1866 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1867 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1869 finish_decl (UOBJC_MODULES_decl,
1870 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1873 /* Mark the decl to avoid "defined but not used" warning. */
1874 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1876 /* Generate a constructor call for the module descriptor.
1877 This code was generated by reading the grammar rules
1878 of c-parse.in; Therefore, it may not be the most efficient
1879 way of generating the requisite code. */
1881 if (flag_next_runtime)
1885 tree parms, execclass_decl, decelerator, void_list_node_1;
1886 tree init_function_name, init_function_decl;
1888 /* Declare void __objc_execClass (void *); */
1890 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1891 execclass_decl = build_decl (FUNCTION_DECL,
1892 get_identifier (TAG_EXECCLASS),
1893 build_function_type (void_type_node,
1894 tree_cons (NULL_TREE, ptr_type_node,
1895 OBJC_VOID_AT_END)));
1897 DECL_EXTERNAL (execclass_decl) = 1;
1898 DECL_ARTIFICIAL (execclass_decl) = 1;
1899 TREE_PUBLIC (execclass_decl) = 1;
1900 pushdecl (execclass_decl);
1901 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1902 assemble_external (execclass_decl);
1904 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1906 init_function_name = get_file_function_name ('I');
1907 start_function (void_list_node_1,
1908 build_nt (CALL_EXPR, init_function_name,
1909 tree_cons (NULL_TREE, NULL_TREE,
1913 store_parm_decls ();
1915 init_function_decl = current_function_decl;
1916 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1917 TREE_USED (init_function_decl) = 1;
1918 /* Don't let this one be deferred. */
1919 DECL_INLINE (init_function_decl) = 0;
1920 DECL_UNINLINABLE (init_function_decl) = 1;
1921 current_function_cannot_inline
1922 = "static constructors and destructors cannot be inlined";
1925 = build_tree_list (NULL_TREE,
1926 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1927 decelerator = build_function_call (execclass_decl, parms);
1929 c_expand_expr_stmt (decelerator);
1933 return XEXP (DECL_RTL (init_function_decl), 0);
1937 /* extern const char _OBJC_STRINGS[]; */
1940 generate_forward_declaration_to_string_table (void)
1942 tree sc_spec, decl_specs, expr_decl;
1944 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1945 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1948 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1950 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1953 /* Return the DECL of the string IDENT in the SECTION. */
1956 get_objc_string_decl (tree ident, enum string_section section)
1960 if (section == class_names)
1961 chain = class_names_chain;
1962 else if (section == meth_var_names)
1963 chain = meth_var_names_chain;
1964 else if (section == meth_var_types)
1965 chain = meth_var_types_chain;
1969 for (; chain != 0; chain = TREE_CHAIN (chain))
1970 if (TREE_VALUE (chain) == ident)
1971 return (TREE_PURPOSE (chain));
1977 /* Output references to all statically allocated objects. Return the DECL
1978 for the array built. */
1981 generate_static_references (void)
1983 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1984 tree class_name, class, decl, initlist;
1985 tree cl_chain, in_chain, type;
1986 int num_inst, num_class;
1989 if (flag_next_runtime)
1992 for (cl_chain = objc_static_instances, num_class = 0;
1993 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1995 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1996 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1998 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1999 ident = get_identifier (buf);
2001 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2002 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2003 build_tree_list (NULL_TREE,
2004 ridpointers[(int) RID_STATIC]));
2005 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2006 DECL_CONTEXT (decl) = 0;
2007 DECL_ARTIFICIAL (decl) = 1;
2009 /* Output {class_name, ...}. */
2010 class = TREE_VALUE (cl_chain);
2011 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2012 initlist = build_tree_list (NULL_TREE,
2013 build_unary_op (ADDR_EXPR, class_name, 1));
2015 /* Output {..., instance, ...}. */
2016 for (in_chain = TREE_PURPOSE (cl_chain);
2017 in_chain; in_chain = TREE_CHAIN (in_chain))
2019 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2020 initlist = tree_cons (NULL_TREE, expr, initlist);
2023 /* Output {..., NULL}. */
2024 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2026 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2027 finish_decl (decl, expr, NULL_TREE);
2028 TREE_USED (decl) = 1;
2030 type = build_array_type (build_pointer_type (void_type_node), 0);
2031 decl = build_decl (VAR_DECL, ident, type);
2032 TREE_USED (decl) = 1;
2033 TREE_STATIC (decl) = 1;
2035 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2038 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2039 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2040 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2041 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2042 build_tree_list (NULL_TREE,
2043 ridpointers[(int) RID_STATIC]));
2044 static_instances_decl
2045 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2046 TREE_USED (static_instances_decl) = 1;
2047 DECL_CONTEXT (static_instances_decl) = 0;
2048 DECL_ARTIFICIAL (static_instances_decl) = 1;
2049 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2051 finish_decl (static_instances_decl, expr, NULL_TREE);
2054 /* Output all strings. */
2057 generate_strings (void)
2059 tree sc_spec, decl_specs, expr_decl;
2060 tree chain, string_expr;
2063 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2065 string = TREE_VALUE (chain);
2066 decl = TREE_PURPOSE (chain);
2068 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2069 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2070 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2071 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2072 DECL_CONTEXT (decl) = NULL_TREE;
2073 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2074 IDENTIFIER_POINTER (string));
2075 finish_decl (decl, string_expr, NULL_TREE);
2078 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2080 string = TREE_VALUE (chain);
2081 decl = TREE_PURPOSE (chain);
2083 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2084 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2085 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2086 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2087 DECL_CONTEXT (decl) = NULL_TREE;
2088 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2089 IDENTIFIER_POINTER (string));
2090 finish_decl (decl, string_expr, NULL_TREE);
2093 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2095 string = TREE_VALUE (chain);
2096 decl = TREE_PURPOSE (chain);
2098 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2099 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2100 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2101 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2102 DECL_CONTEXT (decl) = NULL_TREE;
2103 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2104 IDENTIFIER_POINTER (string));
2105 finish_decl (decl, string_expr, NULL_TREE);
2109 static GTY(()) int selector_reference_idx;
2112 build_selector_reference_decl (void)
2117 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2119 ident = get_identifier (buf);
2121 decl = build_decl (VAR_DECL, ident, selector_type);
2122 DECL_EXTERNAL (decl) = 1;
2123 TREE_PUBLIC (decl) = 0;
2124 TREE_USED (decl) = 1;
2125 DECL_ARTIFICIAL (decl) = 1;
2126 DECL_CONTEXT (decl) = 0;
2128 make_decl_rtl (decl, 0);
2129 pushdecl_top_level (decl);
2134 /* Just a handy wrapper for add_objc_string. */
2137 build_selector (tree ident)
2139 tree expr = add_objc_string (ident, meth_var_names);
2140 if (flag_typed_selectors)
2143 return build_c_cast (selector_type, expr); /* cast! */
2147 build_selector_translation_table (void)
2149 tree sc_spec, decl_specs;
2150 tree chain, initlist = NULL_TREE;
2152 tree decl = NULL_TREE, var_decl, name;
2154 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2158 if (warn_selector && objc_implementation_context)
2162 for (method_chain = meth_var_names_chain;
2164 method_chain = TREE_CHAIN (method_chain))
2166 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2174 /* Adjust line number for warning message. */
2175 int save_lineno = input_line;
2176 if (flag_next_runtime && TREE_PURPOSE (chain))
2177 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2178 warning ("creating selector for non existant method %s",
2179 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2180 input_line = save_lineno;
2184 expr = build_selector (TREE_VALUE (chain));
2186 if (flag_next_runtime)
2188 name = DECL_NAME (TREE_PURPOSE (chain));
2190 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2192 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2193 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2197 /* The `decl' that is returned from start_decl is the one that we
2198 forward declared in `build_selector_reference' */
2199 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2202 /* add one for the '\0' character */
2203 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2205 if (flag_next_runtime)
2206 finish_decl (decl, expr, NULL_TREE);
2209 if (flag_typed_selectors)
2211 tree eltlist = NULL_TREE;
2212 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2213 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2214 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2215 expr = objc_build_constructor (objc_selector_template,
2216 nreverse (eltlist));
2218 initlist = tree_cons (NULL_TREE, expr, initlist);
2223 if (! flag_next_runtime)
2225 /* Cause the variable and its initial value to be actually output. */
2226 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2227 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2228 /* NULL terminate the list and fix the decl for output. */
2229 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2230 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2231 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2232 nreverse (initlist));
2233 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2234 current_function_decl = NULL_TREE;
2239 get_proto_encoding (tree proto)
2244 if (! METHOD_ENCODING (proto))
2246 encoding = encode_method_prototype (proto);
2247 METHOD_ENCODING (proto) = encoding;
2250 encoding = METHOD_ENCODING (proto);
2252 return add_objc_string (encoding, meth_var_types);
2255 return build_int_2 (0, 0);
2258 /* sel_ref_chain is a list whose "value" fields will be instances of
2259 identifier_node that represent the selector. */
2262 build_typed_selector_reference (tree ident, tree prototype)
2264 tree *chain = &sel_ref_chain;
2270 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2271 goto return_at_index;
2274 chain = &TREE_CHAIN (*chain);
2277 *chain = tree_cons (prototype, ident, NULL_TREE);
2280 expr = build_unary_op (ADDR_EXPR,
2281 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2282 build_int_2 (index, 0)),
2284 return build_c_cast (selector_type, expr);
2288 build_selector_reference (tree ident)
2290 tree *chain = &sel_ref_chain;
2296 if (TREE_VALUE (*chain) == ident)
2297 return (flag_next_runtime
2298 ? TREE_PURPOSE (*chain)
2299 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2300 build_int_2 (index, 0)));
2303 chain = &TREE_CHAIN (*chain);
2306 expr = build_selector_reference_decl ();
2308 *chain = tree_cons (expr, ident, NULL_TREE);
2310 return (flag_next_runtime
2312 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2313 build_int_2 (index, 0)));
2316 static GTY(()) int class_reference_idx;
2319 build_class_reference_decl (void)
2324 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2326 ident = get_identifier (buf);
2328 decl = build_decl (VAR_DECL, ident, objc_class_type);
2329 DECL_EXTERNAL (decl) = 1;
2330 TREE_PUBLIC (decl) = 0;
2331 TREE_USED (decl) = 1;
2332 DECL_CONTEXT (decl) = 0;
2333 DECL_ARTIFICIAL (decl) = 1;
2335 make_decl_rtl (decl, 0);
2336 pushdecl_top_level (decl);
2341 /* Create a class reference, but don't create a variable to reference
2345 add_class_reference (tree ident)
2349 if ((chain = cls_ref_chain))
2354 if (ident == TREE_VALUE (chain))
2358 chain = TREE_CHAIN (chain);
2362 /* Append to the end of the list */
2363 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2366 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2369 /* Get a class reference, creating it if necessary. Also create the
2370 reference variable. */
2373 get_class_reference (tree ident)
2378 if (processing_template_decl)
2379 /* Must wait until template instantiation time. */
2380 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2381 if (TREE_CODE (ident) == TYPE_DECL)
2382 ident = DECL_NAME (ident);
2386 if (!(ident = is_class_name (ident)))
2388 error ("`%s' is not an Objective-C class name or alias",
2389 IDENTIFIER_POINTER (orig_ident));
2390 return error_mark_node;
2393 if (flag_next_runtime && !flag_zero_link)
2398 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2399 if (TREE_VALUE (*chain) == ident)
2401 if (! TREE_PURPOSE (*chain))
2402 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2404 return TREE_PURPOSE (*chain);
2407 decl = build_class_reference_decl ();
2408 *chain = tree_cons (decl, ident, NULL_TREE);
2415 add_class_reference (ident);
2417 params = build_tree_list (NULL_TREE,
2418 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2419 IDENTIFIER_POINTER (ident)));
2421 assemble_external (objc_get_class_decl);
2422 return build_function_call (objc_get_class_decl, params);
2426 /* For each string section we have a chain which maps identifier nodes
2427 to decls for the strings. */
2430 add_objc_string (tree ident, enum string_section section)
2434 if (section == class_names)
2435 chain = &class_names_chain;
2436 else if (section == meth_var_names)
2437 chain = &meth_var_names_chain;
2438 else if (section == meth_var_types)
2439 chain = &meth_var_types_chain;
2445 if (TREE_VALUE (*chain) == ident)
2446 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2448 chain = &TREE_CHAIN (*chain);
2451 decl = build_objc_string_decl (section);
2453 *chain = tree_cons (decl, ident, NULL_TREE);
2455 return build_unary_op (ADDR_EXPR, decl, 1);
2458 static GTY(()) int class_names_idx;
2459 static GTY(()) int meth_var_names_idx;
2460 static GTY(()) int meth_var_types_idx;
2463 build_objc_string_decl (enum string_section section)
2468 if (section == class_names)
2469 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2470 else if (section == meth_var_names)
2471 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2472 else if (section == meth_var_types)
2473 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2475 ident = get_identifier (buf);
2477 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2478 DECL_EXTERNAL (decl) = 1;
2479 TREE_PUBLIC (decl) = 0;
2480 TREE_USED (decl) = 1;
2481 TREE_CONSTANT (decl) = 1;
2482 DECL_CONTEXT (decl) = 0;
2483 DECL_ARTIFICIAL (decl) = 1;
2485 make_decl_rtl (decl, 0);
2486 pushdecl_top_level (decl);
2493 objc_declare_alias (tree alias_ident, tree class_ident)
2495 tree underlying_class;
2498 if (current_namespace != global_namespace) {
2499 error ("Objective-C declarations may only appear in global scope");
2501 #endif /* OBJCPLUS */
2503 if (!(underlying_class = is_class_name (class_ident)))
2504 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2505 else if (is_class_name (alias_ident))
2506 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2508 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2512 objc_declare_class (tree ident_list)
2516 if (current_namespace != global_namespace) {
2517 error ("Objective-C declarations may only appear in global scope");
2519 #endif /* OBJCPLUS */
2521 for (list = ident_list; list; list = TREE_CHAIN (list))
2523 tree ident = TREE_VALUE (list);
2525 if (! is_class_name (ident))
2527 tree record = lookup_name (ident);
2529 if (record && ! TREE_STATIC_TEMPLATE (record))
2531 error ("`%s' redeclared as different kind of symbol",
2532 IDENTIFIER_POINTER (ident));
2533 error ("%Jprevious declaration of '%D'",
2537 record = xref_tag (RECORD_TYPE, ident);
2538 TREE_STATIC_TEMPLATE (record) = 1;
2539 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2545 is_class_name (tree ident)
2549 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2550 && identifier_global_value (ident))
2551 ident = identifier_global_value (ident);
2552 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2553 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2556 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2557 ident = TYPE_NAME (ident);
2558 if (ident && TREE_CODE (ident) == TYPE_DECL)
2559 ident = DECL_NAME (ident);
2561 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2564 if (lookup_interface (ident))
2567 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2569 if (ident == TREE_VALUE (chain))
2573 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2575 if (ident == TREE_VALUE (chain))
2576 return TREE_PURPOSE (chain);
2582 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2583 class instance. This is needed by other parts of the compiler to
2584 handle ObjC types gracefully. */
2587 objc_is_object_ptr (tree type)
2589 type = TYPE_MAIN_VARIANT (type);
2590 if (!type || TREE_CODE (type) != POINTER_TYPE)
2592 /* NB: This function may be called before the ObjC front-end has
2593 been initialized, in which case ID_TYPE will be NULL. */
2594 if (id_type && type && TYPE_P (type)
2596 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2598 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2602 lookup_interface (tree ident)
2607 if (ident && TREE_CODE (ident) == TYPE_DECL)
2608 ident = DECL_NAME (ident);
2610 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2612 if (ident == CLASS_NAME (chain))
2618 /* Implement @defs (<classname>) within struct bodies. */
2621 get_class_ivars_from_name (tree class_name)
2623 tree interface = lookup_interface (class_name);
2624 tree field, fields = NULL_TREE;
2628 tree raw_ivar = get_class_ivars (interface, 1);
2630 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2631 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2633 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2634 TREE_PURPOSE (raw_ivar),
2635 TREE_VALUE (TREE_VALUE (raw_ivar)));
2637 finish_member_declaration (field);
2639 fields = chainon (fields, field);
2644 error ("cannot find interface declaration for `%s'",
2645 IDENTIFIER_POINTER (class_name));
2650 /* Used by: build_private_template, continue_class,
2651 and for @defs constructs. */
2654 get_class_ivars (tree interface, int raw)
2656 tree my_name, super_name, ivar_chain;
2658 my_name = CLASS_NAME (interface);
2659 super_name = CLASS_SUPER_NAME (interface);
2661 ivar_chain = CLASS_RAW_IVARS (interface);
2664 ivar_chain = CLASS_IVARS (interface);
2665 /* Save off a pristine copy of the leaf ivars (i.e, those not
2666 inherited from a super class). */
2667 if (!CLASS_OWN_IVARS (interface))
2668 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2674 tree super_interface = lookup_interface (super_name);
2676 if (!super_interface)
2678 /* fatal did not work with 2 args...should fix */
2679 error ("cannot find interface declaration for `%s', superclass of `%s'",
2680 IDENTIFIER_POINTER (super_name),
2681 IDENTIFIER_POINTER (my_name));
2682 exit (FATAL_EXIT_CODE);
2685 if (super_interface == interface)
2686 fatal_error ("circular inheritance in interface declaration for `%s'",
2687 IDENTIFIER_POINTER (super_name));
2689 interface = super_interface;
2690 my_name = CLASS_NAME (interface);
2691 super_name = CLASS_SUPER_NAME (interface);
2693 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2696 tree head = copy_list (op1);
2698 /* Prepend super class ivars...make a copy of the list, we
2699 do not want to alter the original. */
2700 chainon (head, ivar_chain);
2709 objc_enter_block (void)
2714 block = begin_compound_stmt (0);
2716 block = c_begin_compound_stmt ();
2719 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
2722 objc_exception_block_stack = tree_cons (NULL_TREE, block,
2723 objc_exception_block_stack);
2725 blk_nesting_count++;
2730 objc_exit_block (void)
2732 tree block = TREE_VALUE (objc_exception_block_stack);
2734 tree scope_stmt, inner;
2737 objc_clear_super_receiver ();
2739 finish_compound_stmt (0, block);
2741 scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
2742 inner = poplevel (KEEP_MAYBE, 1, 0);
2744 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
2745 = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
2747 RECHAIN_STMTS (block, COMPOUND_BODY (block));
2749 last_expr_type = NULL_TREE;
2750 objc_exception_block_stack = TREE_CHAIN (objc_exception_block_stack);
2752 blk_nesting_count--;
2757 objc_declare_variable (enum rid scspec, tree name, tree type, tree init)
2761 type = tree_cons (NULL_TREE, type,
2762 tree_cons (NULL_TREE, ridpointers[(int) scspec],
2764 TREE_STATIC (type) = 1;
2765 decl = start_decl (name, type, (init != NULL_TREE), NULL_TREE);
2766 finish_decl (decl, init, NULL_TREE);
2767 /* This prevents `unused variable' warnings when compiling with -Wall. */
2768 TREE_USED (decl) = 1;
2769 DECL_ARTIFICIAL (decl) = 1;
2774 objc_build_throw_stmt (tree throw_expr)
2778 if (!flag_objc_exceptions)
2779 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2781 if (!throw_expr && objc_caught_exception)
2782 throw_expr = TREE_VALUE (objc_caught_exception);
2786 error ("`@throw;' (rethrow) used outside of a `@catch' block");
2787 return error_mark_node;
2790 func_params = tree_cons (NULL_TREE, throw_expr, NULL_TREE);
2792 assemble_external (objc_exception_throw_decl);
2793 return c_expand_expr_stmt (build_function_call (objc_exception_throw_decl,
2798 val_stack_push (struct val_stack **nc, long val)
2800 struct val_stack *new_elem = xmalloc (sizeof (struct val_stack));
2801 new_elem->val = val;
2802 new_elem->next = *nc;
2807 val_stack_pop (struct val_stack **nc)
2809 struct val_stack *old_elem = *nc;
2810 *nc = old_elem->next;
2815 objc_build_try_enter_fragment (void)
2817 /* objc_exception_try_enter(&_stackExceptionData);
2818 if (!_setjmp(&_stackExceptionData.buf)) { */
2820 tree func_params, if_stmt, cond;
2823 = tree_cons (NULL_TREE,
2824 build_unary_op (ADDR_EXPR,
2825 TREE_VALUE (objc_stack_exception_data),
2829 assemble_external (objc_exception_try_enter_decl);
2830 c_expand_expr_stmt (build_function_call
2831 (objc_exception_try_enter_decl, func_params));
2833 if_stmt = c_begin_if_stmt ();
2835 /* If <setjmp.h> has been included, the _setjmp prototype has
2836 acquired a real, breathing type for its parameter. Cast our
2837 argument to that type. */
2839 = tree_cons (NULL_TREE,
2840 build_c_cast (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))
2841 ? TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
2845 build_component_ref (TREE_VALUE (objc_stack_exception_data),
2846 get_identifier ("buf")), 0)),
2848 assemble_external (objc_setjmp_decl);
2849 cond = build_unary_op (TRUTH_NOT_EXPR,
2850 build_function_call (objc_setjmp_decl, func_params),
2852 c_expand_start_cond (c_common_truthvalue_conversion (cond),
2854 objc_enter_block ();
2858 objc_build_extract_expr (void)
2860 /* ... = objc_exception_extract(&_stackExceptionData); */
2863 = tree_cons (NULL_TREE,
2864 build_unary_op (ADDR_EXPR,
2865 TREE_VALUE (objc_stack_exception_data), 0),
2868 assemble_external (objc_exception_extract_decl);
2869 return build_function_call (objc_exception_extract_decl, func_params);
2873 objc_build_try_exit_fragment (void)
2875 /* objc_exception_try_exit(&_stackExceptionData); */
2878 = tree_cons (NULL_TREE,
2879 build_unary_op (ADDR_EXPR,
2880 TREE_VALUE (objc_stack_exception_data), 0),
2883 assemble_external (objc_exception_try_exit_decl);
2884 c_expand_expr_stmt (build_function_call (objc_exception_try_exit_decl,
2889 objc_build_extract_fragment (void)
2892 _rethrowException = objc_exception_extract(&_stackExceptionData);
2898 c_expand_start_else ();
2899 objc_enter_block ();
2900 c_expand_expr_stmt (build_modify_expr
2901 (TREE_VALUE (objc_rethrow_exception),
2903 objc_build_extract_expr ()));
2906 c_expand_end_cond ();
2911 objc_build_try_prologue (void)
2914 struct _objc_exception_data _stackExceptionData;
2915 volatile id _rethrowException = nil;
2916 { // begin TRY-CATCH scope
2917 objc_exception_try_enter(&_stackExceptionData);
2918 if (!_setjmp(&_stackExceptionData.buf)) { */
2920 tree try_catch_block;
2922 if (!flag_objc_exceptions)
2923 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2925 objc_mark_locals_volatile ((void *)(exc_binding_stack
2926 ? exc_binding_stack->val
2928 objc_enter_block ();
2929 objc_stack_exception_data
2930 = tree_cons (NULL_TREE,
2931 objc_declare_variable (RID_AUTO,
2932 get_identifier (UTAG_EXCDATA_VAR),
2933 xref_tag (RECORD_TYPE,
2934 get_identifier (UTAG_EXCDATA)),
2936 objc_stack_exception_data);
2937 objc_rethrow_exception = tree_cons (NULL_TREE,
2938 objc_declare_variable (RID_VOLATILE,
2939 get_identifier (UTAG_RETHROWEXC_VAR),
2941 build_int_2 (0, 0)),
2942 objc_rethrow_exception);
2944 try_catch_block = objc_enter_block ();
2945 val_stack_push (&exc_binding_stack, (long) get_current_scope ());
2946 objc_build_try_enter_fragment ();
2948 return try_catch_block;
2952 objc_build_try_epilogue (int also_catch_prologue)
2954 if (also_catch_prologue)
2957 register id _caughtException = objc_exception_extract( &_stackExceptionData);
2958 objc_exception_try_enter(&_stackExceptionData);
2959 if(!_setjmp(&_stackExceptionData.buf)) {
2967 c_expand_start_else ();
2968 objc_enter_block ();
2969 objc_caught_exception
2970 = tree_cons (NULL_TREE,
2971 objc_declare_variable (RID_REGISTER,
2972 get_identifier (UTAG_CAUGHTEXC_VAR),
2974 objc_build_extract_expr ()),
2975 objc_caught_exception);
2976 objc_build_try_enter_fragment ();
2977 val_stack_push (&catch_count_stack, 1);
2978 if_stmt = c_begin_if_stmt ();
2980 c_expand_start_cond (c_common_truthvalue_conversion (boolean_false_node),
2982 objc_enter_block ();
2984 /* Start a new chain of @catch statements for this @try. */
2985 objc_catch_type = tree_cons (objc_catch_type, NULL_TREE, NULL_TREE);
2988 { /* !also_catch_prologue */
2991 _rethrowException = objc_exception_extract( &_stackExceptionData);
2994 objc_build_extract_fragment ();
3000 objc_build_catch_stmt (tree catch_expr)
3002 /* } else if (objc_exception_match(objc_get_class("SomeClass"), _caughtException)) {
3003 register SomeClass *e = _caughtException; */
3005 tree if_stmt, cond, func_params, prev_catch, var_name, var_type;
3009 /* Yet another C/C++ impedance mismatch. */
3010 catch_expr = TREE_PURPOSE (catch_expr);
3013 var_name = TREE_VALUE (catch_expr);
3014 var_type = TREE_VALUE (TREE_PURPOSE (catch_expr));
3015 if (TREE_CODE (var_name) == INDIRECT_REF)
3016 var_name = TREE_OPERAND (var_name, 0);
3017 if (TREE_CODE (var_type) == TYPE_DECL
3018 || TREE_CODE (var_type) == POINTER_TYPE)
3019 var_type = TREE_TYPE (var_type);
3020 catch_id = (var_type == TREE_TYPE (id_type));
3022 if (!flag_objc_exceptions)
3023 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3025 if (!(catch_id || TYPED_OBJECT (var_type)))
3026 fatal_error ("`@catch' parameter is not a known Objective-C class type");
3028 /* Examine previous @catch clauses for the current @try block for
3029 superclasses of the 'var_type' class. */
3030 for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch);
3031 prev_catch = TREE_CHAIN (prev_catch))
3033 if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
3035 warning ("Exception already handled by preceding `@catch(id)'");
3039 && objc_comptypes (TREE_VALUE (prev_catch), var_type, 0) == 1)
3040 warning ("Exception of type `%s *' already handled by `@catch (%s *)'",
3041 IDENTIFIER_POINTER (OBJC_TYPE_NAME (var_type)),
3042 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_VALUE (prev_catch))));
3045 objc_catch_type = tree_cons (NULL_TREE, var_type, objc_catch_type);
3050 c_expand_start_else ();
3051 catch_count_stack->val++;
3052 if_stmt = c_begin_if_stmt ();
3056 cond = integer_one_node;
3059 cond = get_class_reference (OBJC_TYPE_NAME (var_type));
3062 = tree_cons (NULL_TREE, cond,
3063 tree_cons (NULL_TREE,
3064 TREE_VALUE (objc_caught_exception),
3066 assemble_external (objc_exception_match_decl);
3067 cond = build_function_call (objc_exception_match_decl, func_params);
3070 c_expand_start_cond (c_common_truthvalue_conversion (cond),
3072 objc_enter_block ();
3073 objc_declare_variable (RID_REGISTER, var_name,
3074 build_pointer_type (var_type),
3075 TREE_VALUE (objc_caught_exception));
3079 objc_build_catch_epilogue (void)
3082 _rethrowException = _caughtException;
3083 objc_exception_try_exit(&_stackExceptionData);
3086 _rethrowException = objc_exception_extract(&_stackExceptionData);
3089 } // end TRY-CATCH scope
3095 c_expand_start_else ();
3096 objc_enter_block ();
3099 (TREE_VALUE (objc_rethrow_exception),
3101 TREE_VALUE (objc_caught_exception)));
3102 objc_build_try_exit_fragment ();
3104 while (catch_count_stack->val--)
3106 c_finish_else (); /* close off all the nested ifs ! */
3107 c_expand_end_cond ();
3110 val_stack_pop (&catch_count_stack);
3111 objc_caught_exception = TREE_CHAIN (objc_caught_exception);
3113 objc_build_extract_fragment ();
3117 c_expand_end_cond ();
3121 /* Return to enclosing chain of @catch statements (if any). */
3122 while (TREE_VALUE (objc_catch_type))
3123 objc_catch_type = TREE_CHAIN (objc_catch_type);
3124 objc_catch_type = TREE_PURPOSE (objc_catch_type);
3128 objc_build_finally_prologue ()
3130 /* { // begin FINALLY scope
3131 if (!_rethrowException) {
3132 objc_exception_try_exit(&_stackExceptionData);
3135 tree blk = objc_enter_block ();
3137 tree if_stmt = c_begin_if_stmt ();
3140 c_expand_start_cond (c_common_truthvalue_conversion
3143 TREE_VALUE (objc_rethrow_exception), 0)),
3145 objc_enter_block ();
3146 objc_build_try_exit_fragment ();
3149 c_expand_end_cond ();
3156 objc_build_finally_epilogue (void)
3158 /* if (_rethrowException) {
3159 objc_exception_throw(_rethrowException);
3161 } // end FINALLY scope
3164 tree if_stmt = c_begin_if_stmt ();
3168 (c_common_truthvalue_conversion (TREE_VALUE (objc_rethrow_exception)),
3170 objc_enter_block ();
3171 objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception));
3174 c_expand_end_cond ();
3178 objc_rethrow_exception = TREE_CHAIN (objc_rethrow_exception);
3179 objc_stack_exception_data = TREE_CHAIN (objc_stack_exception_data);
3181 val_stack_pop (&exc_binding_stack);
3182 return objc_exit_block ();
3186 objc_build_try_catch_finally_stmt (int has_catch, int has_finally)
3188 /* NB: The operative assumption here is that TRY_FINALLY_EXPR will
3189 deal with all exits from 'try_catch_blk' and route them through
3191 tree outer_blk = objc_build_finally_epilogue ();
3192 tree prec_stmt = TREE_CHAIN (TREE_CHAIN (COMPOUND_BODY (outer_blk)));
3193 tree try_catch_blk = TREE_CHAIN (prec_stmt), try_catch_expr;
3194 tree finally_blk = TREE_CHAIN (try_catch_blk), finally_expr;
3195 tree succ_stmt = TREE_CHAIN (finally_blk);
3196 tree try_finally_stmt, try_finally_expr;
3198 if (!flag_objc_exceptions)
3199 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3201 /* It is an error to have a @try block without a @catch and/or @finally
3202 (even though sensible code can be generated nonetheless). */
3204 if (!has_catch && !has_finally)
3205 error ("`@try' without `@catch' or `@finally'");
3207 /* We shall now do something truly disgusting. We shall remove the
3208 'try_catch_blk' and 'finally_blk' from the 'outer_blk' statement
3209 chain, and replace them with a TRY_FINALLY_EXPR statement! If
3210 this doesn't work, we will have to learn (from Per/gcj) how to
3211 construct the 'outer_blk' lazily. */
3213 TREE_CHAIN (try_catch_blk) = TREE_CHAIN (finally_blk) = NULL_TREE;
3214 try_catch_expr = build1 (STMT_EXPR, void_type_node, try_catch_blk);
3215 TREE_SIDE_EFFECTS (try_catch_expr) = 1;
3216 finally_expr = build1 (STMT_EXPR, void_type_node, finally_blk);
3217 TREE_SIDE_EFFECTS (finally_expr) = 1;
3218 try_finally_expr = build (TRY_FINALLY_EXPR, void_type_node, try_catch_expr,
3220 TREE_SIDE_EFFECTS (try_finally_expr) = 1;
3221 try_finally_stmt = build_stmt (EXPR_STMT, try_finally_expr);
3222 TREE_CHAIN (prec_stmt) = try_finally_stmt;
3223 TREE_CHAIN (try_finally_stmt) = succ_stmt;
3225 return outer_blk; /* the whole enchilada */
3229 objc_build_synchronized_prologue (tree sync_expr)
3232 id _eval_once = <sync_expr>;
3234 objc_sync_enter( _eval_once ); */
3238 if (!flag_objc_exceptions)
3239 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3241 objc_enter_block ();
3243 = tree_cons (NULL_TREE,
3244 objc_declare_variable (RID_AUTO,
3245 get_identifier (UTAG_EVALONCE_VAR),
3249 objc_build_try_prologue ();
3250 objc_enter_block ();
3251 func_params = tree_cons (NULL_TREE,
3252 TREE_VALUE (objc_eval_once),
3255 assemble_external (objc_sync_enter_decl);
3256 c_expand_expr_stmt (build_function_call
3257 (objc_sync_enter_decl, func_params));
3261 objc_build_synchronized_epilogue (void)
3265 objc_sync_exit( _eval_once );
3272 objc_build_try_epilogue (0);
3273 objc_build_finally_prologue ();
3274 func_params = tree_cons (NULL_TREE, TREE_VALUE (objc_eval_once),
3277 assemble_external (objc_sync_exit_decl);
3278 c_expand_expr_stmt (build_function_call (objc_sync_exit_decl,
3280 objc_build_try_catch_finally_stmt (0, 1);
3282 return objc_exit_block ();
3285 /* Predefine the following data type:
3287 struct _objc_exception_data
3293 /* The following yuckiness should prevent users from having to #include
3294 <setjmp.h> in their code... */
3296 #ifdef TARGET_POWERPC
3297 /* snarfed from /usr/include/ppc/setjmp.h */
3298 #define _JBLEN (26 + 36 + 129 + 1)
3300 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3305 build_objc_exception_stuff (void)
3307 tree field_decl, field_decl_chain, index, temp_type;
3309 /* Suppress outputting debug symbols, because
3310 dbxout_init hasn't been called yet. */
3311 enum debug_info_type save_write_symbols = write_symbols;
3312 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3314 write_symbols = NO_DEBUG;
3315 debug_hooks = &do_nothing_debug_hooks;
3316 objc_exception_data_template
3317 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3319 /* int buf[_JBLEN]; */
3321 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3322 field_decl = create_builtin_decl (FIELD_DECL,
3323 build_array_type (integer_type_node, index),
3325 field_decl_chain = field_decl;
3327 /* void *pointers[4]; */
3329 index = build_index_type (build_int_2 (4 - 1, 0));
3330 field_decl = create_builtin_decl (FIELD_DECL,
3331 build_array_type (ptr_type_node, index),
3333 chainon (field_decl_chain, field_decl);
3335 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3337 /* int _setjmp(...); */
3338 /* If the user includes <setjmp.h>, this shall be superceded by
3339 'int _setjmp(jmp_buf);' */
3340 temp_type = build_function_type (integer_type_node, NULL_TREE);
3342 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3344 /* id objc_exception_extract(struct _objc_exception_data *); */
3346 = build_function_type (id_type,
3347 tree_cons (NULL_TREE,
3348 build_pointer_type (objc_exception_data_template),
3350 objc_exception_extract_decl
3351 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3352 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3353 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3355 = build_function_type (void_type_node,
3356 tree_cons (NULL_TREE,
3357 build_pointer_type (objc_exception_data_template),
3359 objc_exception_try_enter_decl
3360 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3361 objc_exception_try_exit_decl
3362 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3363 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3364 /* void objc_sync_enter(id); */
3365 /* void objc_sync_exit(id); */
3366 temp_type = build_function_type (void_type_node,
3367 tree_cons (NULL_TREE, id_type,
3369 objc_exception_throw_decl
3370 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3371 DECL_ATTRIBUTES (objc_exception_throw_decl)
3372 = tree_cons (get_identifier ("noreturn"), NULL_TREE, NULL_TREE);
3373 objc_sync_enter_decl
3374 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3376 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3377 /* int objc_exception_match(id, id); */
3378 temp_type = build_function_type (integer_type_node,
3379 tree_cons (NULL_TREE, id_type,
3380 tree_cons (NULL_TREE, id_type,
3381 OBJC_VOID_AT_END)));
3382 objc_exception_match_decl
3383 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3385 write_symbols = save_write_symbols;
3386 debug_hooks = save_hooks;
3389 /* struct <classname> {
3390 struct objc_class *isa;
3395 build_private_template (tree class)
3399 if (CLASS_STATIC_TEMPLATE (class))
3401 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3402 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3406 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3407 ivar_context = get_class_ivars (class, 0);
3409 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3411 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3413 /* mark this record as class template - for class type checking */
3414 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3418 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3420 build1 (INDIRECT_REF, NULL_TREE,
3423 return ivar_context;
3426 /* Begin code generation for protocols... */
3428 /* struct objc_protocol {
3429 char *protocol_name;
3430 struct objc_protocol **protocol_list;
3431 struct objc_method_desc *instance_methods;
3432 struct objc_method_desc *class_methods;
3436 build_protocol_template (void)
3438 tree decl_specs, field_decl, field_decl_chain;
3441 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3443 /* struct objc_class *isa; */
3445 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3446 get_identifier (UTAG_CLASS)));
3447 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3448 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3449 field_decl_chain = field_decl;
3451 /* char *protocol_name; */
3453 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3455 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3456 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3457 chainon (field_decl_chain, field_decl);
3459 /* struct objc_protocol **protocol_list; */
3461 decl_specs = build_tree_list (NULL_TREE, template);
3463 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3464 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3465 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3466 chainon (field_decl_chain, field_decl);
3468 /* struct objc_method_list *instance_methods; */
3471 = build_tree_list (NULL_TREE,
3472 xref_tag (RECORD_TYPE,
3473 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3475 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3476 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3477 chainon (field_decl_chain, field_decl);
3479 /* struct objc_method_list *class_methods; */
3482 = build_tree_list (NULL_TREE,
3483 xref_tag (RECORD_TYPE,
3484 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3486 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3487 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3488 chainon (field_decl_chain, field_decl);
3490 return finish_struct (template, field_decl_chain, NULL_TREE);
3494 build_descriptor_table_initializer (tree type, tree entries)
3496 tree initlist = NULL_TREE;
3500 tree eltlist = NULL_TREE;
3503 = tree_cons (NULL_TREE,
3504 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3506 = tree_cons (NULL_TREE,
3507 add_objc_string (METHOD_ENCODING (entries),
3512 = tree_cons (NULL_TREE,
3513 objc_build_constructor (type, nreverse (eltlist)),
3516 entries = TREE_CHAIN (entries);
3520 return objc_build_constructor (build_array_type (type, 0),
3521 nreverse (initlist));
3524 /* struct objc_method_prototype_list {
3526 struct objc_method_prototype {
3533 build_method_prototype_list_template (tree list_type, int size)
3535 tree objc_ivar_list_record;
3536 tree decl_specs, field_decl, field_decl_chain;
3538 /* Generate an unnamed struct definition. */
3540 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3542 /* int method_count; */
3544 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3545 field_decl = get_identifier ("method_count");
3546 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3547 field_decl_chain = field_decl;
3549 /* struct objc_method method_list[]; */
3551 decl_specs = build_tree_list (NULL_TREE, list_type);
3552 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3553 build_int_2 (size, 0));
3554 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3555 chainon (field_decl_chain, field_decl);
3557 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3559 return objc_ivar_list_record;
3563 build_method_prototype_template (void)
3566 tree decl_specs, field_decl, field_decl_chain;
3569 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3571 /* struct objc_selector *_cmd; */
3572 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3573 get_identifier (TAG_SELECTOR)), NULL_TREE);
3574 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3575 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3576 field_decl_chain = field_decl;
3578 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3580 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3581 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3582 chainon (field_decl_chain, field_decl);
3584 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3586 return proto_record;
3590 objc_method_parm_type (tree type)
3592 type = groktypename (TREE_TYPE (type));
3593 if (TREE_CODE (type) == TYPE_DECL)
3594 type = TREE_TYPE (type);
3595 return TYPE_MAIN_VARIANT (type);
3599 objc_encoded_type_size (tree type)
3601 int sz = int_size_in_bytes (type);
3603 /* Make all integer and enum types at least as large
3605 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3606 || TREE_CODE (type) == BOOLEAN_TYPE
3607 || TREE_CODE (type) == ENUMERAL_TYPE))
3608 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3609 /* Treat arrays as pointers, since that's how they're
3611 else if (TREE_CODE (type) == ARRAY_TYPE)
3612 sz = int_size_in_bytes (ptr_type_node);
3617 encode_method_prototype (tree method_decl)
3624 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3625 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3627 /* Encode return type. */
3628 encode_type (objc_method_parm_type (method_decl),
3629 obstack_object_size (&util_obstack),
3630 OBJC_ENCODE_INLINE_DEFS);
3633 /* The first two arguments (self and _cmd) are pointers; account for
3635 i = int_size_in_bytes (ptr_type_node);
3636 parm_offset = 2 * i;
3637 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3638 parms = TREE_CHAIN (parms))
3640 tree type = objc_method_parm_type (parms);
3641 int sz = objc_encoded_type_size (type);
3643 /* If a type size is not known, bail out. */
3646 error ("%Jtype '%D' does not have a known size",
3648 /* Pretend that the encoding succeeded; the compilation will
3649 fail nevertheless. */
3650 goto finish_encoding;
3655 sprintf (buf, "%d@0:%d", parm_offset, i);
3656 obstack_grow (&util_obstack, buf, strlen (buf));
3658 /* Argument types. */
3659 parm_offset = 2 * i;
3660 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3661 parms = TREE_CHAIN (parms))
3663 tree type = objc_method_parm_type (parms);
3665 /* Process argument qualifiers for user supplied arguments. */
3666 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3669 encode_type (type, obstack_object_size (&util_obstack),
3670 OBJC_ENCODE_INLINE_DEFS);
3672 /* Compute offset. */
3673 sprintf (buf, "%d", parm_offset);
3674 parm_offset += objc_encoded_type_size (type);
3676 obstack_grow (&util_obstack, buf, strlen (buf));
3680 obstack_1grow (&util_obstack, '\0');
3681 result = get_identifier (obstack_finish (&util_obstack));
3682 obstack_free (&util_obstack, util_firstobj);
3687 generate_descriptor_table (tree type, const char *name, int size, tree list,
3690 tree sc_spec, decl_specs, decl, initlist;
3692 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3693 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3695 decl = start_decl (synth_id_with_class_suffix (name, proto),
3696 decl_specs, 1, NULL_TREE);
3697 DECL_CONTEXT (decl) = NULL_TREE;
3699 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3700 initlist = tree_cons (NULL_TREE, list, initlist);
3702 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3709 generate_method_descriptors (tree protocol)
3711 tree initlist, chain, method_list_template;
3712 tree cast, variable_length_type;
3715 if (!objc_method_prototype_template)
3716 objc_method_prototype_template = build_method_prototype_template ();
3718 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3719 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3721 variable_length_type = groktypename (cast);
3723 chain = PROTOCOL_CLS_METHODS (protocol);
3726 size = list_length (chain);
3728 method_list_template
3729 = build_method_prototype_list_template (objc_method_prototype_template,
3733 = build_descriptor_table_initializer (objc_method_prototype_template,
3736 UOBJC_CLASS_METHODS_decl
3737 = generate_descriptor_table (method_list_template,
3738 "_OBJC_PROTOCOL_CLASS_METHODS",
3739 size, initlist, protocol);
3740 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3743 UOBJC_CLASS_METHODS_decl = 0;
3745 chain = PROTOCOL_NST_METHODS (protocol);
3748 size = list_length (chain);
3750 method_list_template
3751 = build_method_prototype_list_template (objc_method_prototype_template,
3754 = build_descriptor_table_initializer (objc_method_prototype_template,
3757 UOBJC_INSTANCE_METHODS_decl
3758 = generate_descriptor_table (method_list_template,
3759 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3760 size, initlist, protocol);
3761 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3764 UOBJC_INSTANCE_METHODS_decl = 0;
3768 generate_protocol_references (tree plist)
3772 /* Forward declare protocols referenced. */
3773 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3775 tree proto = TREE_VALUE (lproto);
3777 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3778 && PROTOCOL_NAME (proto))
3780 if (! PROTOCOL_FORWARD_DECL (proto))
3781 build_protocol_reference (proto);
3783 if (PROTOCOL_LIST (proto))
3784 generate_protocol_references (PROTOCOL_LIST (proto));
3789 /* For each protocol which was referenced either from a @protocol()
3790 expression, or because a class/category implements it (then a
3791 pointer to the protocol is stored in the struct describing the
3792 class/category), we create a statically allocated instance of the
3793 Protocol class. The code is written in such a way as to generate
3794 as few Protocol objects as possible; we generate a unique Protocol
3795 instance for each protocol, and we don't generate a Protocol
3796 instance if the protocol is never referenced (either from a
3797 @protocol() or from a class/category implementation). These
3798 statically allocated objects can be referred to via the static
3799 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3801 The statically allocated Protocol objects that we generate here
3802 need to be fixed up at runtime in order to be used: the 'isa'
3803 pointer of the objects need to be set up to point to the 'Protocol'
3804 class, as known at runtime.
3806 The NeXT runtime fixes up all protocols at program startup time,
3807 before main() is entered. It uses a low-level trick to look up all
3808 those symbols, then loops on them and fixes them up.
3810 The GNU runtime as well fixes up all protocols before user code
3811 from the module is executed; it requires pointers to those symbols
3812 to be put in the objc_symtab (which is then passed as argument to
3813 the function __objc_exec_class() which the compiler sets up to be
3814 executed automatically when the module is loaded); setup of those
3815 Protocol objects happen in two ways in the GNU runtime: all
3816 Protocol objects referred to by a class or category implementation
3817 are fixed up when the class/category is loaded; all Protocol
3818 objects referred to by a @protocol() expression are added by the
3819 compiler to the list of statically allocated instances to fixup
3820 (the same list holding the statically allocated constant string
3821 objects). Because, as explained above, the compiler generates as
3822 few Protocol objects as possible, some Protocol object might end up
3823 being referenced multiple times when compiled with the GNU runtime,
3824 and end up being fixed up multiple times at runtime inizialization.
3825 But that doesn't hurt, it's just a little inefficient. */
3828 generate_protocols (void)
3831 tree sc_spec, decl_specs, decl;
3832 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3835 if (! objc_protocol_template)
3836 objc_protocol_template = build_protocol_template ();
3838 /* If a protocol was directly referenced, pull in indirect references. */
3839 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3840 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3841 generate_protocol_references (PROTOCOL_LIST (p));
3843 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3845 tree nst_methods = PROTOCOL_NST_METHODS (p);
3846 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3848 /* If protocol wasn't referenced, don't generate any code. */
3849 if (! PROTOCOL_FORWARD_DECL (p))
3852 /* Make sure we link in the Protocol class. */
3853 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3857 if (! METHOD_ENCODING (nst_methods))
3859 encoding = encode_method_prototype (nst_methods);
3860 METHOD_ENCODING (nst_methods) = encoding;
3862 nst_methods = TREE_CHAIN (nst_methods);
3867 if (! METHOD_ENCODING (cls_methods))
3869 encoding = encode_method_prototype (cls_methods);
3870 METHOD_ENCODING (cls_methods) = encoding;
3873 cls_methods = TREE_CHAIN (cls_methods);
3875 generate_method_descriptors (p);
3877 if (PROTOCOL_LIST (p))
3878 refs_decl = generate_protocol_list (p);
3882 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3884 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3886 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3888 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3889 decl_specs, 1, NULL_TREE);
3891 DECL_CONTEXT (decl) = NULL_TREE;
3893 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3899 (build_tree_list (build_tree_list (NULL_TREE,
3900 objc_protocol_template),
3901 build1 (INDIRECT_REF, NULL_TREE,
3902 build1 (INDIRECT_REF, NULL_TREE,
3905 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3906 TREE_TYPE (refs_expr) = cast_type2;
3909 refs_expr = build_int_2 (0, 0);
3911 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3912 by generate_method_descriptors, which is called above. */
3913 initlist = build_protocol_initializer (TREE_TYPE (decl),
3914 protocol_name_expr, refs_expr,
3915 UOBJC_INSTANCE_METHODS_decl,
3916 UOBJC_CLASS_METHODS_decl);
3917 finish_decl (decl, initlist, NULL_TREE);
3919 /* Mark the decl as used to avoid "defined but not used" warning. */
3920 TREE_USED (decl) = 1;
3925 build_protocol_initializer (tree type, tree protocol_name,
3926 tree protocol_list, tree instance_methods,
3929 tree initlist = NULL_TREE, expr;
3932 cast_type = groktypename
3934 (build_tree_list (NULL_TREE,
3935 xref_tag (RECORD_TYPE,
3936 get_identifier (UTAG_CLASS))),
3937 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3939 /* Filling the "isa" in with one allows the runtime system to
3940 detect that the version change...should remove before final release. */
3942 expr = build_int_2 (PROTOCOL_VERSION, 0);
3943 TREE_TYPE (expr) = cast_type;
3944 initlist = tree_cons (NULL_TREE, expr, initlist);
3945 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3946 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3948 if (!instance_methods)
3949 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3952 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3953 initlist = tree_cons (NULL_TREE, expr, initlist);
3957 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3960 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3961 initlist = tree_cons (NULL_TREE, expr, initlist);
3964 return objc_build_constructor (type, nreverse (initlist));
3967 /* struct objc_category {
3968 char *category_name;
3970 struct objc_method_list *instance_methods;
3971 struct objc_method_list *class_methods;
3972 struct objc_protocol_list *protocols;
3976 build_category_template (void)
3978 tree decl_specs, field_decl, field_decl_chain;
3980 objc_category_template = start_struct (RECORD_TYPE,
3981 get_identifier (UTAG_CATEGORY));
3982 /* char *category_name; */
3984 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3986 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3987 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3988 field_decl_chain = field_decl;
3990 /* char *class_name; */
3992 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3993 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3994 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3995 chainon (field_decl_chain, field_decl);
3997 /* struct objc_method_list *instance_methods; */
3999 decl_specs = build_tree_list (NULL_TREE,
4000 xref_tag (RECORD_TYPE,
4001 get_identifier (UTAG_METHOD_LIST)));
4003 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
4004 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4005 chainon (field_decl_chain, field_decl);
4007 /* struct objc_method_list *class_methods; */
4009 decl_specs = build_tree_list (NULL_TREE,
4010 xref_tag (RECORD_TYPE,
4011 get_identifier (UTAG_METHOD_LIST)));
4013 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
4014 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4015 chainon (field_decl_chain, field_decl);
4017 /* struct objc_protocol **protocol_list; */
4019 decl_specs = build_tree_list (NULL_TREE,
4020 xref_tag (RECORD_TYPE,
4021 get_identifier (UTAG_PROTOCOL)));
4023 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4024 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4025 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4026 chainon (field_decl_chain, field_decl);
4028 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4031 /* struct objc_selector {
4037 build_selector_template (void)
4040 tree decl_specs, field_decl, field_decl_chain;
4042 objc_selector_template
4043 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4047 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4048 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4049 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4050 field_decl_chain = field_decl;
4052 /* char *sel_type; */
4054 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4055 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4056 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4057 chainon (field_decl_chain, field_decl);
4059 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4062 /* struct objc_class {
4063 struct objc_class *isa;
4064 struct objc_class *super_class;
4069 struct objc_ivar_list *ivars;
4070 struct objc_method_list *methods;
4071 if (flag_next_runtime)
4072 struct objc_cache *cache;
4074 struct sarray *dtable;
4075 struct objc_class *subclass_list;
4076 struct objc_class *sibling_class;
4078 struct objc_protocol_list *protocols;
4079 if (flag_next_runtime)
4081 void *gc_object_type;
4084 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4085 the NeXT/Apple runtime; still, the compiler must generate them to
4086 maintain backward binary compatibility (and to allow for future
4090 build_class_template (void)
4092 tree decl_specs, field_decl, field_decl_chain;
4095 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4097 /* struct objc_class *isa; */
4099 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4100 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4101 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4102 field_decl_chain = field_decl;
4104 /* struct objc_class *super_class; */
4106 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4108 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4109 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4110 chainon (field_decl_chain, field_decl);
4114 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4115 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4116 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4117 chainon (field_decl_chain, field_decl);
4121 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4122 field_decl = get_identifier ("version");
4123 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4124 chainon (field_decl_chain, field_decl);
4128 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4129 field_decl = get_identifier ("info");
4130 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4131 chainon (field_decl_chain, field_decl);
4133 /* long instance_size; */
4135 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4136 field_decl = get_identifier ("instance_size");
4137 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4138 chainon (field_decl_chain, field_decl);
4140 /* struct objc_ivar_list *ivars; */
4142 decl_specs = build_tree_list (NULL_TREE,
4143 xref_tag (RECORD_TYPE,
4144 get_identifier (UTAG_IVAR_LIST)));
4145 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4146 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4147 chainon (field_decl_chain, field_decl);
4149 /* struct objc_method_list *methods; */
4151 decl_specs = build_tree_list (NULL_TREE,
4152 xref_tag (RECORD_TYPE,
4153 get_identifier (UTAG_METHOD_LIST)));
4154 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4155 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4156 chainon (field_decl_chain, field_decl);
4158 if (flag_next_runtime)
4160 /* struct objc_cache *cache; */
4162 decl_specs = build_tree_list (NULL_TREE,
4163 xref_tag (RECORD_TYPE,
4164 get_identifier ("objc_cache")));
4165 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4166 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4167 chainon (field_decl_chain, field_decl);
4171 /* struct sarray *dtable; */
4173 decl_specs = build_tree_list (NULL_TREE,
4174 xref_tag (RECORD_TYPE,
4175 get_identifier ("sarray")));
4176 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4177 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4178 chainon (field_decl_chain, field_decl);
4180 /* struct objc_class *subclass_list; */
4182 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4184 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4185 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4186 chainon (field_decl_chain, field_decl);
4188 /* struct objc_class *sibling_class; */
4190 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4192 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4193 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4194 chainon (field_decl_chain, field_decl);
4197 /* struct objc_protocol **protocol_list; */
4199 decl_specs = build_tree_list (NULL_TREE,
4200 xref_tag (RECORD_TYPE,
4201 get_identifier (UTAG_PROTOCOL)));
4203 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4205 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4206 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4207 chainon (field_decl_chain, field_decl);
4209 if (flag_next_runtime)
4213 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4214 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4216 = grokfield (field_decl, decl_specs, NULL_TREE);
4217 chainon (field_decl_chain, field_decl);
4220 /* void *gc_object_type; */
4222 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4223 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4224 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4225 chainon (field_decl_chain, field_decl);
4227 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4230 /* Generate appropriate forward declarations for an implementation. */
4233 synth_forward_declarations (void)
4237 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4238 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4239 objc_class_template);
4241 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4242 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4243 objc_class_template);
4245 /* Pre-build the following entities - for speed/convenience. */
4247 an_id = get_identifier ("super_class");
4248 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4249 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4253 error_with_ivar (const char *message, tree decl, tree rawdecl)
4255 error ("%J%s `%s'", decl,
4256 message, gen_declaration (rawdecl, errbuf));
4261 check_ivars (tree inter, tree imp)
4263 tree intdecls = CLASS_IVARS (inter);
4264 tree impdecls = CLASS_IVARS (imp);
4265 tree rawintdecls = CLASS_RAW_IVARS (inter);
4266 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4273 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4274 intdecls = TREE_CHAIN (intdecls);
4276 if (intdecls == 0 && impdecls == 0)
4278 if (intdecls == 0 || impdecls == 0)
4280 error ("inconsistent instance variable specification");
4284 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4286 if (!comptypes (t1, t2, false)
4287 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4288 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4290 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4292 error_with_ivar ("conflicting instance variable type",
4293 impdecls, rawimpdecls);
4294 error_with_ivar ("previous declaration of",
4295 intdecls, rawintdecls);
4297 else /* both the type and the name don't match */
4299 error ("inconsistent instance variable specification");
4304 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4306 error_with_ivar ("conflicting instance variable name",
4307 impdecls, rawimpdecls);
4308 error_with_ivar ("previous declaration of",
4309 intdecls, rawintdecls);
4312 intdecls = TREE_CHAIN (intdecls);
4313 impdecls = TREE_CHAIN (impdecls);
4314 rawintdecls = TREE_CHAIN (rawintdecls);
4315 rawimpdecls = TREE_CHAIN (rawimpdecls);
4319 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4320 This needs to be done just once per compilation. */
4323 build_super_template (void)
4325 tree decl_specs, field_decl, field_decl_chain;
4327 /* Suppress outputting debug symbols, because
4328 dbxout_init hasn't been called yet. */
4329 enum debug_info_type save_write_symbols = write_symbols;
4330 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4332 write_symbols = NO_DEBUG;
4333 debug_hooks = &do_nothing_debug_hooks;
4335 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4337 /* struct objc_object *self; */
4339 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4340 field_decl = get_identifier ("self");
4341 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4342 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4343 field_decl_chain = field_decl;
4345 /* struct objc_class *class; */
4347 decl_specs = get_identifier (UTAG_CLASS);
4348 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4349 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4351 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4352 chainon (field_decl_chain, field_decl);
4354 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4356 write_symbols = save_write_symbols;
4357 debug_hooks = save_hooks;
4360 /* struct objc_ivar {
4367 build_ivar_template (void)
4369 tree objc_ivar_id, objc_ivar_record;
4370 tree decl_specs, field_decl, field_decl_chain;
4372 objc_ivar_id = get_identifier (UTAG_IVAR);
4373 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4375 /* char *ivar_name; */
4377 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4378 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4380 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4381 field_decl_chain = field_decl;
4383 /* char *ivar_type; */
4385 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4386 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4388 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4389 chainon (field_decl_chain, field_decl);
4391 /* int ivar_offset; */
4393 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4394 field_decl = get_identifier ("ivar_offset");
4396 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4397 chainon (field_decl_chain, field_decl);
4399 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4401 return objc_ivar_record;
4406 struct objc_ivar ivar_list[ivar_count];
4410 build_ivar_list_template (tree list_type, int size)
4412 tree objc_ivar_list_record;
4413 tree decl_specs, field_decl, field_decl_chain;
4415 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4417 /* int ivar_count; */
4419 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4420 field_decl = get_identifier ("ivar_count");
4422 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4423 field_decl_chain = field_decl;
4425 /* struct objc_ivar ivar_list[]; */
4427 decl_specs = build_tree_list (NULL_TREE, list_type);
4428 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4429 build_int_2 (size, 0));
4431 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4432 chainon (field_decl_chain, field_decl);
4434 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4436 return objc_ivar_list_record;
4442 struct objc_method method_list[method_count];
4446 build_method_list_template (tree list_type, int size)
4448 tree objc_ivar_list_record;
4449 tree decl_specs, field_decl, field_decl_chain;
4451 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4453 /* int method_next; */
4458 xref_tag (RECORD_TYPE,
4459 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4461 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4462 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4463 field_decl_chain = field_decl;
4465 /* int method_count; */
4467 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4468 field_decl = get_identifier ("method_count");
4470 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4471 chainon (field_decl_chain, field_decl);
4473 /* struct objc_method method_list[]; */
4475 decl_specs = build_tree_list (NULL_TREE, list_type);
4476 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4477 build_int_2 (size, 0));
4479 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4480 chainon (field_decl_chain, field_decl);
4482 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4484 return objc_ivar_list_record;
4488 build_ivar_list_initializer (tree type, tree field_decl)
4490 tree initlist = NULL_TREE;
4494 tree ivar = NULL_TREE;
4497 if (DECL_NAME (field_decl))
4498 ivar = tree_cons (NULL_TREE,
4499 add_objc_string (DECL_NAME (field_decl),
4503 /* Unnamed bit-field ivar (yuck). */
4504 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4507 encode_field_decl (field_decl,
4508 obstack_object_size (&util_obstack),
4509 OBJC_ENCODE_DONT_INLINE_DEFS);
4511 /* Null terminate string. */
4512 obstack_1grow (&util_obstack, 0);
4516 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4519 obstack_free (&util_obstack, util_firstobj);
4522 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4523 initlist = tree_cons (NULL_TREE,
4524 objc_build_constructor (type, nreverse (ivar)),
4527 field_decl = TREE_CHAIN (field_decl);
4528 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4532 return objc_build_constructor (build_array_type (type, 0),
4533 nreverse (initlist));
4537 generate_ivars_list (tree type, const char *name, int size, tree list)
4539 tree sc_spec, decl_specs, decl, initlist;
4541 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4542 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4544 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4545 decl_specs, 1, NULL_TREE);
4547 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4548 initlist = tree_cons (NULL_TREE, list, initlist);
4551 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4557 /* Count only the fields occurring in T. */
4559 ivar_list_length (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 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5071 generate_category (tree cat)
5073 tree sc_spec, decl_specs, decl;
5074 tree initlist, cat_name_expr, class_name_expr;
5075 tree protocol_decl, category;
5077 add_class_reference (CLASS_NAME (cat));
5078 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5080 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5082 category = CLASS_CATEGORY_LIST (implementation_template);
5084 /* find the category interface from the class it is associated with */
5087 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5089 category = CLASS_CATEGORY_LIST (category);
5092 if (category && CLASS_PROTOCOL_LIST (category))
5094 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5095 protocol_decl = generate_protocol_list (category);
5100 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5101 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5103 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5104 objc_implementation_context),
5105 decl_specs, 1, NULL_TREE);
5107 initlist = build_category_initializer (TREE_TYPE (decl),
5108 cat_name_expr, class_name_expr,
5109 UOBJC_INSTANCE_METHODS_decl,
5110 UOBJC_CLASS_METHODS_decl,
5113 finish_decl (decl, initlist, NULL_TREE);
5116 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5117 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5120 generate_shared_structures (void)
5122 tree sc_spec, decl_specs, decl;
5123 tree name_expr, super_expr, root_expr;
5124 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5125 tree cast_type, initlist, protocol_decl;
5127 my_super_id = CLASS_SUPER_NAME (implementation_template);
5130 add_class_reference (my_super_id);
5132 /* Compute "my_root_id" - this is required for code generation.
5133 the "isa" for all meta class structures points to the root of
5134 the inheritance hierarchy (e.g. "__Object")... */
5135 my_root_id = my_super_id;
5138 tree my_root_int = lookup_interface (my_root_id);
5140 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5141 my_root_id = CLASS_SUPER_NAME (my_root_int);
5148 /* No super class. */
5149 my_root_id = CLASS_NAME (implementation_template);
5152 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5153 objc_class_template),
5154 build1 (INDIRECT_REF,
5155 NULL_TREE, NULL_TREE)));
5157 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5160 /* Install class `isa' and `super' pointers at runtime. */
5163 super_expr = add_objc_string (my_super_id, class_names);
5164 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5167 super_expr = build_int_2 (0, 0);
5169 root_expr = add_objc_string (my_root_id, class_names);
5170 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5172 if (CLASS_PROTOCOL_LIST (implementation_template))
5174 generate_protocol_references
5175 (CLASS_PROTOCOL_LIST (implementation_template));
5176 protocol_decl = generate_protocol_list (implementation_template);
5181 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5183 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5184 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5186 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5190 = build_shared_structure_initializer
5192 root_expr, super_expr, name_expr,
5193 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5195 UOBJC_CLASS_METHODS_decl,
5196 UOBJC_CLASS_VARIABLES_decl,
5199 finish_decl (decl, initlist, NULL_TREE);
5201 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5203 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5207 = build_shared_structure_initializer
5209 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5210 super_expr, name_expr,
5211 convert (integer_type_node,
5212 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5213 (implementation_template))),
5215 UOBJC_INSTANCE_METHODS_decl,
5216 UOBJC_INSTANCE_VARIABLES_decl,
5219 finish_decl (decl, initlist, NULL_TREE);
5223 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5226 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5227 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5229 const char *const class_name
5230 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5231 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5232 sprintf (string, "%s_%s", preamble,
5233 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5235 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5236 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5238 /* We have a category. */
5239 const char *const class_name
5240 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5241 const char *const class_super_name
5242 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5243 string = (char *) alloca (strlen (preamble)
5244 + strlen (class_name)
5245 + strlen (class_super_name)
5247 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5249 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5251 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5253 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5254 sprintf (string, "%s_%s", preamble, protocol_name);
5259 return get_identifier (string);
5263 is_objc_type_qualifier (tree node)
5265 return (TREE_CODE (node) == IDENTIFIER_NODE
5266 && (node == ridpointers [(int) RID_CONST]
5267 || node == ridpointers [(int) RID_VOLATILE]
5268 || node == ridpointers [(int) RID_IN]
5269 || node == ridpointers [(int) RID_OUT]
5270 || node == ridpointers [(int) RID_INOUT]
5271 || node == ridpointers [(int) RID_BYCOPY]
5272 || node == ridpointers [(int) RID_BYREF]
5273 || node == ridpointers [(int) RID_ONEWAY]));
5276 /* If type is empty or only type qualifiers are present, add default
5277 type of id (otherwise grokdeclarator will default to int). */
5280 adjust_type_for_id_default (tree type)
5282 tree declspecs, chain;
5285 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5286 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5288 declspecs = TREE_PURPOSE (type);
5290 /* Determine if a typespec is present. */
5291 for (chain = declspecs;
5293 chain = TREE_CHAIN (chain))
5295 if (TYPED_OBJECT (TREE_VALUE (chain))
5296 && !(TREE_VALUE (type)
5297 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5298 error ("can not use an object as parameter to a method\n");
5299 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5303 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5305 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5310 selector ':' '(' typename ')' identifier
5313 Transform an Objective-C keyword argument into
5314 the C equivalent parameter declarator.
5316 In: key_name, an "identifier_node" (optional).
5317 arg_type, a "tree_list" (optional).
5318 arg_name, an "identifier_node".
5320 Note: It would be really nice to strongly type the preceding
5321 arguments in the function prototype; however, then I
5322 could not use the "accessor" macros defined in "tree.h".
5324 Out: an instance of "keyword_decl". */
5327 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5331 /* If no type is specified, default to "id". */
5332 arg_type = adjust_type_for_id_default (arg_type);
5334 keyword_decl = make_node (KEYWORD_DECL);
5336 TREE_TYPE (keyword_decl) = arg_type;
5337 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5338 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5340 return keyword_decl;
5343 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5346 build_keyword_selector (tree selector)
5349 tree key_chain, key_name;
5352 /* Scan the selector to see how much space we'll need. */
5353 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5355 if (TREE_CODE (selector) == KEYWORD_DECL)
5356 key_name = KEYWORD_KEY_NAME (key_chain);
5357 else if (TREE_CODE (selector) == TREE_LIST)
5358 key_name = TREE_PURPOSE (key_chain);
5363 len += IDENTIFIER_LENGTH (key_name) + 1;
5365 /* Just a ':' arg. */
5369 buf = (char *) alloca (len + 1);
5370 /* Start the buffer out as an empty string. */
5373 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5375 if (TREE_CODE (selector) == KEYWORD_DECL)
5376 key_name = KEYWORD_KEY_NAME (key_chain);
5377 else if (TREE_CODE (selector) == TREE_LIST)
5379 key_name = TREE_PURPOSE (key_chain);
5380 /* The keyword decl chain will later be used as a function argument
5381 chain. Unhook the selector itself so as to not confuse other
5382 parts of the compiler. */
5383 TREE_PURPOSE (key_chain) = NULL_TREE;
5389 strcat (buf, IDENTIFIER_POINTER (key_name));
5393 return get_identifier (buf);
5396 /* Used for declarations and definitions. */
5399 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5404 /* If no type is specified, default to "id". */
5405 ret_type = adjust_type_for_id_default (ret_type);
5407 method_decl = make_node (code);
5408 TREE_TYPE (method_decl) = ret_type;
5410 /* If we have a keyword selector, create an identifier_node that
5411 represents the full selector name (`:' included)... */
5412 if (TREE_CODE (selector) == KEYWORD_DECL)
5414 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5415 METHOD_SEL_ARGS (method_decl) = selector;
5416 METHOD_ADD_ARGS (method_decl) = add_args;
5420 METHOD_SEL_NAME (method_decl) = selector;
5421 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5422 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5428 #define METHOD_DEF 0
5429 #define METHOD_REF 1
5431 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5432 an argument list for method METH. CONTEXT is either METHOD_DEF or
5433 METHOD_REF, saying whether we are trying to define a method or call
5434 one. SUPERFLAG says this is for a send to super; this makes a
5435 difference for the NeXT calling sequence in which the lookup and
5436 the method call are done together. If METH is null, user-defined
5437 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5440 get_arg_type_list (tree meth, int context, int superflag)
5444 /* Receiver type. */
5445 if (flag_next_runtime && superflag)
5446 arglist = build_tree_list (NULL_TREE, super_type);
5447 else if (context == METHOD_DEF)
5448 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5450 arglist = build_tree_list (NULL_TREE, id_type);
5452 /* Selector type - will eventually change to `int'. */
5453 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
5455 /* No actual method prototype given -- assume that remaining arguments
5460 /* Build a list of argument types. */
5461 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5463 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5464 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5467 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5468 /* We have a `, ...' immediately following the selector,
5469 finalize the arglist...simulate get_parm_info (0). */
5471 else if (METHOD_ADD_ARGS (meth))
5473 /* we have a variable length selector */
5474 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5475 chainon (arglist, add_arg_list);
5478 /* finalize the arglist...simulate get_parm_info (1) */
5479 chainon (arglist, OBJC_VOID_AT_END);
5485 check_duplicates (hash hsh, int methods)
5487 tree meth = NULL_TREE;
5495 /* We have two or more methods with the same name but
5498 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
5500 warning ("multiple %s named `%c%s' found",
5501 methods ? "methods" : "selectors", type,
5502 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5504 warn_with_method (methods ? "using" : "found", type, meth);
5505 for (loop = hsh->list; loop; loop = loop->next)
5506 warn_with_method ("also found", type, loop->value);
5512 /* If RECEIVER is a class reference, return the identifier node for
5513 the referenced class. RECEIVER is created by get_class_reference,
5514 so we check the exact form created depending on which runtimes are
5518 receiver_is_class_object (tree receiver, int self, int super)
5520 tree chain, exp, arg;
5522 /* The receiver is 'self' or 'super' in the context of a class method. */
5523 if (objc_method_context
5524 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5527 ? CLASS_SUPER_NAME (implementation_template)
5528 : CLASS_NAME (implementation_template));
5530 if (flag_next_runtime)
5532 /* The receiver is a variable created by
5533 build_class_reference_decl. */
5534 if (TREE_CODE (receiver) == VAR_DECL
5535 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5536 /* Look up the identifier. */
5537 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5538 if (TREE_PURPOSE (chain) == receiver)
5539 return TREE_VALUE (chain);
5542 /* The receiver is a function call that returns an id. Check if
5543 it is a call to objc_getClass, if so, pick up the class name. */
5544 if (TREE_CODE (receiver) == CALL_EXPR
5545 && (exp = TREE_OPERAND (receiver, 0))
5546 && TREE_CODE (exp) == ADDR_EXPR
5547 && (exp = TREE_OPERAND (exp, 0))
5548 && TREE_CODE (exp) == FUNCTION_DECL
5549 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5550 prototypes for objc_get_class(). Thankfuly, they seem to share the
5551 same function type. */
5552 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5553 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5554 /* We have a call to objc_get_class/objc_getClass! */
5555 && (arg = TREE_OPERAND (receiver, 1))
5556 && TREE_CODE (arg) == TREE_LIST
5557 && (arg = TREE_VALUE (arg)))
5560 if (TREE_CODE (arg) == ADDR_EXPR
5561 && (arg = TREE_OPERAND (arg, 0))
5562 && TREE_CODE (arg) == STRING_CST)
5563 /* Finally, we have the class name. */
5564 return get_identifier (TREE_STRING_POINTER (arg));
5569 /* If we are currently building a message expr, this holds
5570 the identifier of the selector of the message. This is
5571 used when printing warnings about argument mismatches. */
5573 static tree current_objc_message_selector = 0;
5576 objc_message_selector (void)
5578 return current_objc_message_selector;
5581 /* Construct an expression for sending a message.
5582 MESS has the object to send to in TREE_PURPOSE
5583 and the argument list (including selector) in TREE_VALUE.
5585 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5586 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5589 build_message_expr (tree mess)
5591 tree receiver = TREE_PURPOSE (mess);
5593 tree args = TREE_VALUE (mess);
5594 tree method_params = NULL_TREE;
5596 if (TREE_CODE (receiver) == ERROR_MARK)
5597 return error_mark_node;
5599 /* Obtain the full selector name. */
5600 if (TREE_CODE (args) == IDENTIFIER_NODE)
5601 /* A unary selector. */
5603 else if (TREE_CODE (args) == TREE_LIST)
5604 sel_name = build_keyword_selector (args);
5608 /* Build the parameter list to give to the method. */
5609 if (TREE_CODE (args) == TREE_LIST)
5611 tree chain = args, prev = NULL_TREE;
5613 /* We have a keyword selector--check for comma expressions. */
5616 tree element = TREE_VALUE (chain);
5618 /* We have a comma expression, must collapse... */
5619 if (TREE_CODE (element) == TREE_LIST)
5622 TREE_CHAIN (prev) = element;
5627 chain = TREE_CHAIN (chain);
5629 method_params = args;
5633 if (processing_template_decl)
5634 /* Must wait until template instantiation time. */
5635 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5639 return finish_message_expr (receiver, sel_name, method_params);
5643 lookup_method_in_hash_lists (tree sel_name)
5645 hash method_prototype = hash_lookup (nst_method_hash_list,
5648 if (!method_prototype)
5649 method_prototype = hash_lookup (cls_method_hash_list,
5652 return check_duplicates (method_prototype, 1);
5655 /* The 'finish_message_expr' routine is called from within
5656 'build_message_expr' for non-template functions. In the case of
5657 C++ template functions, it is called from 'build_expr_from_tree'
5658 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5661 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5663 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5664 tree selector, retval, is_class;
5665 int self, super, have_cast;
5667 /* Extract the receiver of the message, as well as its type
5668 (where the latter may take the form of a cast or be inferred
5669 from the implementation context). */
5671 while (TREE_CODE (rtype) == COMPOUND_EXPR
5672 || TREE_CODE (rtype) == MODIFY_EXPR
5673 || TREE_CODE (rtype) == NOP_EXPR
5674 || TREE_CODE (rtype) == COMPONENT_REF)
5675 rtype = TREE_OPERAND (rtype, 0);
5676 self = (rtype == self_decl);
5677 super = (rtype == UOBJC_SUPER_decl);
5678 rtype = TREE_TYPE (receiver);
5679 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5680 || (TREE_CODE (receiver) == COMPOUND_EXPR
5681 && !IS_SUPER (rtype)));
5683 /* If the receiver is a class object, retrieve the corresponding
5684 @interface, if one exists. */
5685 is_class = receiver_is_class_object (receiver, self, super);
5687 /* Now determine the receiver type (if an explicit cast has not been
5692 rtype = lookup_interface (is_class);
5693 /* Handle `self' and `super'. */
5696 if (!CLASS_SUPER_NAME (implementation_template))
5698 error ("no super class declared in @interface for `%s'",
5699 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5700 return error_mark_node;
5702 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5705 rtype = lookup_interface (CLASS_NAME (implementation_template));
5708 /* If receiver is of type `id' or `Class' (or if the @interface for a
5709 class is not visible), we shall be satisfied with the existence of
5710 any instance or class method. */
5711 if (!rtype || IS_ID (rtype)
5712 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5715 rtype = xref_tag (RECORD_TYPE, is_class);
5716 else if (IS_ID (rtype))
5718 rprotos = TYPE_PROTOCOL_LIST (rtype);
5722 is_class = TYPE_NAME (rtype) = get_identifier ("Class");
5726 = lookup_method_in_protocol_list (rprotos, sel_name,
5727 is_class != NULL_TREE);
5728 if (!method_prototype && !rprotos)
5731 ? check_duplicates (hash_lookup (cls_method_hash_list, sel_name), 1)
5732 : lookup_method_in_hash_lists (sel_name));
5736 tree orig_rtype = rtype, saved_rtype;
5738 if (TREE_CODE (rtype) == POINTER_TYPE)
5739 rtype = TREE_TYPE (rtype);
5740 /* Traverse typedef aliases */
5741 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5742 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5743 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5744 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5745 saved_rtype = rtype;
5746 if (TYPED_OBJECT (rtype))
5748 rprotos = TYPE_PROTOCOL_LIST (rtype);
5749 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5751 /* If we could not find an @interface declaration, we must have
5752 only seen a @class declaration; so, we cannot say anything
5753 more intelligent about which methods the receiver will
5756 rtype = saved_rtype;
5757 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5758 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5760 /* We have a valid ObjC class name. Look up the method name
5761 in the published @interface for the class (and its
5764 = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
5766 /* If the method was not found in the @interface, it may still
5767 exist locally as part of the @implementation. */
5768 if (!method_prototype && objc_implementation_context
5769 && CLASS_NAME (objc_implementation_context)
5770 == OBJC_TYPE_NAME (rtype))
5774 ? CLASS_CLS_METHODS (objc_implementation_context)
5775 : CLASS_NST_METHODS (objc_implementation_context)),
5778 /* If we haven't found a candidate method by now, try looking for
5779 it in the protocol list. */
5780 if (!method_prototype && rprotos)
5782 = lookup_method_in_protocol_list (rprotos, sel_name,
5783 is_class != NULL_TREE);
5787 warning ("invalid receiver type `%s'",
5788 gen_declaration (orig_rtype, errbuf));
5789 rtype = rprotos = NULL_TREE;
5793 if (!method_prototype)
5795 static bool warn_missing_methods = false;
5798 warning ("`%s' may not respond to `%c%s'",
5799 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5800 (is_class ? '+' : '-'),
5801 IDENTIFIER_POINTER (sel_name));
5803 warning ("`%c%s' not implemented by protocol(s)",
5804 (is_class ? '+' : '-'),
5805 IDENTIFIER_POINTER (sel_name));
5806 if (!warn_missing_methods)
5808 warning ("(Messages without a matching method signature");
5809 warning ("will be assumed to return `id' and accept");
5810 warning ("`...' as arguments.)");
5811 warn_missing_methods = true;
5815 /* Save the selector name for printing error messages. */
5816 current_objc_message_selector = sel_name;
5818 /* Build the parameters list for looking up the method.
5819 These are the object itself and the selector. */
5821 if (flag_typed_selectors)
5822 selector = build_typed_selector_reference (sel_name, method_prototype);
5824 selector = build_selector_reference (sel_name);
5826 retval = build_objc_method_call (super, method_prototype,
5828 selector, method_params);
5830 current_objc_message_selector = 0;
5835 /* Build a tree expression to send OBJECT the operation SELECTOR,
5836 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5837 assuming the method has prototype METHOD_PROTOTYPE.
5838 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5839 Use METHOD_PARAMS as list of args to pass to the method.
5840 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5843 build_objc_method_call (int super_flag, tree method_prototype,
5844 tree lookup_object, tree selector,
5847 tree sender = (super_flag ? umsg_super_decl :
5848 (!flag_next_runtime || flag_nil_receivers
5850 : umsg_nonnil_decl));
5851 tree rcv_p = (super_flag ? super_type : id_type);
5853 /* If a prototype for the method to be called exists, then cast
5854 the sender's return type and arguments to match that of the method.
5855 Otherwise, leave sender as is. */
5858 ? groktypename (TREE_TYPE (method_prototype))
5861 = build_pointer_type
5862 (build_function_type
5865 (method_prototype, METHOD_REF, super_flag)));
5867 lookup_object = build_c_cast (rcv_p, lookup_object);
5869 if (flag_next_runtime)
5872 /* If we are returning a struct in memory, and the address
5873 of that memory location is passed as a hidden first
5874 argument, then change which messenger entry point this
5875 expr will call. NB: Note that sender_cast remains
5876 unchanged (it already has a struct return type). */
5877 if ((TREE_CODE (ret_type) == RECORD_TYPE
5878 || TREE_CODE (ret_type) == UNION_TYPE)
5879 #if defined (DEFAULT_PCC_STRUCT_RETURN) && DEFAULT_PCC_STRUCT_RETURN == 0
5880 && RETURN_IN_MEMORY (ret_type)
5882 && STRUCT_VALUE == 0)
5883 sender = (super_flag ? umsg_super_stret_decl :
5884 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5886 method_params = tree_cons (NULL_TREE, lookup_object,
5887 tree_cons (NULL_TREE, selector,
5889 TREE_USED (sender) = 1;
5890 assemble_external (sender);
5891 /* We want to cast the sender, not convert it. */
5892 return build_function_call (build_c_cast (sender_cast, sender),
5897 /* This is the portable (GNU) way. */
5898 tree method, object;
5900 /* First, call the lookup function to get a pointer to the method,
5901 then cast the pointer, then call it with the method arguments.
5902 Use SAVE_EXPR to avoid evaluating the receiver twice. */
5903 lookup_object = save_expr (lookup_object);
5904 object = (super_flag ? self_decl : lookup_object);
5905 TREE_USED (sender) = 1;
5906 assemble_external (sender);
5908 = build_function_call (sender,
5909 tree_cons (NULL_TREE, lookup_object,
5910 tree_cons (NULL_TREE, selector,
5913 /* Pass the object to the method. */
5914 TREE_USED (method) = 1;
5915 assemble_external (method);
5916 return build_function_call
5917 (build_c_cast (sender_cast, method),
5918 tree_cons (NULL_TREE, object,
5919 tree_cons (NULL_TREE, selector, method_params)));
5924 build_protocol_reference (tree p)
5926 tree decl, ident, ptype;
5928 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5930 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5932 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5933 objc_protocol_template),
5936 if (identifier_global_value (ident))
5937 decl = identifier_global_value (ident); /* Set by pushdecl. */
5940 decl = build_decl (VAR_DECL, ident, ptype);
5941 DECL_EXTERNAL (decl) = 1;
5942 TREE_PUBLIC (decl) = 0;
5943 TREE_USED (decl) = 1;
5944 DECL_ARTIFICIAL (decl) = 1;
5946 make_decl_rtl (decl, 0);
5947 pushdecl_top_level (decl);
5950 PROTOCOL_FORWARD_DECL (p) = decl;
5953 /* This function is called by the parser when (and only when) a
5954 @protocol() expression is found, in order to compile it. */
5956 build_protocol_expr (tree protoname)
5959 tree p = lookup_protocol (protoname);
5963 error ("cannot find protocol declaration for `%s'",
5964 IDENTIFIER_POINTER (protoname));
5965 return error_mark_node;
5968 if (!PROTOCOL_FORWARD_DECL (p))
5969 build_protocol_reference (p);
5971 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5973 TREE_TYPE (expr) = protocol_type;
5975 /* The @protocol() expression is being compiled into a pointer to a
5976 statically allocated instance of the Protocol class. To become
5977 usable at runtime, the 'isa' pointer of the instance need to be
5978 fixed up at runtime by the runtime library, to point to the
5979 actual 'Protocol' class. */
5981 /* For the GNU runtime, put the static Protocol instance in the list
5982 of statically allocated instances, so that we make sure that its
5983 'isa' pointer is fixed up at runtime by the GNU runtime library
5984 to point to the Protocol class (at runtime, when loading the
5985 module, the GNU runtime library loops on the statically allocated
5986 instances (as found in the defs field in objc_symtab) and fixups
5987 all the 'isa' pointers of those objects). */
5988 if (! flag_next_runtime)
5990 /* This type is a struct containing the fields of a Protocol
5991 object. (Cfr. protocol_type instead is the type of a pointer
5992 to such a struct). */
5993 tree protocol_struct_type = xref_tag
5994 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5997 /* Look for the list of Protocol statically allocated instances
5998 to fixup at runtime. Create a new list to hold Protocol
5999 statically allocated instances, if the list is not found. At
6000 present there is only another list, holding NSConstantString
6001 static instances to be fixed up at runtime. */
6002 for (chain = &objc_static_instances;
6003 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6004 chain = &TREE_CHAIN (*chain));
6007 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6008 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6012 /* Add this statically allocated instance to the Protocol list. */
6013 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6014 PROTOCOL_FORWARD_DECL (p),
6015 TREE_PURPOSE (*chain));
6022 /* This function is called by the parser when a @selector() expression
6023 is found, in order to compile it. It is only called by the parser
6024 and only to compile a @selector(). */
6026 build_selector_expr (tree selnamelist)
6030 /* Obtain the full selector name. */
6031 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6032 /* A unary selector. */
6033 selname = selnamelist;
6034 else if (TREE_CODE (selnamelist) == TREE_LIST)
6035 selname = build_keyword_selector (selnamelist);
6039 /* If we are required to check @selector() expressions as they
6040 are found, check that the selector has been declared. */
6041 if (warn_undeclared_selector)
6043 /* Look the selector up in the list of all known class and
6044 instance methods (up to this line) to check that the selector
6048 /* First try with instance methods. */
6049 hsh = hash_lookup (nst_method_hash_list, selname);
6051 /* If not found, try with class methods. */
6054 hsh = hash_lookup (cls_method_hash_list, selname);
6057 /* If still not found, print out a warning. */
6060 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6065 if (flag_typed_selectors)
6066 return build_typed_selector_reference (selname, 0);
6068 return build_selector_reference (selname);
6072 build_encode_expr (tree type)
6077 encode_type (type, obstack_object_size (&util_obstack),
6078 OBJC_ENCODE_INLINE_DEFS);
6079 obstack_1grow (&util_obstack, 0); /* null terminate string */
6080 string = obstack_finish (&util_obstack);
6082 /* Synthesize a string that represents the encoded struct/union. */
6083 result = my_build_string (strlen (string) + 1, string);
6084 obstack_free (&util_obstack, util_firstobj);
6089 build_ivar_reference (tree id)
6091 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6093 /* Historically, a class method that produced objects (factory
6094 method) would assign `self' to the instance that it
6095 allocated. This would effectively turn the class method into
6096 an instance method. Following this assignment, the instance
6097 variables could be accessed. That practice, while safe,
6098 violates the simple rule that a class method should not refer
6099 to an instance variable. It's better to catch the cases
6100 where this is done unknowingly than to support the above
6102 warning ("instance variable `%s' accessed in class method",
6103 IDENTIFIER_POINTER (id));
6104 TREE_TYPE (self_decl) = instance_type; /* cast */
6107 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6110 /* Compute a hash value for a given method SEL_NAME. */
6113 hash_func (tree sel_name)
6115 const unsigned char *s
6116 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6120 h = h * 67 + *s++ - 113;
6127 nst_method_hash_list
6128 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6129 cls_method_hash_list
6130 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6133 /* WARNING!!!! hash_enter is called with a method, and will peek
6134 inside to find its selector! But hash_lookup is given a selector
6135 directly, and looks for the selector that's inside the found
6136 entry's key (method) for comparison. */
6139 hash_enter (hash *hashlist, tree method)
6142 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6144 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6146 obj->next = hashlist[slot];
6149 hashlist[slot] = obj; /* append to front */
6153 hash_lookup (hash *hashlist, tree sel_name)
6157 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6161 if (sel_name == METHOD_SEL_NAME (target->key))
6164 target = target->next;
6170 hash_add_attr (hash entry, tree value)
6174 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6175 obj->next = entry->list;
6178 entry->list = obj; /* append to front */
6182 lookup_method (tree mchain, tree method)
6186 if (TREE_CODE (method) == IDENTIFIER_NODE)
6189 key = METHOD_SEL_NAME (method);
6193 if (METHOD_SEL_NAME (mchain) == key)
6196 mchain = TREE_CHAIN (mchain);
6202 lookup_method_static (tree interface, tree ident, int is_class)
6204 tree meth = NULL_TREE, root_inter = NULL_TREE;
6205 tree inter = interface;
6209 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6210 tree category = inter;
6212 /* First, look up the method in the class itself. */
6213 if ((meth = lookup_method (chain, ident)))
6216 /* Failing that, look for the method in each category of the class. */
6217 while ((category = CLASS_CATEGORY_LIST (category)))
6219 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6221 /* Check directly in each category. */
6222 if ((meth = lookup_method (chain, ident)))
6225 /* Failing that, check in each category's protocols. */
6226 if (CLASS_PROTOCOL_LIST (category))
6228 if ((meth = (lookup_method_in_protocol_list
6229 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6234 /* If not found in categories, check in protocols of the main class. */
6235 if (CLASS_PROTOCOL_LIST (inter))
6237 if ((meth = (lookup_method_in_protocol_list
6238 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6242 /* Failing that, climb up the inheritance hierarchy. */
6244 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6248 /* If no class (factory) method was found, check if an _instance_
6249 method of the same name exists in the root class. This is what
6250 the Objective-C runtime will do. If an instance method was not
6252 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6256 add_method (tree class, tree method, int is_class)
6261 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6263 /* put method on list in reverse order */
6266 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6267 CLASS_CLS_METHODS (class) = method;
6271 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6272 CLASS_NST_METHODS (class) = method;
6277 /* When processing an @interface for a class or category, give hard errors on methods with
6278 identical selectors but differing argument and/or return types. We do not do this for
6279 @implementations, because C/C++ will do it for us (i.e., there will be
6280 duplicate function definition errors). */
6281 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6282 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6283 && !comp_proto_with_proto (method, mth))
6284 error ("duplicate declaration of method `%c%s'",
6285 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6288 if (!(hsh = hash_lookup (is_class
6289 ? cls_method_hash_list
6290 : nst_method_hash_list, METHOD_SEL_NAME (method))))
6292 /* Install on a global chain. */
6293 hash_enter (is_class ? cls_method_hash_list : nst_method_hash_list, method);
6297 /* Check types against those; if different, add to a list. */
6299 int already_there = comp_proto_with_proto (method, hsh->key);
6300 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6301 already_there |= comp_proto_with_proto (method, loop->value);
6303 hash_add_attr (hsh, method);
6309 add_class (tree class)
6311 /* Put interfaces on list in reverse order. */
6312 TREE_CHAIN (class) = interface_chain;
6313 interface_chain = class;
6314 return interface_chain;
6318 add_category (tree class, tree category)
6320 /* Put categories on list in reverse order. */
6321 tree cat = CLASS_CATEGORY_LIST (class);
6325 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
6327 error ("duplicate interface declaration for category `%s(%s)'",
6329 warning ("duplicate interface declaration for category `%s(%s)'",
6331 IDENTIFIER_POINTER (CLASS_NAME (class)),
6332 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6333 cat = CLASS_CATEGORY_LIST (cat);
6336 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6337 CLASS_CATEGORY_LIST (class) = category;
6340 /* Called after parsing each instance variable declaration. Necessary to
6341 preserve typedefs and implement public/private...
6343 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6346 add_instance_variable (tree class, int public, tree declarator,
6347 tree declspecs, tree width)
6349 tree field_decl = grokfield (declarator, declspecs, width);
6350 tree field_type = TREE_TYPE (field_decl);
6351 const char *ivar_name = DECL_NAME (field_decl)
6352 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6357 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6359 error ("illegal reference type specified for instance variable `%s'",
6361 /* Return class as is without adding this ivar. */
6366 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6367 || TYPE_SIZE (field_type) == error_mark_node
6368 /* 'type[0]' is allowed, but 'type[]' is not! */
6370 || (TYPE_SIZE (field_type) == bitsize_zero_node
6371 && !TREE_OPERAND (declarator, 1))
6375 error ("instance variable `%s' has unknown size", ivar_name);
6376 /* Return class as is without adding this ivar. */
6381 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6382 cannot be ivars; ditto for classes with vtables. */
6383 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6384 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6386 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6387 if(TYPE_POLYMORPHIC_P (field_type)) {
6388 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6389 error ("type `%s' has virtual member functions", type_name);
6390 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6391 type_name, ivar_name);
6392 /* Return class as is without adding this ivar. */
6395 /* user-defined constructors and destructors are not known to Obj-C and
6396 hence will not be called. This may or may not be a problem. */
6397 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6398 warning ("type `%s' has a user-defined constructor", type_name);
6399 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6400 warning ("type `%s' has a user-defined destructor", type_name);
6401 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6405 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6409 TREE_PUBLIC (field_decl) = 0;
6410 TREE_PRIVATE (field_decl) = 0;
6411 TREE_PROTECTED (field_decl) = 1;
6415 TREE_PUBLIC (field_decl) = 1;
6416 TREE_PRIVATE (field_decl) = 0;
6417 TREE_PROTECTED (field_decl) = 0;
6421 TREE_PUBLIC (field_decl) = 0;
6422 TREE_PRIVATE (field_decl) = 1;
6423 TREE_PROTECTED (field_decl) = 0;
6428 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6429 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6430 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6435 is_ivar (tree decl_chain, tree ident)
6437 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6438 if (DECL_NAME (decl_chain) == ident)
6443 /* True if the ivar is private and we are not in its implementation. */
6446 is_private (tree decl)
6448 if (TREE_PRIVATE (decl)
6449 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
6451 error ("instance variable `%s' is declared private",
6452 IDENTIFIER_POINTER (DECL_NAME (decl)));
6459 /* We have an instance variable reference;, check to see if it is public. */
6462 is_public (tree expr, tree identifier)
6464 tree basetype = TREE_TYPE (expr);
6465 enum tree_code code = TREE_CODE (basetype);
6468 if (code == RECORD_TYPE)
6470 if (TREE_STATIC_TEMPLATE (basetype))
6472 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6474 error ("cannot find interface declaration for `%s'",
6475 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6479 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6481 if (TREE_PUBLIC (decl))
6484 /* Important difference between the Stepstone translator:
6485 all instance variables should be public within the context
6486 of the implementation. */
6487 if (objc_implementation_context
6488 && (((TREE_CODE (objc_implementation_context)
6489 == CLASS_IMPLEMENTATION_TYPE)
6490 || (TREE_CODE (objc_implementation_context)
6491 == CATEGORY_IMPLEMENTATION_TYPE))
6492 && (CLASS_NAME (objc_implementation_context)
6493 == OBJC_TYPE_NAME (basetype))))
6494 return ! is_private (decl);
6496 /* The 2.95.2 compiler sometimes allowed C functions to access
6497 non-@public ivars. We will let this slide for now... */
6498 if (!objc_method_context)
6500 warning ("instance variable `%s' is %s; "
6501 "this will be a hard error in the future",
6502 IDENTIFIER_POINTER (identifier),
6503 TREE_PRIVATE (decl) ? "@private" : "@protected");
6507 error ("instance variable `%s' is declared %s",
6508 IDENTIFIER_POINTER (identifier),
6509 TREE_PRIVATE (decl) ? "private" : "protected");
6514 else if (objc_implementation_context && (basetype == objc_object_reference))
6516 TREE_TYPE (expr) = uprivate_record;
6517 warning ("static access to object of type `id'");
6524 /* Make sure all entries in CHAIN are also in LIST. */
6527 check_methods (tree chain, tree list, int mtype)
6533 if (!lookup_method (list, chain))
6537 if (TREE_CODE (objc_implementation_context)
6538 == CLASS_IMPLEMENTATION_TYPE)
6539 warning ("incomplete implementation of class `%s'",
6540 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6541 else if (TREE_CODE (objc_implementation_context)
6542 == CATEGORY_IMPLEMENTATION_TYPE)
6543 warning ("incomplete implementation of category `%s'",
6544 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6548 warning ("method definition for `%c%s' not found",
6549 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6552 chain = TREE_CHAIN (chain);
6558 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6561 conforms_to_protocol (tree class, tree protocol)
6563 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6565 tree p = CLASS_PROTOCOL_LIST (class);
6566 while (p && TREE_VALUE (p) != protocol)
6571 tree super = (CLASS_SUPER_NAME (class)
6572 ? lookup_interface (CLASS_SUPER_NAME (class))
6574 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6583 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6584 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6587 check_methods_accessible (tree chain, tree context, int mtype)
6591 tree base_context = context;
6595 context = base_context;
6599 list = CLASS_CLS_METHODS (context);
6601 list = CLASS_NST_METHODS (context);
6603 if (lookup_method (list, chain))
6606 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6607 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6608 context = (CLASS_SUPER_NAME (context)
6609 ? lookup_interface (CLASS_SUPER_NAME (context))
6612 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6613 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6614 context = (CLASS_NAME (context)
6615 ? lookup_interface (CLASS_NAME (context))
6621 if (context == NULL_TREE)
6625 if (TREE_CODE (objc_implementation_context)
6626 == CLASS_IMPLEMENTATION_TYPE)
6627 warning ("incomplete implementation of class `%s'",
6629 (CLASS_NAME (objc_implementation_context)));
6630 else if (TREE_CODE (objc_implementation_context)
6631 == CATEGORY_IMPLEMENTATION_TYPE)
6632 warning ("incomplete implementation of category `%s'",
6634 (CLASS_SUPER_NAME (objc_implementation_context)));
6637 warning ("method definition for `%c%s' not found",
6638 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6641 chain = TREE_CHAIN (chain); /* next method... */
6646 /* Check whether the current interface (accessible via
6647 'objc_implementation_context') actually implements protocol P, along
6648 with any protocols that P inherits. */
6651 check_protocol (tree p, const char *type, const char *name)
6653 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6657 /* Ensure that all protocols have bodies! */
6660 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6661 CLASS_CLS_METHODS (objc_implementation_context),
6663 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6664 CLASS_NST_METHODS (objc_implementation_context),
6669 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6670 objc_implementation_context,
6672 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6673 objc_implementation_context,
6678 warning ("%s `%s' does not fully implement the `%s' protocol",
6679 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6682 /* Check protocols recursively. */
6683 if (PROTOCOL_LIST (p))
6685 tree subs = PROTOCOL_LIST (p);
6687 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6691 tree sub = TREE_VALUE (subs);
6693 /* If the superclass does not conform to the protocols
6694 inherited by P, then we must! */
6695 if (!super_class || !conforms_to_protocol (super_class, sub))
6696 check_protocol (sub, type, name);
6697 subs = TREE_CHAIN (subs);
6702 /* Check whether the current interface (accessible via
6703 'objc_implementation_context') actually implements the protocols listed
6707 check_protocols (tree proto_list, const char *type, const char *name)
6709 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6711 tree p = TREE_VALUE (proto_list);
6713 check_protocol (p, type, name);
6717 /* Make sure that the class CLASS_NAME is defined
6718 CODE says which kind of thing CLASS_NAME ought to be.
6719 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6720 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6723 start_class (enum tree_code code, tree class_name, tree super_name,
6729 if (current_namespace != global_namespace) {
6730 error ("Objective-C declarations may only appear in global scope");
6732 #endif /* OBJCPLUS */
6734 if (objc_implementation_context)
6736 warning ("`@end' missing in implementation context");
6737 finish_class (objc_implementation_context);
6738 objc_ivar_chain = NULL_TREE;
6739 objc_implementation_context = NULL_TREE;
6742 class = make_node (code);
6743 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6745 CLASS_NAME (class) = class_name;
6746 CLASS_SUPER_NAME (class) = super_name;
6747 CLASS_CLS_METHODS (class) = NULL_TREE;
6749 if (! is_class_name (class_name)
6750 && (decl = lookup_name (class_name)))
6752 error ("`%s' redeclared as different kind of symbol",
6753 IDENTIFIER_POINTER (class_name));
6754 error ("%Jprevious declaration of '%D'",
6758 if (code == CLASS_IMPLEMENTATION_TYPE)
6763 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6764 if (TREE_VALUE (chain) == class_name)
6766 error ("reimplementation of class `%s'",
6767 IDENTIFIER_POINTER (class_name));
6768 return error_mark_node;
6770 implemented_classes = tree_cons (NULL_TREE, class_name,
6771 implemented_classes);
6774 /* Reset for multiple classes per file. */
6777 objc_implementation_context = class;
6779 /* Lookup the interface for this implementation. */
6781 if (!(implementation_template = lookup_interface (class_name)))
6783 warning ("cannot find interface declaration for `%s'",
6784 IDENTIFIER_POINTER (class_name));
6785 add_class (implementation_template = objc_implementation_context);
6788 /* If a super class has been specified in the implementation,
6789 insure it conforms to the one specified in the interface. */
6792 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6794 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6795 const char *const name =
6796 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6797 error ("conflicting super class name `%s'",
6798 IDENTIFIER_POINTER (super_name));
6799 error ("previous declaration of `%s'", name);
6802 else if (! super_name)
6804 CLASS_SUPER_NAME (objc_implementation_context)
6805 = CLASS_SUPER_NAME (implementation_template);
6809 else if (code == CLASS_INTERFACE_TYPE)
6811 if (lookup_interface (class_name))
6813 error ("duplicate interface declaration for class `%s'",
6815 warning ("duplicate interface declaration for class `%s'",
6817 IDENTIFIER_POINTER (class_name));
6822 CLASS_PROTOCOL_LIST (class)
6823 = lookup_and_install_protocols (protocol_list);
6826 else if (code == CATEGORY_INTERFACE_TYPE)
6828 tree class_category_is_assoc_with;
6830 /* For a category, class_name is really the name of the class that
6831 the following set of methods will be associated with. We must
6832 find the interface so that can derive the objects template. */
6834 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6836 error ("cannot find interface declaration for `%s'",
6837 IDENTIFIER_POINTER (class_name));
6838 exit (FATAL_EXIT_CODE);
6841 add_category (class_category_is_assoc_with, class);
6844 CLASS_PROTOCOL_LIST (class)
6845 = lookup_and_install_protocols (protocol_list);
6848 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6850 /* Reset for multiple classes per file. */
6853 objc_implementation_context = class;
6855 /* For a category, class_name is really the name of the class that
6856 the following set of methods will be associated with. We must
6857 find the interface so that can derive the objects template. */
6859 if (!(implementation_template = lookup_interface (class_name)))
6861 error ("cannot find interface declaration for `%s'",
6862 IDENTIFIER_POINTER (class_name));
6863 exit (FATAL_EXIT_CODE);
6870 continue_class (tree class)
6872 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6873 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6875 struct imp_entry *imp_entry;
6878 /* Check consistency of the instance variables. */
6880 if (CLASS_IVARS (class))
6881 check_ivars (implementation_template, class);
6883 /* code generation */
6885 ivar_context = build_private_template (implementation_template);
6887 if (!objc_class_template)
6888 build_class_template ();
6890 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6892 imp_entry->next = imp_list;
6893 imp_entry->imp_context = class;
6894 imp_entry->imp_template = implementation_template;
6896 synth_forward_declarations ();
6897 imp_entry->class_decl = UOBJC_CLASS_decl;
6898 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6900 /* Append to front and increment count. */
6901 imp_list = imp_entry;
6902 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6907 return ivar_context;
6910 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6912 if (!CLASS_STATIC_TEMPLATE (class))
6914 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6915 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6916 CLASS_STATIC_TEMPLATE (class) = record;
6918 /* Mark this record as a class template for static typing. */
6919 TREE_STATIC_TEMPLATE (record) = 1;
6926 return error_mark_node;
6929 /* This is called once we see the "@end" in an interface/implementation. */
6932 finish_class (tree class)
6934 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6936 /* All code generation is done in finish_objc. */
6938 if (implementation_template != objc_implementation_context)
6940 /* Ensure that all method listed in the interface contain bodies. */
6941 check_methods (CLASS_CLS_METHODS (implementation_template),
6942 CLASS_CLS_METHODS (objc_implementation_context), '+');
6943 check_methods (CLASS_NST_METHODS (implementation_template),
6944 CLASS_NST_METHODS (objc_implementation_context), '-');
6946 if (CLASS_PROTOCOL_LIST (implementation_template))
6947 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6949 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6953 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6955 tree category = CLASS_CATEGORY_LIST (implementation_template);
6957 /* Find the category interface from the class it is associated with. */
6960 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6962 category = CLASS_CATEGORY_LIST (category);
6967 /* Ensure all method listed in the interface contain bodies. */
6968 check_methods (CLASS_CLS_METHODS (category),
6969 CLASS_CLS_METHODS (objc_implementation_context), '+');
6970 check_methods (CLASS_NST_METHODS (category),
6971 CLASS_NST_METHODS (objc_implementation_context), '-');
6973 if (CLASS_PROTOCOL_LIST (category))
6974 check_protocols (CLASS_PROTOCOL_LIST (category),
6976 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6980 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6983 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6984 char *string = (char *) alloca (strlen (class_name) + 3);
6986 /* extern struct objc_object *_<my_name>; */
6988 sprintf (string, "_%s", class_name);
6990 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6991 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6992 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6998 add_protocol (tree protocol)
7000 /* Put protocol on list in reverse order. */
7001 TREE_CHAIN (protocol) = protocol_chain;
7002 protocol_chain = protocol;
7003 return protocol_chain;
7007 lookup_protocol (tree ident)
7011 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7012 if (ident == PROTOCOL_NAME (chain))
7018 /* This function forward declares the protocols named by NAMES. If
7019 they are already declared or defined, the function has no effect. */
7022 objc_declare_protocols (tree names)
7027 if (current_namespace != global_namespace) {
7028 error ("Objective-C declarations may only appear in global scope");
7030 #endif /* OBJCPLUS */
7032 for (list = names; list; list = TREE_CHAIN (list))
7034 tree name = TREE_VALUE (list);
7036 if (lookup_protocol (name) == NULL_TREE)
7038 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7040 TYPE_BINFO (protocol) = make_tree_vec (2);
7041 PROTOCOL_NAME (protocol) = name;
7042 PROTOCOL_LIST (protocol) = NULL_TREE;
7043 add_protocol (protocol);
7044 PROTOCOL_DEFINED (protocol) = 0;
7045 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7051 start_protocol (enum tree_code code, tree name, tree list)
7056 if (current_namespace != global_namespace) {
7057 error ("Objective-C declarations may only appear in global scope");
7059 #endif /* OBJCPLUS */
7061 /* This is as good a place as any. Need to invoke
7062 push_tag_toplevel. */
7063 if (!objc_protocol_template)
7064 objc_protocol_template = build_protocol_template ();
7066 protocol = lookup_protocol (name);
7070 protocol = make_node (code);
7071 TYPE_BINFO (protocol) = make_tree_vec (2);
7073 PROTOCOL_NAME (protocol) = name;
7074 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7075 add_protocol (protocol);
7076 PROTOCOL_DEFINED (protocol) = 1;
7077 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7079 check_protocol_recursively (protocol, list);
7081 else if (! PROTOCOL_DEFINED (protocol))
7083 PROTOCOL_DEFINED (protocol) = 1;
7084 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7086 check_protocol_recursively (protocol, list);
7090 warning ("duplicate declaration for protocol `%s'",
7091 IDENTIFIER_POINTER (name));
7097 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7102 /* "Encode" a data type into a string, which grows in util_obstack.
7103 ??? What is the FORMAT? Someone please document this! */
7106 encode_type_qualifiers (tree declspecs)
7110 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7112 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7113 obstack_1grow (&util_obstack, 'r');
7114 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7115 obstack_1grow (&util_obstack, 'n');
7116 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7117 obstack_1grow (&util_obstack, 'N');
7118 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7119 obstack_1grow (&util_obstack, 'o');
7120 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7121 obstack_1grow (&util_obstack, 'O');
7122 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7123 obstack_1grow (&util_obstack, 'R');
7124 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7125 obstack_1grow (&util_obstack, 'V');
7129 /* Encode a pointer type. */
7132 encode_pointer (tree type, int curtype, int format)
7134 tree pointer_to = TREE_TYPE (type);
7136 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7138 if (OBJC_TYPE_NAME (pointer_to)
7139 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7141 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7143 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7145 obstack_1grow (&util_obstack, '@');
7148 else if (TREE_STATIC_TEMPLATE (pointer_to))
7150 if (generating_instance_variables)
7152 obstack_1grow (&util_obstack, '@');
7153 obstack_1grow (&util_obstack, '"');
7154 obstack_grow (&util_obstack, name, strlen (name));
7155 obstack_1grow (&util_obstack, '"');
7160 obstack_1grow (&util_obstack, '@');
7164 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7166 obstack_1grow (&util_obstack, '#');
7169 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7171 obstack_1grow (&util_obstack, ':');
7176 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7177 && TYPE_MODE (pointer_to) == QImode)
7179 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7180 ? OBJC_TYPE_NAME (pointer_to)
7181 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7183 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7185 obstack_1grow (&util_obstack, '*');
7190 /* We have a type that does not get special treatment. */
7192 /* NeXT extension */
7193 obstack_1grow (&util_obstack, '^');
7194 encode_type (pointer_to, curtype, format);
7198 encode_array (tree type, int curtype, int format)
7200 tree an_int_cst = TYPE_SIZE (type);
7201 tree array_of = TREE_TYPE (type);
7204 /* An incomplete array is treated like a pointer. */
7205 if (an_int_cst == NULL)
7207 encode_pointer (type, curtype, format);
7211 sprintf (buffer, "[%ld",
7212 (long) (TREE_INT_CST_LOW (an_int_cst)
7213 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7215 obstack_grow (&util_obstack, buffer, strlen (buffer));
7216 encode_type (array_of, curtype, format);
7217 obstack_1grow (&util_obstack, ']');
7222 encode_aggregate_within (tree type, int curtype, int format, int left,
7226 /* NB: aggregates that are pointed to have slightly different encoding
7227 rules in that you never encode the names of instance variables. */
7229 = (obstack_object_size (&util_obstack) > 0
7230 && *(obstack_next_free (&util_obstack) - 1) == '^');
7232 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7233 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7235 /* Traverse struct aliases; it is important to get the
7236 original struct and its tag name (if any). */
7237 type = TYPE_MAIN_VARIANT (type);
7238 name = OBJC_TYPE_NAME (type);
7239 /* Open parenth/bracket. */
7240 obstack_1grow (&util_obstack, left);
7242 /* Encode the struct/union tag name, or '?' if a tag was
7243 not provided. Typedef aliases do not qualify. */
7244 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7246 /* Did this struct have a tag? */
7247 && !TYPE_WAS_ANONYMOUS (type)
7250 obstack_grow (&util_obstack,
7251 IDENTIFIER_POINTER (name),
7252 strlen (IDENTIFIER_POINTER (name)));
7254 obstack_1grow (&util_obstack, '?');
7256 /* Encode the types (and possibly names) of the inner fields,
7258 if (inline_contents)
7260 tree fields = TYPE_FIELDS (type);
7262 obstack_1grow (&util_obstack, '=');
7263 for (; fields; fields = TREE_CHAIN (fields))
7266 /* C++ static members, and things that are not fields at all,
7267 should not appear in the encoding. */
7268 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7271 if (generating_instance_variables && !pointed_to)
7273 tree fname = DECL_NAME (fields);
7275 obstack_1grow (&util_obstack, '"');
7276 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7277 obstack_grow (&util_obstack,
7278 IDENTIFIER_POINTER (fname),
7279 strlen (IDENTIFIER_POINTER (fname)));
7280 obstack_1grow (&util_obstack, '"');
7282 encode_field_decl (fields, curtype, format);
7285 /* Close parenth/bracket. */
7286 obstack_1grow (&util_obstack, right);
7290 encode_aggregate (tree type, int curtype, int format)
7292 enum tree_code code = TREE_CODE (type);
7298 encode_aggregate_within (type, curtype, format, '{', '}');
7303 encode_aggregate_within (type, curtype, format, '(', ')');
7308 obstack_1grow (&util_obstack, 'i');
7316 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7320 encode_next_bitfield (int width)
7323 sprintf (buffer, "b%d", width);
7324 obstack_grow (&util_obstack, buffer, strlen (buffer));
7327 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7330 encode_type (tree type, int curtype, int format)
7332 enum tree_code code = TREE_CODE (type);
7334 if (code == INTEGER_TYPE)
7336 if (integer_zerop (TYPE_MIN_VALUE (type)))
7338 /* Unsigned integer types. */
7340 if (TYPE_MODE (type) == QImode)
7341 obstack_1grow (&util_obstack, 'C');
7342 else if (TYPE_MODE (type) == HImode)
7343 obstack_1grow (&util_obstack, 'S');
7344 else if (TYPE_MODE (type) == SImode)
7346 if (type == long_unsigned_type_node)
7347 obstack_1grow (&util_obstack, 'L');
7349 obstack_1grow (&util_obstack, 'I');
7351 else if (TYPE_MODE (type) == DImode)
7352 obstack_1grow (&util_obstack, 'Q');
7356 /* Signed integer types. */
7358 if (TYPE_MODE (type) == QImode)
7359 obstack_1grow (&util_obstack, 'c');
7360 else if (TYPE_MODE (type) == HImode)
7361 obstack_1grow (&util_obstack, 's');
7362 else if (TYPE_MODE (type) == SImode)
7364 if (type == long_integer_type_node)
7365 obstack_1grow (&util_obstack, 'l');
7367 obstack_1grow (&util_obstack, 'i');
7370 else if (TYPE_MODE (type) == DImode)
7371 obstack_1grow (&util_obstack, 'q');
7375 else if (code == REAL_TYPE)
7377 /* Floating point types. */
7379 if (TYPE_MODE (type) == SFmode)
7380 obstack_1grow (&util_obstack, 'f');
7381 else if (TYPE_MODE (type) == DFmode
7382 || TYPE_MODE (type) == TFmode)
7383 obstack_1grow (&util_obstack, 'd');
7386 else if (code == VOID_TYPE)
7387 obstack_1grow (&util_obstack, 'v');
7389 else if (code == BOOLEAN_TYPE)
7390 obstack_1grow (&util_obstack, 'B');
7392 else if (code == ARRAY_TYPE)
7393 encode_array (type, curtype, format);
7395 else if (code == POINTER_TYPE)
7396 encode_pointer (type, curtype, format);
7398 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7399 encode_aggregate (type, curtype, format);
7401 else if (code == FUNCTION_TYPE) /* '?' */
7402 obstack_1grow (&util_obstack, '?');
7406 encode_gnu_bitfield (int position, tree type, int size)
7408 enum tree_code code = TREE_CODE (type);
7410 char charType = '?';
7412 if (code == INTEGER_TYPE)
7414 if (integer_zerop (TYPE_MIN_VALUE (type)))
7416 /* Unsigned integer types. */
7418 if (TYPE_MODE (type) == QImode)
7420 else if (TYPE_MODE (type) == HImode)
7422 else if (TYPE_MODE (type) == SImode)
7424 if (type == long_unsigned_type_node)
7429 else if (TYPE_MODE (type) == DImode)
7434 /* Signed integer types. */
7436 if (TYPE_MODE (type) == QImode)
7438 else if (TYPE_MODE (type) == HImode)
7440 else if (TYPE_MODE (type) == SImode)
7442 if (type == long_integer_type_node)
7448 else if (TYPE_MODE (type) == DImode)
7452 else if (code == ENUMERAL_TYPE)
7457 sprintf (buffer, "b%d%c%d", position, charType, size);
7458 obstack_grow (&util_obstack, buffer, strlen (buffer));
7462 encode_field_decl (tree field_decl, int curtype, int format)
7467 /* C++ static members, and things that are not fields at all,
7468 should not appear in the encoding. */
7469 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7473 type = TREE_TYPE (field_decl);
7475 /* Generate the bitfield typing information, if needed. Note the difference
7476 between GNU and NeXT runtimes. */
7477 if (DECL_BIT_FIELD_TYPE (field_decl))
7479 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7481 if (flag_next_runtime)
7482 encode_next_bitfield (size);
7484 encode_gnu_bitfield (int_bit_position (field_decl),
7485 DECL_BIT_FIELD_TYPE (field_decl), size);
7488 encode_type (TREE_TYPE (field_decl), curtype, format);
7492 objc_expr_last (tree complex_expr)
7497 while ((next = TREE_OPERAND (complex_expr, 0)))
7498 complex_expr = next;
7500 return complex_expr;
7504 synth_self_and_ucmd_args (void)
7508 if (objc_method_context
7509 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7510 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7512 /* Really a `struct objc_class *'. However, we allow people to
7513 assign to self, which changes its type midstream. */
7514 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7516 push_parm_decl (build_tree_list
7517 (build_tree_list (decl_specs,
7518 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7521 decl_specs = build_tree_list (NULL_TREE,
7522 xref_tag (RECORD_TYPE,
7523 get_identifier (TAG_SELECTOR)));
7524 push_parm_decl (build_tree_list
7525 (build_tree_list (decl_specs,
7526 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7530 /* Transform a method definition into a function definition as follows:
7531 - synthesize the first two arguments, "self" and "_cmd". */
7534 start_method_def (tree method)
7536 /* Required to implement _msgSuper. */
7537 objc_method_context = method;
7538 UOBJC_SUPER_decl = NULL_TREE;
7540 /* Must be called BEFORE start_function. */
7543 /* Generate prototype declarations for arguments..."new-style". */
7544 synth_self_and_ucmd_args ();
7546 /* Generate argument declarations if a keyword_decl. */
7547 if (METHOD_SEL_ARGS (method))
7549 tree arglist = METHOD_SEL_ARGS (method);
7552 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7553 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7557 tree last_expr = objc_expr_last (arg_decl);
7559 /* Unite the abstract decl with its name. */
7560 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7561 push_parm_decl (build_tree_list
7562 (build_tree_list (arg_spec, arg_decl),
7566 /* Unhook: restore the abstract declarator. */
7567 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7572 push_parm_decl (build_tree_list
7573 (build_tree_list (arg_spec,
7574 KEYWORD_ARG_NAME (arglist)),
7577 arglist = TREE_CHAIN (arglist);
7582 if (METHOD_ADD_ARGS (method) != NULL_TREE
7583 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7585 /* We have a variable length selector - in "prototype" format. */
7586 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7589 /* This must be done prior to calling pushdecl. pushdecl is
7590 going to change our chain on us. */
7591 tree nextkey = TREE_CHAIN (akey);
7599 warn_with_method (const char *message, int mtype, tree method)
7601 /* Add a readable method name to the warning. */
7602 warning ("%J%s `%c%s'", method,
7603 message, mtype, gen_method_decl (method, errbuf));
7606 /* Return 1 if METHOD is consistent with PROTO. */
7609 comp_method_with_proto (tree method, tree proto)
7611 /* Create a function template node at most once. */
7612 if (!function1_template)
7613 function1_template = make_node (FUNCTION_TYPE);
7615 /* Install argument types - normally set by build_function_type. */
7616 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7618 /* install return type */
7619 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7621 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
7625 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7628 objc_types_are_equivalent (tree type1, tree type2)
7632 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7634 type1 = TYPE_PROTOCOL_LIST (type1);
7635 type2 = TYPE_PROTOCOL_LIST (type2);
7636 if (list_length (type1) == list_length (type2))
7638 for (; type2; type2 = TREE_CHAIN (type2))
7639 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7646 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7649 comp_proto_with_proto (tree proto1, tree proto2)
7653 /* The following test is needed in case there are hashing
7655 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7658 /* Compare return types. */
7659 type1 = groktypename (TREE_TYPE (proto1));
7660 type2 = groktypename (TREE_TYPE (proto2));
7662 if (!objc_types_are_equivalent (type1, type2))
7665 /* Compare argument types. */
7666 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7667 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7669 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7671 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7675 return (!type1 && !type2);
7678 /* - Generate an identifier for the function. the format is "_n_cls",
7679 where 1 <= n <= nMethods, and cls is the name the implementation we
7681 - Install the return type from the method declaration.
7682 - If we have a prototype, check for type consistency. */
7685 really_start_method (tree method, tree parmlist)
7687 tree sc_spec, ret_spec, ret_decl, decl_specs;
7688 tree method_decl, method_id;
7689 const char *sel_name, *class_name, *cat_name;
7692 /* Synth the storage class & assemble the return type. */
7693 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7694 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7695 decl_specs = chainon (sc_spec, ret_spec);
7697 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7698 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7699 cat_name = ((TREE_CODE (objc_implementation_context)
7700 == CLASS_IMPLEMENTATION_TYPE)
7702 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7705 /* Make sure this is big enough for any plausible method label. */
7706 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7707 + (cat_name ? strlen (cat_name) : 0));
7709 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7710 class_name, cat_name, sel_name, method_slot);
7712 method_id = get_identifier (buf);
7715 /* Objective-C methods cannot be overloaded, so we don't need
7716 the type encoding appended. It looks bad anyway... */
7717 push_lang_context (lang_name_c);
7720 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7722 /* Check the declarator portion of the return type for the method. */
7723 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7725 /* Unite the complex decl (specified in the abstract decl) with the
7726 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7727 tree save_expr = objc_expr_last (ret_decl);
7729 TREE_OPERAND (save_expr, 0) = method_decl;
7730 method_decl = ret_decl;
7732 /* Fool the parser into thinking it is starting a function. */
7733 start_function (decl_specs, method_decl, NULL_TREE);
7735 /* Unhook: this has the effect of restoring the abstract declarator. */
7736 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7741 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7743 /* Fool the parser into thinking it is starting a function. */
7744 start_function (decl_specs, method_decl, NULL_TREE);
7746 /* Unhook: this has the effect of restoring the abstract declarator. */
7747 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7751 /* set self_decl from the first argument...this global is used by
7752 * build_ivar_reference().build_indirect_ref().
7754 self_decl = DECL_ARGUMENTS (current_function_decl);
7756 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7757 * the following: warning:unused parameter `struct objc_selector * _cmd'
7759 TREE_USED (self_decl) = 1;
7760 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7761 /* Ditto for the underlying (static) C function. */
7762 TREE_USED (current_function_decl) = 1;
7763 pop_lang_context ();
7766 METHOD_DEFINITION (method) = current_function_decl;
7768 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7770 if (implementation_template != objc_implementation_context)
7773 = lookup_method_static (implementation_template,
7774 METHOD_SEL_NAME (method),
7775 TREE_CODE (method) == CLASS_METHOD_DECL);
7777 if (proto && ! comp_method_with_proto (method, proto))
7779 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7781 warn_with_method ("conflicting types for", type, method);
7782 warn_with_method ("previous declaration of", type, proto);
7787 /* The following routine is always called...this "architecture" is to
7788 accommodate "old-style" variable length selectors.
7790 - a:a b:b // prototype ; id c; id d; // old-style. */
7793 continue_method_def (void)
7797 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7798 /* We have a `, ...' immediately following the selector. */
7799 parmlist = get_parm_info (0);
7801 parmlist = get_parm_info (1); /* place a `void_at_end' */
7804 /* Set self_decl from the first argument...this global is used by
7805 build_ivar_reference calling build_indirect_ref. */
7806 self_decl = TREE_PURPOSE (parmlist);
7807 #endif /* !OBJCPLUS */
7810 really_start_method (objc_method_context, parmlist);
7811 store_parm_decls ();
7814 static void *UOBJC_SUPER_scope = 0;
7816 /* _n_Method (id self, SEL sel, ...)
7818 struct objc_super _S;
7819 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7823 get_super_receiver (void)
7825 if (objc_method_context)
7827 tree super_expr, super_expr_list;
7829 if (!UOBJC_SUPER_decl)
7831 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7832 build_tree_list (NULL_TREE,
7833 objc_super_template),
7836 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7838 /* This prevents `unused variable' warnings when compiling with -Wall. */
7839 TREE_USED (UOBJC_SUPER_decl) = 1;
7840 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7842 UOBJC_SUPER_scope = get_current_scope ();
7845 /* Set receiver to self. */
7846 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7847 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7848 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7850 /* Set class to begin searching. */
7851 super_expr = build_component_ref (UOBJC_SUPER_decl,
7852 get_identifier ("class"));
7854 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7856 /* [_cls, __cls]Super are "pre-built" in
7857 synth_forward_declarations. */
7859 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7860 ((TREE_CODE (objc_method_context)
7861 == INSTANCE_METHOD_DECL)
7863 : uucls_super_ref));
7867 /* We have a category. */
7869 tree super_name = CLASS_SUPER_NAME (implementation_template);
7872 /* Barf if super used in a category of Object. */
7875 error ("no super class declared in interface for `%s'",
7876 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7877 return error_mark_node;
7880 if (flag_next_runtime && !flag_zero_link)
7882 super_class = get_class_reference (super_name);
7883 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7884 /* If we are in a class method, we must retrieve the
7885 _metaclass_ for the current class, pointed at by
7886 the class's "isa" pointer. The following assumes that
7887 "isa" is the first ivar in a class (which it must be). */
7889 = build_indirect_ref
7890 (build_c_cast (build_pointer_type (objc_class_type),
7891 super_class), "unary *");
7895 add_class_reference (super_name);
7896 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7897 ? objc_get_class_decl : objc_get_meta_class_decl);
7898 assemble_external (super_class);
7900 = build_function_call
7904 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7905 IDENTIFIER_POINTER (super_name))));
7909 = build_modify_expr (super_expr, NOP_EXPR,
7910 build_c_cast (TREE_TYPE (super_expr),
7914 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7916 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7917 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7919 return build_compound_expr (super_expr_list);
7923 error ("[super ...] must appear in a method context");
7924 return error_mark_node;
7928 /* When exiting a scope, sever links to a 'super' declaration (if any)
7929 therein contained. */
7932 objc_clear_super_receiver (void)
7934 if (objc_method_context
7935 && UOBJC_SUPER_scope == get_current_scope ()) {
7936 UOBJC_SUPER_decl = 0;
7937 UOBJC_SUPER_scope = 0;
7942 objc_expand_function_end (void)
7944 /* This routine may also get called for C functions, including those
7945 nested within ObjC methods. In such cases, method encoding is
7947 if (objc_method_context == NULL_TREE
7948 || DECL_INITIAL (objc_method_context) != current_function_decl)
7951 METHOD_ENCODING (objc_method_context)
7952 = encode_method_prototype (objc_method_context);
7956 finish_method_def (void)
7958 lang_expand_function_end = objc_expand_function_end;
7959 /* We cannot validly inline ObjC methods, at least not without a language
7960 extension to declare that a method need not be dynamically
7961 dispatched, so suppress all thoughts of doing so. */
7962 DECL_INLINE (current_function_decl) = 0;
7963 DECL_UNINLINABLE (current_function_decl) = 1;
7964 current_function_cannot_inline = "methods cannot be inlined";
7967 lang_expand_function_end = NULL;
7969 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7970 since the optimizer may find "may be used before set" errors. */
7971 objc_method_context = NULL_TREE;
7976 lang_report_error_function (tree decl)
7978 if (objc_method_context)
7980 fprintf (stderr, "In method `%s'\n",
7981 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7991 is_complex_decl (tree type)
7993 return (TREE_CODE (type) == ARRAY_TYPE
7994 || TREE_CODE (type) == FUNCTION_TYPE
7995 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7999 /* Code to convert a decl node into text for a declaration in C. */
8001 static char tmpbuf[256];
8004 adorn_decl (tree decl, char *str)
8006 enum tree_code code = TREE_CODE (decl);
8008 if (code == ARRAY_REF)
8010 tree an_int_cst = TREE_OPERAND (decl, 1);
8012 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8013 sprintf (str + strlen (str), "[%ld]",
8014 (long) TREE_INT_CST_LOW (an_int_cst));
8019 else if (code == ARRAY_TYPE)
8021 tree an_int_cst = TYPE_SIZE (decl);
8022 tree array_of = TREE_TYPE (decl);
8024 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8025 sprintf (str + strlen (str), "[%ld]",
8026 (long) (TREE_INT_CST_LOW (an_int_cst)
8027 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8032 else if (code == CALL_EXPR)
8034 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8039 gen_declaration_1 (chain, str);
8040 chain = TREE_CHAIN (chain);
8047 else if (code == FUNCTION_TYPE)
8049 tree chain = TYPE_ARG_TYPES (decl);
8052 while (chain && TREE_VALUE (chain) != void_type_node)
8054 gen_declaration_1 (TREE_VALUE (chain), str);
8055 chain = TREE_CHAIN (chain);
8056 if (chain && TREE_VALUE (chain) != void_type_node)
8062 else if (code == INDIRECT_REF)
8064 strcpy (tmpbuf, "*");
8065 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8069 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8071 chain = TREE_CHAIN (chain))
8073 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8075 strcat (tmpbuf, " ");
8076 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8080 strcat (tmpbuf, " ");
8082 strcat (tmpbuf, str);
8083 strcpy (str, tmpbuf);
8086 else if (code == POINTER_TYPE)
8088 strcpy (tmpbuf, "*");
8089 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
8091 if (TREE_READONLY (decl))
8092 strcat (tmpbuf, " const");
8093 if (TYPE_VOLATILE (decl))
8094 strcat (tmpbuf, " volatile");
8096 strcat (tmpbuf, " ");
8098 strcat (tmpbuf, str);
8099 strcpy (str, tmpbuf);
8104 gen_declarator (tree decl, char *buf, const char *name)
8108 enum tree_code code = TREE_CODE (decl);
8118 op = TREE_OPERAND (decl, 0);
8120 /* We have a pointer to a function or array...(*)(), (*)[] */
8121 if ((code == ARRAY_REF || code == CALL_EXPR)
8122 && op && TREE_CODE (op) == INDIRECT_REF)
8125 str = gen_declarator (op, buf, name);
8129 strcpy (tmpbuf, "(");
8130 strcat (tmpbuf, str);
8131 strcat (tmpbuf, ")");
8132 strcpy (str, tmpbuf);
8135 adorn_decl (decl, str);
8144 /* This clause is done iteratively rather than recursively. */
8147 op = (is_complex_decl (TREE_TYPE (decl))
8148 ? TREE_TYPE (decl) : NULL_TREE);
8150 adorn_decl (decl, str);
8152 /* We have a pointer to a function or array...(*)(), (*)[] */
8153 if (code == POINTER_TYPE
8154 && op && (TREE_CODE (op) == FUNCTION_TYPE
8155 || TREE_CODE (op) == ARRAY_TYPE))
8157 strcpy (tmpbuf, "(");
8158 strcat (tmpbuf, str);
8159 strcat (tmpbuf, ")");
8160 strcpy (str, tmpbuf);
8163 decl = (is_complex_decl (TREE_TYPE (decl))
8164 ? TREE_TYPE (decl) : NULL_TREE);
8167 while (decl && (code = TREE_CODE (decl)))
8172 case IDENTIFIER_NODE:
8173 /* Will only happen if we are processing a "raw" expr-decl. */
8174 strcpy (buf, IDENTIFIER_POINTER (decl));
8185 /* We have an abstract declarator or a _DECL node. */
8193 gen_declspecs (tree declspecs, char *buf, int raw)
8199 for (chain = nreverse (copy_list (declspecs));
8200 chain; chain = TREE_CHAIN (chain))
8202 tree aspec = TREE_VALUE (chain);
8204 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8205 strcat (buf, IDENTIFIER_POINTER (aspec));
8206 else if (TREE_CODE (aspec) == RECORD_TYPE)
8208 if (OBJC_TYPE_NAME (aspec))
8210 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8212 if (! TREE_STATIC_TEMPLATE (aspec))
8213 strcat (buf, "struct ");
8214 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8219 tree chain = protocol_list;
8226 (PROTOCOL_NAME (TREE_VALUE (chain))));
8227 chain = TREE_CHAIN (chain);
8236 strcat (buf, "untagged struct");
8239 else if (TREE_CODE (aspec) == UNION_TYPE)
8241 if (OBJC_TYPE_NAME (aspec))
8243 if (! TREE_STATIC_TEMPLATE (aspec))
8244 strcat (buf, "union ");
8245 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8248 strcat (buf, "untagged union");
8251 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8253 if (OBJC_TYPE_NAME (aspec))
8255 if (! TREE_STATIC_TEMPLATE (aspec))
8256 strcat (buf, "enum ");
8257 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8260 strcat (buf, "untagged enum");
8263 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8264 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8266 else if (IS_ID (aspec))
8268 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8273 tree chain = protocol_list;
8280 (PROTOCOL_NAME (TREE_VALUE (chain))));
8281 chain = TREE_CHAIN (chain);
8288 if (TREE_CHAIN (chain))
8294 /* Type qualifiers. */
8295 if (TREE_READONLY (declspecs))
8296 strcat (buf, "const ");
8297 if (TYPE_VOLATILE (declspecs))
8298 strcat (buf, "volatile ");
8300 switch (TREE_CODE (declspecs))
8302 /* Type specifiers. */
8305 declspecs = TYPE_MAIN_VARIANT (declspecs);
8307 /* Signed integer types. */
8309 if (declspecs == short_integer_type_node)
8310 strcat (buf, "short int ");
8311 else if (declspecs == integer_type_node)
8312 strcat (buf, "int ");
8313 else if (declspecs == long_integer_type_node)
8314 strcat (buf, "long int ");
8315 else if (declspecs == long_long_integer_type_node)
8316 strcat (buf, "long long int ");
8317 else if (declspecs == signed_char_type_node
8318 || declspecs == char_type_node)
8319 strcat (buf, "char ");
8321 /* Unsigned integer types. */
8323 else if (declspecs == short_unsigned_type_node)
8324 strcat (buf, "unsigned short ");
8325 else if (declspecs == unsigned_type_node)
8326 strcat (buf, "unsigned int ");
8327 else if (declspecs == long_unsigned_type_node)
8328 strcat (buf, "unsigned long ");
8329 else if (declspecs == long_long_unsigned_type_node)
8330 strcat (buf, "unsigned long long ");
8331 else if (declspecs == unsigned_char_type_node)
8332 strcat (buf, "unsigned char ");
8336 declspecs = TYPE_MAIN_VARIANT (declspecs);
8338 if (declspecs == float_type_node)
8339 strcat (buf, "float ");
8340 else if (declspecs == double_type_node)
8341 strcat (buf, "double ");
8342 else if (declspecs == long_double_type_node)
8343 strcat (buf, "long double ");
8347 if (OBJC_TYPE_NAME (declspecs)
8348 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8350 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8352 if (! TREE_STATIC_TEMPLATE (declspecs))
8353 strcat (buf, "struct ");
8354 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8358 tree chain = protocol_list;
8365 (PROTOCOL_NAME (TREE_VALUE (chain))));
8366 chain = TREE_CHAIN (chain);
8375 strcat (buf, "untagged struct");
8381 if (OBJC_TYPE_NAME (declspecs)
8382 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8384 strcat (buf, "union ");
8385 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8390 strcat (buf, "untagged union ");
8394 if (OBJC_TYPE_NAME (declspecs)
8395 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8397 strcat (buf, "enum ");
8398 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8403 strcat (buf, "untagged enum ");
8407 strcat (buf, "void ");
8412 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8417 tree chain = protocol_list;
8424 (PROTOCOL_NAME (TREE_VALUE (chain))));
8425 chain = TREE_CHAIN (chain);
8441 /* Given a tree node, produce a printable description of it in the given
8442 buffer, overwriting the buffer. */
8445 gen_declaration (tree atype_or_adecl, char *buf)
8448 gen_declaration_1 (atype_or_adecl, buf);
8452 /* Given a tree node, append a printable description to the end of the
8456 gen_declaration_1 (tree atype_or_adecl, char *buf)
8460 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8462 tree declspecs; /* "identifier_node", "record_type" */
8463 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8464 tree width = NULL_TREE; /* for bitfields */
8466 /* We have a "raw", abstract declarator (typename). */
8467 declarator = TREE_VALUE (atype_or_adecl);
8468 /* In the case of raw ivars, the declarator itself is a list,
8469 and contains bitfield widths. */
8470 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8472 width = TREE_VALUE (declarator);
8473 declarator = TREE_PURPOSE (declarator);
8475 declspecs = TREE_PURPOSE (atype_or_adecl);
8477 gen_declspecs (declspecs, buf, 1);
8481 strcat (buf, gen_declarator (declarator, declbuf, ""));
8484 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8485 TREE_INT_CST_LOW (width));
8491 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8492 tree declarator; /* "array_type", "function_type", "pointer_type". */
8494 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8495 || TREE_CODE (atype_or_adecl) == PARM_DECL
8496 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8497 atype = TREE_TYPE (atype_or_adecl);
8499 /* Assume we have a *_type node. */
8500 atype = atype_or_adecl;
8502 if (is_complex_decl (atype))
8506 /* Get the declaration specifier; it is at the end of the list. */
8507 declarator = chain = atype;
8509 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8510 while (is_complex_decl (chain));
8517 declarator = NULL_TREE;
8520 gen_declspecs (declspecs, buf, 0);
8522 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8523 || TREE_CODE (atype_or_adecl) == PARM_DECL
8524 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8526 const char *const decl_name =
8527 (DECL_NAME (atype_or_adecl)
8528 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8533 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8536 else if (decl_name[0])
8539 strcat (buf, decl_name);
8542 else if (declarator)
8545 strcat (buf, gen_declarator (declarator, declbuf, ""));
8550 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8552 /* Given a method tree, put a printable description into the given
8553 buffer (overwriting) and return a pointer to the buffer. */
8556 gen_method_decl (tree method, char *buf)
8561 if (RAW_TYPESPEC (method) != objc_object_reference)
8564 gen_declaration_1 (TREE_TYPE (method), buf);
8568 chain = METHOD_SEL_ARGS (method);
8571 /* We have a chain of keyword_decls. */
8574 if (KEYWORD_KEY_NAME (chain))
8575 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8578 if (RAW_TYPESPEC (chain) != objc_object_reference)
8581 gen_declaration_1 (TREE_TYPE (chain), buf);
8585 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8586 if ((chain = TREE_CHAIN (chain)))
8591 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8592 strcat (buf, ", ...");
8593 else if (METHOD_ADD_ARGS (method))
8595 /* We have a tree list node as generate by get_parm_info. */
8596 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8598 /* Know we have a chain of parm_decls. */
8602 gen_declaration_1 (chain, buf);
8603 chain = TREE_CHAIN (chain);
8609 /* We have a unary selector. */
8610 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8618 /* Dump an @interface declaration of the supplied class CHAIN to the
8619 supplied file FP. Used to implement the -gen-decls option (which
8620 prints out an @interface declaration of all classes compiled in
8621 this run); potentially useful for debugging the compiler too. */
8623 dump_interface (FILE *fp, tree chain)
8625 /* FIXME: A heap overflow here whenever a method (or ivar)
8626 declaration is so long that it doesn't fit in the buffer. The
8627 code and all the related functions should be rewritten to avoid
8628 using fixed size buffers. */
8629 char *buf = (char *) xmalloc (1024 * 10);
8630 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8631 tree ivar_decls = CLASS_RAW_IVARS (chain);
8632 tree nst_methods = CLASS_NST_METHODS (chain);
8633 tree cls_methods = CLASS_CLS_METHODS (chain);
8635 fprintf (fp, "\n@interface %s", my_name);
8637 /* CLASS_SUPER_NAME is used to store the superclass name for
8638 classes, and the category name for categories. */
8639 if (CLASS_SUPER_NAME (chain))
8641 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8643 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8644 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8646 fprintf (fp, " (%s)\n", name);
8650 fprintf (fp, " : %s\n", name);
8656 /* FIXME - the following doesn't seem to work at the moment. */
8659 fprintf (fp, "{\n");
8662 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8663 ivar_decls = TREE_CHAIN (ivar_decls);
8666 fprintf (fp, "}\n");
8671 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8672 nst_methods = TREE_CHAIN (nst_methods);
8677 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8678 cls_methods = TREE_CHAIN (cls_methods);
8681 fprintf (fp, "@end\n");
8684 /* Demangle function for Objective-C */
8686 objc_demangle (const char *mangled)
8688 char *demangled, *cp;
8690 if (mangled[0] == '_' &&
8691 (mangled[1] == 'i' || mangled[1] == 'c') &&
8694 cp = demangled = xmalloc(strlen(mangled) + 2);
8695 if (mangled[1] == 'i')
8696 *cp++ = '-'; /* for instance method */
8698 *cp++ = '+'; /* for class method */
8699 *cp++ = '['; /* opening left brace */
8700 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8701 while (*cp && *cp == '_')
8702 cp++; /* skip any initial underbars in class name */
8703 cp = strchr(cp, '_'); /* find first non-initial underbar */
8706 free(demangled); /* not mangled name */
8709 if (cp[1] == '_') /* easy case: no category name */
8711 *cp++ = ' '; /* replace two '_' with one ' ' */
8712 strcpy(cp, mangled + (cp - demangled) + 2);
8716 *cp++ = '('; /* less easy case: category name */
8717 cp = strchr(cp, '_');
8720 free(demangled); /* not mangled name */
8724 *cp++ = ' '; /* overwriting 1st char of method name... */
8725 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8727 while (*cp && *cp == '_')
8728 cp++; /* skip any initial underbars in method name */
8731 *cp = ':'; /* replace remaining '_' with ':' */
8732 *cp++ = ']'; /* closing right brace */
8733 *cp++ = 0; /* string terminator */
8737 return mangled; /* not an objc mangled name */
8741 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8743 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8749 gcc_obstack_init (&util_obstack);
8750 util_firstobj = (char *) obstack_finish (&util_obstack);
8752 errbuf = (char *) xmalloc (BUFSIZE);
8754 synth_module_prologue ();
8760 struct imp_entry *impent;
8762 /* The internally generated initializers appear to have missing braces.
8763 Don't warn about this. */
8764 int save_warn_missing_braces = warn_missing_braces;
8765 warn_missing_braces = 0;
8767 /* A missing @end may not be detected by the parser. */
8768 if (objc_implementation_context)
8770 warning ("`@end' missing in implementation context");
8771 finish_class (objc_implementation_context);
8772 objc_ivar_chain = NULL_TREE;
8773 objc_implementation_context = NULL_TREE;
8776 generate_forward_declaration_to_string_table ();
8778 /* Process the static instances here because initialization of objc_symtab
8780 if (objc_static_instances)
8781 generate_static_references ();
8783 if (imp_list || class_names_chain
8784 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8785 generate_objc_symtab_decl ();
8787 for (impent = imp_list; impent; impent = impent->next)
8789 objc_implementation_context = impent->imp_context;
8790 implementation_template = impent->imp_template;
8792 UOBJC_CLASS_decl = impent->class_decl;
8793 UOBJC_METACLASS_decl = impent->meta_decl;
8795 /* Dump the @interface of each class as we compile it, if the
8796 -gen-decls option is in use. TODO: Dump the classes in the
8797 order they were found, rather than in reverse order as we
8799 if (flag_gen_declaration)
8801 dump_interface (gen_declaration_file, objc_implementation_context);
8804 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8806 /* all of the following reference the string pool... */
8807 generate_ivar_lists ();
8808 generate_dispatch_tables ();
8809 generate_shared_structures ();
8813 generate_dispatch_tables ();
8814 generate_category (objc_implementation_context);
8818 /* If we are using an array of selectors, we must always
8819 finish up the array decl even if no selectors were used. */
8820 if (! flag_next_runtime || sel_ref_chain)
8821 build_selector_translation_table ();
8824 generate_protocols ();
8826 if (flag_replace_objc_classes && imp_list)
8827 generate_objc_image_info ();
8829 if (objc_implementation_context || class_names_chain || objc_static_instances
8830 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8832 /* Arrange for ObjC data structures to be initialized at run time. */
8833 rtx init_sym = build_module_descriptor ();
8834 if (init_sym && targetm.have_ctors_dtors)
8835 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8838 /* Dump the class references. This forces the appropriate classes
8839 to be linked into the executable image, preserving unix archive
8840 semantics. This can be removed when we move to a more dynamically
8841 linked environment. */
8843 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8845 handle_class_ref (chain);
8846 if (TREE_PURPOSE (chain))
8847 generate_classref_translation_entry (chain);
8850 for (impent = imp_list; impent; impent = impent->next)
8851 handle_impent (impent);
8853 /* Dump the string table last. */
8855 generate_strings ();
8862 /* Run through the selector hash tables and print a warning for any
8863 selector which has multiple methods. */
8865 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8867 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8868 check_duplicates (hsh, 0);
8869 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8870 check_duplicates (hsh, 0);
8874 warn_missing_braces = save_warn_missing_braces;
8877 /* Subroutines of finish_objc. */
8880 generate_classref_translation_entry (tree chain)
8882 tree expr, name, decl_specs, decl, sc_spec;
8885 type = TREE_TYPE (TREE_PURPOSE (chain));
8887 expr = add_objc_string (TREE_VALUE (chain), class_names);
8888 expr = build_c_cast (type, expr); /* cast! */
8890 name = DECL_NAME (TREE_PURPOSE (chain));
8892 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8894 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8895 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8897 /* The decl that is returned from start_decl is the one that we
8898 forward declared in build_class_reference. */
8899 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8900 DECL_CONTEXT (decl) = NULL_TREE;
8901 finish_decl (decl, expr, NULL_TREE);
8906 handle_class_ref (tree chain)
8908 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8909 char *string = (char *) alloca (strlen (name) + 30);
8913 sprintf (string, "%sobjc_class_name_%s",
8914 (flag_next_runtime ? "." : "__"), name);
8916 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8917 if (flag_next_runtime)
8919 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8924 /* Make a decl for this name, so we can use its address in a tree. */
8925 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8926 DECL_EXTERNAL (decl) = 1;
8927 TREE_PUBLIC (decl) = 1;
8930 rest_of_decl_compilation (decl, 0, 0, 0);
8932 /* Make a decl for the address. */
8933 sprintf (string, "%sobjc_class_ref_%s",
8934 (flag_next_runtime ? "." : "__"), name);
8935 exp = build1 (ADDR_EXPR, string_type_node, decl);
8936 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8937 DECL_INITIAL (decl) = exp;
8938 TREE_STATIC (decl) = 1;
8939 TREE_USED (decl) = 1;
8942 rest_of_decl_compilation (decl, 0, 0, 0);
8946 handle_impent (struct imp_entry *impent)
8950 objc_implementation_context = impent->imp_context;
8951 implementation_template = impent->imp_template;
8953 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8955 const char *const class_name =
8956 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8958 string = (char *) alloca (strlen (class_name) + 30);
8960 sprintf (string, "%sobjc_class_name_%s",
8961 (flag_next_runtime ? "." : "__"), class_name);
8963 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8965 const char *const class_name =
8966 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8967 const char *const class_super_name =
8968 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8970 string = (char *) alloca (strlen (class_name)
8971 + strlen (class_super_name) + 30);
8973 /* Do the same for categories. Even though no references to
8974 these symbols are generated automatically by the compiler, it
8975 gives you a handle to pull them into an archive by hand. */
8976 sprintf (string, "*%sobjc_category_name_%s_%s",
8977 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8982 #ifdef ASM_DECLARE_CLASS_REFERENCE
8983 if (flag_next_runtime)
8985 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8993 init = build_int_2 (0, 0);
8994 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8995 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8996 TREE_PUBLIC (decl) = 1;
8997 TREE_READONLY (decl) = 1;
8998 TREE_USED (decl) = 1;
8999 TREE_CONSTANT (decl) = 1;
9000 DECL_CONTEXT (decl) = 0;
9001 DECL_ARTIFICIAL (decl) = 1;
9002 DECL_INITIAL (decl) = init;
9003 assemble_variable (decl, 1, 0, 0);
9007 /* The Fix-and-Countinue functionality available in Mac OS X 10.3 and
9008 later requires that ObjC translation units participating in F&C be
9009 specially marked. The following routine accomplishes this. */
9011 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9014 generate_objc_image_info (void)
9016 tree sc_spec, decl, initlist;
9018 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9020 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9021 tree_cons (NULL_TREE,
9024 build_index_type (build_int_2 (1, 0))),
9029 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9030 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9031 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9033 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9034 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9035 finish_decl (decl, initlist, NULL_TREE);
9038 /* Look up ID as an instance variable. */
9041 lookup_objc_ivar (tree id)
9045 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9046 /* We have a message to super. */
9047 return get_super_receiver ();
9048 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9050 if (is_private (decl))
9051 return error_mark_node;
9053 return build_ivar_reference (id);
9059 #include "gt-objc-objc-act.h"
9060 #include "gtype-objc.h"