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"
53 #include "langhooks.h"
64 #include "diagnostic.h"
67 /* This is the default way of generating a method name. */
68 /* I am not sure it is really correct.
69 Perhaps there's a danger that it will make name conflicts
70 if method names contain underscores. -- rms. */
71 #ifndef OBJC_GEN_METHOD_LABEL
72 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
75 sprintf ((BUF), "_%s_%s_%s_%s", \
76 ((IS_INST) ? "i" : "c"), \
78 ((CAT_NAME)? (CAT_NAME) : ""), \
80 for (temp = (BUF); *temp; temp++) \
81 if (*temp == ':') *temp = '_'; \
85 /* These need specifying. */
86 #ifndef OBJC_FORWARDING_STACK_OFFSET
87 #define OBJC_FORWARDING_STACK_OFFSET 0
90 #ifndef OBJC_FORWARDING_MIN_OFFSET
91 #define OBJC_FORWARDING_MIN_OFFSET 0
94 /* Set up for use of obstacks. */
98 /* This obstack is used to accumulate the encoding of a data type. */
99 static struct obstack util_obstack;
101 /* This points to the beginning of obstack contents, so we can free
102 the whole contents. */
105 /* The version identifies which language generation and runtime
106 the module (file) was compiled for, and is recorded in the
107 module descriptor. */
109 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
110 #define PROTOCOL_VERSION 2
112 /* (Decide if these can ever be validly changed.) */
113 #define OBJC_ENCODE_INLINE_DEFS 0
114 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
116 /*** Private Interface (procedures) ***/
118 /* Used by compile_file. */
120 static void init_objc (void);
121 static void finish_objc (void);
123 /* Code generation. */
125 static void synth_module_prologue (void);
126 static tree objc_build_constructor (tree, tree);
127 static rtx build_module_descriptor (void);
128 static tree init_module_descriptor (tree);
129 static tree build_objc_method_call (int, tree, tree, tree, tree);
130 static void generate_strings (void);
131 static tree get_proto_encoding (tree);
132 static void build_selector_translation_table (void);
134 static tree objc_add_static_instance (tree, tree);
136 static void build_objc_exception_stuff (void);
137 static tree objc_declare_variable (enum rid, tree, tree, tree);
138 static tree objc_enter_block (void);
139 static tree objc_exit_block (void);
140 static void objc_build_try_enter_fragment (void);
141 static void objc_build_try_exit_fragment (void);
142 static void objc_build_extract_fragment (void);
143 static tree objc_build_extract_expr (void);
145 static tree build_ivar_template (void);
146 static tree build_method_template (void);
147 static tree build_private_template (tree);
148 static void build_class_template (void);
149 static void build_selector_template (void);
150 static void build_category_template (void);
151 static tree lookup_method_in_hash_lists (tree, int);
152 static void build_super_template (void);
153 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
154 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
155 static void synth_forward_declarations (void);
156 static int ivar_list_length (tree);
157 static tree get_class_ivars (tree, int);
158 static void generate_ivar_lists (void);
159 static void generate_dispatch_tables (void);
160 static void generate_shared_structures (void);
161 static tree generate_protocol_list (tree);
162 static void build_protocol_reference (tree);
164 static tree build_keyword_selector (tree);
165 static tree synth_id_with_class_suffix (const char *, tree);
167 static void generate_static_references (void);
168 static int check_methods_accessible (tree, tree, int);
169 static void encode_aggregate_within (tree, int, int, int, int);
170 static const char *objc_demangle (const char *);
171 static void objc_expand_function_end (void);
173 /* Hash tables to manage the global pool of method prototypes. */
175 hash *nst_method_hash_list = 0;
176 hash *cls_method_hash_list = 0;
178 static size_t hash_func (tree);
179 static void hash_init (void);
180 static void hash_enter (hash *, tree);
181 static hash hash_lookup (hash *, tree);
182 static void hash_add_attr (hash, tree);
183 static tree lookup_method (tree, tree);
184 static tree lookup_method_static (tree, tree, int);
185 static void add_method_to_hash_list (hash *, tree);
186 static tree add_class (tree);
187 static void add_category (tree, tree);
188 static inline tree lookup_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, 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> *' && `<class> *' != `Class'! */
908 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
909 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
912 /* `<class> *' = `<class> *' */
914 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
916 tree lname = OBJC_TYPE_NAME (lhs);
917 tree rname = OBJC_TYPE_NAME (rhs);
923 /* If the left hand side is a super class of the right hand side,
925 for (inter = lookup_interface (rname); inter;
926 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
927 if (lname == CLASS_SUPER_NAME (inter))
930 /* Allow the reverse when reflexive. */
932 for (inter = lookup_interface (lname); inter;
933 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
934 if (rname == CLASS_SUPER_NAME (inter))
940 /* Not an ObjC type - let comptypes do the check. */
944 /* Called from finish_decl. */
947 objc_check_decl (tree decl)
949 tree type = TREE_TYPE (decl);
951 if (TREE_CODE (type) != RECORD_TYPE)
953 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
954 error ("statically allocated instance of Objective-C class `%s'",
955 IDENTIFIER_POINTER (type));
958 /* Implement static typing. At this point, we know we have an interface. */
961 get_static_reference (tree interface, tree protocols)
963 tree type = xref_tag (RECORD_TYPE, interface);
967 tree t, m = TYPE_MAIN_VARIANT (type);
969 t = copy_node (type);
971 /* Add this type to the chain of variants of TYPE. */
972 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
973 TYPE_NEXT_VARIANT (m) = t;
975 /* Look up protocols and install in lang specific list. Note
976 that the protocol list can have a different lifetime than T! */
977 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
979 /* This forces a new pointer type to be created later
980 (in build_pointer_type)...so that the new template
981 we just created will actually be used...what a hack! */
982 if (TYPE_POINTER_TO (t))
983 TYPE_POINTER_TO (t) = NULL_TREE;
992 get_object_reference (tree protocols)
994 tree type_decl = lookup_name (objc_id_id);
997 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
999 type = TREE_TYPE (type_decl);
1000 if (TYPE_MAIN_VARIANT (type) != id_type)
1001 warning ("unexpected type for `id' (%s)",
1002 gen_declaration (type, errbuf));
1006 error ("undefined type `id', please import <objc/objc.h>");
1007 return error_mark_node;
1010 /* This clause creates a new pointer type that is qualified with
1011 the protocol specification...this info is used later to do more
1012 elaborate type checking. */
1016 tree t, m = TYPE_MAIN_VARIANT (type);
1018 t = copy_node (type);
1020 /* Add this type to the chain of variants of TYPE. */
1021 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1022 TYPE_NEXT_VARIANT (m) = t;
1024 /* Look up protocols...and install in lang specific list */
1025 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1027 /* This forces a new pointer type to be created later
1028 (in build_pointer_type)...so that the new template
1029 we just created will actually be used...what a hack! */
1030 if (TYPE_POINTER_TO (t))
1031 TYPE_POINTER_TO (t) = NULL_TREE;
1038 /* Check for circular dependencies in protocols. The arguments are
1039 PROTO, the protocol to check, and LIST, a list of protocol it
1043 check_protocol_recursively (tree proto, tree list)
1047 for (p = list; p; p = TREE_CHAIN (p))
1049 tree pp = TREE_VALUE (p);
1051 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1052 pp = lookup_protocol (pp);
1055 fatal_error ("protocol `%s' has circular dependency",
1056 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1058 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1062 /* Look up PROTOCOLS, and return a list of those that are found.
1063 If none are found, return NULL. */
1066 lookup_and_install_protocols (tree protocols)
1069 tree return_value = NULL_TREE;
1071 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1073 tree ident = TREE_VALUE (proto);
1074 tree p = lookup_protocol (ident);
1077 error ("cannot find protocol declaration for `%s'",
1078 IDENTIFIER_POINTER (ident));
1080 return_value = chainon (return_value,
1081 build_tree_list (NULL_TREE, p));
1084 return return_value;
1087 /* Create and push a decl for a built-in external variable or field NAME.
1089 TYPE is its data type. */
1092 create_builtin_decl (enum tree_code code, tree type, const char *name)
1094 tree decl = build_decl (code, get_identifier (name), type);
1096 if (code == VAR_DECL)
1098 TREE_STATIC (decl) = 1;
1099 make_decl_rtl (decl, 0);
1101 DECL_ARTIFICIAL (decl) = 1;
1107 /* Find the decl for the constant string class. */
1110 setup_string_decl (void)
1112 if (!string_class_decl)
1114 if (!constant_string_global_id)
1118 /* %s in format will provide room for terminating null */
1119 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1120 + strlen (constant_string_class_name);
1121 name = xmalloc (length);
1122 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1123 constant_string_class_name);
1124 constant_string_global_id = get_identifier (name);
1126 string_class_decl = lookup_name (constant_string_global_id);
1130 /* Purpose: "play" parser, creating/installing representations
1131 of the declarations that are required by Objective-C.
1135 type_spec--------->sc_spec
1136 (tree_list) (tree_list)
1139 identifier_node identifier_node */
1142 synth_module_prologue (void)
1146 /* Defined in `objc.h' */
1147 objc_object_id = get_identifier (TAG_OBJECT);
1149 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1151 id_type = build_pointer_type (objc_object_reference);
1153 objc_id_id = get_identifier (TYPE_ID);
1154 objc_class_id = get_identifier (TAG_CLASS);
1156 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1157 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1158 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1159 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1162 /* Declare type of selector-objects that represent an operation name. */
1164 if (flag_next_runtime)
1165 /* `struct objc_selector *' */
1167 = build_pointer_type (xref_tag (RECORD_TYPE,
1168 get_identifier (TAG_SELECTOR)));
1170 /* `const struct objc_selector *' */
1172 = build_pointer_type
1173 (build_qualified_type (xref_tag (RECORD_TYPE,
1174 get_identifier (TAG_SELECTOR)),
1177 /* Declare receiver type used for dispatching messages to 'super'. */
1179 /* `struct objc_super *' */
1180 super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1181 get_identifier (TAG_SUPER)));
1183 if (flag_next_runtime)
1185 /* NB: In order to call one of the ..._stret (struct-returning)
1186 functions, the function *MUST* first be cast to a signature that
1187 corresponds to the actual ObjC method being invoked. This is
1188 what is done by the build_objc_method_call() routine below. */
1190 /* id objc_msgSend (id, SEL, ...); */
1191 /* id objc_msgSendNonNil (id, SEL, ...); */
1192 /* id objc_msgSend_stret (id, SEL, ...); */
1193 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1195 = build_function_type (id_type,
1196 tree_cons (NULL_TREE, id_type,
1197 tree_cons (NULL_TREE, selector_type,
1199 umsg_decl = builtin_function (TAG_MSGSEND,
1200 temp_type, 0, NOT_BUILT_IN,
1202 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1203 temp_type, 0, NOT_BUILT_IN,
1205 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1206 temp_type, 0, NOT_BUILT_IN,
1208 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1209 temp_type, 0, NOT_BUILT_IN,
1212 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1213 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1215 = build_function_type (id_type,
1216 tree_cons (NULL_TREE, super_type,
1217 tree_cons (NULL_TREE, selector_type,
1219 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1220 temp_type, 0, NOT_BUILT_IN,
1222 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1223 temp_type, 0, NOT_BUILT_IN, 0,
1228 /* GNU runtime messenger entry points. */
1230 /* typedef id (*IMP)(id, SEL, ...); */
1232 = build_pointer_type
1233 (build_function_type (id_type,
1234 tree_cons (NULL_TREE, id_type,
1235 tree_cons (NULL_TREE, selector_type,
1238 /* IMP objc_msg_lookup (id, SEL); */
1240 = build_function_type (IMP_type,
1241 tree_cons (NULL_TREE, id_type,
1242 tree_cons (NULL_TREE, selector_type,
1244 umsg_decl = builtin_function (TAG_MSGSEND,
1245 temp_type, 0, NOT_BUILT_IN,
1248 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1250 = build_function_type (IMP_type,
1251 tree_cons (NULL_TREE, super_type,
1252 tree_cons (NULL_TREE, selector_type,
1254 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1255 temp_type, 0, NOT_BUILT_IN,
1259 /* id objc_getClass (const char *); */
1261 temp_type = build_function_type (id_type,
1262 tree_cons (NULL_TREE,
1263 const_string_type_node,
1267 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1270 /* id objc_getMetaClass (const char *); */
1272 objc_get_meta_class_decl
1273 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1275 build_super_template ();
1276 if (flag_next_runtime)
1277 build_objc_exception_stuff ();
1279 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1281 if (! flag_next_runtime)
1283 if (flag_typed_selectors)
1285 /* Suppress outputting debug symbols, because
1286 dbxout_init hasn'r been called yet. */
1287 enum debug_info_type save_write_symbols = write_symbols;
1288 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1289 write_symbols = NO_DEBUG;
1290 debug_hooks = &do_nothing_debug_hooks;
1292 build_selector_template ();
1293 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1295 write_symbols = save_write_symbols;
1296 debug_hooks = save_hooks;
1299 temp_type = build_array_type (selector_type, NULL_TREE);
1301 layout_type (temp_type);
1302 UOBJC_SELECTOR_TABLE_decl
1303 = create_builtin_decl (VAR_DECL, temp_type,
1304 "_OBJC_SELECTOR_TABLE");
1306 /* Avoid warning when not sending messages. */
1307 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1310 /* Forward declare constant_string_id and constant_string_type. */
1311 if (!constant_string_class_name)
1312 constant_string_class_name = default_constant_string_class_name;
1314 constant_string_id = get_identifier (constant_string_class_name);
1315 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1317 /* Pre-build the following entities - for speed/convenience. */
1318 self_id = get_identifier ("self");
1319 ucmd_id = get_identifier ("_cmd");
1321 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1322 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1326 /* Ensure that the ivar list for NSConstantString/NXConstantString
1327 (or whatever was specified via `-fconstant-string-class')
1328 contains fields at least as large as the following three, so that
1329 the runtime can stomp on them with confidence:
1331 struct STRING_OBJECT_CLASS_NAME
1335 unsigned int length;
1339 check_string_class_template (void)
1341 tree field_decl = TYPE_FIELDS (constant_string_type);
1343 #define AT_LEAST_AS_LARGE_AS(F, T) \
1344 (F && TREE_CODE (F) == FIELD_DECL \
1345 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1346 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1348 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1351 field_decl = TREE_CHAIN (field_decl);
1352 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1355 field_decl = TREE_CHAIN (field_decl);
1356 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1358 #undef AT_LEAST_AS_LARGE_AS
1361 /* Avoid calling `check_string_class_template ()' more than once. */
1362 static GTY(()) int string_layout_checked;
1364 /* Custom build_string which sets TREE_TYPE! */
1367 my_build_string (int len, const char *str)
1369 return fix_string_type (build_string (len, str));
1372 /* Given a chain of STRING_CST's, build a static instance of
1373 NXConstantString which points at the concatenation of those
1374 strings. We place the string object in the __string_objects
1375 section of the __OBJC segment. The Objective-C runtime will
1376 initialize the isa pointers of the string objects to point at the
1377 NXConstantString class object. */
1380 build_objc_string_object (tree string)
1382 tree initlist, constructor, constant_string_class;
1386 string = fix_string_type (string);
1388 constant_string_class = lookup_interface (constant_string_id);
1389 if (!constant_string_class
1390 || !(constant_string_type
1391 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1393 error ("cannot find interface declaration for `%s'",
1394 IDENTIFIER_POINTER (constant_string_id));
1395 return error_mark_node;
1398 /* Call to 'combine_strings' has been moved above. */
1399 TREE_SET_CODE (string, STRING_CST);
1400 length = TREE_STRING_LENGTH (string) - 1;
1402 if (!string_layout_checked)
1404 /* The NSConstantString/NXConstantString ivar layout is now
1406 if (!check_string_class_template ())
1408 error ("interface `%s' does not have valid constant string layout",
1409 IDENTIFIER_POINTER (constant_string_id));
1410 return error_mark_node;
1412 add_class_reference (constant_string_id);
1414 fields = TYPE_FIELDS (constant_string_type);
1416 /* & ((NXConstantString) { NULL, string, length }) */
1418 if (flag_next_runtime)
1420 /* For the NeXT runtime, we can generate a literal reference
1421 to the string class, don't need to run a constructor. */
1422 setup_string_decl ();
1423 if (string_class_decl == NULL_TREE)
1425 error ("cannot find reference tag for class `%s'",
1426 IDENTIFIER_POINTER (constant_string_id));
1427 return error_mark_node;
1429 initlist = build_tree_list
1431 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1435 initlist = build_tree_list (fields, build_int_2 (0, 0));
1438 fields = TREE_CHAIN (fields);
1441 = tree_cons (fields, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1444 fields = TREE_CHAIN (fields);
1446 initlist = tree_cons (fields, build_int_2 (length, 0), initlist);
1447 constructor = objc_build_constructor (constant_string_type,
1448 nreverse (initlist));
1450 if (!flag_next_runtime)
1453 = objc_add_static_instance (constructor, constant_string_type);
1456 return (build_unary_op (ADDR_EXPR, constructor, 1));
1459 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1461 static GTY(()) int num_static_inst;
1464 objc_add_static_instance (tree constructor, tree class_decl)
1469 /* Find the list of static instances for the CLASS_DECL. Create one if
1471 for (chain = &objc_static_instances;
1472 *chain && TREE_VALUE (*chain) != class_decl;
1473 chain = &TREE_CHAIN (*chain));
1476 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1477 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1480 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1481 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1482 DECL_COMMON (decl) = 1;
1483 TREE_STATIC (decl) = 1;
1484 DECL_ARTIFICIAL (decl) = 1;
1485 DECL_INITIAL (decl) = constructor;
1487 /* We may be writing something else just now.
1488 Postpone till end of input. */
1489 DECL_DEFER_OUTPUT (decl) = 1;
1490 pushdecl_top_level (decl);
1491 rest_of_decl_compilation (decl, 0, 1, 0);
1493 /* Add the DECL to the head of this CLASS' list. */
1494 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1499 /* Build a static constant CONSTRUCTOR
1500 with type TYPE and elements ELTS. */
1503 objc_build_constructor (tree type, tree elts)
1505 tree constructor, f, e;
1507 /* ??? Most of the places that we build constructors, we don't fill in
1508 the type of integers properly. Convert them all en masse. */
1509 if (TREE_CODE (type) == ARRAY_TYPE)
1511 f = TREE_TYPE (type);
1512 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1513 for (e = elts; e ; e = TREE_CHAIN (e))
1514 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1518 f = TYPE_FIELDS (type);
1519 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1520 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1521 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1522 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1525 constructor = build_constructor (type, elts);
1526 TREE_CONSTANT (constructor) = 1;
1527 TREE_STATIC (constructor) = 1;
1528 TREE_READONLY (constructor) = 1;
1531 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1532 build_unary_op (wasn't true in 2.7.2.1 days) */
1533 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1538 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1540 /* Predefine the following data type:
1548 void *defs[cls_def_cnt + cat_def_cnt];
1552 build_objc_symtab_template (void)
1554 tree field_decl, field_decl_chain;
1556 objc_symtab_template
1557 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1559 /* long sel_ref_cnt; */
1561 field_decl = create_builtin_decl (FIELD_DECL,
1562 long_integer_type_node,
1564 field_decl_chain = field_decl;
1568 field_decl = create_builtin_decl (FIELD_DECL,
1569 build_pointer_type (selector_type),
1571 chainon (field_decl_chain, field_decl);
1573 /* short cls_def_cnt; */
1575 field_decl = create_builtin_decl (FIELD_DECL,
1576 short_integer_type_node,
1578 chainon (field_decl_chain, field_decl);
1580 /* short cat_def_cnt; */
1582 field_decl = create_builtin_decl (FIELD_DECL,
1583 short_integer_type_node,
1585 chainon (field_decl_chain, field_decl);
1587 if (imp_count || cat_count || !flag_next_runtime)
1589 /* void *defs[imp_count + cat_count (+ 1)]; */
1590 /* NB: The index is one less than the size of the array. */
1591 int index = imp_count + cat_count
1592 + (flag_next_runtime? -1: 0);
1593 field_decl = create_builtin_decl
1597 build_index_type (build_int_2 (index, 0))),
1599 chainon (field_decl_chain, field_decl);
1602 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1605 /* Create the initial value for the `defs' field of _objc_symtab.
1606 This is a CONSTRUCTOR. */
1609 init_def_list (tree type)
1611 tree expr, initlist = NULL_TREE;
1612 struct imp_entry *impent;
1615 for (impent = imp_list; impent; impent = impent->next)
1617 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1619 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1620 initlist = tree_cons (NULL_TREE, expr, initlist);
1625 for (impent = imp_list; impent; impent = impent->next)
1627 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1629 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1630 initlist = tree_cons (NULL_TREE, expr, initlist);
1634 if (!flag_next_runtime)
1636 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1639 if (static_instances_decl)
1640 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1642 expr = build_int_2 (0, 0);
1644 initlist = tree_cons (NULL_TREE, expr, initlist);
1647 return objc_build_constructor (type, nreverse (initlist));
1650 /* Construct the initial value for all of _objc_symtab. */
1653 init_objc_symtab (tree type)
1657 /* sel_ref_cnt = { ..., 5, ... } */
1659 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1661 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1663 if (flag_next_runtime || ! sel_ref_chain)
1664 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1666 initlist = tree_cons (NULL_TREE,
1667 build_unary_op (ADDR_EXPR,
1668 UOBJC_SELECTOR_TABLE_decl, 1),
1671 /* cls_def_cnt = { ..., 5, ... } */
1673 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1675 /* cat_def_cnt = { ..., 5, ... } */
1677 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1679 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1681 if (imp_count || cat_count || !flag_next_runtime)
1684 tree field = TYPE_FIELDS (type);
1685 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1687 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1691 return objc_build_constructor (type, nreverse (initlist));
1694 /* Generate forward declarations for metadata such as
1695 'OBJC_CLASS_...'. */
1698 build_metadata_decl (const char *name, tree type)
1700 tree decl, decl_specs;
1701 /* extern struct TYPE NAME_<name>; */
1702 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1703 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1704 decl = define_decl (synth_id_with_class_suffix
1706 objc_implementation_context),
1708 TREE_USED (decl) = 1;
1709 DECL_ARTIFICIAL (decl) = 1;
1710 TREE_PUBLIC (decl) = 0;
1714 /* Push forward-declarations of all the categories so that
1715 init_def_list can use them in a CONSTRUCTOR. */
1718 forward_declare_categories (void)
1720 struct imp_entry *impent;
1721 tree sav = objc_implementation_context;
1723 for (impent = imp_list; impent; impent = impent->next)
1725 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1727 /* Set an invisible arg to synth_id_with_class_suffix. */
1728 objc_implementation_context = impent->imp_context;
1729 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1730 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1731 objc_category_template);
1734 objc_implementation_context = sav;
1737 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1738 and initialized appropriately. */
1741 generate_objc_symtab_decl (void)
1745 if (!objc_category_template)
1746 build_category_template ();
1748 /* forward declare categories */
1750 forward_declare_categories ();
1752 if (!objc_symtab_template)
1753 build_objc_symtab_template ();
1755 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1757 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1758 tree_cons (NULL_TREE,
1759 objc_symtab_template, sc_spec),
1763 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1764 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1765 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1766 finish_decl (UOBJC_SYMBOLS_decl,
1767 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1772 init_module_descriptor (tree type)
1774 tree initlist, expr;
1776 /* version = { 1, ... } */
1778 expr = build_int_2 (OBJC_VERSION, 0);
1779 initlist = build_tree_list (NULL_TREE, expr);
1781 /* size = { ..., sizeof (struct objc_module), ... } */
1783 expr = size_in_bytes (objc_module_template);
1784 initlist = tree_cons (NULL_TREE, expr, initlist);
1786 /* name = { ..., "foo.m", ... } */
1788 expr = add_objc_string (get_identifier (input_filename), class_names);
1789 initlist = tree_cons (NULL_TREE, expr, initlist);
1791 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1793 if (UOBJC_SYMBOLS_decl)
1794 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1796 expr = build_int_2 (0, 0);
1797 initlist = tree_cons (NULL_TREE, expr, initlist);
1799 return objc_build_constructor (type, nreverse (initlist));
1802 /* Write out the data structures to describe Objective C classes defined.
1803 If appropriate, compile and output a setup function to initialize them.
1804 Return a symbol_ref to the function to call to initialize the Objective C
1805 data structures for this file (and perhaps for other files also).
1807 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1810 build_module_descriptor (void)
1812 tree decl_specs, field_decl, field_decl_chain;
1814 objc_module_template
1815 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1819 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1820 field_decl = get_identifier ("version");
1821 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1822 field_decl_chain = field_decl;
1826 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1827 field_decl = get_identifier ("size");
1828 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1829 chainon (field_decl_chain, field_decl);
1833 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1834 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1835 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1836 chainon (field_decl_chain, field_decl);
1838 /* struct objc_symtab *symtab; */
1840 decl_specs = get_identifier (UTAG_SYMTAB);
1841 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1842 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1843 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1844 chainon (field_decl_chain, field_decl);
1846 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1848 /* Create an instance of "objc_module". */
1850 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1851 build_tree_list (NULL_TREE,
1852 ridpointers[(int) RID_STATIC]));
1854 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1855 decl_specs, 1, NULL_TREE);
1857 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1858 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1859 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1861 finish_decl (UOBJC_MODULES_decl,
1862 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1865 /* Mark the decl to avoid "defined but not used" warning. */
1866 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1868 /* Generate a constructor call for the module descriptor.
1869 This code was generated by reading the grammar rules
1870 of c-parse.in; Therefore, it may not be the most efficient
1871 way of generating the requisite code. */
1873 if (flag_next_runtime)
1877 tree parms, execclass_decl, decelerator, void_list_node_1;
1878 tree init_function_name, init_function_decl;
1880 /* Declare void __objc_execClass (void *); */
1882 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1883 execclass_decl = build_decl (FUNCTION_DECL,
1884 get_identifier (TAG_EXECCLASS),
1885 build_function_type (void_type_node,
1886 tree_cons (NULL_TREE, ptr_type_node,
1889 DECL_EXTERNAL (execclass_decl) = 1;
1890 DECL_ARTIFICIAL (execclass_decl) = 1;
1891 TREE_PUBLIC (execclass_decl) = 1;
1892 pushdecl (execclass_decl);
1893 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1894 assemble_external (execclass_decl);
1896 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1898 init_function_name = get_file_function_name ('I');
1899 start_function (void_list_node_1,
1900 build_nt (CALL_EXPR, init_function_name,
1901 tree_cons (NULL_TREE, NULL_TREE,
1905 store_parm_decls ();
1907 init_function_decl = current_function_decl;
1908 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1909 TREE_USED (init_function_decl) = 1;
1910 /* Don't let this one be deferred. */
1911 DECL_INLINE (init_function_decl) = 0;
1912 DECL_UNINLINABLE (init_function_decl) = 1;
1913 current_function_cannot_inline
1914 = "static constructors and destructors cannot be inlined";
1917 = build_tree_list (NULL_TREE,
1918 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1919 decelerator = build_function_call (execclass_decl, parms);
1921 c_expand_expr_stmt (decelerator);
1925 return XEXP (DECL_RTL (init_function_decl), 0);
1929 /* Return the DECL of the string IDENT in the SECTION. */
1932 get_objc_string_decl (tree ident, enum string_section section)
1936 if (section == class_names)
1937 chain = class_names_chain;
1938 else if (section == meth_var_names)
1939 chain = meth_var_names_chain;
1940 else if (section == meth_var_types)
1941 chain = meth_var_types_chain;
1945 for (; chain != 0; chain = TREE_CHAIN (chain))
1946 if (TREE_VALUE (chain) == ident)
1947 return (TREE_PURPOSE (chain));
1953 /* Output references to all statically allocated objects. Return the DECL
1954 for the array built. */
1957 generate_static_references (void)
1959 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1960 tree class_name, class, decl, initlist;
1961 tree cl_chain, in_chain, type;
1962 int num_inst, num_class;
1965 if (flag_next_runtime)
1968 for (cl_chain = objc_static_instances, num_class = 0;
1969 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1971 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1972 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1974 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1975 ident = get_identifier (buf);
1977 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1978 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1979 build_tree_list (NULL_TREE,
1980 ridpointers[(int) RID_STATIC]));
1981 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1982 DECL_CONTEXT (decl) = 0;
1983 DECL_ARTIFICIAL (decl) = 1;
1985 /* Output {class_name, ...}. */
1986 class = TREE_VALUE (cl_chain);
1987 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
1988 initlist = build_tree_list (NULL_TREE,
1989 build_unary_op (ADDR_EXPR, class_name, 1));
1991 /* Output {..., instance, ...}. */
1992 for (in_chain = TREE_PURPOSE (cl_chain);
1993 in_chain; in_chain = TREE_CHAIN (in_chain))
1995 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1996 initlist = tree_cons (NULL_TREE, expr, initlist);
1999 /* Output {..., NULL}. */
2000 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2002 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2003 finish_decl (decl, expr, NULL_TREE);
2004 TREE_USED (decl) = 1;
2006 type = build_array_type (build_pointer_type (void_type_node), 0);
2007 decl = build_decl (VAR_DECL, ident, type);
2008 TREE_USED (decl) = 1;
2009 TREE_STATIC (decl) = 1;
2011 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2014 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2015 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2016 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2017 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2018 build_tree_list (NULL_TREE,
2019 ridpointers[(int) RID_STATIC]));
2020 static_instances_decl
2021 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2022 TREE_USED (static_instances_decl) = 1;
2023 DECL_CONTEXT (static_instances_decl) = 0;
2024 DECL_ARTIFICIAL (static_instances_decl) = 1;
2025 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2027 finish_decl (static_instances_decl, expr, NULL_TREE);
2030 /* Output all strings. */
2033 generate_strings (void)
2035 tree sc_spec, decl_specs, expr_decl;
2036 tree chain, string_expr;
2039 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2041 string = TREE_VALUE (chain);
2042 decl = TREE_PURPOSE (chain);
2044 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2045 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2046 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2047 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2048 DECL_CONTEXT (decl) = NULL_TREE;
2049 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2050 IDENTIFIER_POINTER (string));
2051 finish_decl (decl, string_expr, NULL_TREE);
2054 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2056 string = TREE_VALUE (chain);
2057 decl = TREE_PURPOSE (chain);
2059 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2060 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2061 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2062 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2063 DECL_CONTEXT (decl) = NULL_TREE;
2064 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2065 IDENTIFIER_POINTER (string));
2066 finish_decl (decl, string_expr, NULL_TREE);
2069 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2071 string = TREE_VALUE (chain);
2072 decl = TREE_PURPOSE (chain);
2074 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2075 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2076 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2077 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2078 DECL_CONTEXT (decl) = NULL_TREE;
2079 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2080 IDENTIFIER_POINTER (string));
2081 finish_decl (decl, string_expr, NULL_TREE);
2085 static GTY(()) int selector_reference_idx;
2088 build_selector_reference_decl (void)
2093 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2095 ident = get_identifier (buf);
2097 decl = build_decl (VAR_DECL, ident, selector_type);
2098 DECL_EXTERNAL (decl) = 1;
2099 TREE_PUBLIC (decl) = 0;
2100 TREE_USED (decl) = 1;
2101 DECL_ARTIFICIAL (decl) = 1;
2102 DECL_CONTEXT (decl) = 0;
2104 make_decl_rtl (decl, 0);
2105 pushdecl_top_level (decl);
2110 /* Just a handy wrapper for add_objc_string. */
2113 build_selector (tree ident)
2115 tree expr = add_objc_string (ident, meth_var_names);
2116 if (flag_typed_selectors)
2119 return build_c_cast (selector_type, expr); /* cast! */
2123 build_selector_translation_table (void)
2125 tree sc_spec, decl_specs;
2126 tree chain, initlist = NULL_TREE;
2128 tree decl = NULL_TREE, var_decl, name;
2130 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2134 if (warn_selector && objc_implementation_context)
2138 for (method_chain = meth_var_names_chain;
2140 method_chain = TREE_CHAIN (method_chain))
2142 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2150 /* Adjust line number for warning message. */
2151 int save_lineno = input_line;
2152 if (flag_next_runtime && TREE_PURPOSE (chain))
2153 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2154 warning ("creating selector for non existant method %s",
2155 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2156 input_line = save_lineno;
2160 expr = build_selector (TREE_VALUE (chain));
2162 if (flag_next_runtime)
2164 name = DECL_NAME (TREE_PURPOSE (chain));
2166 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2168 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2169 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2173 /* The `decl' that is returned from start_decl is the one that we
2174 forward declared in `build_selector_reference' */
2175 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2178 /* add one for the '\0' character */
2179 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2181 if (flag_next_runtime)
2182 finish_decl (decl, expr, NULL_TREE);
2185 if (flag_typed_selectors)
2187 tree eltlist = NULL_TREE;
2188 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2189 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2190 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2191 expr = objc_build_constructor (objc_selector_template,
2192 nreverse (eltlist));
2194 initlist = tree_cons (NULL_TREE, expr, initlist);
2199 if (! flag_next_runtime)
2201 /* Cause the variable and its initial value to be actually output. */
2202 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2203 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2204 /* NULL terminate the list and fix the decl for output. */
2205 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2206 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2207 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2208 nreverse (initlist));
2209 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2210 current_function_decl = NULL_TREE;
2215 get_proto_encoding (tree proto)
2220 if (! METHOD_ENCODING (proto))
2222 encoding = encode_method_prototype (proto);
2223 METHOD_ENCODING (proto) = encoding;
2226 encoding = METHOD_ENCODING (proto);
2228 return add_objc_string (encoding, meth_var_types);
2231 return build_int_2 (0, 0);
2234 /* sel_ref_chain is a list whose "value" fields will be instances of
2235 identifier_node that represent the selector. */
2238 build_typed_selector_reference (tree ident, tree prototype)
2240 tree *chain = &sel_ref_chain;
2246 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2247 goto return_at_index;
2250 chain = &TREE_CHAIN (*chain);
2253 *chain = tree_cons (prototype, ident, NULL_TREE);
2256 expr = build_unary_op (ADDR_EXPR,
2257 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2258 build_int_2 (index, 0)),
2260 return build_c_cast (selector_type, expr);
2264 build_selector_reference (tree ident)
2266 tree *chain = &sel_ref_chain;
2272 if (TREE_VALUE (*chain) == ident)
2273 return (flag_next_runtime
2274 ? TREE_PURPOSE (*chain)
2275 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2276 build_int_2 (index, 0)));
2279 chain = &TREE_CHAIN (*chain);
2282 expr = build_selector_reference_decl ();
2284 *chain = tree_cons (expr, ident, NULL_TREE);
2286 return (flag_next_runtime
2288 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2289 build_int_2 (index, 0)));
2292 static GTY(()) int class_reference_idx;
2295 build_class_reference_decl (void)
2300 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2302 ident = get_identifier (buf);
2304 decl = build_decl (VAR_DECL, ident, objc_class_type);
2305 DECL_EXTERNAL (decl) = 1;
2306 TREE_PUBLIC (decl) = 0;
2307 TREE_USED (decl) = 1;
2308 DECL_CONTEXT (decl) = 0;
2309 DECL_ARTIFICIAL (decl) = 1;
2311 make_decl_rtl (decl, 0);
2312 pushdecl_top_level (decl);
2317 /* Create a class reference, but don't create a variable to reference
2321 add_class_reference (tree ident)
2325 if ((chain = cls_ref_chain))
2330 if (ident == TREE_VALUE (chain))
2334 chain = TREE_CHAIN (chain);
2338 /* Append to the end of the list */
2339 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2342 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2345 /* Get a class reference, creating it if necessary. Also create the
2346 reference variable. */
2349 get_class_reference (tree ident)
2354 if (processing_template_decl)
2355 /* Must wait until template instantiation time. */
2356 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2357 if (TREE_CODE (ident) == TYPE_DECL)
2358 ident = DECL_NAME (ident);
2362 if (!(ident = is_class_name (ident)))
2364 error ("`%s' is not an Objective-C class name or alias",
2365 IDENTIFIER_POINTER (orig_ident));
2366 return error_mark_node;
2369 if (flag_next_runtime && !flag_zero_link)
2374 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2375 if (TREE_VALUE (*chain) == ident)
2377 if (! TREE_PURPOSE (*chain))
2378 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2380 return TREE_PURPOSE (*chain);
2383 decl = build_class_reference_decl ();
2384 *chain = tree_cons (decl, ident, NULL_TREE);
2391 add_class_reference (ident);
2393 params = build_tree_list (NULL_TREE,
2394 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2395 IDENTIFIER_POINTER (ident)));
2397 assemble_external (objc_get_class_decl);
2398 return build_function_call (objc_get_class_decl, params);
2402 /* For each string section we have a chain which maps identifier nodes
2403 to decls for the strings. */
2406 add_objc_string (tree ident, enum string_section section)
2410 if (section == class_names)
2411 chain = &class_names_chain;
2412 else if (section == meth_var_names)
2413 chain = &meth_var_names_chain;
2414 else if (section == meth_var_types)
2415 chain = &meth_var_types_chain;
2421 if (TREE_VALUE (*chain) == ident)
2422 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2424 chain = &TREE_CHAIN (*chain);
2427 decl = build_objc_string_decl (section);
2429 *chain = tree_cons (decl, ident, NULL_TREE);
2431 return build_unary_op (ADDR_EXPR, decl, 1);
2434 static GTY(()) int class_names_idx;
2435 static GTY(()) int meth_var_names_idx;
2436 static GTY(()) int meth_var_types_idx;
2439 build_objc_string_decl (enum string_section section)
2444 if (section == class_names)
2445 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2446 else if (section == meth_var_names)
2447 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2448 else if (section == meth_var_types)
2449 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2451 ident = get_identifier (buf);
2453 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2454 DECL_EXTERNAL (decl) = 1;
2455 TREE_PUBLIC (decl) = 0;
2456 TREE_USED (decl) = 1;
2457 TREE_CONSTANT (decl) = 1;
2458 DECL_CONTEXT (decl) = 0;
2459 DECL_ARTIFICIAL (decl) = 1;
2461 make_decl_rtl (decl, 0);
2462 pushdecl_top_level (decl);
2469 objc_declare_alias (tree alias_ident, tree class_ident)
2471 tree underlying_class;
2474 if (current_namespace != global_namespace) {
2475 error ("Objective-C declarations may only appear in global scope");
2477 #endif /* OBJCPLUS */
2479 if (!(underlying_class = is_class_name (class_ident)))
2480 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2481 else if (is_class_name (alias_ident))
2482 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2484 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2488 objc_declare_class (tree ident_list)
2492 if (current_namespace != global_namespace) {
2493 error ("Objective-C declarations may only appear in global scope");
2495 #endif /* OBJCPLUS */
2497 for (list = ident_list; list; list = TREE_CHAIN (list))
2499 tree ident = TREE_VALUE (list);
2501 if (! is_class_name (ident))
2503 tree record = lookup_name (ident);
2505 if (record && ! TREE_STATIC_TEMPLATE (record))
2507 error ("`%s' redeclared as different kind of symbol",
2508 IDENTIFIER_POINTER (ident));
2509 error ("%Jprevious declaration of '%D'",
2513 record = xref_tag (RECORD_TYPE, ident);
2514 TREE_STATIC_TEMPLATE (record) = 1;
2515 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2521 is_class_name (tree ident)
2525 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2526 && identifier_global_value (ident))
2527 ident = identifier_global_value (ident);
2528 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2529 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2532 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2533 ident = TYPE_NAME (ident);
2534 if (ident && TREE_CODE (ident) == TYPE_DECL)
2535 ident = DECL_NAME (ident);
2537 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2540 if (lookup_interface (ident))
2543 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2545 if (ident == TREE_VALUE (chain))
2549 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2551 if (ident == TREE_VALUE (chain))
2552 return TREE_PURPOSE (chain);
2558 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2559 class instance. This is needed by other parts of the compiler to
2560 handle ObjC types gracefully. */
2563 objc_is_object_ptr (tree type)
2565 type = TYPE_MAIN_VARIANT (type);
2566 if (!type || TREE_CODE (type) != POINTER_TYPE)
2568 /* NB: This function may be called before the ObjC front-end has
2569 been initialized, in which case ID_TYPE will be NULL. */
2570 if (id_type && type && TYPE_P (type)
2572 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2574 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2578 lookup_interface (tree ident)
2583 if (ident && TREE_CODE (ident) == TYPE_DECL)
2584 ident = DECL_NAME (ident);
2586 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2588 if (ident == CLASS_NAME (chain))
2594 /* Implement @defs (<classname>) within struct bodies. */
2597 get_class_ivars_from_name (tree class_name)
2599 tree interface = lookup_interface (class_name);
2600 tree field, fields = NULL_TREE;
2604 tree raw_ivar = get_class_ivars (interface, 1);
2606 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2607 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2609 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2610 TREE_PURPOSE (raw_ivar),
2611 TREE_VALUE (TREE_VALUE (raw_ivar)));
2613 finish_member_declaration (field);
2615 fields = chainon (fields, field);
2620 error ("cannot find interface declaration for `%s'",
2621 IDENTIFIER_POINTER (class_name));
2626 /* Used by: build_private_template, continue_class,
2627 and for @defs constructs. */
2630 get_class_ivars (tree interface, int raw)
2632 tree my_name, super_name, ivar_chain;
2634 my_name = CLASS_NAME (interface);
2635 super_name = CLASS_SUPER_NAME (interface);
2637 ivar_chain = CLASS_RAW_IVARS (interface);
2640 ivar_chain = CLASS_IVARS (interface);
2641 /* Save off a pristine copy of the leaf ivars (i.e, those not
2642 inherited from a super class). */
2643 if (!CLASS_OWN_IVARS (interface))
2644 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2650 tree super_interface = lookup_interface (super_name);
2652 if (!super_interface)
2654 /* fatal did not work with 2 args...should fix */
2655 error ("cannot find interface declaration for `%s', superclass of `%s'",
2656 IDENTIFIER_POINTER (super_name),
2657 IDENTIFIER_POINTER (my_name));
2658 exit (FATAL_EXIT_CODE);
2661 if (super_interface == interface)
2662 fatal_error ("circular inheritance in interface declaration for `%s'",
2663 IDENTIFIER_POINTER (super_name));
2665 interface = super_interface;
2666 my_name = CLASS_NAME (interface);
2667 super_name = CLASS_SUPER_NAME (interface);
2669 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2672 tree head = copy_list (op1);
2674 /* Prepend super class ivars...make a copy of the list, we
2675 do not want to alter the original. */
2676 chainon (head, ivar_chain);
2685 objc_enter_block (void)
2690 block = begin_compound_stmt (0);
2692 block = c_begin_compound_stmt ();
2695 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
2698 objc_exception_block_stack = tree_cons (NULL_TREE, block,
2699 objc_exception_block_stack);
2701 blk_nesting_count++;
2706 objc_exit_block (void)
2708 tree block = TREE_VALUE (objc_exception_block_stack);
2710 tree scope_stmt, inner;
2713 objc_clear_super_receiver ();
2715 finish_compound_stmt (0, block);
2717 scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
2718 inner = pop_scope ();
2720 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
2721 = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
2723 RECHAIN_STMTS (block, COMPOUND_BODY (block));
2725 last_expr_type = NULL_TREE;
2726 objc_exception_block_stack = TREE_CHAIN (objc_exception_block_stack);
2728 blk_nesting_count--;
2733 objc_declare_variable (enum rid scspec, tree name, tree type, tree init)
2737 type = tree_cons (NULL_TREE, type,
2738 tree_cons (NULL_TREE, ridpointers[(int) scspec],
2740 TREE_STATIC (type) = 1;
2741 decl = start_decl (name, type, (init != NULL_TREE), NULL_TREE);
2742 finish_decl (decl, init, NULL_TREE);
2743 /* This prevents `unused variable' warnings when compiling with -Wall. */
2744 TREE_USED (decl) = 1;
2745 DECL_ARTIFICIAL (decl) = 1;
2750 objc_build_throw_stmt (tree throw_expr)
2754 if (!flag_objc_exceptions)
2755 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2757 if (!throw_expr && objc_caught_exception)
2758 throw_expr = TREE_VALUE (objc_caught_exception);
2762 error ("`@throw;' (rethrow) used outside of a `@catch' block");
2763 return error_mark_node;
2766 func_params = tree_cons (NULL_TREE, throw_expr, NULL_TREE);
2768 assemble_external (objc_exception_throw_decl);
2769 return c_expand_expr_stmt (build_function_call (objc_exception_throw_decl,
2774 val_stack_push (struct val_stack **nc, long val)
2776 struct val_stack *new_elem = xmalloc (sizeof (struct val_stack));
2777 new_elem->val = val;
2778 new_elem->next = *nc;
2783 val_stack_pop (struct val_stack **nc)
2785 struct val_stack *old_elem = *nc;
2786 *nc = old_elem->next;
2791 objc_build_try_enter_fragment (void)
2793 /* objc_exception_try_enter(&_stackExceptionData);
2794 if (!_setjmp(&_stackExceptionData.buf)) { */
2796 tree func_params, if_stmt, cond;
2799 = tree_cons (NULL_TREE,
2800 build_unary_op (ADDR_EXPR,
2801 TREE_VALUE (objc_stack_exception_data),
2805 assemble_external (objc_exception_try_enter_decl);
2806 c_expand_expr_stmt (build_function_call
2807 (objc_exception_try_enter_decl, func_params));
2809 if_stmt = c_begin_if_stmt ();
2811 /* If <setjmp.h> has been included, the _setjmp prototype has
2812 acquired a real, breathing type for its parameter. Cast our
2813 argument to that type. */
2815 = tree_cons (NULL_TREE,
2816 build_c_cast (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))
2817 ? TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
2821 build_component_ref (TREE_VALUE (objc_stack_exception_data),
2822 get_identifier ("buf")), 0)),
2824 assemble_external (objc_setjmp_decl);
2825 cond = build_unary_op (TRUTH_NOT_EXPR,
2826 build_function_call (objc_setjmp_decl, func_params),
2828 c_expand_start_cond (lang_hooks.truthvalue_conversion (cond), 0, if_stmt);
2829 objc_enter_block ();
2833 objc_build_extract_expr (void)
2835 /* ... = objc_exception_extract(&_stackExceptionData); */
2838 = tree_cons (NULL_TREE,
2839 build_unary_op (ADDR_EXPR,
2840 TREE_VALUE (objc_stack_exception_data), 0),
2843 assemble_external (objc_exception_extract_decl);
2844 return build_function_call (objc_exception_extract_decl, func_params);
2848 objc_build_try_exit_fragment (void)
2850 /* objc_exception_try_exit(&_stackExceptionData); */
2853 = tree_cons (NULL_TREE,
2854 build_unary_op (ADDR_EXPR,
2855 TREE_VALUE (objc_stack_exception_data), 0),
2858 assemble_external (objc_exception_try_exit_decl);
2859 c_expand_expr_stmt (build_function_call (objc_exception_try_exit_decl,
2864 objc_build_extract_fragment (void)
2867 _rethrowException = objc_exception_extract(&_stackExceptionData);
2873 c_expand_start_else ();
2874 objc_enter_block ();
2875 c_expand_expr_stmt (build_modify_expr
2876 (TREE_VALUE (objc_rethrow_exception),
2878 objc_build_extract_expr ()));
2881 c_expand_end_cond ();
2886 objc_build_try_prologue (void)
2889 struct _objc_exception_data _stackExceptionData;
2890 volatile id _rethrowException = nil;
2891 { // begin TRY-CATCH scope
2892 objc_exception_try_enter(&_stackExceptionData);
2893 if (!_setjmp(&_stackExceptionData.buf)) { */
2895 tree try_catch_block;
2897 if (!flag_objc_exceptions)
2898 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2900 objc_mark_locals_volatile ((void *)(exc_binding_stack
2901 ? exc_binding_stack->val
2903 objc_enter_block ();
2904 objc_stack_exception_data
2905 = tree_cons (NULL_TREE,
2906 objc_declare_variable (RID_AUTO,
2907 get_identifier (UTAG_EXCDATA_VAR),
2908 xref_tag (RECORD_TYPE,
2909 get_identifier (UTAG_EXCDATA)),
2911 objc_stack_exception_data);
2912 objc_rethrow_exception = tree_cons (NULL_TREE,
2913 objc_declare_variable (RID_VOLATILE,
2914 get_identifier (UTAG_RETHROWEXC_VAR),
2916 build_int_2 (0, 0)),
2917 objc_rethrow_exception);
2919 try_catch_block = objc_enter_block ();
2920 val_stack_push (&exc_binding_stack, (long) get_current_scope ());
2921 objc_build_try_enter_fragment ();
2923 return try_catch_block;
2927 objc_build_try_epilogue (int also_catch_prologue)
2929 if (also_catch_prologue)
2932 register id _caughtException = objc_exception_extract( &_stackExceptionData);
2933 objc_exception_try_enter(&_stackExceptionData);
2934 if(!_setjmp(&_stackExceptionData.buf)) {
2942 c_expand_start_else ();
2943 objc_enter_block ();
2944 objc_caught_exception
2945 = tree_cons (NULL_TREE,
2946 objc_declare_variable (RID_REGISTER,
2947 get_identifier (UTAG_CAUGHTEXC_VAR),
2949 objc_build_extract_expr ()),
2950 objc_caught_exception);
2951 objc_build_try_enter_fragment ();
2952 val_stack_push (&catch_count_stack, 1);
2953 if_stmt = c_begin_if_stmt ();
2955 c_expand_start_cond (lang_hooks.truthvalue_conversion (boolean_false_node),
2957 objc_enter_block ();
2959 /* Start a new chain of @catch statements for this @try. */
2960 objc_catch_type = tree_cons (objc_catch_type, NULL_TREE, NULL_TREE);
2963 { /* !also_catch_prologue */
2966 _rethrowException = objc_exception_extract( &_stackExceptionData);
2969 objc_build_extract_fragment ();
2975 objc_build_catch_stmt (tree catch_expr)
2977 /* } else if (objc_exception_match(objc_get_class("SomeClass"), _caughtException)) {
2978 register SomeClass *e = _caughtException; */
2980 tree if_stmt, cond, func_params, prev_catch, var_name, var_type;
2984 /* Yet another C/C++ impedance mismatch. */
2985 catch_expr = TREE_PURPOSE (catch_expr);
2988 var_name = TREE_VALUE (catch_expr);
2989 var_type = TREE_VALUE (TREE_PURPOSE (catch_expr));
2990 if (TREE_CODE (var_name) == INDIRECT_REF)
2991 var_name = TREE_OPERAND (var_name, 0);
2992 if (TREE_CODE (var_type) == TYPE_DECL
2993 || TREE_CODE (var_type) == POINTER_TYPE)
2994 var_type = TREE_TYPE (var_type);
2995 catch_id = (var_type == TREE_TYPE (id_type));
2997 if (!flag_objc_exceptions)
2998 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3000 if (!(catch_id || TYPED_OBJECT (var_type)))
3001 fatal_error ("`@catch' parameter is not a known Objective-C class type");
3003 /* Examine previous @catch clauses for the current @try block for
3004 superclasses of the 'var_type' class. */
3005 for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch);
3006 prev_catch = TREE_CHAIN (prev_catch))
3008 if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
3010 warning ("Exception already handled by preceding `@catch(id)'");
3014 && objc_comptypes (TREE_VALUE (prev_catch), var_type, 0) == 1)
3015 warning ("Exception of type `%s *' already handled by `@catch (%s *)'",
3016 IDENTIFIER_POINTER (OBJC_TYPE_NAME (var_type)),
3017 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_VALUE (prev_catch))));
3020 objc_catch_type = tree_cons (NULL_TREE, var_type, objc_catch_type);
3025 c_expand_start_else ();
3026 catch_count_stack->val++;
3027 if_stmt = c_begin_if_stmt ();
3031 cond = integer_one_node;
3034 cond = get_class_reference (OBJC_TYPE_NAME (var_type));
3037 = tree_cons (NULL_TREE, cond,
3038 tree_cons (NULL_TREE,
3039 TREE_VALUE (objc_caught_exception),
3041 assemble_external (objc_exception_match_decl);
3042 cond = build_function_call (objc_exception_match_decl, func_params);
3045 c_expand_start_cond (lang_hooks.truthvalue_conversion (cond), 0, if_stmt);
3046 objc_enter_block ();
3047 objc_declare_variable (RID_REGISTER, var_name,
3048 build_pointer_type (var_type),
3049 TREE_VALUE (objc_caught_exception));
3053 objc_build_catch_epilogue (void)
3056 _rethrowException = _caughtException;
3057 objc_exception_try_exit(&_stackExceptionData);
3060 _rethrowException = objc_exception_extract(&_stackExceptionData);
3063 } // end TRY-CATCH scope
3069 c_expand_start_else ();
3070 objc_enter_block ();
3073 (TREE_VALUE (objc_rethrow_exception),
3075 TREE_VALUE (objc_caught_exception)));
3076 objc_build_try_exit_fragment ();
3078 while (catch_count_stack->val--)
3080 c_finish_else (); /* close off all the nested ifs ! */
3081 c_expand_end_cond ();
3084 val_stack_pop (&catch_count_stack);
3085 objc_caught_exception = TREE_CHAIN (objc_caught_exception);
3087 objc_build_extract_fragment ();
3091 c_expand_end_cond ();
3095 /* Return to enclosing chain of @catch statements (if any). */
3096 while (TREE_VALUE (objc_catch_type))
3097 objc_catch_type = TREE_CHAIN (objc_catch_type);
3098 objc_catch_type = TREE_PURPOSE (objc_catch_type);
3102 objc_build_finally_prologue (void)
3104 /* { // begin FINALLY scope
3105 if (!_rethrowException) {
3106 objc_exception_try_exit(&_stackExceptionData);
3109 tree blk = objc_enter_block ();
3111 tree if_stmt = c_begin_if_stmt ();
3114 c_expand_start_cond (lang_hooks.truthvalue_conversion
3115 (build_unary_op (TRUTH_NOT_EXPR,
3116 TREE_VALUE (objc_rethrow_exception),
3119 objc_enter_block ();
3120 objc_build_try_exit_fragment ();
3123 c_expand_end_cond ();
3130 objc_build_finally_epilogue (void)
3132 /* if (_rethrowException) {
3133 objc_exception_throw(_rethrowException);
3135 } // end FINALLY scope
3138 tree if_stmt = c_begin_if_stmt ();
3142 (lang_hooks.truthvalue_conversion (TREE_VALUE (objc_rethrow_exception)),
3144 objc_enter_block ();
3145 objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception));
3148 c_expand_end_cond ();
3152 objc_rethrow_exception = TREE_CHAIN (objc_rethrow_exception);
3153 objc_stack_exception_data = TREE_CHAIN (objc_stack_exception_data);
3155 val_stack_pop (&exc_binding_stack);
3156 return objc_exit_block ();
3160 objc_build_try_catch_finally_stmt (int has_catch, int has_finally)
3162 /* NB: The operative assumption here is that TRY_FINALLY_EXPR will
3163 deal with all exits from 'try_catch_blk' and route them through
3165 tree outer_blk = objc_build_finally_epilogue ();
3166 tree prec_stmt = TREE_CHAIN (TREE_CHAIN (COMPOUND_BODY (outer_blk)));
3167 tree try_catch_blk = TREE_CHAIN (prec_stmt), try_catch_expr;
3168 tree finally_blk = TREE_CHAIN (try_catch_blk), finally_expr;
3169 tree succ_stmt = TREE_CHAIN (finally_blk);
3170 tree try_finally_stmt, try_finally_expr;
3172 if (!flag_objc_exceptions)
3173 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3175 /* It is an error to have a @try block without a @catch and/or @finally
3176 (even though sensible code can be generated nonetheless). */
3178 if (!has_catch && !has_finally)
3179 error ("`@try' without `@catch' or `@finally'");
3181 /* We shall now do something truly disgusting. We shall remove the
3182 'try_catch_blk' and 'finally_blk' from the 'outer_blk' statement
3183 chain, and replace them with a TRY_FINALLY_EXPR statement! If
3184 this doesn't work, we will have to learn (from Per/gcj) how to
3185 construct the 'outer_blk' lazily. */
3187 TREE_CHAIN (try_catch_blk) = TREE_CHAIN (finally_blk) = NULL_TREE;
3188 try_catch_expr = build1 (STMT_EXPR, void_type_node, try_catch_blk);
3189 TREE_SIDE_EFFECTS (try_catch_expr) = 1;
3190 finally_expr = build1 (STMT_EXPR, void_type_node, finally_blk);
3191 TREE_SIDE_EFFECTS (finally_expr) = 1;
3192 try_finally_expr = build (TRY_FINALLY_EXPR, void_type_node, try_catch_expr,
3194 TREE_SIDE_EFFECTS (try_finally_expr) = 1;
3195 try_finally_stmt = build_stmt (EXPR_STMT, try_finally_expr);
3196 TREE_CHAIN (prec_stmt) = try_finally_stmt;
3197 TREE_CHAIN (try_finally_stmt) = succ_stmt;
3199 return outer_blk; /* the whole enchilada */
3203 objc_build_synchronized_prologue (tree sync_expr)
3206 id _eval_once = <sync_expr>;
3208 objc_sync_enter( _eval_once ); */
3212 if (!flag_objc_exceptions)
3213 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3215 objc_enter_block ();
3217 = tree_cons (NULL_TREE,
3218 objc_declare_variable (RID_AUTO,
3219 get_identifier (UTAG_EVALONCE_VAR),
3223 objc_build_try_prologue ();
3224 objc_enter_block ();
3225 func_params = tree_cons (NULL_TREE,
3226 TREE_VALUE (objc_eval_once),
3229 assemble_external (objc_sync_enter_decl);
3230 c_expand_expr_stmt (build_function_call
3231 (objc_sync_enter_decl, func_params));
3235 objc_build_synchronized_epilogue (void)
3239 objc_sync_exit( _eval_once );
3246 objc_build_try_epilogue (0);
3247 objc_build_finally_prologue ();
3248 func_params = tree_cons (NULL_TREE, TREE_VALUE (objc_eval_once),
3251 assemble_external (objc_sync_exit_decl);
3252 c_expand_expr_stmt (build_function_call (objc_sync_exit_decl,
3254 objc_build_try_catch_finally_stmt (0, 1);
3256 return objc_exit_block ();
3259 /* Predefine the following data type:
3261 struct _objc_exception_data
3267 /* The following yuckiness should prevent users from having to #include
3268 <setjmp.h> in their code... */
3270 #ifdef TARGET_POWERPC
3271 /* snarfed from /usr/include/ppc/setjmp.h */
3272 #define _JBLEN (26 + 36 + 129 + 1)
3274 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3279 build_objc_exception_stuff (void)
3281 tree field_decl, field_decl_chain, index, temp_type;
3283 /* Suppress outputting debug symbols, because
3284 dbxout_init hasn't been called yet. */
3285 enum debug_info_type save_write_symbols = write_symbols;
3286 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3288 write_symbols = NO_DEBUG;
3289 debug_hooks = &do_nothing_debug_hooks;
3290 objc_exception_data_template
3291 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3293 /* int buf[_JBLEN]; */
3295 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3296 field_decl = create_builtin_decl (FIELD_DECL,
3297 build_array_type (integer_type_node, index),
3299 field_decl_chain = field_decl;
3301 /* void *pointers[4]; */
3303 index = build_index_type (build_int_2 (4 - 1, 0));
3304 field_decl = create_builtin_decl (FIELD_DECL,
3305 build_array_type (ptr_type_node, index),
3307 chainon (field_decl_chain, field_decl);
3309 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3311 /* int _setjmp(...); */
3312 /* If the user includes <setjmp.h>, this shall be superseded by
3313 'int _setjmp(jmp_buf);' */
3314 temp_type = build_function_type (integer_type_node, NULL_TREE);
3316 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3318 /* id objc_exception_extract(struct _objc_exception_data *); */
3320 = build_function_type (id_type,
3321 tree_cons (NULL_TREE,
3322 build_pointer_type (objc_exception_data_template),
3324 objc_exception_extract_decl
3325 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3326 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3327 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3329 = build_function_type (void_type_node,
3330 tree_cons (NULL_TREE,
3331 build_pointer_type (objc_exception_data_template),
3333 objc_exception_try_enter_decl
3334 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3335 objc_exception_try_exit_decl
3336 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3337 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3338 /* void objc_sync_enter(id); */
3339 /* void objc_sync_exit(id); */
3340 temp_type = build_function_type (void_type_node,
3341 tree_cons (NULL_TREE, id_type,
3343 objc_exception_throw_decl
3344 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3345 DECL_ATTRIBUTES (objc_exception_throw_decl)
3346 = tree_cons (get_identifier ("noreturn"), NULL_TREE, NULL_TREE);
3347 objc_sync_enter_decl
3348 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3350 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3351 /* int objc_exception_match(id, id); */
3352 temp_type = build_function_type (integer_type_node,
3353 tree_cons (NULL_TREE, id_type,
3354 tree_cons (NULL_TREE, id_type,
3356 objc_exception_match_decl
3357 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3359 write_symbols = save_write_symbols;
3360 debug_hooks = save_hooks;
3363 /* struct <classname> {
3364 struct objc_class *isa;
3369 build_private_template (tree class)
3373 if (CLASS_STATIC_TEMPLATE (class))
3375 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3376 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3380 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3381 ivar_context = get_class_ivars (class, 0);
3383 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3385 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3387 /* mark this record as class template - for class type checking */
3388 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3392 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3394 build1 (INDIRECT_REF, NULL_TREE,
3397 return ivar_context;
3400 /* Begin code generation for protocols... */
3402 /* struct objc_protocol {
3403 char *protocol_name;
3404 struct objc_protocol **protocol_list;
3405 struct objc_method_desc *instance_methods;
3406 struct objc_method_desc *class_methods;
3410 build_protocol_template (void)
3412 tree decl_specs, field_decl, field_decl_chain;
3415 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3417 /* struct objc_class *isa; */
3419 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3420 get_identifier (UTAG_CLASS)));
3421 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3422 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3423 field_decl_chain = field_decl;
3425 /* char *protocol_name; */
3427 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3429 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3430 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3431 chainon (field_decl_chain, field_decl);
3433 /* struct objc_protocol **protocol_list; */
3435 decl_specs = build_tree_list (NULL_TREE, template);
3437 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3438 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3439 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3440 chainon (field_decl_chain, field_decl);
3442 /* struct objc_method_list *instance_methods; */
3445 = build_tree_list (NULL_TREE,
3446 xref_tag (RECORD_TYPE,
3447 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3449 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3450 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3451 chainon (field_decl_chain, field_decl);
3453 /* struct objc_method_list *class_methods; */
3456 = build_tree_list (NULL_TREE,
3457 xref_tag (RECORD_TYPE,
3458 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3460 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3461 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3462 chainon (field_decl_chain, field_decl);
3464 return finish_struct (template, field_decl_chain, NULL_TREE);
3468 build_descriptor_table_initializer (tree type, tree entries)
3470 tree initlist = NULL_TREE;
3474 tree eltlist = NULL_TREE;
3477 = tree_cons (NULL_TREE,
3478 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3480 = tree_cons (NULL_TREE,
3481 add_objc_string (METHOD_ENCODING (entries),
3486 = tree_cons (NULL_TREE,
3487 objc_build_constructor (type, nreverse (eltlist)),
3490 entries = TREE_CHAIN (entries);
3494 return objc_build_constructor (build_array_type (type, 0),
3495 nreverse (initlist));
3498 /* struct objc_method_prototype_list {
3500 struct objc_method_prototype {
3507 build_method_prototype_list_template (tree list_type, int size)
3509 tree objc_ivar_list_record;
3510 tree decl_specs, field_decl, field_decl_chain;
3512 /* Generate an unnamed struct definition. */
3514 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3516 /* int method_count; */
3518 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3519 field_decl = get_identifier ("method_count");
3520 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3521 field_decl_chain = field_decl;
3523 /* struct objc_method method_list[]; */
3525 decl_specs = build_tree_list (NULL_TREE, list_type);
3526 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3527 build_int_2 (size, 0));
3528 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3529 chainon (field_decl_chain, field_decl);
3531 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3533 return objc_ivar_list_record;
3537 build_method_prototype_template (void)
3540 tree decl_specs, field_decl, field_decl_chain;
3543 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3545 /* struct objc_selector *_cmd; */
3546 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3547 get_identifier (TAG_SELECTOR)), NULL_TREE);
3548 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3549 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3550 field_decl_chain = field_decl;
3552 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3554 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3555 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3556 chainon (field_decl_chain, field_decl);
3558 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3560 return proto_record;
3564 objc_method_parm_type (tree type)
3566 type = groktypename (TREE_TYPE (type));
3567 if (TREE_CODE (type) == TYPE_DECL)
3568 type = TREE_TYPE (type);
3569 return TYPE_MAIN_VARIANT (type);
3573 objc_encoded_type_size (tree type)
3575 int sz = int_size_in_bytes (type);
3577 /* Make all integer and enum types at least as large
3579 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3580 || TREE_CODE (type) == BOOLEAN_TYPE
3581 || TREE_CODE (type) == ENUMERAL_TYPE))
3582 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3583 /* Treat arrays as pointers, since that's how they're
3585 else if (TREE_CODE (type) == ARRAY_TYPE)
3586 sz = int_size_in_bytes (ptr_type_node);
3591 encode_method_prototype (tree method_decl)
3598 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3599 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3601 /* Encode return type. */
3602 encode_type (objc_method_parm_type (method_decl),
3603 obstack_object_size (&util_obstack),
3604 OBJC_ENCODE_INLINE_DEFS);
3607 /* The first two arguments (self and _cmd) are pointers; account for
3609 i = int_size_in_bytes (ptr_type_node);
3610 parm_offset = 2 * i;
3611 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3612 parms = TREE_CHAIN (parms))
3614 tree type = objc_method_parm_type (parms);
3615 int sz = objc_encoded_type_size (type);
3617 /* If a type size is not known, bail out. */
3620 error ("%Jtype '%D' does not have a known size",
3622 /* Pretend that the encoding succeeded; the compilation will
3623 fail nevertheless. */
3624 goto finish_encoding;
3629 sprintf (buf, "%d@0:%d", parm_offset, i);
3630 obstack_grow (&util_obstack, buf, strlen (buf));
3632 /* Argument types. */
3633 parm_offset = 2 * i;
3634 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3635 parms = TREE_CHAIN (parms))
3637 tree type = objc_method_parm_type (parms);
3639 /* Process argument qualifiers for user supplied arguments. */
3640 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3643 encode_type (type, obstack_object_size (&util_obstack),
3644 OBJC_ENCODE_INLINE_DEFS);
3646 /* Compute offset. */
3647 sprintf (buf, "%d", parm_offset);
3648 parm_offset += objc_encoded_type_size (type);
3650 obstack_grow (&util_obstack, buf, strlen (buf));
3654 obstack_1grow (&util_obstack, '\0');
3655 result = get_identifier (obstack_finish (&util_obstack));
3656 obstack_free (&util_obstack, util_firstobj);
3661 generate_descriptor_table (tree type, const char *name, int size, tree list,
3664 tree sc_spec, decl_specs, decl, initlist;
3666 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3667 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3669 decl = start_decl (synth_id_with_class_suffix (name, proto),
3670 decl_specs, 1, NULL_TREE);
3671 DECL_CONTEXT (decl) = NULL_TREE;
3673 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3674 initlist = tree_cons (NULL_TREE, list, initlist);
3676 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3683 generate_method_descriptors (tree protocol)
3685 tree initlist, chain, method_list_template;
3686 tree cast, variable_length_type;
3689 if (!objc_method_prototype_template)
3690 objc_method_prototype_template = build_method_prototype_template ();
3692 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3693 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3695 variable_length_type = groktypename (cast);
3697 chain = PROTOCOL_CLS_METHODS (protocol);
3700 size = list_length (chain);
3702 method_list_template
3703 = build_method_prototype_list_template (objc_method_prototype_template,
3707 = build_descriptor_table_initializer (objc_method_prototype_template,
3710 UOBJC_CLASS_METHODS_decl
3711 = generate_descriptor_table (method_list_template,
3712 "_OBJC_PROTOCOL_CLASS_METHODS",
3713 size, initlist, protocol);
3714 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3717 UOBJC_CLASS_METHODS_decl = 0;
3719 chain = PROTOCOL_NST_METHODS (protocol);
3722 size = list_length (chain);
3724 method_list_template
3725 = build_method_prototype_list_template (objc_method_prototype_template,
3728 = build_descriptor_table_initializer (objc_method_prototype_template,
3731 UOBJC_INSTANCE_METHODS_decl
3732 = generate_descriptor_table (method_list_template,
3733 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3734 size, initlist, protocol);
3735 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3738 UOBJC_INSTANCE_METHODS_decl = 0;
3742 generate_protocol_references (tree plist)
3746 /* Forward declare protocols referenced. */
3747 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3749 tree proto = TREE_VALUE (lproto);
3751 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3752 && PROTOCOL_NAME (proto))
3754 if (! PROTOCOL_FORWARD_DECL (proto))
3755 build_protocol_reference (proto);
3757 if (PROTOCOL_LIST (proto))
3758 generate_protocol_references (PROTOCOL_LIST (proto));
3763 /* For each protocol which was referenced either from a @protocol()
3764 expression, or because a class/category implements it (then a
3765 pointer to the protocol is stored in the struct describing the
3766 class/category), we create a statically allocated instance of the
3767 Protocol class. The code is written in such a way as to generate
3768 as few Protocol objects as possible; we generate a unique Protocol
3769 instance for each protocol, and we don't generate a Protocol
3770 instance if the protocol is never referenced (either from a
3771 @protocol() or from a class/category implementation). These
3772 statically allocated objects can be referred to via the static
3773 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3775 The statically allocated Protocol objects that we generate here
3776 need to be fixed up at runtime in order to be used: the 'isa'
3777 pointer of the objects need to be set up to point to the 'Protocol'
3778 class, as known at runtime.
3780 The NeXT runtime fixes up all protocols at program startup time,
3781 before main() is entered. It uses a low-level trick to look up all
3782 those symbols, then loops on them and fixes them up.
3784 The GNU runtime as well fixes up all protocols before user code
3785 from the module is executed; it requires pointers to those symbols
3786 to be put in the objc_symtab (which is then passed as argument to
3787 the function __objc_exec_class() which the compiler sets up to be
3788 executed automatically when the module is loaded); setup of those
3789 Protocol objects happen in two ways in the GNU runtime: all
3790 Protocol objects referred to by a class or category implementation
3791 are fixed up when the class/category is loaded; all Protocol
3792 objects referred to by a @protocol() expression are added by the
3793 compiler to the list of statically allocated instances to fixup
3794 (the same list holding the statically allocated constant string
3795 objects). Because, as explained above, the compiler generates as
3796 few Protocol objects as possible, some Protocol object might end up
3797 being referenced multiple times when compiled with the GNU runtime,
3798 and end up being fixed up multiple times at runtime inizialization.
3799 But that doesn't hurt, it's just a little inefficient. */
3802 generate_protocols (void)
3805 tree sc_spec, decl_specs, decl;
3806 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3809 if (! objc_protocol_template)
3810 objc_protocol_template = build_protocol_template ();
3812 /* If a protocol was directly referenced, pull in indirect references. */
3813 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3814 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3815 generate_protocol_references (PROTOCOL_LIST (p));
3817 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3819 tree nst_methods = PROTOCOL_NST_METHODS (p);
3820 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3822 /* If protocol wasn't referenced, don't generate any code. */
3823 if (! PROTOCOL_FORWARD_DECL (p))
3826 /* Make sure we link in the Protocol class. */
3827 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3831 if (! METHOD_ENCODING (nst_methods))
3833 encoding = encode_method_prototype (nst_methods);
3834 METHOD_ENCODING (nst_methods) = encoding;
3836 nst_methods = TREE_CHAIN (nst_methods);
3841 if (! METHOD_ENCODING (cls_methods))
3843 encoding = encode_method_prototype (cls_methods);
3844 METHOD_ENCODING (cls_methods) = encoding;
3847 cls_methods = TREE_CHAIN (cls_methods);
3849 generate_method_descriptors (p);
3851 if (PROTOCOL_LIST (p))
3852 refs_decl = generate_protocol_list (p);
3856 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3858 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3860 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3862 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3863 decl_specs, 1, NULL_TREE);
3865 DECL_CONTEXT (decl) = NULL_TREE;
3867 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3873 (build_tree_list (build_tree_list (NULL_TREE,
3874 objc_protocol_template),
3875 build1 (INDIRECT_REF, NULL_TREE,
3876 build1 (INDIRECT_REF, NULL_TREE,
3879 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3880 TREE_TYPE (refs_expr) = cast_type2;
3883 refs_expr = build_int_2 (0, 0);
3885 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3886 by generate_method_descriptors, which is called above. */
3887 initlist = build_protocol_initializer (TREE_TYPE (decl),
3888 protocol_name_expr, refs_expr,
3889 UOBJC_INSTANCE_METHODS_decl,
3890 UOBJC_CLASS_METHODS_decl);
3891 finish_decl (decl, initlist, NULL_TREE);
3893 /* Mark the decl as used to avoid "defined but not used" warning. */
3894 TREE_USED (decl) = 1;
3899 build_protocol_initializer (tree type, tree protocol_name,
3900 tree protocol_list, tree instance_methods,
3903 tree initlist = NULL_TREE, expr;
3906 cast_type = groktypename
3908 (build_tree_list (NULL_TREE,
3909 xref_tag (RECORD_TYPE,
3910 get_identifier (UTAG_CLASS))),
3911 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3913 /* Filling the "isa" in with one allows the runtime system to
3914 detect that the version change...should remove before final release. */
3916 expr = build_int_2 (PROTOCOL_VERSION, 0);
3917 TREE_TYPE (expr) = cast_type;
3918 initlist = tree_cons (NULL_TREE, expr, initlist);
3919 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3920 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3922 if (!instance_methods)
3923 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3926 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3927 initlist = tree_cons (NULL_TREE, expr, initlist);
3931 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3934 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3935 initlist = tree_cons (NULL_TREE, expr, initlist);
3938 return objc_build_constructor (type, nreverse (initlist));
3941 /* struct objc_category {
3942 char *category_name;
3944 struct objc_method_list *instance_methods;
3945 struct objc_method_list *class_methods;
3946 struct objc_protocol_list *protocols;
3950 build_category_template (void)
3952 tree decl_specs, field_decl, field_decl_chain;
3954 objc_category_template = start_struct (RECORD_TYPE,
3955 get_identifier (UTAG_CATEGORY));
3956 /* char *category_name; */
3958 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3960 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3961 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3962 field_decl_chain = field_decl;
3964 /* char *class_name; */
3966 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3967 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3968 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3969 chainon (field_decl_chain, field_decl);
3971 /* struct objc_method_list *instance_methods; */
3973 decl_specs = build_tree_list (NULL_TREE,
3974 xref_tag (RECORD_TYPE,
3975 get_identifier (UTAG_METHOD_LIST)));
3977 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3978 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3979 chainon (field_decl_chain, field_decl);
3981 /* struct objc_method_list *class_methods; */
3983 decl_specs = build_tree_list (NULL_TREE,
3984 xref_tag (RECORD_TYPE,
3985 get_identifier (UTAG_METHOD_LIST)));
3987 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3988 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3989 chainon (field_decl_chain, field_decl);
3991 /* struct objc_protocol **protocol_list; */
3993 decl_specs = build_tree_list (NULL_TREE,
3994 xref_tag (RECORD_TYPE,
3995 get_identifier (UTAG_PROTOCOL)));
3997 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3998 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3999 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4000 chainon (field_decl_chain, field_decl);
4002 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4005 /* struct objc_selector {
4011 build_selector_template (void)
4014 tree decl_specs, field_decl, field_decl_chain;
4016 objc_selector_template
4017 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4021 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4022 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4023 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4024 field_decl_chain = field_decl;
4026 /* char *sel_type; */
4028 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4029 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4030 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4031 chainon (field_decl_chain, field_decl);
4033 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4036 /* struct objc_class {
4037 struct objc_class *isa;
4038 struct objc_class *super_class;
4043 struct objc_ivar_list *ivars;
4044 struct objc_method_list *methods;
4045 if (flag_next_runtime)
4046 struct objc_cache *cache;
4048 struct sarray *dtable;
4049 struct objc_class *subclass_list;
4050 struct objc_class *sibling_class;
4052 struct objc_protocol_list *protocols;
4053 if (flag_next_runtime)
4055 void *gc_object_type;
4058 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4059 the NeXT/Apple runtime; still, the compiler must generate them to
4060 maintain backward binary compatibility (and to allow for future
4064 build_class_template (void)
4066 tree decl_specs, field_decl, field_decl_chain;
4069 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4071 /* struct objc_class *isa; */
4073 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4074 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4075 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4076 field_decl_chain = field_decl;
4078 /* struct objc_class *super_class; */
4080 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4082 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4083 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4084 chainon (field_decl_chain, field_decl);
4088 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4089 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4090 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4091 chainon (field_decl_chain, field_decl);
4095 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4096 field_decl = get_identifier ("version");
4097 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4098 chainon (field_decl_chain, field_decl);
4102 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4103 field_decl = get_identifier ("info");
4104 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4105 chainon (field_decl_chain, field_decl);
4107 /* long instance_size; */
4109 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4110 field_decl = get_identifier ("instance_size");
4111 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4112 chainon (field_decl_chain, field_decl);
4114 /* struct objc_ivar_list *ivars; */
4116 decl_specs = build_tree_list (NULL_TREE,
4117 xref_tag (RECORD_TYPE,
4118 get_identifier (UTAG_IVAR_LIST)));
4119 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4120 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4121 chainon (field_decl_chain, field_decl);
4123 /* struct objc_method_list *methods; */
4125 decl_specs = build_tree_list (NULL_TREE,
4126 xref_tag (RECORD_TYPE,
4127 get_identifier (UTAG_METHOD_LIST)));
4128 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4129 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4130 chainon (field_decl_chain, field_decl);
4132 if (flag_next_runtime)
4134 /* struct objc_cache *cache; */
4136 decl_specs = build_tree_list (NULL_TREE,
4137 xref_tag (RECORD_TYPE,
4138 get_identifier ("objc_cache")));
4139 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4140 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4141 chainon (field_decl_chain, field_decl);
4145 /* struct sarray *dtable; */
4147 decl_specs = build_tree_list (NULL_TREE,
4148 xref_tag (RECORD_TYPE,
4149 get_identifier ("sarray")));
4150 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4151 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4152 chainon (field_decl_chain, field_decl);
4154 /* struct objc_class *subclass_list; */
4156 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4158 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4159 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4160 chainon (field_decl_chain, field_decl);
4162 /* struct objc_class *sibling_class; */
4164 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4166 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4167 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4168 chainon (field_decl_chain, field_decl);
4171 /* struct objc_protocol **protocol_list; */
4173 decl_specs = build_tree_list (NULL_TREE,
4174 xref_tag (RECORD_TYPE,
4175 get_identifier (UTAG_PROTOCOL)));
4177 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4179 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4180 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4181 chainon (field_decl_chain, field_decl);
4183 if (flag_next_runtime)
4187 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4188 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4190 = grokfield (field_decl, decl_specs, NULL_TREE);
4191 chainon (field_decl_chain, field_decl);
4194 /* void *gc_object_type; */
4196 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4197 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4198 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4199 chainon (field_decl_chain, field_decl);
4201 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4204 /* Generate appropriate forward declarations for an implementation. */
4207 synth_forward_declarations (void)
4211 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4212 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4213 objc_class_template);
4215 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4216 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4217 objc_class_template);
4219 /* Pre-build the following entities - for speed/convenience. */
4221 an_id = get_identifier ("super_class");
4222 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4223 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4227 error_with_ivar (const char *message, tree decl, tree rawdecl)
4229 error ("%J%s `%s'", decl,
4230 message, gen_declaration (rawdecl, errbuf));
4235 check_ivars (tree inter, tree imp)
4237 tree intdecls = CLASS_IVARS (inter);
4238 tree impdecls = CLASS_IVARS (imp);
4239 tree rawintdecls = CLASS_RAW_IVARS (inter);
4240 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4247 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4248 intdecls = TREE_CHAIN (intdecls);
4250 if (intdecls == 0 && impdecls == 0)
4252 if (intdecls == 0 || impdecls == 0)
4254 error ("inconsistent instance variable specification");
4258 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4260 if (!comptypes (t1, t2, false)
4261 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4262 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4264 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4266 error_with_ivar ("conflicting instance variable type",
4267 impdecls, rawimpdecls);
4268 error_with_ivar ("previous declaration of",
4269 intdecls, rawintdecls);
4271 else /* both the type and the name don't match */
4273 error ("inconsistent instance variable specification");
4278 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4280 error_with_ivar ("conflicting instance variable name",
4281 impdecls, rawimpdecls);
4282 error_with_ivar ("previous declaration of",
4283 intdecls, rawintdecls);
4286 intdecls = TREE_CHAIN (intdecls);
4287 impdecls = TREE_CHAIN (impdecls);
4288 rawintdecls = TREE_CHAIN (rawintdecls);
4289 rawimpdecls = TREE_CHAIN (rawimpdecls);
4293 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4294 This needs to be done just once per compilation. */
4297 build_super_template (void)
4299 tree decl_specs, field_decl, field_decl_chain;
4301 /* Suppress outputting debug symbols, because
4302 dbxout_init hasn't been called yet. */
4303 enum debug_info_type save_write_symbols = write_symbols;
4304 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4306 write_symbols = NO_DEBUG;
4307 debug_hooks = &do_nothing_debug_hooks;
4309 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4311 /* struct objc_object *self; */
4313 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4314 field_decl = get_identifier ("self");
4315 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4316 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4317 field_decl_chain = field_decl;
4320 /* struct objc_class *super_class; */
4322 /* struct objc_class *class; */
4325 decl_specs = get_identifier (UTAG_CLASS);
4326 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4328 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4330 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4333 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4334 chainon (field_decl_chain, field_decl);
4336 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4338 write_symbols = save_write_symbols;
4339 debug_hooks = save_hooks;
4342 /* struct objc_ivar {
4349 build_ivar_template (void)
4351 tree objc_ivar_id, objc_ivar_record;
4352 tree decl_specs, field_decl, field_decl_chain;
4354 objc_ivar_id = get_identifier (UTAG_IVAR);
4355 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4357 /* char *ivar_name; */
4359 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4360 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4362 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4363 field_decl_chain = field_decl;
4365 /* char *ivar_type; */
4367 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4368 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4370 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4371 chainon (field_decl_chain, field_decl);
4373 /* int ivar_offset; */
4375 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4376 field_decl = get_identifier ("ivar_offset");
4378 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4379 chainon (field_decl_chain, field_decl);
4381 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4383 return objc_ivar_record;
4388 struct objc_ivar ivar_list[ivar_count];
4392 build_ivar_list_template (tree list_type, int size)
4394 tree objc_ivar_list_record;
4395 tree decl_specs, field_decl, field_decl_chain;
4397 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4399 /* int ivar_count; */
4401 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4402 field_decl = get_identifier ("ivar_count");
4404 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4405 field_decl_chain = field_decl;
4407 /* struct objc_ivar ivar_list[]; */
4409 decl_specs = build_tree_list (NULL_TREE, list_type);
4410 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4411 build_int_2 (size, 0));
4413 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4414 chainon (field_decl_chain, field_decl);
4416 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4418 return objc_ivar_list_record;
4424 struct objc_method method_list[method_count];
4428 build_method_list_template (tree list_type, int size)
4430 tree objc_ivar_list_record;
4431 tree decl_specs, field_decl, field_decl_chain;
4433 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4435 /* int method_next; */
4440 xref_tag (RECORD_TYPE,
4441 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4443 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4444 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4445 field_decl_chain = field_decl;
4447 /* int method_count; */
4449 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4450 field_decl = get_identifier ("method_count");
4452 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4453 chainon (field_decl_chain, field_decl);
4455 /* struct objc_method method_list[]; */
4457 decl_specs = build_tree_list (NULL_TREE, list_type);
4458 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4459 build_int_2 (size, 0));
4461 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4462 chainon (field_decl_chain, field_decl);
4464 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4466 return objc_ivar_list_record;
4470 build_ivar_list_initializer (tree type, tree field_decl)
4472 tree initlist = NULL_TREE;
4476 tree ivar = NULL_TREE;
4479 if (DECL_NAME (field_decl))
4480 ivar = tree_cons (NULL_TREE,
4481 add_objc_string (DECL_NAME (field_decl),
4485 /* Unnamed bit-field ivar (yuck). */
4486 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4489 encode_field_decl (field_decl,
4490 obstack_object_size (&util_obstack),
4491 OBJC_ENCODE_DONT_INLINE_DEFS);
4493 /* Null terminate string. */
4494 obstack_1grow (&util_obstack, 0);
4498 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4501 obstack_free (&util_obstack, util_firstobj);
4504 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4505 initlist = tree_cons (NULL_TREE,
4506 objc_build_constructor (type, nreverse (ivar)),
4509 field_decl = TREE_CHAIN (field_decl);
4510 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4514 return objc_build_constructor (build_array_type (type, 0),
4515 nreverse (initlist));
4519 generate_ivars_list (tree type, const char *name, int size, tree list)
4521 tree sc_spec, decl_specs, decl, initlist;
4523 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4524 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4526 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4527 decl_specs, 1, NULL_TREE);
4529 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4530 initlist = tree_cons (NULL_TREE, list, initlist);
4533 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4539 /* Count only the fields occurring in T. */
4541 ivar_list_length (tree t)
4545 for (; t; t = TREE_CHAIN (t))
4546 if (TREE_CODE (t) == FIELD_DECL)
4553 generate_ivar_lists (void)
4555 tree initlist, ivar_list_template, chain;
4556 tree cast, variable_length_type;
4559 generating_instance_variables = 1;
4561 if (!objc_ivar_template)
4562 objc_ivar_template = build_ivar_template ();
4566 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4567 get_identifier (UTAG_IVAR_LIST))),
4569 variable_length_type = groktypename (cast);
4571 /* Only generate class variables for the root of the inheritance
4572 hierarchy since these will be the same for every class. */
4574 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4575 && (chain = TYPE_FIELDS (objc_class_template)))
4577 size = ivar_list_length (chain);
4579 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4580 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4582 UOBJC_CLASS_VARIABLES_decl
4583 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4585 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4588 UOBJC_CLASS_VARIABLES_decl = 0;
4590 chain = CLASS_IVARS (implementation_template);
4593 size = ivar_list_length (chain);
4594 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4595 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4597 UOBJC_INSTANCE_VARIABLES_decl
4598 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4600 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4603 UOBJC_INSTANCE_VARIABLES_decl = 0;
4605 generating_instance_variables = 0;
4609 build_dispatch_table_initializer (tree type, tree entries)
4611 tree initlist = NULL_TREE;
4615 tree elemlist = NULL_TREE;
4617 elemlist = tree_cons (NULL_TREE,
4618 build_selector (METHOD_SEL_NAME (entries)),
4621 /* Generate the method encoding if we don't have one already. */
4622 if (! METHOD_ENCODING (entries))
4623 METHOD_ENCODING (entries) =
4624 encode_method_prototype (entries);
4626 elemlist = tree_cons (NULL_TREE,
4627 add_objc_string (METHOD_ENCODING (entries),
4631 elemlist = tree_cons (NULL_TREE,
4632 build_unary_op (ADDR_EXPR,
4633 METHOD_DEFINITION (entries), 1),
4636 initlist = tree_cons (NULL_TREE,
4637 objc_build_constructor (type, nreverse (elemlist)),
4640 entries = TREE_CHAIN (entries);
4644 return objc_build_constructor (build_array_type (type, 0),
4645 nreverse (initlist));
4648 /* To accomplish method prototyping without generating all kinds of
4649 inane warnings, the definition of the dispatch table entries were
4652 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4654 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4657 build_method_template (void)
4660 tree decl_specs, field_decl, field_decl_chain;
4662 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4664 /* struct objc_selector *_cmd; */
4665 decl_specs = tree_cons (NULL_TREE,
4666 xref_tag (RECORD_TYPE,
4667 get_identifier (TAG_SELECTOR)),
4669 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4671 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4672 field_decl_chain = field_decl;
4674 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4675 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4676 get_identifier ("method_types"));
4677 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4678 chainon (field_decl_chain, field_decl);
4682 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4683 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4684 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4685 chainon (field_decl_chain, field_decl);
4687 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4694 generate_dispatch_table (tree type, const char *name, int size, tree list)
4696 tree sc_spec, decl_specs, decl, initlist;
4698 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4699 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4701 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4702 decl_specs, 1, NULL_TREE);
4704 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4705 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4706 initlist = tree_cons (NULL_TREE, list, initlist);
4709 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4716 mark_referenced_methods (void)
4718 struct imp_entry *impent;
4721 for (impent = imp_list; impent; impent = impent->next)
4723 chain = CLASS_CLS_METHODS (impent->imp_context);
4726 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4727 chain = TREE_CHAIN (chain);
4730 chain = CLASS_NST_METHODS (impent->imp_context);
4733 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4734 chain = TREE_CHAIN (chain);
4740 generate_dispatch_tables (void)
4742 tree initlist, chain, method_list_template;
4743 tree cast, variable_length_type;
4746 if (!objc_method_template)
4747 objc_method_template = build_method_template ();
4751 (build_tree_list (NULL_TREE,
4752 xref_tag (RECORD_TYPE,
4753 get_identifier (UTAG_METHOD_LIST))),
4756 variable_length_type = groktypename (cast);
4758 chain = CLASS_CLS_METHODS (objc_implementation_context);
4761 size = list_length (chain);
4763 method_list_template
4764 = build_method_list_template (objc_method_template, size);
4766 = build_dispatch_table_initializer (objc_method_template, chain);
4768 UOBJC_CLASS_METHODS_decl
4769 = generate_dispatch_table (method_list_template,
4770 ((TREE_CODE (objc_implementation_context)
4771 == CLASS_IMPLEMENTATION_TYPE)
4772 ? "_OBJC_CLASS_METHODS"
4773 : "_OBJC_CATEGORY_CLASS_METHODS"),
4775 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4778 UOBJC_CLASS_METHODS_decl = 0;
4780 chain = CLASS_NST_METHODS (objc_implementation_context);
4783 size = list_length (chain);
4785 method_list_template
4786 = build_method_list_template (objc_method_template, size);
4788 = build_dispatch_table_initializer (objc_method_template, chain);
4790 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4791 UOBJC_INSTANCE_METHODS_decl
4792 = generate_dispatch_table (method_list_template,
4793 "_OBJC_INSTANCE_METHODS",
4796 /* We have a category. */
4797 UOBJC_INSTANCE_METHODS_decl
4798 = generate_dispatch_table (method_list_template,
4799 "_OBJC_CATEGORY_INSTANCE_METHODS",
4801 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4804 UOBJC_INSTANCE_METHODS_decl = 0;
4808 generate_protocol_list (tree i_or_p)
4810 tree initlist, decl_specs, sc_spec;
4811 tree refs_decl, expr_decl, lproto, e, plist;
4815 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4816 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4817 plist = CLASS_PROTOCOL_LIST (i_or_p);
4818 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4819 plist = PROTOCOL_LIST (i_or_p);
4823 cast_type = groktypename
4825 (build_tree_list (NULL_TREE,
4826 xref_tag (RECORD_TYPE,
4827 get_identifier (UTAG_PROTOCOL))),
4828 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4831 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4832 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4833 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4836 /* Build initializer. */
4837 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4839 e = build_int_2 (size, 0);
4840 TREE_TYPE (e) = cast_type;
4841 initlist = tree_cons (NULL_TREE, e, initlist);
4843 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4845 tree pval = TREE_VALUE (lproto);
4847 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4848 && PROTOCOL_FORWARD_DECL (pval))
4850 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4851 initlist = tree_cons (NULL_TREE, e, initlist);
4855 /* static struct objc_protocol *refs[n]; */
4857 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4858 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4859 get_identifier (UTAG_PROTOCOL)),
4862 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4863 expr_decl = build_nt (ARRAY_REF,
4864 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4866 build_int_2 (size + 2, 0));
4867 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4868 expr_decl = build_nt (ARRAY_REF,
4869 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4871 build_int_2 (size + 2, 0));
4872 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4874 = build_nt (ARRAY_REF,
4875 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4877 build_int_2 (size + 2, 0));
4881 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4883 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4884 DECL_CONTEXT (refs_decl) = NULL_TREE;
4886 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4887 nreverse (initlist)),
4894 build_category_initializer (tree type, tree cat_name, tree class_name,
4895 tree instance_methods, tree class_methods,
4898 tree initlist = NULL_TREE, expr;
4900 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4901 initlist = tree_cons (NULL_TREE, class_name, initlist);
4903 if (!instance_methods)
4904 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4907 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4908 initlist = tree_cons (NULL_TREE, expr, initlist);
4911 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4914 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4915 initlist = tree_cons (NULL_TREE, expr, initlist);
4918 /* protocol_list = */
4920 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4923 tree cast_type2 = groktypename
4925 (build_tree_list (NULL_TREE,
4926 xref_tag (RECORD_TYPE,
4927 get_identifier (UTAG_PROTOCOL))),
4928 build1 (INDIRECT_REF, NULL_TREE,
4929 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4931 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4932 TREE_TYPE (expr) = cast_type2;
4933 initlist = tree_cons (NULL_TREE, expr, initlist);
4936 return objc_build_constructor (type, nreverse (initlist));
4939 /* struct objc_class {
4940 struct objc_class *isa;
4941 struct objc_class *super_class;
4946 struct objc_ivar_list *ivars;
4947 struct objc_method_list *methods;
4948 if (flag_next_runtime)
4949 struct objc_cache *cache;
4951 struct sarray *dtable;
4952 struct objc_class *subclass_list;
4953 struct objc_class *sibling_class;
4955 struct objc_protocol_list *protocols;
4956 if (flag_next_runtime)
4958 void *gc_object_type;
4962 build_shared_structure_initializer (tree type, tree isa, tree super,
4963 tree name, tree size, int status,
4964 tree dispatch_table, tree ivar_list,
4967 tree initlist = NULL_TREE, expr;
4970 initlist = tree_cons (NULL_TREE, isa, initlist);
4973 initlist = tree_cons (NULL_TREE, super, initlist);
4976 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4979 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4982 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4984 /* instance_size = */
4985 initlist = tree_cons (NULL_TREE, size, initlist);
4987 /* objc_ivar_list = */
4989 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4992 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4993 initlist = tree_cons (NULL_TREE, expr, initlist);
4996 /* objc_method_list = */
4997 if (!dispatch_table)
4998 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5001 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
5002 initlist = tree_cons (NULL_TREE, expr, initlist);
5005 if (flag_next_runtime)
5006 /* method_cache = */
5007 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5011 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5013 /* subclass_list = */
5014 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5016 /* sibling_class = */
5017 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5020 /* protocol_list = */
5021 if (! protocol_list)
5022 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5028 (build_tree_list (NULL_TREE,
5029 xref_tag (RECORD_TYPE,
5030 get_identifier (UTAG_PROTOCOL))),
5031 build1 (INDIRECT_REF, NULL_TREE,
5032 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5034 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5035 TREE_TYPE (expr) = cast_type2;
5036 initlist = tree_cons (NULL_TREE, expr, initlist);
5039 if (flag_next_runtime)
5041 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5043 /* gc_object_type = NULL */
5044 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5046 return objc_build_constructor (type, nreverse (initlist));
5049 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5052 lookup_category (tree class, tree cat_name)
5054 tree category = CLASS_CATEGORY_LIST (class);
5056 while (category && CLASS_SUPER_NAME (category) != cat_name)
5057 category = CLASS_CATEGORY_LIST (category);
5061 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5064 generate_category (tree cat)
5066 tree sc_spec, decl_specs, decl;
5067 tree initlist, cat_name_expr, class_name_expr;
5068 tree protocol_decl, category;
5070 add_class_reference (CLASS_NAME (cat));
5071 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5073 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5075 category = lookup_category (implementation_template,
5076 CLASS_SUPER_NAME (cat));
5078 if (category && CLASS_PROTOCOL_LIST (category))
5080 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5081 protocol_decl = generate_protocol_list (category);
5086 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5087 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5089 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5090 objc_implementation_context),
5091 decl_specs, 1, NULL_TREE);
5093 initlist = build_category_initializer (TREE_TYPE (decl),
5094 cat_name_expr, class_name_expr,
5095 UOBJC_INSTANCE_METHODS_decl,
5096 UOBJC_CLASS_METHODS_decl,
5099 finish_decl (decl, initlist, NULL_TREE);
5102 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5103 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5106 generate_shared_structures (void)
5108 tree sc_spec, decl_specs, decl;
5109 tree name_expr, super_expr, root_expr;
5110 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5111 tree cast_type, initlist, protocol_decl;
5113 my_super_id = CLASS_SUPER_NAME (implementation_template);
5116 add_class_reference (my_super_id);
5118 /* Compute "my_root_id" - this is required for code generation.
5119 the "isa" for all meta class structures points to the root of
5120 the inheritance hierarchy (e.g. "__Object")... */
5121 my_root_id = my_super_id;
5124 tree my_root_int = lookup_interface (my_root_id);
5126 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5127 my_root_id = CLASS_SUPER_NAME (my_root_int);
5134 /* No super class. */
5135 my_root_id = CLASS_NAME (implementation_template);
5138 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5139 objc_class_template),
5140 build1 (INDIRECT_REF,
5141 NULL_TREE, NULL_TREE)));
5143 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5146 /* Install class `isa' and `super' pointers at runtime. */
5149 super_expr = add_objc_string (my_super_id, class_names);
5150 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5153 super_expr = build_int_2 (0, 0);
5155 root_expr = add_objc_string (my_root_id, class_names);
5156 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5158 if (CLASS_PROTOCOL_LIST (implementation_template))
5160 generate_protocol_references
5161 (CLASS_PROTOCOL_LIST (implementation_template));
5162 protocol_decl = generate_protocol_list (implementation_template);
5167 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5169 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5170 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5172 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5176 = build_shared_structure_initializer
5178 root_expr, super_expr, name_expr,
5179 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5181 UOBJC_CLASS_METHODS_decl,
5182 UOBJC_CLASS_VARIABLES_decl,
5185 finish_decl (decl, initlist, NULL_TREE);
5187 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5189 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5193 = build_shared_structure_initializer
5195 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5196 super_expr, name_expr,
5197 convert (integer_type_node,
5198 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5199 (implementation_template))),
5201 UOBJC_INSTANCE_METHODS_decl,
5202 UOBJC_INSTANCE_VARIABLES_decl,
5205 finish_decl (decl, initlist, NULL_TREE);
5209 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5212 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5213 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5215 const char *const class_name
5216 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5217 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5218 sprintf (string, "%s_%s", preamble,
5219 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5221 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5222 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5224 /* We have a category. */
5225 const char *const class_name
5226 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5227 const char *const class_super_name
5228 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5229 string = (char *) alloca (strlen (preamble)
5230 + strlen (class_name)
5231 + strlen (class_super_name)
5233 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5235 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5237 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5239 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5240 sprintf (string, "%s_%s", preamble, protocol_name);
5245 return get_identifier (string);
5249 is_objc_type_qualifier (tree node)
5251 return (TREE_CODE (node) == IDENTIFIER_NODE
5252 && (node == ridpointers [(int) RID_CONST]
5253 || node == ridpointers [(int) RID_VOLATILE]
5254 || node == ridpointers [(int) RID_IN]
5255 || node == ridpointers [(int) RID_OUT]
5256 || node == ridpointers [(int) RID_INOUT]
5257 || node == ridpointers [(int) RID_BYCOPY]
5258 || node == ridpointers [(int) RID_BYREF]
5259 || node == ridpointers [(int) RID_ONEWAY]));
5262 /* If type is empty or only type qualifiers are present, add default
5263 type of id (otherwise grokdeclarator will default to int). */
5266 adjust_type_for_id_default (tree type)
5268 tree declspecs, chain;
5271 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5272 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5274 declspecs = TREE_PURPOSE (type);
5276 /* Determine if a typespec is present. */
5277 for (chain = declspecs;
5279 chain = TREE_CHAIN (chain))
5281 if (TYPED_OBJECT (TREE_VALUE (chain))
5282 && !(TREE_VALUE (type)
5283 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5284 error ("can not use an object as parameter to a method\n");
5285 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5289 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5291 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5296 selector ':' '(' typename ')' identifier
5299 Transform an Objective-C keyword argument into
5300 the C equivalent parameter declarator.
5302 In: key_name, an "identifier_node" (optional).
5303 arg_type, a "tree_list" (optional).
5304 arg_name, an "identifier_node".
5306 Note: It would be really nice to strongly type the preceding
5307 arguments in the function prototype; however, then I
5308 could not use the "accessor" macros defined in "tree.h".
5310 Out: an instance of "keyword_decl". */
5313 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5317 /* If no type is specified, default to "id". */
5318 arg_type = adjust_type_for_id_default (arg_type);
5320 keyword_decl = make_node (KEYWORD_DECL);
5322 TREE_TYPE (keyword_decl) = arg_type;
5323 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5324 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5326 return keyword_decl;
5329 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5332 build_keyword_selector (tree selector)
5335 tree key_chain, key_name;
5338 /* Scan the selector to see how much space we'll need. */
5339 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5341 if (TREE_CODE (selector) == KEYWORD_DECL)
5342 key_name = KEYWORD_KEY_NAME (key_chain);
5343 else if (TREE_CODE (selector) == TREE_LIST)
5344 key_name = TREE_PURPOSE (key_chain);
5349 len += IDENTIFIER_LENGTH (key_name) + 1;
5351 /* Just a ':' arg. */
5355 buf = (char *) alloca (len + 1);
5356 /* Start the buffer out as an empty string. */
5359 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5361 if (TREE_CODE (selector) == KEYWORD_DECL)
5362 key_name = KEYWORD_KEY_NAME (key_chain);
5363 else if (TREE_CODE (selector) == TREE_LIST)
5365 key_name = TREE_PURPOSE (key_chain);
5366 /* The keyword decl chain will later be used as a function argument
5367 chain. Unhook the selector itself so as to not confuse other
5368 parts of the compiler. */
5369 TREE_PURPOSE (key_chain) = NULL_TREE;
5375 strcat (buf, IDENTIFIER_POINTER (key_name));
5379 return get_identifier (buf);
5382 /* Used for declarations and definitions. */
5385 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5390 /* If no type is specified, default to "id". */
5391 ret_type = adjust_type_for_id_default (ret_type);
5393 method_decl = make_node (code);
5394 TREE_TYPE (method_decl) = ret_type;
5396 /* If we have a keyword selector, create an identifier_node that
5397 represents the full selector name (`:' included)... */
5398 if (TREE_CODE (selector) == KEYWORD_DECL)
5400 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5401 METHOD_SEL_ARGS (method_decl) = selector;
5402 METHOD_ADD_ARGS (method_decl) = add_args;
5406 METHOD_SEL_NAME (method_decl) = selector;
5407 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5408 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5414 #define METHOD_DEF 0
5415 #define METHOD_REF 1
5417 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5418 an argument list for method METH. CONTEXT is either METHOD_DEF or
5419 METHOD_REF, saying whether we are trying to define a method or call
5420 one. SUPERFLAG says this is for a send to super; this makes a
5421 difference for the NeXT calling sequence in which the lookup and
5422 the method call are done together. If METH is null, user-defined
5423 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5426 get_arg_type_list (tree meth, int context, int superflag)
5430 /* Receiver type. */
5431 if (flag_next_runtime && superflag)
5432 arglist = build_tree_list (NULL_TREE, super_type);
5433 else if (context == METHOD_DEF)
5434 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5436 arglist = build_tree_list (NULL_TREE, id_type);
5438 /* Selector type - will eventually change to `int'. */
5439 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
5441 /* No actual method prototype given -- assume that remaining arguments
5446 /* Build a list of argument types. */
5447 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5449 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5450 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5453 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5454 /* We have a `, ...' immediately following the selector,
5455 finalize the arglist...simulate get_parm_info (true). */
5457 else if (METHOD_ADD_ARGS (meth))
5459 /* we have a variable length selector */
5460 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5461 chainon (arglist, add_arg_list);
5464 /* finalize the arglist...simulate get_parm_info (false) */
5465 chainon (arglist, void_list_node);
5471 check_duplicates (hash hsh, int methods, int is_class)
5473 tree meth = NULL_TREE;
5481 /* We have two or more methods with the same name but
5485 warning ("multiple %s named `%c%s' found",
5486 methods ? "methods" : "selectors",
5487 (is_class ? '+' : '-'),
5488 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5490 warn_with_method (methods ? "using" : "found",
5491 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5495 for (loop = hsh->list; loop; loop = loop->next)
5496 warn_with_method ("also found",
5497 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5506 /* If RECEIVER is a class reference, return the identifier node for
5507 the referenced class. RECEIVER is created by get_class_reference,
5508 so we check the exact form created depending on which runtimes are
5512 receiver_is_class_object (tree receiver, int self, int super)
5514 tree chain, exp, arg;
5516 /* The receiver is 'self' or 'super' in the context of a class method. */
5517 if (objc_method_context
5518 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5521 ? CLASS_SUPER_NAME (implementation_template)
5522 : CLASS_NAME (implementation_template));
5524 if (flag_next_runtime)
5526 /* The receiver is a variable created by
5527 build_class_reference_decl. */
5528 if (TREE_CODE (receiver) == VAR_DECL
5529 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5530 /* Look up the identifier. */
5531 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5532 if (TREE_PURPOSE (chain) == receiver)
5533 return TREE_VALUE (chain);
5536 /* The receiver is a function call that returns an id. Check if
5537 it is a call to objc_getClass, if so, pick up the class name. */
5538 if (TREE_CODE (receiver) == CALL_EXPR
5539 && (exp = TREE_OPERAND (receiver, 0))
5540 && TREE_CODE (exp) == ADDR_EXPR
5541 && (exp = TREE_OPERAND (exp, 0))
5542 && TREE_CODE (exp) == FUNCTION_DECL
5543 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5544 prototypes for objc_get_class(). Thankfully, they seem to share the
5545 same function type. */
5546 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5547 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5548 /* We have a call to objc_get_class/objc_getClass! */
5549 && (arg = TREE_OPERAND (receiver, 1))
5550 && TREE_CODE (arg) == TREE_LIST
5551 && (arg = TREE_VALUE (arg)))
5554 if (TREE_CODE (arg) == ADDR_EXPR
5555 && (arg = TREE_OPERAND (arg, 0))
5556 && TREE_CODE (arg) == STRING_CST)
5557 /* Finally, we have the class name. */
5558 return get_identifier (TREE_STRING_POINTER (arg));
5563 /* If we are currently building a message expr, this holds
5564 the identifier of the selector of the message. This is
5565 used when printing warnings about argument mismatches. */
5567 static tree current_objc_message_selector = 0;
5570 objc_message_selector (void)
5572 return current_objc_message_selector;
5575 /* Construct an expression for sending a message.
5576 MESS has the object to send to in TREE_PURPOSE
5577 and the argument list (including selector) in TREE_VALUE.
5579 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5580 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5583 build_message_expr (tree mess)
5585 tree receiver = TREE_PURPOSE (mess);
5587 tree args = TREE_VALUE (mess);
5588 tree method_params = NULL_TREE;
5590 if (TREE_CODE (receiver) == ERROR_MARK)
5591 return error_mark_node;
5593 /* Obtain the full selector name. */
5594 if (TREE_CODE (args) == IDENTIFIER_NODE)
5595 /* A unary selector. */
5597 else if (TREE_CODE (args) == TREE_LIST)
5598 sel_name = build_keyword_selector (args);
5602 /* Build the parameter list to give to the method. */
5603 if (TREE_CODE (args) == TREE_LIST)
5605 tree chain = args, prev = NULL_TREE;
5607 /* We have a keyword selector--check for comma expressions. */
5610 tree element = TREE_VALUE (chain);
5612 /* We have a comma expression, must collapse... */
5613 if (TREE_CODE (element) == TREE_LIST)
5616 TREE_CHAIN (prev) = element;
5621 chain = TREE_CHAIN (chain);
5623 method_params = args;
5627 if (processing_template_decl)
5628 /* Must wait until template instantiation time. */
5629 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5633 return finish_message_expr (receiver, sel_name, method_params);
5636 /* Look up method SEL_NAME that would be suitable for receiver
5637 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5638 nonzero), and report on any duplicates. */
5641 lookup_method_in_hash_lists (tree sel_name, int is_class)
5643 hash method_prototype = NULL;
5646 method_prototype = hash_lookup (nst_method_hash_list,
5649 if (!method_prototype)
5651 method_prototype = hash_lookup (cls_method_hash_list,
5656 return check_duplicates (method_prototype, 1, is_class);
5659 /* The 'finish_message_expr' routine is called from within
5660 'build_message_expr' for non-template functions. In the case of
5661 C++ template functions, it is called from 'build_expr_from_tree'
5662 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5665 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5667 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5668 tree selector, retval, is_class;
5669 int self, super, have_cast;
5671 /* Extract the receiver of the message, as well as its type
5672 (where the latter may take the form of a cast or be inferred
5673 from the implementation context). */
5675 while (TREE_CODE (rtype) == COMPOUND_EXPR
5676 || TREE_CODE (rtype) == MODIFY_EXPR
5677 || TREE_CODE (rtype) == NOP_EXPR
5678 || TREE_CODE (rtype) == COMPONENT_REF)
5679 rtype = TREE_OPERAND (rtype, 0);
5680 self = (rtype == self_decl);
5681 super = (rtype == UOBJC_SUPER_decl);
5682 rtype = TREE_TYPE (receiver);
5683 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5684 || (TREE_CODE (receiver) == COMPOUND_EXPR
5685 && !IS_SUPER (rtype)));
5687 /* If the receiver is a class object, retrieve the corresponding
5688 @interface, if one exists. */
5689 is_class = receiver_is_class_object (receiver, self, super);
5691 /* Now determine the receiver type (if an explicit cast has not been
5696 rtype = lookup_interface (is_class);
5697 /* Handle `self' and `super'. */
5700 if (!CLASS_SUPER_NAME (implementation_template))
5702 error ("no super class declared in @interface for `%s'",
5703 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5704 return error_mark_node;
5706 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5709 rtype = lookup_interface (CLASS_NAME (implementation_template));
5712 /* If receiver is of type `id' or `Class' (or if the @interface for a
5713 class is not visible), we shall be satisfied with the existence of
5714 any instance or class method. */
5715 if (!rtype || IS_ID (rtype)
5716 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5719 rtype = xref_tag (RECORD_TYPE, is_class);
5720 else if (IS_ID (rtype))
5722 rprotos = TYPE_PROTOCOL_LIST (rtype);
5726 is_class = TYPE_NAME (rtype) = get_identifier ("Class");
5730 = lookup_method_in_protocol_list (rprotos, sel_name,
5731 is_class != NULL_TREE);
5732 if (!method_prototype && !rprotos)
5734 = lookup_method_in_hash_lists (sel_name,
5735 is_class != NULL_TREE);
5739 tree orig_rtype = rtype, saved_rtype;
5741 if (TREE_CODE (rtype) == POINTER_TYPE)
5742 rtype = TREE_TYPE (rtype);
5743 /* Traverse typedef aliases */
5744 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5745 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5746 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5747 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5748 saved_rtype = rtype;
5749 if (TYPED_OBJECT (rtype))
5751 rprotos = TYPE_PROTOCOL_LIST (rtype);
5752 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5754 /* If we could not find an @interface declaration, we must have
5755 only seen a @class declaration; so, we cannot say anything
5756 more intelligent about which methods the receiver will
5759 rtype = saved_rtype;
5760 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5761 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5763 /* We have a valid ObjC class name. Look up the method name
5764 in the published @interface for the class (and its
5767 = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
5769 /* If the method was not found in the @interface, it may still
5770 exist locally as part of the @implementation. */
5771 if (!method_prototype && objc_implementation_context
5772 && CLASS_NAME (objc_implementation_context)
5773 == OBJC_TYPE_NAME (rtype))
5777 ? CLASS_CLS_METHODS (objc_implementation_context)
5778 : CLASS_NST_METHODS (objc_implementation_context)),
5781 /* If we haven't found a candidate method by now, try looking for
5782 it in the protocol list. */
5783 if (!method_prototype && rprotos)
5785 = lookup_method_in_protocol_list (rprotos, sel_name,
5786 is_class != NULL_TREE);
5790 warning ("invalid receiver type `%s'",
5791 gen_declaration (orig_rtype, errbuf));
5792 rtype = rprotos = NULL_TREE;
5796 if (!method_prototype)
5798 static bool warn_missing_methods = false;
5801 warning ("`%s' may not respond to `%c%s'",
5802 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5803 (is_class ? '+' : '-'),
5804 IDENTIFIER_POINTER (sel_name));
5806 warning ("`%c%s' not implemented by protocol(s)",
5807 (is_class ? '+' : '-'),
5808 IDENTIFIER_POINTER (sel_name));
5809 if (!warn_missing_methods)
5811 warning ("(Messages without a matching method signature");
5812 warning ("will be assumed to return `id' and accept");
5813 warning ("`...' as arguments.)");
5814 warn_missing_methods = true;
5818 /* Save the selector name for printing error messages. */
5819 current_objc_message_selector = sel_name;
5821 /* Build the parameters list for looking up the method.
5822 These are the object itself and the selector. */
5824 if (flag_typed_selectors)
5825 selector = build_typed_selector_reference (sel_name, method_prototype);
5827 selector = build_selector_reference (sel_name);
5829 retval = build_objc_method_call (super, method_prototype,
5831 selector, method_params);
5833 current_objc_message_selector = 0;
5838 /* Build a tree expression to send OBJECT the operation SELECTOR,
5839 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5840 assuming the method has prototype METHOD_PROTOTYPE.
5841 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5842 Use METHOD_PARAMS as list of args to pass to the method.
5843 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5846 build_objc_method_call (int super_flag, tree method_prototype,
5847 tree lookup_object, tree selector,
5850 tree sender = (super_flag ? umsg_super_decl :
5851 (!flag_next_runtime || flag_nil_receivers
5853 : umsg_nonnil_decl));
5854 tree rcv_p = (super_flag ? super_type : id_type);
5856 /* If a prototype for the method to be called exists, then cast
5857 the sender's return type and arguments to match that of the method.
5858 Otherwise, leave sender as is. */
5861 ? groktypename (TREE_TYPE (method_prototype))
5864 = build_pointer_type
5865 (build_function_type
5868 (method_prototype, METHOD_REF, super_flag)));
5870 lookup_object = build_c_cast (rcv_p, lookup_object);
5872 if (flag_next_runtime)
5874 /* If we are returning a struct in memory, and the address
5875 of that memory location is passed as a hidden first
5876 argument, then change which messenger entry point this
5877 expr will call. NB: Note that sender_cast remains
5878 unchanged (it already has a struct return type). */
5879 if (!targetm.calls.struct_value_rtx (0, 0)
5880 && (TREE_CODE (ret_type) == RECORD_TYPE
5881 || TREE_CODE (ret_type) == UNION_TYPE)
5882 && targetm.calls.return_in_memory (ret_type, 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 /* ??? Ideally we'd build the reference with protocol_type directly,
5974 if we have it, rather than converting it here. */
5975 expr = convert (protocol_type, expr);
5977 /* The @protocol() expression is being compiled into a pointer to a
5978 statically allocated instance of the Protocol class. To become
5979 usable at runtime, the 'isa' pointer of the instance need to be
5980 fixed up at runtime by the runtime library, to point to the
5981 actual 'Protocol' class. */
5983 /* For the GNU runtime, put the static Protocol instance in the list
5984 of statically allocated instances, so that we make sure that its
5985 'isa' pointer is fixed up at runtime by the GNU runtime library
5986 to point to the Protocol class (at runtime, when loading the
5987 module, the GNU runtime library loops on the statically allocated
5988 instances (as found in the defs field in objc_symtab) and fixups
5989 all the 'isa' pointers of those objects). */
5990 if (! flag_next_runtime)
5992 /* This type is a struct containing the fields of a Protocol
5993 object. (Cfr. protocol_type instead is the type of a pointer
5994 to such a struct). */
5995 tree protocol_struct_type = xref_tag
5996 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5999 /* Look for the list of Protocol statically allocated instances
6000 to fixup at runtime. Create a new list to hold Protocol
6001 statically allocated instances, if the list is not found. At
6002 present there is only another list, holding NSConstantString
6003 static instances to be fixed up at runtime. */
6004 for (chain = &objc_static_instances;
6005 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6006 chain = &TREE_CHAIN (*chain));
6009 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6010 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6014 /* Add this statically allocated instance to the Protocol list. */
6015 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6016 PROTOCOL_FORWARD_DECL (p),
6017 TREE_PURPOSE (*chain));
6024 /* This function is called by the parser when a @selector() expression
6025 is found, in order to compile it. It is only called by the parser
6026 and only to compile a @selector(). */
6028 build_selector_expr (tree selnamelist)
6032 /* Obtain the full selector name. */
6033 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6034 /* A unary selector. */
6035 selname = selnamelist;
6036 else if (TREE_CODE (selnamelist) == TREE_LIST)
6037 selname = build_keyword_selector (selnamelist);
6041 /* If we are required to check @selector() expressions as they
6042 are found, check that the selector has been declared. */
6043 if (warn_undeclared_selector)
6045 /* Look the selector up in the list of all known class and
6046 instance methods (up to this line) to check that the selector
6050 /* First try with instance methods. */
6051 hsh = hash_lookup (nst_method_hash_list, selname);
6053 /* If not found, try with class methods. */
6056 hsh = hash_lookup (cls_method_hash_list, selname);
6059 /* If still not found, print out a warning. */
6062 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6067 if (flag_typed_selectors)
6068 return build_typed_selector_reference (selname, 0);
6070 return build_selector_reference (selname);
6074 build_encode_expr (tree type)
6079 encode_type (type, obstack_object_size (&util_obstack),
6080 OBJC_ENCODE_INLINE_DEFS);
6081 obstack_1grow (&util_obstack, 0); /* null terminate string */
6082 string = obstack_finish (&util_obstack);
6084 /* Synthesize a string that represents the encoded struct/union. */
6085 result = my_build_string (strlen (string) + 1, string);
6086 obstack_free (&util_obstack, util_firstobj);
6091 build_ivar_reference (tree id)
6093 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6095 /* Historically, a class method that produced objects (factory
6096 method) would assign `self' to the instance that it
6097 allocated. This would effectively turn the class method into
6098 an instance method. Following this assignment, the instance
6099 variables could be accessed. That practice, while safe,
6100 violates the simple rule that a class method should not refer
6101 to an instance variable. It's better to catch the cases
6102 where this is done unknowingly than to support the above
6104 warning ("instance variable `%s' accessed in class method",
6105 IDENTIFIER_POINTER (id));
6106 TREE_TYPE (self_decl) = instance_type; /* cast */
6109 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6112 /* Compute a hash value for a given method SEL_NAME. */
6115 hash_func (tree sel_name)
6117 const unsigned char *s
6118 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6122 h = h * 67 + *s++ - 113;
6129 nst_method_hash_list
6130 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6131 cls_method_hash_list
6132 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6135 /* WARNING!!!! hash_enter is called with a method, and will peek
6136 inside to find its selector! But hash_lookup is given a selector
6137 directly, and looks for the selector that's inside the found
6138 entry's key (method) for comparison. */
6141 hash_enter (hash *hashlist, tree method)
6144 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6146 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6148 obj->next = hashlist[slot];
6151 hashlist[slot] = obj; /* append to front */
6155 hash_lookup (hash *hashlist, tree sel_name)
6159 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6163 if (sel_name == METHOD_SEL_NAME (target->key))
6166 target = target->next;
6172 hash_add_attr (hash entry, tree value)
6176 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6177 obj->next = entry->list;
6180 entry->list = obj; /* append to front */
6184 lookup_method (tree mchain, tree method)
6188 if (TREE_CODE (method) == IDENTIFIER_NODE)
6191 key = METHOD_SEL_NAME (method);
6195 if (METHOD_SEL_NAME (mchain) == key)
6198 mchain = TREE_CHAIN (mchain);
6204 lookup_method_static (tree interface, tree ident, int is_class)
6206 tree meth = NULL_TREE, root_inter = NULL_TREE;
6207 tree inter = interface;
6211 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6212 tree category = inter;
6214 /* First, look up the method in the class itself. */
6215 if ((meth = lookup_method (chain, ident)))
6218 /* Failing that, look for the method in each category of the class. */
6219 while ((category = CLASS_CATEGORY_LIST (category)))
6221 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6223 /* Check directly in each category. */
6224 if ((meth = lookup_method (chain, ident)))
6227 /* Failing that, check in each category's protocols. */
6228 if (CLASS_PROTOCOL_LIST (category))
6230 if ((meth = (lookup_method_in_protocol_list
6231 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6236 /* If not found in categories, check in protocols of the main class. */
6237 if (CLASS_PROTOCOL_LIST (inter))
6239 if ((meth = (lookup_method_in_protocol_list
6240 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6244 /* Failing that, climb up the inheritance hierarchy. */
6246 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6250 /* If no class (factory) method was found, check if an _instance_
6251 method of the same name exists in the root class. This is what
6252 the Objective-C runtime will do. If an instance method was not
6254 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6257 /* Add the method to the hash list if it doesn't contain an identical
6260 add_method_to_hash_list (hash *hash_list, tree method)
6264 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6266 /* Install on a global chain. */
6267 hash_enter (hash_list, method);
6271 /* Check types against those; if different, add to a list. */
6273 int already_there = comp_proto_with_proto (method, hsh->key);
6274 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6275 already_there |= comp_proto_with_proto (method, loop->value);
6277 hash_add_attr (hsh, method);
6282 objc_add_method (tree class, tree method, int is_class)
6286 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6288 /* put method on list in reverse order */
6291 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6292 CLASS_CLS_METHODS (class) = method;
6296 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6297 CLASS_NST_METHODS (class) = method;
6302 /* When processing an @interface for a class or category, give hard
6303 errors on methods with identical selectors but differing argument
6304 and/or return types. We do not do this for @implementations, because
6305 C/C++ will do it for us (i.e., there will be duplicate function
6306 definition errors). */
6307 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6308 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6309 && !comp_proto_with_proto (method, mth))
6310 error ("duplicate declaration of method `%c%s'",
6311 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6315 add_method_to_hash_list (cls_method_hash_list, method);
6318 add_method_to_hash_list (nst_method_hash_list, method);
6320 /* Instance methods in root classes (and categories thereof)
6321 may acts as class methods as a last resort. */
6322 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6323 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6324 class = lookup_interface (CLASS_NAME (class));
6326 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6327 && !CLASS_SUPER_NAME (class))
6328 add_method_to_hash_list (cls_method_hash_list, method);
6335 add_class (tree class)
6337 /* Put interfaces on list in reverse order. */
6338 TREE_CHAIN (class) = interface_chain;
6339 interface_chain = class;
6340 return interface_chain;
6344 add_category (tree class, tree category)
6346 /* Put categories on list in reverse order. */
6347 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6351 warning ("duplicate interface declaration for category `%s(%s)'",
6352 IDENTIFIER_POINTER (CLASS_NAME (class)),
6353 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6357 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6358 CLASS_CATEGORY_LIST (class) = category;
6362 /* Called after parsing each instance variable declaration. Necessary to
6363 preserve typedefs and implement public/private...
6365 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6368 add_instance_variable (tree class, int public, tree declarator,
6369 tree declspecs, tree width)
6371 tree field_decl = grokfield (declarator, declspecs, width);
6372 tree field_type = TREE_TYPE (field_decl);
6373 const char *ivar_name = DECL_NAME (field_decl)
6374 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6379 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6381 error ("illegal reference type specified for instance variable `%s'",
6383 /* Return class as is without adding this ivar. */
6388 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6389 || TYPE_SIZE (field_type) == error_mark_node
6390 /* 'type[0]' is allowed, but 'type[]' is not! */
6392 || (TYPE_SIZE (field_type) == bitsize_zero_node
6393 && !TREE_OPERAND (declarator, 1))
6397 error ("instance variable `%s' has unknown size", ivar_name);
6398 /* Return class as is without adding this ivar. */
6403 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6404 cannot be ivars; ditto for classes with vtables. */
6405 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6406 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6408 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6409 if(TYPE_POLYMORPHIC_P (field_type)) {
6410 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6411 error ("type `%s' has virtual member functions", type_name);
6412 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6413 type_name, ivar_name);
6414 /* Return class as is without adding this ivar. */
6417 /* user-defined constructors and destructors are not known to Obj-C and
6418 hence will not be called. This may or may not be a problem. */
6419 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6420 warning ("type `%s' has a user-defined constructor", type_name);
6421 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6422 warning ("type `%s' has a user-defined destructor", type_name);
6423 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6427 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6431 TREE_PUBLIC (field_decl) = 0;
6432 TREE_PRIVATE (field_decl) = 0;
6433 TREE_PROTECTED (field_decl) = 1;
6437 TREE_PUBLIC (field_decl) = 1;
6438 TREE_PRIVATE (field_decl) = 0;
6439 TREE_PROTECTED (field_decl) = 0;
6443 TREE_PUBLIC (field_decl) = 0;
6444 TREE_PRIVATE (field_decl) = 1;
6445 TREE_PROTECTED (field_decl) = 0;
6450 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6451 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6452 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6457 is_ivar (tree decl_chain, tree ident)
6459 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6460 if (DECL_NAME (decl_chain) == ident)
6465 /* True if the ivar is private and we are not in its implementation. */
6468 is_private (tree decl)
6470 if (TREE_PRIVATE (decl)
6471 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
6473 error ("instance variable `%s' is declared private",
6474 IDENTIFIER_POINTER (DECL_NAME (decl)));
6481 /* We have an instance variable reference;, check to see if it is public. */
6484 is_public (tree expr, tree identifier)
6486 tree basetype = TREE_TYPE (expr);
6487 enum tree_code code = TREE_CODE (basetype);
6490 if (code == RECORD_TYPE)
6492 if (TREE_STATIC_TEMPLATE (basetype))
6494 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6496 error ("cannot find interface declaration for `%s'",
6497 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6501 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6503 if (TREE_PUBLIC (decl))
6506 /* Important difference between the Stepstone translator:
6507 all instance variables should be public within the context
6508 of the implementation. */
6509 if (objc_implementation_context
6510 && (((TREE_CODE (objc_implementation_context)
6511 == CLASS_IMPLEMENTATION_TYPE)
6512 || (TREE_CODE (objc_implementation_context)
6513 == CATEGORY_IMPLEMENTATION_TYPE))
6514 && (CLASS_NAME (objc_implementation_context)
6515 == OBJC_TYPE_NAME (basetype))))
6516 return ! is_private (decl);
6518 /* The 2.95.2 compiler sometimes allowed C functions to access
6519 non-@public ivars. We will let this slide for now... */
6520 if (!objc_method_context)
6522 warning ("instance variable `%s' is %s; "
6523 "this will be a hard error in the future",
6524 IDENTIFIER_POINTER (identifier),
6525 TREE_PRIVATE (decl) ? "@private" : "@protected");
6529 error ("instance variable `%s' is declared %s",
6530 IDENTIFIER_POINTER (identifier),
6531 TREE_PRIVATE (decl) ? "private" : "protected");
6536 else if (objc_implementation_context && (basetype == objc_object_reference))
6538 TREE_TYPE (expr) = uprivate_record;
6539 warning ("static access to object of type `id'");
6546 /* Make sure all entries in CHAIN are also in LIST. */
6549 check_methods (tree chain, tree list, int mtype)
6555 if (!lookup_method (list, chain))
6559 if (TREE_CODE (objc_implementation_context)
6560 == CLASS_IMPLEMENTATION_TYPE)
6561 warning ("incomplete implementation of class `%s'",
6562 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6563 else if (TREE_CODE (objc_implementation_context)
6564 == CATEGORY_IMPLEMENTATION_TYPE)
6565 warning ("incomplete implementation of category `%s'",
6566 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6570 warning ("method definition for `%c%s' not found",
6571 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6574 chain = TREE_CHAIN (chain);
6580 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6583 conforms_to_protocol (tree class, tree protocol)
6585 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6587 tree p = CLASS_PROTOCOL_LIST (class);
6588 while (p && TREE_VALUE (p) != protocol)
6593 tree super = (CLASS_SUPER_NAME (class)
6594 ? lookup_interface (CLASS_SUPER_NAME (class))
6596 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6605 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6606 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6609 check_methods_accessible (tree chain, tree context, int mtype)
6613 tree base_context = context;
6617 context = base_context;
6621 list = CLASS_CLS_METHODS (context);
6623 list = CLASS_NST_METHODS (context);
6625 if (lookup_method (list, chain))
6628 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6629 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6630 context = (CLASS_SUPER_NAME (context)
6631 ? lookup_interface (CLASS_SUPER_NAME (context))
6634 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6635 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6636 context = (CLASS_NAME (context)
6637 ? lookup_interface (CLASS_NAME (context))
6643 if (context == NULL_TREE)
6647 if (TREE_CODE (objc_implementation_context)
6648 == CLASS_IMPLEMENTATION_TYPE)
6649 warning ("incomplete implementation of class `%s'",
6651 (CLASS_NAME (objc_implementation_context)));
6652 else if (TREE_CODE (objc_implementation_context)
6653 == CATEGORY_IMPLEMENTATION_TYPE)
6654 warning ("incomplete implementation of category `%s'",
6656 (CLASS_SUPER_NAME (objc_implementation_context)));
6659 warning ("method definition for `%c%s' not found",
6660 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6663 chain = TREE_CHAIN (chain); /* next method... */
6668 /* Check whether the current interface (accessible via
6669 'objc_implementation_context') actually implements protocol P, along
6670 with any protocols that P inherits. */
6673 check_protocol (tree p, const char *type, const char *name)
6675 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6679 /* Ensure that all protocols have bodies! */
6682 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6683 CLASS_CLS_METHODS (objc_implementation_context),
6685 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6686 CLASS_NST_METHODS (objc_implementation_context),
6691 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6692 objc_implementation_context,
6694 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6695 objc_implementation_context,
6700 warning ("%s `%s' does not fully implement the `%s' protocol",
6701 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6704 /* Check protocols recursively. */
6705 if (PROTOCOL_LIST (p))
6707 tree subs = PROTOCOL_LIST (p);
6709 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6713 tree sub = TREE_VALUE (subs);
6715 /* If the superclass does not conform to the protocols
6716 inherited by P, then we must! */
6717 if (!super_class || !conforms_to_protocol (super_class, sub))
6718 check_protocol (sub, type, name);
6719 subs = TREE_CHAIN (subs);
6724 /* Check whether the current interface (accessible via
6725 'objc_implementation_context') actually implements the protocols listed
6729 check_protocols (tree proto_list, const char *type, const char *name)
6731 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6733 tree p = TREE_VALUE (proto_list);
6735 check_protocol (p, type, name);
6739 /* Make sure that the class CLASS_NAME is defined
6740 CODE says which kind of thing CLASS_NAME ought to be.
6741 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6742 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6745 start_class (enum tree_code code, tree class_name, tree super_name,
6751 if (current_namespace != global_namespace) {
6752 error ("Objective-C declarations may only appear in global scope");
6754 #endif /* OBJCPLUS */
6756 if (objc_implementation_context)
6758 warning ("`@end' missing in implementation context");
6759 finish_class (objc_implementation_context);
6760 objc_ivar_chain = NULL_TREE;
6761 objc_implementation_context = NULL_TREE;
6764 class = make_node (code);
6765 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6767 CLASS_NAME (class) = class_name;
6768 CLASS_SUPER_NAME (class) = super_name;
6769 CLASS_CLS_METHODS (class) = NULL_TREE;
6771 if (! is_class_name (class_name)
6772 && (decl = lookup_name (class_name)))
6774 error ("`%s' redeclared as different kind of symbol",
6775 IDENTIFIER_POINTER (class_name));
6776 error ("%Jprevious declaration of '%D'",
6780 if (code == CLASS_IMPLEMENTATION_TYPE)
6785 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6786 if (TREE_VALUE (chain) == class_name)
6788 error ("reimplementation of class `%s'",
6789 IDENTIFIER_POINTER (class_name));
6790 return error_mark_node;
6792 implemented_classes = tree_cons (NULL_TREE, class_name,
6793 implemented_classes);
6796 /* Reset for multiple classes per file. */
6799 objc_implementation_context = class;
6801 /* Lookup the interface for this implementation. */
6803 if (!(implementation_template = lookup_interface (class_name)))
6805 warning ("cannot find interface declaration for `%s'",
6806 IDENTIFIER_POINTER (class_name));
6807 add_class (implementation_template = objc_implementation_context);
6810 /* If a super class has been specified in the implementation,
6811 insure it conforms to the one specified in the interface. */
6814 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6816 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6817 const char *const name =
6818 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6819 error ("conflicting super class name `%s'",
6820 IDENTIFIER_POINTER (super_name));
6821 error ("previous declaration of `%s'", name);
6824 else if (! super_name)
6826 CLASS_SUPER_NAME (objc_implementation_context)
6827 = CLASS_SUPER_NAME (implementation_template);
6831 else if (code == CLASS_INTERFACE_TYPE)
6833 if (lookup_interface (class_name))
6835 error ("duplicate interface declaration for class `%s'",
6837 warning ("duplicate interface declaration for class `%s'",
6839 IDENTIFIER_POINTER (class_name));
6844 CLASS_PROTOCOL_LIST (class)
6845 = lookup_and_install_protocols (protocol_list);
6848 else if (code == CATEGORY_INTERFACE_TYPE)
6850 tree class_category_is_assoc_with;
6852 /* For a category, class_name is really the name of the class that
6853 the following set of methods will be associated with. We must
6854 find the interface so that can derive the objects template. */
6856 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6858 error ("cannot find interface declaration for `%s'",
6859 IDENTIFIER_POINTER (class_name));
6860 exit (FATAL_EXIT_CODE);
6863 add_category (class_category_is_assoc_with, class);
6866 CLASS_PROTOCOL_LIST (class)
6867 = lookup_and_install_protocols (protocol_list);
6870 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6872 /* Reset for multiple classes per file. */
6875 objc_implementation_context = class;
6877 /* For a category, class_name is really the name of the class that
6878 the following set of methods will be associated with. We must
6879 find the interface so that can derive the objects template. */
6881 if (!(implementation_template = lookup_interface (class_name)))
6883 error ("cannot find interface declaration for `%s'",
6884 IDENTIFIER_POINTER (class_name));
6885 exit (FATAL_EXIT_CODE);
6892 continue_class (tree class)
6894 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6895 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6897 struct imp_entry *imp_entry;
6900 /* Check consistency of the instance variables. */
6902 if (CLASS_IVARS (class))
6903 check_ivars (implementation_template, class);
6905 /* code generation */
6907 ivar_context = build_private_template (implementation_template);
6909 if (!objc_class_template)
6910 build_class_template ();
6912 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6914 imp_entry->next = imp_list;
6915 imp_entry->imp_context = class;
6916 imp_entry->imp_template = implementation_template;
6918 synth_forward_declarations ();
6919 imp_entry->class_decl = UOBJC_CLASS_decl;
6920 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6922 /* Append to front and increment count. */
6923 imp_list = imp_entry;
6924 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6929 return ivar_context;
6932 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6934 if (!CLASS_STATIC_TEMPLATE (class))
6936 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6937 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6938 CLASS_STATIC_TEMPLATE (class) = record;
6940 /* Mark this record as a class template for static typing. */
6941 TREE_STATIC_TEMPLATE (record) = 1;
6948 return error_mark_node;
6951 /* This is called once we see the "@end" in an interface/implementation. */
6954 finish_class (tree class)
6956 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6958 /* All code generation is done in finish_objc. */
6960 if (implementation_template != objc_implementation_context)
6962 /* Ensure that all method listed in the interface contain bodies. */
6963 check_methods (CLASS_CLS_METHODS (implementation_template),
6964 CLASS_CLS_METHODS (objc_implementation_context), '+');
6965 check_methods (CLASS_NST_METHODS (implementation_template),
6966 CLASS_NST_METHODS (objc_implementation_context), '-');
6968 if (CLASS_PROTOCOL_LIST (implementation_template))
6969 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6971 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6975 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6977 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6981 /* Ensure all method listed in the interface contain bodies. */
6982 check_methods (CLASS_CLS_METHODS (category),
6983 CLASS_CLS_METHODS (objc_implementation_context), '+');
6984 check_methods (CLASS_NST_METHODS (category),
6985 CLASS_NST_METHODS (objc_implementation_context), '-');
6987 if (CLASS_PROTOCOL_LIST (category))
6988 check_protocols (CLASS_PROTOCOL_LIST (category),
6990 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6994 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6997 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6998 char *string = (char *) alloca (strlen (class_name) + 3);
7000 /* extern struct objc_object *_<my_name>; */
7002 sprintf (string, "_%s", class_name);
7004 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
7005 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
7006 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7012 add_protocol (tree protocol)
7014 /* Put protocol on list in reverse order. */
7015 TREE_CHAIN (protocol) = protocol_chain;
7016 protocol_chain = protocol;
7017 return protocol_chain;
7021 lookup_protocol (tree ident)
7025 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7026 if (ident == PROTOCOL_NAME (chain))
7032 /* This function forward declares the protocols named by NAMES. If
7033 they are already declared or defined, the function has no effect. */
7036 objc_declare_protocols (tree names)
7041 if (current_namespace != global_namespace) {
7042 error ("Objective-C declarations may only appear in global scope");
7044 #endif /* OBJCPLUS */
7046 for (list = names; list; list = TREE_CHAIN (list))
7048 tree name = TREE_VALUE (list);
7050 if (lookup_protocol (name) == NULL_TREE)
7052 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7054 TYPE_BINFO (protocol) = make_tree_vec (2);
7055 PROTOCOL_NAME (protocol) = name;
7056 PROTOCOL_LIST (protocol) = NULL_TREE;
7057 add_protocol (protocol);
7058 PROTOCOL_DEFINED (protocol) = 0;
7059 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7065 start_protocol (enum tree_code code, tree name, tree list)
7070 if (current_namespace != global_namespace) {
7071 error ("Objective-C declarations may only appear in global scope");
7073 #endif /* OBJCPLUS */
7075 /* This is as good a place as any. Need to invoke
7076 push_tag_toplevel. */
7077 if (!objc_protocol_template)
7078 objc_protocol_template = build_protocol_template ();
7080 protocol = lookup_protocol (name);
7084 protocol = make_node (code);
7085 TYPE_BINFO (protocol) = make_tree_vec (2);
7087 PROTOCOL_NAME (protocol) = name;
7088 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7089 add_protocol (protocol);
7090 PROTOCOL_DEFINED (protocol) = 1;
7091 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7093 check_protocol_recursively (protocol, list);
7095 else if (! PROTOCOL_DEFINED (protocol))
7097 PROTOCOL_DEFINED (protocol) = 1;
7098 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7100 check_protocol_recursively (protocol, list);
7104 warning ("duplicate declaration for protocol `%s'",
7105 IDENTIFIER_POINTER (name));
7111 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7116 /* "Encode" a data type into a string, which grows in util_obstack.
7117 ??? What is the FORMAT? Someone please document this! */
7120 encode_type_qualifiers (tree declspecs)
7124 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7126 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7127 obstack_1grow (&util_obstack, 'r');
7128 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7129 obstack_1grow (&util_obstack, 'n');
7130 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7131 obstack_1grow (&util_obstack, 'N');
7132 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7133 obstack_1grow (&util_obstack, 'o');
7134 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7135 obstack_1grow (&util_obstack, 'O');
7136 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7137 obstack_1grow (&util_obstack, 'R');
7138 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7139 obstack_1grow (&util_obstack, 'V');
7143 /* Encode a pointer type. */
7146 encode_pointer (tree type, int curtype, int format)
7148 tree pointer_to = TREE_TYPE (type);
7150 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7152 if (OBJC_TYPE_NAME (pointer_to)
7153 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7155 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7157 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7159 obstack_1grow (&util_obstack, '@');
7162 else if (TREE_STATIC_TEMPLATE (pointer_to))
7164 if (generating_instance_variables)
7166 obstack_1grow (&util_obstack, '@');
7167 obstack_1grow (&util_obstack, '"');
7168 obstack_grow (&util_obstack, name, strlen (name));
7169 obstack_1grow (&util_obstack, '"');
7174 obstack_1grow (&util_obstack, '@');
7178 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7180 obstack_1grow (&util_obstack, '#');
7183 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7185 obstack_1grow (&util_obstack, ':');
7190 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7191 && TYPE_MODE (pointer_to) == QImode)
7193 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7194 ? OBJC_TYPE_NAME (pointer_to)
7195 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7197 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7199 obstack_1grow (&util_obstack, '*');
7204 /* We have a type that does not get special treatment. */
7206 /* NeXT extension */
7207 obstack_1grow (&util_obstack, '^');
7208 encode_type (pointer_to, curtype, format);
7212 encode_array (tree type, int curtype, int format)
7214 tree an_int_cst = TYPE_SIZE (type);
7215 tree array_of = TREE_TYPE (type);
7218 /* An incomplete array is treated like a pointer. */
7219 if (an_int_cst == NULL)
7221 encode_pointer (type, curtype, format);
7225 sprintf (buffer, "[%ld",
7226 (long) (TREE_INT_CST_LOW (an_int_cst)
7227 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7229 obstack_grow (&util_obstack, buffer, strlen (buffer));
7230 encode_type (array_of, curtype, format);
7231 obstack_1grow (&util_obstack, ']');
7236 encode_aggregate_within (tree type, int curtype, int format, int left,
7240 /* NB: aggregates that are pointed to have slightly different encoding
7241 rules in that you never encode the names of instance variables. */
7243 = (obstack_object_size (&util_obstack) > 0
7244 && *(obstack_next_free (&util_obstack) - 1) == '^');
7246 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7247 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7249 /* Traverse struct aliases; it is important to get the
7250 original struct and its tag name (if any). */
7251 type = TYPE_MAIN_VARIANT (type);
7252 name = OBJC_TYPE_NAME (type);
7253 /* Open parenth/bracket. */
7254 obstack_1grow (&util_obstack, left);
7256 /* Encode the struct/union tag name, or '?' if a tag was
7257 not provided. Typedef aliases do not qualify. */
7258 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7260 /* Did this struct have a tag? */
7261 && !TYPE_WAS_ANONYMOUS (type)
7264 obstack_grow (&util_obstack,
7265 IDENTIFIER_POINTER (name),
7266 strlen (IDENTIFIER_POINTER (name)));
7268 obstack_1grow (&util_obstack, '?');
7270 /* Encode the types (and possibly names) of the inner fields,
7272 if (inline_contents)
7274 tree fields = TYPE_FIELDS (type);
7276 obstack_1grow (&util_obstack, '=');
7277 for (; fields; fields = TREE_CHAIN (fields))
7280 /* C++ static members, and things that are not fields at all,
7281 should not appear in the encoding. */
7282 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7285 if (generating_instance_variables && !pointed_to)
7287 tree fname = DECL_NAME (fields);
7289 obstack_1grow (&util_obstack, '"');
7290 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7291 obstack_grow (&util_obstack,
7292 IDENTIFIER_POINTER (fname),
7293 strlen (IDENTIFIER_POINTER (fname)));
7294 obstack_1grow (&util_obstack, '"');
7296 encode_field_decl (fields, curtype, format);
7299 /* Close parenth/bracket. */
7300 obstack_1grow (&util_obstack, right);
7304 encode_aggregate (tree type, int curtype, int format)
7306 enum tree_code code = TREE_CODE (type);
7312 encode_aggregate_within (type, curtype, format, '{', '}');
7317 encode_aggregate_within (type, curtype, format, '(', ')');
7322 obstack_1grow (&util_obstack, 'i');
7330 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7334 encode_next_bitfield (int width)
7337 sprintf (buffer, "b%d", width);
7338 obstack_grow (&util_obstack, buffer, strlen (buffer));
7341 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7343 encode_type (tree type, int curtype, int format)
7345 enum tree_code code = TREE_CODE (type);
7348 if (code == INTEGER_TYPE)
7350 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7352 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7353 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7355 if (type == long_unsigned_type_node
7356 || type == long_integer_type_node)
7357 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7359 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7361 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7364 obstack_1grow (&util_obstack, c);
7367 else if (code == REAL_TYPE)
7369 /* Floating point types. */
7370 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7372 case 32: c = 'f'; break;
7374 case 128: c = 'd'; break;
7377 obstack_1grow (&util_obstack, c);
7380 else if (code == VOID_TYPE)
7381 obstack_1grow (&util_obstack, 'v');
7383 else if (code == BOOLEAN_TYPE)
7384 obstack_1grow (&util_obstack, 'B');
7386 else if (code == ARRAY_TYPE)
7387 encode_array (type, curtype, format);
7389 else if (code == POINTER_TYPE)
7390 encode_pointer (type, curtype, format);
7392 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7393 encode_aggregate (type, curtype, format);
7395 else if (code == FUNCTION_TYPE) /* '?' */
7396 obstack_1grow (&util_obstack, '?');
7400 encode_gnu_bitfield (int position, tree type, int size)
7402 enum tree_code code = TREE_CODE (type);
7404 char charType = '?';
7406 if (code == INTEGER_TYPE)
7408 if (integer_zerop (TYPE_MIN_VALUE (type)))
7410 /* Unsigned integer types. */
7412 if (TYPE_MODE (type) == QImode)
7414 else if (TYPE_MODE (type) == HImode)
7416 else if (TYPE_MODE (type) == SImode)
7418 if (type == long_unsigned_type_node)
7423 else if (TYPE_MODE (type) == DImode)
7428 /* Signed integer types. */
7430 if (TYPE_MODE (type) == QImode)
7432 else if (TYPE_MODE (type) == HImode)
7434 else if (TYPE_MODE (type) == SImode)
7436 if (type == long_integer_type_node)
7442 else if (TYPE_MODE (type) == DImode)
7446 else if (code == ENUMERAL_TYPE)
7451 sprintf (buffer, "b%d%c%d", position, charType, size);
7452 obstack_grow (&util_obstack, buffer, strlen (buffer));
7456 encode_field_decl (tree field_decl, int curtype, int format)
7461 /* C++ static members, and things that are not fields at all,
7462 should not appear in the encoding. */
7463 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7467 type = TREE_TYPE (field_decl);
7469 /* Generate the bitfield typing information, if needed. Note the difference
7470 between GNU and NeXT runtimes. */
7471 if (DECL_BIT_FIELD_TYPE (field_decl))
7473 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7475 if (flag_next_runtime)
7476 encode_next_bitfield (size);
7478 encode_gnu_bitfield (int_bit_position (field_decl),
7479 DECL_BIT_FIELD_TYPE (field_decl), size);
7482 encode_type (TREE_TYPE (field_decl), curtype, format);
7486 objc_expr_last (tree complex_expr)
7491 while ((next = TREE_OPERAND (complex_expr, 0)))
7492 complex_expr = next;
7494 return complex_expr;
7498 synth_self_and_ucmd_args (void)
7502 if (objc_method_context
7503 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7504 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7506 /* Really a `struct objc_class *'. However, we allow people to
7507 assign to self, which changes its type midstream. */
7508 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7510 push_parm_decl (build_tree_list
7511 (build_tree_list (decl_specs,
7512 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7515 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (selector_type));
7516 push_parm_decl (build_tree_list
7517 (build_tree_list (decl_specs,
7518 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7522 /* Transform a method definition into a function definition as follows:
7523 - synthesize the first two arguments, "self" and "_cmd". */
7526 start_method_def (tree method)
7528 /* Required to implement _msgSuper. */
7529 objc_method_context = method;
7530 UOBJC_SUPER_decl = NULL_TREE;
7532 /* Must be called BEFORE start_function. */
7534 declare_parm_level ();
7536 /* Generate prototype declarations for arguments..."new-style". */
7537 synth_self_and_ucmd_args ();
7539 /* Generate argument declarations if a keyword_decl. */
7540 if (METHOD_SEL_ARGS (method))
7542 tree arglist = METHOD_SEL_ARGS (method);
7545 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7546 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7550 tree last_expr = objc_expr_last (arg_decl);
7552 /* Unite the abstract decl with its name. */
7553 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7554 push_parm_decl (build_tree_list
7555 (build_tree_list (arg_spec, arg_decl),
7559 /* Unhook: restore the abstract declarator. */
7560 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7565 push_parm_decl (build_tree_list
7566 (build_tree_list (arg_spec,
7567 KEYWORD_ARG_NAME (arglist)),
7570 arglist = TREE_CHAIN (arglist);
7575 if (METHOD_ADD_ARGS (method) != NULL_TREE
7576 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7578 /* We have a variable length selector - in "prototype" format. */
7579 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7582 /* This must be done prior to calling pushdecl. pushdecl is
7583 going to change our chain on us. */
7584 tree nextkey = TREE_CHAIN (akey);
7592 warn_with_method (const char *message, int mtype, tree method)
7594 /* Add a readable method name to the warning. */
7595 warning ("%J%s `%c%s'", method,
7596 message, mtype, gen_method_decl (method, errbuf));
7599 /* Return 1 if METHOD is consistent with PROTO. */
7602 comp_method_with_proto (tree method, tree proto)
7604 /* Create a function template node at most once. */
7605 if (!function1_template)
7606 function1_template = make_node (FUNCTION_TYPE);
7608 /* Install argument types - normally set by build_function_type. */
7609 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7611 /* install return type */
7612 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7614 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
7618 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7621 objc_types_are_equivalent (tree type1, tree type2)
7625 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7627 type1 = TYPE_PROTOCOL_LIST (type1);
7628 type2 = TYPE_PROTOCOL_LIST (type2);
7629 if (list_length (type1) == list_length (type2))
7631 for (; type2; type2 = TREE_CHAIN (type2))
7632 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7639 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7642 comp_proto_with_proto (tree proto1, tree proto2)
7646 /* The following test is needed in case there are hashing
7648 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7651 /* Compare return types. */
7652 type1 = groktypename (TREE_TYPE (proto1));
7653 type2 = groktypename (TREE_TYPE (proto2));
7655 if (!objc_types_are_equivalent (type1, type2))
7658 /* Compare argument types. */
7659 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7660 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7662 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7664 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7668 return (!type1 && !type2);
7671 /* - Generate an identifier for the function. the format is "_n_cls",
7672 where 1 <= n <= nMethods, and cls is the name the implementation we
7674 - Install the return type from the method declaration.
7675 - If we have a prototype, check for type consistency. */
7678 really_start_method (tree method, tree parmlist)
7680 tree sc_spec, ret_spec, ret_decl, decl_specs;
7681 tree method_decl, method_id;
7682 const char *sel_name, *class_name, *cat_name;
7685 /* Synth the storage class & assemble the return type. */
7686 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7687 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7688 decl_specs = chainon (sc_spec, ret_spec);
7690 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7691 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7692 cat_name = ((TREE_CODE (objc_implementation_context)
7693 == CLASS_IMPLEMENTATION_TYPE)
7695 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7698 /* Make sure this is big enough for any plausible method label. */
7699 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7700 + (cat_name ? strlen (cat_name) : 0));
7702 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7703 class_name, cat_name, sel_name, method_slot);
7705 method_id = get_identifier (buf);
7708 /* Objective-C methods cannot be overloaded, so we don't need
7709 the type encoding appended. It looks bad anyway... */
7710 push_lang_context (lang_name_c);
7713 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7715 /* Check the declarator portion of the return type for the method. */
7716 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7718 /* Unite the complex decl (specified in the abstract decl) with the
7719 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7720 tree save_expr = objc_expr_last (ret_decl);
7722 TREE_OPERAND (save_expr, 0) = method_decl;
7723 method_decl = ret_decl;
7725 /* Fool the parser into thinking it is starting a function. */
7726 start_function (decl_specs, method_decl, NULL_TREE);
7728 /* Unhook: this has the effect of restoring the abstract declarator. */
7729 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7734 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7736 /* Fool the parser into thinking it is starting a function. */
7737 start_function (decl_specs, method_decl, NULL_TREE);
7739 /* Unhook: this has the effect of restoring the abstract declarator. */
7740 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7744 /* set self_decl from the first argument...this global is used by
7745 * build_ivar_reference().build_indirect_ref().
7747 self_decl = DECL_ARGUMENTS (current_function_decl);
7749 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7750 * the following: warning:unused parameter `struct objc_selector * _cmd'
7752 TREE_USED (self_decl) = 1;
7753 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7754 /* Ditto for the underlying (static) C function. */
7755 TREE_USED (current_function_decl) = 1;
7756 pop_lang_context ();
7759 METHOD_DEFINITION (method) = current_function_decl;
7761 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7763 if (implementation_template != objc_implementation_context)
7766 = lookup_method_static (implementation_template,
7767 METHOD_SEL_NAME (method),
7768 TREE_CODE (method) == CLASS_METHOD_DECL);
7772 if (!comp_method_with_proto (method, proto))
7774 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7776 warn_with_method ("conflicting types for", type, method);
7777 warn_with_method ("previous declaration of", type, proto);
7782 /* We have a method @implementation even though we did not
7783 see a corresponding @interface declaration (which is allowed
7784 by Objective-C rules). Go ahead and place the method in
7785 the @interface anyway, so that message dispatch lookups
7787 tree interface = implementation_template;
7789 if (TREE_CODE (objc_implementation_context)
7790 == CATEGORY_IMPLEMENTATION_TYPE)
7791 interface = lookup_category
7793 CLASS_SUPER_NAME (objc_implementation_context));
7796 objc_add_method (interface, copy_node (method),
7797 TREE_CODE (method) == CLASS_METHOD_DECL);
7802 /* The following routine is always called...this "architecture" is to
7803 accommodate "old-style" variable length selectors.
7805 - a:a b:b // prototype ; id c; id d; // old-style. */
7808 continue_method_def (void)
7812 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7813 /* We have a `, ...' immediately following the selector. */
7814 parmlist = get_parm_info (/*ellipsis=*/true);
7816 parmlist = get_parm_info (/*ellipsis=*/false);
7819 /* Set self_decl from the first argument...this global is used by
7820 build_ivar_reference calling build_indirect_ref. */
7821 self_decl = TREE_PURPOSE (parmlist);
7822 #endif /* !OBJCPLUS */
7825 really_start_method (objc_method_context, parmlist);
7826 store_parm_decls ();
7829 static void *UOBJC_SUPER_scope = 0;
7831 /* _n_Method (id self, SEL sel, ...)
7833 struct objc_super _S;
7834 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7838 get_super_receiver (void)
7840 if (objc_method_context)
7842 tree super_expr, super_expr_list;
7844 if (!UOBJC_SUPER_decl)
7846 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7847 build_tree_list (NULL_TREE,
7848 objc_super_template),
7851 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7853 /* This prevents `unused variable' warnings when compiling with -Wall. */
7854 TREE_USED (UOBJC_SUPER_decl) = 1;
7855 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7857 UOBJC_SUPER_scope = get_current_scope ();
7860 /* Set receiver to self. */
7861 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7862 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7863 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7865 /* Set class to begin searching. */
7867 super_expr = build_component_ref (UOBJC_SUPER_decl,
7868 get_identifier ("super_class"));
7870 super_expr = build_component_ref (UOBJC_SUPER_decl,
7871 get_identifier ("class"));
7874 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7876 /* [_cls, __cls]Super are "pre-built" in
7877 synth_forward_declarations. */
7879 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7880 ((TREE_CODE (objc_method_context)
7881 == INSTANCE_METHOD_DECL)
7883 : uucls_super_ref));
7887 /* We have a category. */
7889 tree super_name = CLASS_SUPER_NAME (implementation_template);
7892 /* Barf if super used in a category of Object. */
7895 error ("no super class declared in interface for `%s'",
7896 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7897 return error_mark_node;
7900 if (flag_next_runtime && !flag_zero_link)
7902 super_class = get_class_reference (super_name);
7903 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7904 /* If we are in a class method, we must retrieve the
7905 _metaclass_ for the current class, pointed at by
7906 the class's "isa" pointer. The following assumes that
7907 "isa" is the first ivar in a class (which it must be). */
7909 = build_indirect_ref
7910 (build_c_cast (build_pointer_type (objc_class_type),
7911 super_class), "unary *");
7915 add_class_reference (super_name);
7916 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7917 ? objc_get_class_decl : objc_get_meta_class_decl);
7918 assemble_external (super_class);
7920 = build_function_call
7924 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7925 IDENTIFIER_POINTER (super_name))));
7929 = build_modify_expr (super_expr, NOP_EXPR,
7930 build_c_cast (TREE_TYPE (super_expr),
7934 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7936 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7937 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7939 return build_compound_expr (super_expr_list);
7943 error ("[super ...] must appear in a method context");
7944 return error_mark_node;
7948 /* When exiting a scope, sever links to a 'super' declaration (if any)
7949 therein contained. */
7952 objc_clear_super_receiver (void)
7954 if (objc_method_context
7955 && UOBJC_SUPER_scope == get_current_scope ()) {
7956 UOBJC_SUPER_decl = 0;
7957 UOBJC_SUPER_scope = 0;
7962 objc_expand_function_end (void)
7964 /* This routine may also get called for C functions, including those
7965 nested within ObjC methods. In such cases, method encoding is
7967 if (objc_method_context == NULL_TREE
7968 || DECL_INITIAL (objc_method_context) != current_function_decl)
7971 METHOD_ENCODING (objc_method_context)
7972 = encode_method_prototype (objc_method_context);
7976 finish_method_def (void)
7978 lang_expand_function_end = objc_expand_function_end;
7979 /* We cannot validly inline ObjC methods, at least not without a language
7980 extension to declare that a method need not be dynamically
7981 dispatched, so suppress all thoughts of doing so. */
7982 DECL_INLINE (current_function_decl) = 0;
7983 DECL_UNINLINABLE (current_function_decl) = 1;
7984 current_function_cannot_inline = "methods cannot be inlined";
7987 lang_expand_function_end = NULL;
7989 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7990 since the optimizer may find "may be used before set" errors. */
7991 objc_method_context = NULL_TREE;
7996 lang_report_error_function (tree decl)
7998 if (objc_method_context)
8000 fprintf (stderr, "In method `%s'\n",
8001 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8011 is_complex_decl (tree type)
8013 return (TREE_CODE (type) == ARRAY_TYPE
8014 || TREE_CODE (type) == FUNCTION_TYPE
8015 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8019 /* Code to convert a decl node into text for a declaration in C. */
8021 static char tmpbuf[256];
8024 adorn_decl (tree decl, char *str)
8026 enum tree_code code = TREE_CODE (decl);
8028 if (code == ARRAY_REF)
8030 tree an_int_cst = TREE_OPERAND (decl, 1);
8032 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8033 sprintf (str + strlen (str), "[%ld]",
8034 (long) TREE_INT_CST_LOW (an_int_cst));
8039 else if (code == ARRAY_TYPE)
8041 tree an_int_cst = TYPE_SIZE (decl);
8042 tree array_of = TREE_TYPE (decl);
8044 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8045 sprintf (str + strlen (str), "[%ld]",
8046 (long) (TREE_INT_CST_LOW (an_int_cst)
8047 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8052 else if (code == CALL_EXPR)
8054 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8059 gen_declaration_1 (chain, str);
8060 chain = TREE_CHAIN (chain);
8067 else if (code == FUNCTION_TYPE)
8069 tree chain = TYPE_ARG_TYPES (decl);
8072 while (chain && TREE_VALUE (chain) != void_type_node)
8074 gen_declaration_1 (TREE_VALUE (chain), str);
8075 chain = TREE_CHAIN (chain);
8076 if (chain && TREE_VALUE (chain) != void_type_node)
8082 else if (code == INDIRECT_REF)
8084 strcpy (tmpbuf, "*");
8085 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8089 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8091 chain = TREE_CHAIN (chain))
8093 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8095 strcat (tmpbuf, " ");
8096 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8100 strcat (tmpbuf, " ");
8102 strcat (tmpbuf, str);
8103 strcpy (str, tmpbuf);
8106 else if (code == POINTER_TYPE)
8108 strcpy (tmpbuf, "*");
8109 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8111 if (TYPE_READONLY (decl))
8112 strcat (tmpbuf, " const");
8113 if (TYPE_VOLATILE (decl))
8114 strcat (tmpbuf, " volatile");
8116 strcat (tmpbuf, " ");
8118 strcat (tmpbuf, str);
8119 strcpy (str, tmpbuf);
8124 gen_declarator (tree decl, char *buf, const char *name)
8128 enum tree_code code = TREE_CODE (decl);
8138 op = TREE_OPERAND (decl, 0);
8140 /* We have a pointer to a function or array...(*)(), (*)[] */
8141 if ((code == ARRAY_REF || code == CALL_EXPR)
8142 && op && TREE_CODE (op) == INDIRECT_REF)
8145 str = gen_declarator (op, buf, name);
8149 strcpy (tmpbuf, "(");
8150 strcat (tmpbuf, str);
8151 strcat (tmpbuf, ")");
8152 strcpy (str, tmpbuf);
8155 adorn_decl (decl, str);
8164 /* This clause is done iteratively rather than recursively. */
8167 op = (is_complex_decl (TREE_TYPE (decl))
8168 ? TREE_TYPE (decl) : NULL_TREE);
8170 adorn_decl (decl, str);
8172 /* We have a pointer to a function or array...(*)(), (*)[] */
8173 if (code == POINTER_TYPE
8174 && op && (TREE_CODE (op) == FUNCTION_TYPE
8175 || TREE_CODE (op) == ARRAY_TYPE))
8177 strcpy (tmpbuf, "(");
8178 strcat (tmpbuf, str);
8179 strcat (tmpbuf, ")");
8180 strcpy (str, tmpbuf);
8183 decl = (is_complex_decl (TREE_TYPE (decl))
8184 ? TREE_TYPE (decl) : NULL_TREE);
8187 while (decl && (code = TREE_CODE (decl)))
8192 case IDENTIFIER_NODE:
8193 /* Will only happen if we are processing a "raw" expr-decl. */
8194 strcpy (buf, IDENTIFIER_POINTER (decl));
8205 /* We have an abstract declarator or a _DECL node. */
8213 gen_declspecs (tree declspecs, char *buf, int raw)
8219 for (chain = nreverse (copy_list (declspecs));
8220 chain; chain = TREE_CHAIN (chain))
8222 tree aspec = TREE_VALUE (chain);
8224 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8225 strcat (buf, IDENTIFIER_POINTER (aspec));
8226 else if (TREE_CODE (aspec) == RECORD_TYPE)
8228 if (OBJC_TYPE_NAME (aspec))
8230 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8232 if (! TREE_STATIC_TEMPLATE (aspec))
8233 strcat (buf, "struct ");
8234 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8239 tree chain = protocol_list;
8246 (PROTOCOL_NAME (TREE_VALUE (chain))));
8247 chain = TREE_CHAIN (chain);
8256 strcat (buf, "untagged struct");
8259 else if (TREE_CODE (aspec) == UNION_TYPE)
8261 if (OBJC_TYPE_NAME (aspec))
8263 if (! TREE_STATIC_TEMPLATE (aspec))
8264 strcat (buf, "union ");
8265 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8268 strcat (buf, "untagged union");
8271 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8273 if (OBJC_TYPE_NAME (aspec))
8275 if (! TREE_STATIC_TEMPLATE (aspec))
8276 strcat (buf, "enum ");
8277 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8280 strcat (buf, "untagged enum");
8283 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8284 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8286 else if (IS_ID (aspec))
8288 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8293 tree chain = protocol_list;
8300 (PROTOCOL_NAME (TREE_VALUE (chain))));
8301 chain = TREE_CHAIN (chain);
8308 if (TREE_CHAIN (chain))
8314 /* Type qualifiers. */
8315 if (TYPE_READONLY (declspecs))
8316 strcat (buf, "const ");
8317 if (TYPE_VOLATILE (declspecs))
8318 strcat (buf, "volatile ");
8320 switch (TREE_CODE (declspecs))
8322 /* Type specifiers. */
8325 declspecs = TYPE_MAIN_VARIANT (declspecs);
8327 /* Signed integer types. */
8329 if (declspecs == short_integer_type_node)
8330 strcat (buf, "short int ");
8331 else if (declspecs == integer_type_node)
8332 strcat (buf, "int ");
8333 else if (declspecs == long_integer_type_node)
8334 strcat (buf, "long int ");
8335 else if (declspecs == long_long_integer_type_node)
8336 strcat (buf, "long long int ");
8337 else if (declspecs == signed_char_type_node
8338 || declspecs == char_type_node)
8339 strcat (buf, "char ");
8341 /* Unsigned integer types. */
8343 else if (declspecs == short_unsigned_type_node)
8344 strcat (buf, "unsigned short ");
8345 else if (declspecs == unsigned_type_node)
8346 strcat (buf, "unsigned int ");
8347 else if (declspecs == long_unsigned_type_node)
8348 strcat (buf, "unsigned long ");
8349 else if (declspecs == long_long_unsigned_type_node)
8350 strcat (buf, "unsigned long long ");
8351 else if (declspecs == unsigned_char_type_node)
8352 strcat (buf, "unsigned char ");
8356 declspecs = TYPE_MAIN_VARIANT (declspecs);
8358 if (declspecs == float_type_node)
8359 strcat (buf, "float ");
8360 else if (declspecs == double_type_node)
8361 strcat (buf, "double ");
8362 else if (declspecs == long_double_type_node)
8363 strcat (buf, "long double ");
8367 if (OBJC_TYPE_NAME (declspecs)
8368 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8370 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8372 if (! TREE_STATIC_TEMPLATE (declspecs))
8373 strcat (buf, "struct ");
8374 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8378 tree chain = protocol_list;
8385 (PROTOCOL_NAME (TREE_VALUE (chain))));
8386 chain = TREE_CHAIN (chain);
8395 strcat (buf, "untagged struct");
8401 if (OBJC_TYPE_NAME (declspecs)
8402 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8404 strcat (buf, "union ");
8405 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8410 strcat (buf, "untagged union ");
8414 if (OBJC_TYPE_NAME (declspecs)
8415 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8417 strcat (buf, "enum ");
8418 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8423 strcat (buf, "untagged enum ");
8427 strcat (buf, "void ");
8432 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8437 tree chain = protocol_list;
8444 (PROTOCOL_NAME (TREE_VALUE (chain))));
8445 chain = TREE_CHAIN (chain);
8461 /* Given a tree node, produce a printable description of it in the given
8462 buffer, overwriting the buffer. */
8465 gen_declaration (tree atype_or_adecl, char *buf)
8468 gen_declaration_1 (atype_or_adecl, buf);
8472 /* Given a tree node, append a printable description to the end of the
8476 gen_declaration_1 (tree atype_or_adecl, char *buf)
8480 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8482 tree declspecs; /* "identifier_node", "record_type" */
8483 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8484 tree width = NULL_TREE; /* for bitfields */
8486 /* We have a "raw", abstract declarator (typename). */
8487 declarator = TREE_VALUE (atype_or_adecl);
8488 /* In the case of raw ivars, the declarator itself is a list,
8489 and contains bitfield widths. */
8490 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8492 width = TREE_VALUE (declarator);
8493 declarator = TREE_PURPOSE (declarator);
8495 declspecs = TREE_PURPOSE (atype_or_adecl);
8497 gen_declspecs (declspecs, buf, 1);
8501 strcat (buf, gen_declarator (declarator, declbuf, ""));
8504 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8505 TREE_INT_CST_LOW (width));
8511 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8512 tree declarator; /* "array_type", "function_type", "pointer_type". */
8514 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8515 || TREE_CODE (atype_or_adecl) == PARM_DECL
8516 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8517 atype = TREE_TYPE (atype_or_adecl);
8519 /* Assume we have a *_type node. */
8520 atype = atype_or_adecl;
8522 if (is_complex_decl (atype))
8526 /* Get the declaration specifier; it is at the end of the list. */
8527 declarator = chain = atype;
8529 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8530 while (is_complex_decl (chain));
8537 declarator = NULL_TREE;
8540 gen_declspecs (declspecs, buf, 0);
8542 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8543 || TREE_CODE (atype_or_adecl) == PARM_DECL
8544 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8546 const char *const decl_name =
8547 (DECL_NAME (atype_or_adecl)
8548 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8553 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8556 else if (decl_name[0])
8559 strcat (buf, decl_name);
8562 else if (declarator)
8565 strcat (buf, gen_declarator (declarator, declbuf, ""));
8570 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8572 /* Given a method tree, put a printable description into the given
8573 buffer (overwriting) and return a pointer to the buffer. */
8576 gen_method_decl (tree method, char *buf)
8581 if (RAW_TYPESPEC (method) != objc_object_reference)
8584 gen_declaration_1 (TREE_TYPE (method), buf);
8588 chain = METHOD_SEL_ARGS (method);
8591 /* We have a chain of keyword_decls. */
8594 if (KEYWORD_KEY_NAME (chain))
8595 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8598 if (RAW_TYPESPEC (chain) != objc_object_reference)
8601 gen_declaration_1 (TREE_TYPE (chain), buf);
8605 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8606 if ((chain = TREE_CHAIN (chain)))
8611 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8612 strcat (buf, ", ...");
8613 else if (METHOD_ADD_ARGS (method))
8615 /* We have a tree list node as generate by get_parm_info. */
8616 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8618 /* Know we have a chain of parm_decls. */
8622 gen_declaration_1 (chain, buf);
8623 chain = TREE_CHAIN (chain);
8629 /* We have a unary selector. */
8630 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8638 /* Dump an @interface declaration of the supplied class CHAIN to the
8639 supplied file FP. Used to implement the -gen-decls option (which
8640 prints out an @interface declaration of all classes compiled in
8641 this run); potentially useful for debugging the compiler too. */
8643 dump_interface (FILE *fp, tree chain)
8645 /* FIXME: A heap overflow here whenever a method (or ivar)
8646 declaration is so long that it doesn't fit in the buffer. The
8647 code and all the related functions should be rewritten to avoid
8648 using fixed size buffers. */
8649 char *buf = (char *) xmalloc (1024 * 10);
8650 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8651 tree ivar_decls = CLASS_RAW_IVARS (chain);
8652 tree nst_methods = CLASS_NST_METHODS (chain);
8653 tree cls_methods = CLASS_CLS_METHODS (chain);
8655 fprintf (fp, "\n@interface %s", my_name);
8657 /* CLASS_SUPER_NAME is used to store the superclass name for
8658 classes, and the category name for categories. */
8659 if (CLASS_SUPER_NAME (chain))
8661 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8663 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8664 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8666 fprintf (fp, " (%s)\n", name);
8670 fprintf (fp, " : %s\n", name);
8676 /* FIXME - the following doesn't seem to work at the moment. */
8679 fprintf (fp, "{\n");
8682 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8683 ivar_decls = TREE_CHAIN (ivar_decls);
8686 fprintf (fp, "}\n");
8691 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8692 nst_methods = TREE_CHAIN (nst_methods);
8697 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8698 cls_methods = TREE_CHAIN (cls_methods);
8701 fprintf (fp, "@end\n");
8704 /* Demangle function for Objective-C */
8706 objc_demangle (const char *mangled)
8708 char *demangled, *cp;
8710 if (mangled[0] == '_' &&
8711 (mangled[1] == 'i' || mangled[1] == 'c') &&
8714 cp = demangled = xmalloc(strlen(mangled) + 2);
8715 if (mangled[1] == 'i')
8716 *cp++ = '-'; /* for instance method */
8718 *cp++ = '+'; /* for class method */
8719 *cp++ = '['; /* opening left brace */
8720 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8721 while (*cp && *cp == '_')
8722 cp++; /* skip any initial underbars in class name */
8723 cp = strchr(cp, '_'); /* find first non-initial underbar */
8726 free(demangled); /* not mangled name */
8729 if (cp[1] == '_') /* easy case: no category name */
8731 *cp++ = ' '; /* replace two '_' with one ' ' */
8732 strcpy(cp, mangled + (cp - demangled) + 2);
8736 *cp++ = '('; /* less easy case: category name */
8737 cp = strchr(cp, '_');
8740 free(demangled); /* not mangled name */
8744 *cp++ = ' '; /* overwriting 1st char of method name... */
8745 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8747 while (*cp && *cp == '_')
8748 cp++; /* skip any initial underbars in method name */
8751 *cp = ':'; /* replace remaining '_' with ':' */
8752 *cp++ = ']'; /* closing right brace */
8753 *cp++ = 0; /* string terminator */
8757 return mangled; /* not an objc mangled name */
8761 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8763 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8769 gcc_obstack_init (&util_obstack);
8770 util_firstobj = (char *) obstack_finish (&util_obstack);
8772 errbuf = (char *) xmalloc (BUFSIZE);
8774 synth_module_prologue ();
8780 struct imp_entry *impent;
8782 /* The internally generated initializers appear to have missing braces.
8783 Don't warn about this. */
8784 int save_warn_missing_braces = warn_missing_braces;
8785 warn_missing_braces = 0;
8787 /* A missing @end may not be detected by the parser. */
8788 if (objc_implementation_context)
8790 warning ("`@end' missing in implementation context");
8791 finish_class (objc_implementation_context);
8792 objc_ivar_chain = NULL_TREE;
8793 objc_implementation_context = NULL_TREE;
8796 /* Process the static instances here because initialization of objc_symtab
8798 if (objc_static_instances)
8799 generate_static_references ();
8801 if (imp_list || class_names_chain
8802 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8803 generate_objc_symtab_decl ();
8805 for (impent = imp_list; impent; impent = impent->next)
8807 objc_implementation_context = impent->imp_context;
8808 implementation_template = impent->imp_template;
8810 UOBJC_CLASS_decl = impent->class_decl;
8811 UOBJC_METACLASS_decl = impent->meta_decl;
8813 /* Dump the @interface of each class as we compile it, if the
8814 -gen-decls option is in use. TODO: Dump the classes in the
8815 order they were found, rather than in reverse order as we
8817 if (flag_gen_declaration)
8819 dump_interface (gen_declaration_file, objc_implementation_context);
8822 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8824 /* all of the following reference the string pool... */
8825 generate_ivar_lists ();
8826 generate_dispatch_tables ();
8827 generate_shared_structures ();
8831 generate_dispatch_tables ();
8832 generate_category (objc_implementation_context);
8836 /* If we are using an array of selectors, we must always
8837 finish up the array decl even if no selectors were used. */
8838 if (! flag_next_runtime || sel_ref_chain)
8839 build_selector_translation_table ();
8842 generate_protocols ();
8844 if (flag_replace_objc_classes && imp_list)
8845 generate_objc_image_info ();
8847 if (objc_implementation_context || class_names_chain || objc_static_instances
8848 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8850 /* Arrange for ObjC data structures to be initialized at run time. */
8851 rtx init_sym = build_module_descriptor ();
8852 if (init_sym && targetm.have_ctors_dtors)
8853 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8856 /* Dump the class references. This forces the appropriate classes
8857 to be linked into the executable image, preserving unix archive
8858 semantics. This can be removed when we move to a more dynamically
8859 linked environment. */
8861 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8863 handle_class_ref (chain);
8864 if (TREE_PURPOSE (chain))
8865 generate_classref_translation_entry (chain);
8868 for (impent = imp_list; impent; impent = impent->next)
8869 handle_impent (impent);
8871 /* Dump the string table last. */
8873 generate_strings ();
8880 /* Run through the selector hash tables and print a warning for any
8881 selector which has multiple methods. */
8883 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8885 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8886 check_duplicates (hsh, 0, 1);
8887 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8888 check_duplicates (hsh, 0, 1);
8892 warn_missing_braces = save_warn_missing_braces;
8895 /* Subroutines of finish_objc. */
8898 generate_classref_translation_entry (tree chain)
8900 tree expr, name, decl_specs, decl, sc_spec;
8903 type = TREE_TYPE (TREE_PURPOSE (chain));
8905 expr = add_objc_string (TREE_VALUE (chain), class_names);
8906 expr = build_c_cast (type, expr); /* cast! */
8908 name = DECL_NAME (TREE_PURPOSE (chain));
8910 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8912 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8913 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8915 /* The decl that is returned from start_decl is the one that we
8916 forward declared in build_class_reference. */
8917 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8918 DECL_CONTEXT (decl) = NULL_TREE;
8919 finish_decl (decl, expr, NULL_TREE);
8924 handle_class_ref (tree chain)
8926 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8927 char *string = (char *) alloca (strlen (name) + 30);
8931 sprintf (string, "%sobjc_class_name_%s",
8932 (flag_next_runtime ? "." : "__"), name);
8934 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8935 if (flag_next_runtime)
8937 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8942 /* Make a decl for this name, so we can use its address in a tree. */
8943 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8944 DECL_EXTERNAL (decl) = 1;
8945 TREE_PUBLIC (decl) = 1;
8948 rest_of_decl_compilation (decl, 0, 0, 0);
8950 /* Make a decl for the address. */
8951 sprintf (string, "%sobjc_class_ref_%s",
8952 (flag_next_runtime ? "." : "__"), name);
8953 exp = build1 (ADDR_EXPR, string_type_node, decl);
8954 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8955 DECL_INITIAL (decl) = exp;
8956 TREE_STATIC (decl) = 1;
8957 TREE_USED (decl) = 1;
8960 rest_of_decl_compilation (decl, 0, 0, 0);
8964 handle_impent (struct imp_entry *impent)
8968 objc_implementation_context = impent->imp_context;
8969 implementation_template = impent->imp_template;
8971 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8973 const char *const class_name =
8974 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8976 string = (char *) alloca (strlen (class_name) + 30);
8978 sprintf (string, "%sobjc_class_name_%s",
8979 (flag_next_runtime ? "." : "__"), class_name);
8981 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8983 const char *const class_name =
8984 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8985 const char *const class_super_name =
8986 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8988 string = (char *) alloca (strlen (class_name)
8989 + strlen (class_super_name) + 30);
8991 /* Do the same for categories. Even though no references to
8992 these symbols are generated automatically by the compiler, it
8993 gives you a handle to pull them into an archive by hand. */
8994 sprintf (string, "*%sobjc_category_name_%s_%s",
8995 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9000 #ifdef ASM_DECLARE_CLASS_REFERENCE
9001 if (flag_next_runtime)
9003 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9011 init = build_int_2 (0, 0);
9012 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
9013 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9014 TREE_PUBLIC (decl) = 1;
9015 TREE_READONLY (decl) = 1;
9016 TREE_USED (decl) = 1;
9017 TREE_CONSTANT (decl) = 1;
9018 DECL_CONTEXT (decl) = 0;
9019 DECL_ARTIFICIAL (decl) = 1;
9020 DECL_INITIAL (decl) = init;
9021 assemble_variable (decl, 1, 0, 0);
9025 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9026 later requires that ObjC translation units participating in F&C be
9027 specially marked. The following routine accomplishes this. */
9029 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9032 generate_objc_image_info (void)
9034 tree sc_spec, decl, initlist;
9036 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9038 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9039 tree_cons (NULL_TREE,
9042 build_index_type (build_int_2 (1, 0))),
9047 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9048 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9049 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9051 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9052 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9053 finish_decl (decl, initlist, NULL_TREE);
9056 /* Look up ID as an instance variable. */
9059 lookup_objc_ivar (tree id)
9063 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9064 /* We have a message to super. */
9065 return get_super_receiver ();
9066 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9068 if (is_private (decl))
9069 return error_mark_node;
9071 return build_ivar_reference (id);
9077 #include "gt-objc-objc-act.h"
9078 #include "gtype-objc.h"