1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
53 #include "langhooks.h"
64 #include "diagnostic.h"
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, compound;
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 ();
1906 compound = c_begin_compound_stmt (true);
1908 init_function_decl = current_function_decl;
1909 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1910 TREE_USED (init_function_decl) = 1;
1911 /* Don't let this one be deferred. */
1912 DECL_INLINE (init_function_decl) = 0;
1913 DECL_UNINLINABLE (init_function_decl) = 1;
1916 = build_tree_list (NULL_TREE,
1917 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1918 decelerator = build_function_call (execclass_decl, parms);
1920 c_expand_expr_stmt (decelerator);
1921 add_stmt (c_end_compound_stmt (compound, true));
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 (1);
2695 objc_exception_block_stack = tree_cons (NULL_TREE, block,
2696 objc_exception_block_stack);
2698 blk_nesting_count++;
2703 objc_exit_block (void)
2705 tree block = TREE_VALUE (objc_exception_block_stack);
2706 objc_exception_block_stack = TREE_CHAIN (objc_exception_block_stack);
2708 objc_clear_super_receiver ();
2710 finish_compound_stmt (block);
2712 block = c_end_compound_stmt (block, 1);
2715 blk_nesting_count--;
2720 objc_declare_variable (enum rid scspec, tree name, tree type, tree init)
2724 type = tree_cons (NULL_TREE, type,
2725 tree_cons (NULL_TREE, ridpointers[(int) scspec],
2727 TREE_STATIC (type) = 1;
2728 decl = start_decl (name, type, (init != NULL_TREE), NULL_TREE);
2729 finish_decl (decl, init, NULL_TREE);
2730 /* This prevents `unused variable' warnings when compiling with -Wall. */
2731 TREE_USED (decl) = 1;
2732 DECL_ARTIFICIAL (decl) = 1;
2737 objc_build_throw_stmt (tree throw_expr)
2741 if (!flag_objc_exceptions)
2742 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2744 if (!throw_expr && objc_caught_exception)
2745 throw_expr = TREE_VALUE (objc_caught_exception);
2749 error ("`@throw;' (rethrow) used outside of a `@catch' block");
2750 return error_mark_node;
2753 func_params = tree_cons (NULL_TREE, throw_expr, NULL_TREE);
2755 assemble_external (objc_exception_throw_decl);
2756 return c_expand_expr_stmt (build_function_call (objc_exception_throw_decl,
2761 val_stack_push (struct val_stack **nc, long val)
2763 struct val_stack *new_elem = xmalloc (sizeof (struct val_stack));
2764 new_elem->val = val;
2765 new_elem->next = *nc;
2770 val_stack_pop (struct val_stack **nc)
2772 struct val_stack *old_elem = *nc;
2773 *nc = old_elem->next;
2778 objc_build_try_enter_fragment (void)
2780 /* objc_exception_try_enter(&_stackExceptionData);
2781 if (!_setjmp(&_stackExceptionData.buf)) { */
2783 tree func_params, if_stmt, cond;
2786 = tree_cons (NULL_TREE,
2787 build_unary_op (ADDR_EXPR,
2788 TREE_VALUE (objc_stack_exception_data),
2792 assemble_external (objc_exception_try_enter_decl);
2793 c_expand_expr_stmt (build_function_call
2794 (objc_exception_try_enter_decl, func_params));
2797 /* Um, C and C++ have very different statement construction functions.
2798 Partly because different scoping rules are in effect, but partly
2799 because of how their parsers are constructed. I highly recommend
2800 simply constructing the statements by hand here. You don't need
2801 any of the ancilliary tracking necessary for user parsing bits anyway. */
2805 if_stmt = c_begin_if_stmt ();
2807 /* If <setjmp.h> has been included, the _setjmp prototype has
2808 acquired a real, breathing type for its parameter. Cast our
2809 argument to that type. */
2811 = tree_cons (NULL_TREE,
2812 build_c_cast (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))
2813 ? TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
2817 build_component_ref (TREE_VALUE (objc_stack_exception_data),
2818 get_identifier ("buf")), 0)),
2820 assemble_external (objc_setjmp_decl);
2821 cond = build_unary_op (TRUTH_NOT_EXPR,
2822 build_function_call (objc_setjmp_decl, func_params),
2824 c_expand_start_cond (lang_hooks.truthvalue_conversion (cond), 0, if_stmt);
2825 objc_enter_block ();
2829 objc_build_extract_expr (void)
2831 /* ... = objc_exception_extract(&_stackExceptionData); */
2834 = tree_cons (NULL_TREE,
2835 build_unary_op (ADDR_EXPR,
2836 TREE_VALUE (objc_stack_exception_data), 0),
2839 assemble_external (objc_exception_extract_decl);
2840 return build_function_call (objc_exception_extract_decl, func_params);
2844 objc_build_try_exit_fragment (void)
2846 /* objc_exception_try_exit(&_stackExceptionData); */
2849 = tree_cons (NULL_TREE,
2850 build_unary_op (ADDR_EXPR,
2851 TREE_VALUE (objc_stack_exception_data), 0),
2854 assemble_external (objc_exception_try_exit_decl);
2855 c_expand_expr_stmt (build_function_call (objc_exception_try_exit_decl,
2860 objc_build_extract_fragment (void)
2863 _rethrowException = objc_exception_extract(&_stackExceptionData);
2866 c_finish_then (objc_exit_block ());
2868 c_expand_start_else ();
2869 objc_enter_block ();
2870 c_expand_expr_stmt (build_modify_expr
2871 (TREE_VALUE (objc_rethrow_exception),
2873 objc_build_extract_expr ()));
2874 c_finish_else (objc_exit_block ());
2875 c_expand_end_cond ();
2880 objc_build_try_prologue (void)
2883 struct _objc_exception_data _stackExceptionData;
2884 volatile id _rethrowException = nil;
2885 { // begin TRY-CATCH scope
2886 objc_exception_try_enter(&_stackExceptionData);
2887 if (!_setjmp(&_stackExceptionData.buf)) { */
2889 tree try_catch_block;
2891 if (!flag_objc_exceptions)
2892 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2894 objc_mark_locals_volatile ((void *)(exc_binding_stack
2895 ? exc_binding_stack->val
2897 objc_enter_block ();
2898 objc_stack_exception_data
2899 = tree_cons (NULL_TREE,
2900 objc_declare_variable (RID_AUTO,
2901 get_identifier (UTAG_EXCDATA_VAR),
2902 xref_tag (RECORD_TYPE,
2903 get_identifier (UTAG_EXCDATA)),
2905 objc_stack_exception_data);
2906 objc_rethrow_exception = tree_cons (NULL_TREE,
2907 objc_declare_variable (RID_VOLATILE,
2908 get_identifier (UTAG_RETHROWEXC_VAR),
2910 build_int_2 (0, 0)),
2911 objc_rethrow_exception);
2913 try_catch_block = objc_enter_block ();
2914 val_stack_push (&exc_binding_stack, (long) get_current_scope ());
2915 objc_build_try_enter_fragment ();
2917 return try_catch_block;
2921 objc_build_try_epilogue (int also_catch_prologue)
2923 if (also_catch_prologue)
2926 register id _caughtException = objc_exception_extract( &_stackExceptionData);
2927 objc_exception_try_enter(&_stackExceptionData);
2928 if(!_setjmp(&_stackExceptionData.buf)) {
2933 c_finish_then (objc_exit_block ());
2935 c_expand_start_else ();
2936 objc_enter_block ();
2937 objc_caught_exception
2938 = tree_cons (NULL_TREE,
2939 objc_declare_variable (RID_REGISTER,
2940 get_identifier (UTAG_CAUGHTEXC_VAR),
2942 objc_build_extract_expr ()),
2943 objc_caught_exception);
2944 objc_build_try_enter_fragment ();
2945 val_stack_push (&catch_count_stack, 1);
2946 if_stmt = c_begin_if_stmt ();
2948 c_expand_start_cond (lang_hooks.truthvalue_conversion (boolean_false_node),
2950 objc_enter_block ();
2952 /* Start a new chain of @catch statements for this @try. */
2953 objc_catch_type = tree_cons (objc_catch_type, NULL_TREE, NULL_TREE);
2956 { /* !also_catch_prologue */
2959 _rethrowException = objc_exception_extract( &_stackExceptionData);
2962 objc_build_extract_fragment ();
2968 objc_build_catch_stmt (tree catch_expr)
2970 /* } else if (objc_exception_match(objc_get_class("SomeClass"), _caughtException)) {
2971 register SomeClass *e = _caughtException; */
2973 tree if_stmt, cond, func_params, prev_catch, var_name, var_type;
2977 /* Yet another C/C++ impedance mismatch. */
2978 catch_expr = TREE_PURPOSE (catch_expr);
2981 var_name = TREE_VALUE (catch_expr);
2982 var_type = TREE_VALUE (TREE_PURPOSE (catch_expr));
2983 if (TREE_CODE (var_name) == INDIRECT_REF)
2984 var_name = TREE_OPERAND (var_name, 0);
2985 if (TREE_CODE (var_type) == TYPE_DECL
2986 || TREE_CODE (var_type) == POINTER_TYPE)
2987 var_type = TREE_TYPE (var_type);
2988 catch_id = (var_type == TREE_TYPE (id_type));
2990 if (!flag_objc_exceptions)
2991 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2993 if (!(catch_id || TYPED_OBJECT (var_type)))
2994 fatal_error ("`@catch' parameter is not a known Objective-C class type");
2996 /* Examine previous @catch clauses for the current @try block for
2997 superclasses of the 'var_type' class. */
2998 for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch);
2999 prev_catch = TREE_CHAIN (prev_catch))
3001 if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
3003 warning ("Exception already handled by preceding `@catch(id)'");
3007 && objc_comptypes (TREE_VALUE (prev_catch), var_type, 0) == 1)
3008 warning ("Exception of type `%s *' already handled by `@catch (%s *)'",
3009 IDENTIFIER_POINTER (OBJC_TYPE_NAME (var_type)),
3010 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_VALUE (prev_catch))));
3013 objc_catch_type = tree_cons (NULL_TREE, var_type, objc_catch_type);
3015 c_finish_then (objc_exit_block ());
3017 c_expand_start_else ();
3018 catch_count_stack->val++;
3019 if_stmt = c_begin_if_stmt ();
3023 cond = integer_one_node;
3026 cond = get_class_reference (OBJC_TYPE_NAME (var_type));
3029 = tree_cons (NULL_TREE, cond,
3030 tree_cons (NULL_TREE,
3031 TREE_VALUE (objc_caught_exception),
3033 assemble_external (objc_exception_match_decl);
3034 cond = build_function_call (objc_exception_match_decl, func_params);
3037 c_expand_start_cond (lang_hooks.truthvalue_conversion (cond), 0, if_stmt);
3038 objc_enter_block ();
3039 objc_declare_variable (RID_REGISTER, var_name,
3040 build_pointer_type (var_type),
3041 TREE_VALUE (objc_caught_exception));
3045 objc_build_catch_epilogue (void)
3048 _rethrowException = _caughtException;
3049 objc_exception_try_exit(&_stackExceptionData);
3052 _rethrowException = objc_exception_extract(&_stackExceptionData);
3055 } // end TRY-CATCH scope
3058 c_finish_then (objc_exit_block ());
3060 c_expand_start_else ();
3061 objc_enter_block ();
3064 (TREE_VALUE (objc_rethrow_exception),
3066 TREE_VALUE (objc_caught_exception)));
3067 objc_build_try_exit_fragment ();
3069 while (catch_count_stack->val--)
3071 /* FIXME. Need to have the block of each else that was opened. */
3072 c_finish_else ((abort (), NULL)); /* close off all the nested ifs ! */
3073 c_expand_end_cond ();
3076 val_stack_pop (&catch_count_stack);
3077 objc_caught_exception = TREE_CHAIN (objc_caught_exception);
3079 objc_build_extract_fragment ();
3081 c_finish_else (objc_exit_block ());
3082 c_expand_end_cond ();
3086 /* Return to enclosing chain of @catch statements (if any). */
3087 while (TREE_VALUE (objc_catch_type))
3088 objc_catch_type = TREE_CHAIN (objc_catch_type);
3089 objc_catch_type = TREE_PURPOSE (objc_catch_type);
3093 objc_build_finally_prologue (void)
3095 /* { // begin FINALLY scope
3096 if (!_rethrowException) {
3097 objc_exception_try_exit(&_stackExceptionData);
3100 tree blk = objc_enter_block ();
3102 tree if_stmt = c_begin_if_stmt ();
3105 c_expand_start_cond (lang_hooks.truthvalue_conversion
3106 (build_unary_op (TRUTH_NOT_EXPR,
3107 TREE_VALUE (objc_rethrow_exception),
3110 objc_enter_block ();
3111 objc_build_try_exit_fragment ();
3112 c_finish_then (objc_exit_block ());
3113 c_expand_end_cond ();
3120 objc_build_finally_epilogue (void)
3122 /* if (_rethrowException) {
3123 objc_exception_throw(_rethrowException);
3125 } // end FINALLY scope
3128 tree if_stmt = c_begin_if_stmt ();
3132 (lang_hooks.truthvalue_conversion (TREE_VALUE (objc_rethrow_exception)),
3134 objc_enter_block ();
3135 objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception));
3136 c_finish_then (objc_exit_block ());
3137 c_expand_end_cond ();
3141 objc_rethrow_exception = TREE_CHAIN (objc_rethrow_exception);
3142 objc_stack_exception_data = TREE_CHAIN (objc_stack_exception_data);
3144 val_stack_pop (&exc_binding_stack);
3145 return objc_exit_block ();
3149 objc_build_try_catch_finally_stmt (int has_catch, int has_finally)
3151 /* NB: The operative assumption here is that TRY_FINALLY_EXPR will
3152 deal with all exits from 'try_catch_blk' and route them through
3154 tree outer_blk = objc_build_finally_epilogue ();
3155 tree prec_stmt = TREE_CHAIN (TREE_CHAIN (COMPOUND_BODY (outer_blk)));
3156 tree try_catch_blk = TREE_CHAIN (prec_stmt), try_catch_expr;
3157 tree finally_blk = TREE_CHAIN (try_catch_blk), finally_expr;
3158 tree succ_stmt = TREE_CHAIN (finally_blk);
3159 tree try_finally_stmt, try_finally_expr;
3161 if (!flag_objc_exceptions)
3162 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3164 /* It is an error to have a @try block without a @catch and/or @finally
3165 (even though sensible code can be generated nonetheless). */
3167 if (!has_catch && !has_finally)
3168 error ("`@try' without `@catch' or `@finally'");
3170 /* We shall now do something truly disgusting. We shall remove the
3171 'try_catch_blk' and 'finally_blk' from the 'outer_blk' statement
3172 chain, and replace them with a TRY_FINALLY_EXPR statement! If
3173 this doesn't work, we will have to learn (from Per/gcj) how to
3174 construct the 'outer_blk' lazily. */
3176 TREE_CHAIN (try_catch_blk) = TREE_CHAIN (finally_blk) = NULL_TREE;
3177 try_catch_expr = build1 (STMT_EXPR, void_type_node, try_catch_blk);
3178 TREE_SIDE_EFFECTS (try_catch_expr) = 1;
3179 finally_expr = build1 (STMT_EXPR, void_type_node, finally_blk);
3180 TREE_SIDE_EFFECTS (finally_expr) = 1;
3181 try_finally_expr = build (TRY_FINALLY_EXPR, void_type_node, try_catch_expr,
3183 TREE_SIDE_EFFECTS (try_finally_expr) = 1;
3184 try_finally_stmt = build_stmt (EXPR_STMT, try_finally_expr);
3185 TREE_CHAIN (prec_stmt) = try_finally_stmt;
3186 TREE_CHAIN (try_finally_stmt) = succ_stmt;
3188 return outer_blk; /* the whole enchilada */
3192 objc_build_synchronized_prologue (tree sync_expr)
3195 id _eval_once = <sync_expr>;
3197 objc_sync_enter( _eval_once ); */
3201 if (!flag_objc_exceptions)
3202 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3204 objc_enter_block ();
3206 = tree_cons (NULL_TREE,
3207 objc_declare_variable (RID_AUTO,
3208 get_identifier (UTAG_EVALONCE_VAR),
3212 objc_build_try_prologue ();
3213 objc_enter_block ();
3214 func_params = tree_cons (NULL_TREE,
3215 TREE_VALUE (objc_eval_once),
3218 assemble_external (objc_sync_enter_decl);
3219 c_expand_expr_stmt (build_function_call
3220 (objc_sync_enter_decl, func_params));
3224 objc_build_synchronized_epilogue (void)
3228 objc_sync_exit( _eval_once );
3235 objc_build_try_epilogue (0);
3236 objc_build_finally_prologue ();
3237 func_params = tree_cons (NULL_TREE, TREE_VALUE (objc_eval_once),
3240 assemble_external (objc_sync_exit_decl);
3241 c_expand_expr_stmt (build_function_call (objc_sync_exit_decl,
3243 objc_build_try_catch_finally_stmt (0, 1);
3245 return objc_exit_block ();
3248 /* Predefine the following data type:
3250 struct _objc_exception_data
3256 /* The following yuckiness should prevent users from having to #include
3257 <setjmp.h> in their code... */
3259 #ifdef TARGET_POWERPC
3260 /* snarfed from /usr/include/ppc/setjmp.h */
3261 #define _JBLEN (26 + 36 + 129 + 1)
3263 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3268 build_objc_exception_stuff (void)
3270 tree field_decl, field_decl_chain, index, temp_type;
3272 /* Suppress outputting debug symbols, because
3273 dbxout_init hasn't been called yet. */
3274 enum debug_info_type save_write_symbols = write_symbols;
3275 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3277 write_symbols = NO_DEBUG;
3278 debug_hooks = &do_nothing_debug_hooks;
3279 objc_exception_data_template
3280 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3282 /* int buf[_JBLEN]; */
3284 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3285 field_decl = create_builtin_decl (FIELD_DECL,
3286 build_array_type (integer_type_node, index),
3288 field_decl_chain = field_decl;
3290 /* void *pointers[4]; */
3292 index = build_index_type (build_int_2 (4 - 1, 0));
3293 field_decl = create_builtin_decl (FIELD_DECL,
3294 build_array_type (ptr_type_node, index),
3296 chainon (field_decl_chain, field_decl);
3298 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3300 /* int _setjmp(...); */
3301 /* If the user includes <setjmp.h>, this shall be superseded by
3302 'int _setjmp(jmp_buf);' */
3303 temp_type = build_function_type (integer_type_node, NULL_TREE);
3305 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3307 /* id objc_exception_extract(struct _objc_exception_data *); */
3309 = build_function_type (id_type,
3310 tree_cons (NULL_TREE,
3311 build_pointer_type (objc_exception_data_template),
3313 objc_exception_extract_decl
3314 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3315 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3316 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3318 = build_function_type (void_type_node,
3319 tree_cons (NULL_TREE,
3320 build_pointer_type (objc_exception_data_template),
3322 objc_exception_try_enter_decl
3323 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3324 objc_exception_try_exit_decl
3325 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3326 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3327 /* void objc_sync_enter(id); */
3328 /* void objc_sync_exit(id); */
3329 temp_type = build_function_type (void_type_node,
3330 tree_cons (NULL_TREE, id_type,
3332 objc_exception_throw_decl
3333 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3334 DECL_ATTRIBUTES (objc_exception_throw_decl)
3335 = tree_cons (get_identifier ("noreturn"), NULL_TREE, NULL_TREE);
3336 objc_sync_enter_decl
3337 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3339 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3340 /* int objc_exception_match(id, id); */
3341 temp_type = build_function_type (integer_type_node,
3342 tree_cons (NULL_TREE, id_type,
3343 tree_cons (NULL_TREE, id_type,
3345 objc_exception_match_decl
3346 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3348 write_symbols = save_write_symbols;
3349 debug_hooks = save_hooks;
3352 /* struct <classname> {
3353 struct objc_class *isa;
3358 build_private_template (tree class)
3362 if (CLASS_STATIC_TEMPLATE (class))
3364 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3365 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3369 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3370 ivar_context = get_class_ivars (class, 0);
3372 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3374 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3376 /* mark this record as class template - for class type checking */
3377 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3381 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3383 build1 (INDIRECT_REF, NULL_TREE,
3386 return ivar_context;
3389 /* Begin code generation for protocols... */
3391 /* struct objc_protocol {
3392 char *protocol_name;
3393 struct objc_protocol **protocol_list;
3394 struct objc_method_desc *instance_methods;
3395 struct objc_method_desc *class_methods;
3399 build_protocol_template (void)
3401 tree decl_specs, field_decl, field_decl_chain;
3404 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3406 /* struct objc_class *isa; */
3408 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3409 get_identifier (UTAG_CLASS)));
3410 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3411 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3412 field_decl_chain = field_decl;
3414 /* char *protocol_name; */
3416 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3418 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3419 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3420 chainon (field_decl_chain, field_decl);
3422 /* struct objc_protocol **protocol_list; */
3424 decl_specs = build_tree_list (NULL_TREE, template);
3426 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3427 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3428 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3429 chainon (field_decl_chain, field_decl);
3431 /* struct objc_method_list *instance_methods; */
3434 = build_tree_list (NULL_TREE,
3435 xref_tag (RECORD_TYPE,
3436 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3438 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3439 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3440 chainon (field_decl_chain, field_decl);
3442 /* struct objc_method_list *class_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 ("class_methods"));
3450 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3451 chainon (field_decl_chain, field_decl);
3453 return finish_struct (template, field_decl_chain, NULL_TREE);
3457 build_descriptor_table_initializer (tree type, tree entries)
3459 tree initlist = NULL_TREE;
3463 tree eltlist = NULL_TREE;
3466 = tree_cons (NULL_TREE,
3467 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3469 = tree_cons (NULL_TREE,
3470 add_objc_string (METHOD_ENCODING (entries),
3475 = tree_cons (NULL_TREE,
3476 objc_build_constructor (type, nreverse (eltlist)),
3479 entries = TREE_CHAIN (entries);
3483 return objc_build_constructor (build_array_type (type, 0),
3484 nreverse (initlist));
3487 /* struct objc_method_prototype_list {
3489 struct objc_method_prototype {
3496 build_method_prototype_list_template (tree list_type, int size)
3498 tree objc_ivar_list_record;
3499 tree decl_specs, field_decl, field_decl_chain;
3501 /* Generate an unnamed struct definition. */
3503 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3505 /* int method_count; */
3507 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3508 field_decl = get_identifier ("method_count");
3509 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3510 field_decl_chain = field_decl;
3512 /* struct objc_method method_list[]; */
3514 decl_specs = build_tree_list (NULL_TREE, list_type);
3515 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3516 build_int_2 (size, 0));
3517 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3518 chainon (field_decl_chain, field_decl);
3520 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3522 return objc_ivar_list_record;
3526 build_method_prototype_template (void)
3529 tree decl_specs, field_decl, field_decl_chain;
3532 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3534 /* struct objc_selector *_cmd; */
3535 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3536 get_identifier (TAG_SELECTOR)), NULL_TREE);
3537 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3538 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3539 field_decl_chain = field_decl;
3541 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3543 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3544 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3545 chainon (field_decl_chain, field_decl);
3547 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3549 return proto_record;
3553 objc_method_parm_type (tree type)
3555 type = groktypename (TREE_TYPE (type));
3556 if (TREE_CODE (type) == TYPE_DECL)
3557 type = TREE_TYPE (type);
3558 return TYPE_MAIN_VARIANT (type);
3562 objc_encoded_type_size (tree type)
3564 int sz = int_size_in_bytes (type);
3566 /* Make all integer and enum types at least as large
3568 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3569 || TREE_CODE (type) == BOOLEAN_TYPE
3570 || TREE_CODE (type) == ENUMERAL_TYPE))
3571 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3572 /* Treat arrays as pointers, since that's how they're
3574 else if (TREE_CODE (type) == ARRAY_TYPE)
3575 sz = int_size_in_bytes (ptr_type_node);
3580 encode_method_prototype (tree method_decl)
3587 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3588 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3590 /* Encode return type. */
3591 encode_type (objc_method_parm_type (method_decl),
3592 obstack_object_size (&util_obstack),
3593 OBJC_ENCODE_INLINE_DEFS);
3596 /* The first two arguments (self and _cmd) are pointers; account for
3598 i = int_size_in_bytes (ptr_type_node);
3599 parm_offset = 2 * i;
3600 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3601 parms = TREE_CHAIN (parms))
3603 tree type = objc_method_parm_type (parms);
3604 int sz = objc_encoded_type_size (type);
3606 /* If a type size is not known, bail out. */
3609 error ("%Jtype '%D' does not have a known size",
3611 /* Pretend that the encoding succeeded; the compilation will
3612 fail nevertheless. */
3613 goto finish_encoding;
3618 sprintf (buf, "%d@0:%d", parm_offset, i);
3619 obstack_grow (&util_obstack, buf, strlen (buf));
3621 /* Argument types. */
3622 parm_offset = 2 * i;
3623 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3624 parms = TREE_CHAIN (parms))
3626 tree type = objc_method_parm_type (parms);
3628 /* Process argument qualifiers for user supplied arguments. */
3629 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3632 encode_type (type, obstack_object_size (&util_obstack),
3633 OBJC_ENCODE_INLINE_DEFS);
3635 /* Compute offset. */
3636 sprintf (buf, "%d", parm_offset);
3637 parm_offset += objc_encoded_type_size (type);
3639 obstack_grow (&util_obstack, buf, strlen (buf));
3643 obstack_1grow (&util_obstack, '\0');
3644 result = get_identifier (obstack_finish (&util_obstack));
3645 obstack_free (&util_obstack, util_firstobj);
3650 generate_descriptor_table (tree type, const char *name, int size, tree list,
3653 tree sc_spec, decl_specs, decl, initlist;
3655 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3656 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3658 decl = start_decl (synth_id_with_class_suffix (name, proto),
3659 decl_specs, 1, NULL_TREE);
3660 DECL_CONTEXT (decl) = NULL_TREE;
3662 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3663 initlist = tree_cons (NULL_TREE, list, initlist);
3665 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3672 generate_method_descriptors (tree protocol)
3674 tree initlist, chain, method_list_template;
3675 tree cast, variable_length_type;
3678 if (!objc_method_prototype_template)
3679 objc_method_prototype_template = build_method_prototype_template ();
3681 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3682 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3684 variable_length_type = groktypename (cast);
3686 chain = PROTOCOL_CLS_METHODS (protocol);
3689 size = list_length (chain);
3691 method_list_template
3692 = build_method_prototype_list_template (objc_method_prototype_template,
3696 = build_descriptor_table_initializer (objc_method_prototype_template,
3699 UOBJC_CLASS_METHODS_decl
3700 = generate_descriptor_table (method_list_template,
3701 "_OBJC_PROTOCOL_CLASS_METHODS",
3702 size, initlist, protocol);
3703 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3706 UOBJC_CLASS_METHODS_decl = 0;
3708 chain = PROTOCOL_NST_METHODS (protocol);
3711 size = list_length (chain);
3713 method_list_template
3714 = build_method_prototype_list_template (objc_method_prototype_template,
3717 = build_descriptor_table_initializer (objc_method_prototype_template,
3720 UOBJC_INSTANCE_METHODS_decl
3721 = generate_descriptor_table (method_list_template,
3722 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3723 size, initlist, protocol);
3724 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3727 UOBJC_INSTANCE_METHODS_decl = 0;
3731 generate_protocol_references (tree plist)
3735 /* Forward declare protocols referenced. */
3736 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3738 tree proto = TREE_VALUE (lproto);
3740 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3741 && PROTOCOL_NAME (proto))
3743 if (! PROTOCOL_FORWARD_DECL (proto))
3744 build_protocol_reference (proto);
3746 if (PROTOCOL_LIST (proto))
3747 generate_protocol_references (PROTOCOL_LIST (proto));
3752 /* For each protocol which was referenced either from a @protocol()
3753 expression, or because a class/category implements it (then a
3754 pointer to the protocol is stored in the struct describing the
3755 class/category), we create a statically allocated instance of the
3756 Protocol class. The code is written in such a way as to generate
3757 as few Protocol objects as possible; we generate a unique Protocol
3758 instance for each protocol, and we don't generate a Protocol
3759 instance if the protocol is never referenced (either from a
3760 @protocol() or from a class/category implementation). These
3761 statically allocated objects can be referred to via the static
3762 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3764 The statically allocated Protocol objects that we generate here
3765 need to be fixed up at runtime in order to be used: the 'isa'
3766 pointer of the objects need to be set up to point to the 'Protocol'
3767 class, as known at runtime.
3769 The NeXT runtime fixes up all protocols at program startup time,
3770 before main() is entered. It uses a low-level trick to look up all
3771 those symbols, then loops on them and fixes them up.
3773 The GNU runtime as well fixes up all protocols before user code
3774 from the module is executed; it requires pointers to those symbols
3775 to be put in the objc_symtab (which is then passed as argument to
3776 the function __objc_exec_class() which the compiler sets up to be
3777 executed automatically when the module is loaded); setup of those
3778 Protocol objects happen in two ways in the GNU runtime: all
3779 Protocol objects referred to by a class or category implementation
3780 are fixed up when the class/category is loaded; all Protocol
3781 objects referred to by a @protocol() expression are added by the
3782 compiler to the list of statically allocated instances to fixup
3783 (the same list holding the statically allocated constant string
3784 objects). Because, as explained above, the compiler generates as
3785 few Protocol objects as possible, some Protocol object might end up
3786 being referenced multiple times when compiled with the GNU runtime,
3787 and end up being fixed up multiple times at runtime inizialization.
3788 But that doesn't hurt, it's just a little inefficient. */
3791 generate_protocols (void)
3794 tree sc_spec, decl_specs, decl;
3795 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3798 if (! objc_protocol_template)
3799 objc_protocol_template = build_protocol_template ();
3801 /* If a protocol was directly referenced, pull in indirect references. */
3802 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3803 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3804 generate_protocol_references (PROTOCOL_LIST (p));
3806 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3808 tree nst_methods = PROTOCOL_NST_METHODS (p);
3809 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3811 /* If protocol wasn't referenced, don't generate any code. */
3812 if (! PROTOCOL_FORWARD_DECL (p))
3815 /* Make sure we link in the Protocol class. */
3816 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3820 if (! METHOD_ENCODING (nst_methods))
3822 encoding = encode_method_prototype (nst_methods);
3823 METHOD_ENCODING (nst_methods) = encoding;
3825 nst_methods = TREE_CHAIN (nst_methods);
3830 if (! METHOD_ENCODING (cls_methods))
3832 encoding = encode_method_prototype (cls_methods);
3833 METHOD_ENCODING (cls_methods) = encoding;
3836 cls_methods = TREE_CHAIN (cls_methods);
3838 generate_method_descriptors (p);
3840 if (PROTOCOL_LIST (p))
3841 refs_decl = generate_protocol_list (p);
3845 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3847 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3849 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3851 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3852 decl_specs, 1, NULL_TREE);
3854 DECL_CONTEXT (decl) = NULL_TREE;
3856 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3862 (build_tree_list (build_tree_list (NULL_TREE,
3863 objc_protocol_template),
3864 build1 (INDIRECT_REF, NULL_TREE,
3865 build1 (INDIRECT_REF, NULL_TREE,
3868 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3869 TREE_TYPE (refs_expr) = cast_type2;
3872 refs_expr = build_int_2 (0, 0);
3874 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3875 by generate_method_descriptors, which is called above. */
3876 initlist = build_protocol_initializer (TREE_TYPE (decl),
3877 protocol_name_expr, refs_expr,
3878 UOBJC_INSTANCE_METHODS_decl,
3879 UOBJC_CLASS_METHODS_decl);
3880 finish_decl (decl, initlist, NULL_TREE);
3882 /* Mark the decl as used to avoid "defined but not used" warning. */
3883 TREE_USED (decl) = 1;
3888 build_protocol_initializer (tree type, tree protocol_name,
3889 tree protocol_list, tree instance_methods,
3892 tree initlist = NULL_TREE, expr;
3895 cast_type = groktypename
3897 (build_tree_list (NULL_TREE,
3898 xref_tag (RECORD_TYPE,
3899 get_identifier (UTAG_CLASS))),
3900 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3902 /* Filling the "isa" in with one allows the runtime system to
3903 detect that the version change...should remove before final release. */
3905 expr = build_int_2 (PROTOCOL_VERSION, 0);
3906 TREE_TYPE (expr) = cast_type;
3907 initlist = tree_cons (NULL_TREE, expr, initlist);
3908 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3909 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3911 if (!instance_methods)
3912 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3915 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3916 initlist = tree_cons (NULL_TREE, expr, initlist);
3920 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3923 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3924 initlist = tree_cons (NULL_TREE, expr, initlist);
3927 return objc_build_constructor (type, nreverse (initlist));
3930 /* struct objc_category {
3931 char *category_name;
3933 struct objc_method_list *instance_methods;
3934 struct objc_method_list *class_methods;
3935 struct objc_protocol_list *protocols;
3939 build_category_template (void)
3941 tree decl_specs, field_decl, field_decl_chain;
3943 objc_category_template = start_struct (RECORD_TYPE,
3944 get_identifier (UTAG_CATEGORY));
3945 /* char *category_name; */
3947 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3949 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3950 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3951 field_decl_chain = field_decl;
3953 /* char *class_name; */
3955 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3956 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3957 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3958 chainon (field_decl_chain, field_decl);
3960 /* struct objc_method_list *instance_methods; */
3962 decl_specs = build_tree_list (NULL_TREE,
3963 xref_tag (RECORD_TYPE,
3964 get_identifier (UTAG_METHOD_LIST)));
3966 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3967 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3968 chainon (field_decl_chain, field_decl);
3970 /* struct objc_method_list *class_methods; */
3972 decl_specs = build_tree_list (NULL_TREE,
3973 xref_tag (RECORD_TYPE,
3974 get_identifier (UTAG_METHOD_LIST)));
3976 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3977 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3978 chainon (field_decl_chain, field_decl);
3980 /* struct objc_protocol **protocol_list; */
3982 decl_specs = build_tree_list (NULL_TREE,
3983 xref_tag (RECORD_TYPE,
3984 get_identifier (UTAG_PROTOCOL)));
3986 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3987 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3988 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3989 chainon (field_decl_chain, field_decl);
3991 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
3994 /* struct objc_selector {
4000 build_selector_template (void)
4003 tree decl_specs, field_decl, field_decl_chain;
4005 objc_selector_template
4006 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4010 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4011 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4012 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4013 field_decl_chain = field_decl;
4015 /* char *sel_type; */
4017 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4018 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4019 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4020 chainon (field_decl_chain, field_decl);
4022 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4025 /* struct objc_class {
4026 struct objc_class *isa;
4027 struct objc_class *super_class;
4032 struct objc_ivar_list *ivars;
4033 struct objc_method_list *methods;
4034 if (flag_next_runtime)
4035 struct objc_cache *cache;
4037 struct sarray *dtable;
4038 struct objc_class *subclass_list;
4039 struct objc_class *sibling_class;
4041 struct objc_protocol_list *protocols;
4042 if (flag_next_runtime)
4044 void *gc_object_type;
4047 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4048 the NeXT/Apple runtime; still, the compiler must generate them to
4049 maintain backward binary compatibility (and to allow for future
4053 build_class_template (void)
4055 tree decl_specs, field_decl, field_decl_chain;
4058 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4060 /* struct objc_class *isa; */
4062 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4063 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4064 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4065 field_decl_chain = field_decl;
4067 /* struct objc_class *super_class; */
4069 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4071 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4072 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4073 chainon (field_decl_chain, field_decl);
4077 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4078 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4079 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4080 chainon (field_decl_chain, field_decl);
4084 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4085 field_decl = get_identifier ("version");
4086 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4087 chainon (field_decl_chain, field_decl);
4091 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4092 field_decl = get_identifier ("info");
4093 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4094 chainon (field_decl_chain, field_decl);
4096 /* long instance_size; */
4098 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4099 field_decl = get_identifier ("instance_size");
4100 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4101 chainon (field_decl_chain, field_decl);
4103 /* struct objc_ivar_list *ivars; */
4105 decl_specs = build_tree_list (NULL_TREE,
4106 xref_tag (RECORD_TYPE,
4107 get_identifier (UTAG_IVAR_LIST)));
4108 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4109 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4110 chainon (field_decl_chain, field_decl);
4112 /* struct objc_method_list *methods; */
4114 decl_specs = build_tree_list (NULL_TREE,
4115 xref_tag (RECORD_TYPE,
4116 get_identifier (UTAG_METHOD_LIST)));
4117 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4118 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4119 chainon (field_decl_chain, field_decl);
4121 if (flag_next_runtime)
4123 /* struct objc_cache *cache; */
4125 decl_specs = build_tree_list (NULL_TREE,
4126 xref_tag (RECORD_TYPE,
4127 get_identifier ("objc_cache")));
4128 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4129 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4130 chainon (field_decl_chain, field_decl);
4134 /* struct sarray *dtable; */
4136 decl_specs = build_tree_list (NULL_TREE,
4137 xref_tag (RECORD_TYPE,
4138 get_identifier ("sarray")));
4139 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4140 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4141 chainon (field_decl_chain, field_decl);
4143 /* struct objc_class *subclass_list; */
4145 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4147 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4148 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4149 chainon (field_decl_chain, field_decl);
4151 /* struct objc_class *sibling_class; */
4153 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4155 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4156 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4157 chainon (field_decl_chain, field_decl);
4160 /* struct objc_protocol **protocol_list; */
4162 decl_specs = build_tree_list (NULL_TREE,
4163 xref_tag (RECORD_TYPE,
4164 get_identifier (UTAG_PROTOCOL)));
4166 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4168 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4169 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4170 chainon (field_decl_chain, field_decl);
4172 if (flag_next_runtime)
4176 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4177 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4179 = grokfield (field_decl, decl_specs, NULL_TREE);
4180 chainon (field_decl_chain, field_decl);
4183 /* void *gc_object_type; */
4185 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4186 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4187 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4188 chainon (field_decl_chain, field_decl);
4190 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4193 /* Generate appropriate forward declarations for an implementation. */
4196 synth_forward_declarations (void)
4200 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4201 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4202 objc_class_template);
4204 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4205 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4206 objc_class_template);
4208 /* Pre-build the following entities - for speed/convenience. */
4210 an_id = get_identifier ("super_class");
4211 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4212 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4216 error_with_ivar (const char *message, tree decl, tree rawdecl)
4218 error ("%J%s `%s'", decl,
4219 message, gen_declaration (rawdecl, errbuf));
4224 check_ivars (tree inter, tree imp)
4226 tree intdecls = CLASS_IVARS (inter);
4227 tree impdecls = CLASS_IVARS (imp);
4228 tree rawintdecls = CLASS_RAW_IVARS (inter);
4229 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4236 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4237 intdecls = TREE_CHAIN (intdecls);
4239 if (intdecls == 0 && impdecls == 0)
4241 if (intdecls == 0 || impdecls == 0)
4243 error ("inconsistent instance variable specification");
4247 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4249 if (!comptypes (t1, t2)
4250 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4251 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4253 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4255 error_with_ivar ("conflicting instance variable type",
4256 impdecls, rawimpdecls);
4257 error_with_ivar ("previous declaration of",
4258 intdecls, rawintdecls);
4260 else /* both the type and the name don't match */
4262 error ("inconsistent instance variable specification");
4267 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4269 error_with_ivar ("conflicting instance variable name",
4270 impdecls, rawimpdecls);
4271 error_with_ivar ("previous declaration of",
4272 intdecls, rawintdecls);
4275 intdecls = TREE_CHAIN (intdecls);
4276 impdecls = TREE_CHAIN (impdecls);
4277 rawintdecls = TREE_CHAIN (rawintdecls);
4278 rawimpdecls = TREE_CHAIN (rawimpdecls);
4282 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4283 This needs to be done just once per compilation. */
4286 build_super_template (void)
4288 tree decl_specs, field_decl, field_decl_chain;
4290 /* Suppress outputting debug symbols, because
4291 dbxout_init hasn't been called yet. */
4292 enum debug_info_type save_write_symbols = write_symbols;
4293 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4295 write_symbols = NO_DEBUG;
4296 debug_hooks = &do_nothing_debug_hooks;
4298 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4300 /* struct objc_object *self; */
4302 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4303 field_decl = get_identifier ("self");
4304 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4305 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4306 field_decl_chain = field_decl;
4309 /* struct objc_class *super_class; */
4311 /* struct objc_class *class; */
4314 decl_specs = get_identifier (UTAG_CLASS);
4315 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4317 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4319 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4322 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4323 chainon (field_decl_chain, field_decl);
4325 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4327 write_symbols = save_write_symbols;
4328 debug_hooks = save_hooks;
4331 /* struct objc_ivar {
4338 build_ivar_template (void)
4340 tree objc_ivar_id, objc_ivar_record;
4341 tree decl_specs, field_decl, field_decl_chain;
4343 objc_ivar_id = get_identifier (UTAG_IVAR);
4344 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4346 /* char *ivar_name; */
4348 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4349 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4351 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4352 field_decl_chain = field_decl;
4354 /* char *ivar_type; */
4356 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4357 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4359 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4360 chainon (field_decl_chain, field_decl);
4362 /* int ivar_offset; */
4364 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4365 field_decl = get_identifier ("ivar_offset");
4367 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4368 chainon (field_decl_chain, field_decl);
4370 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4372 return objc_ivar_record;
4377 struct objc_ivar ivar_list[ivar_count];
4381 build_ivar_list_template (tree list_type, int size)
4383 tree objc_ivar_list_record;
4384 tree decl_specs, field_decl, field_decl_chain;
4386 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4388 /* int ivar_count; */
4390 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4391 field_decl = get_identifier ("ivar_count");
4393 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4394 field_decl_chain = field_decl;
4396 /* struct objc_ivar ivar_list[]; */
4398 decl_specs = build_tree_list (NULL_TREE, list_type);
4399 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4400 build_int_2 (size, 0));
4402 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4403 chainon (field_decl_chain, field_decl);
4405 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4407 return objc_ivar_list_record;
4413 struct objc_method method_list[method_count];
4417 build_method_list_template (tree list_type, int size)
4419 tree objc_ivar_list_record;
4420 tree decl_specs, field_decl, field_decl_chain;
4422 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4424 /* int method_next; */
4429 xref_tag (RECORD_TYPE,
4430 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4432 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4433 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4434 field_decl_chain = field_decl;
4436 /* int method_count; */
4438 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4439 field_decl = get_identifier ("method_count");
4441 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4442 chainon (field_decl_chain, field_decl);
4444 /* struct objc_method method_list[]; */
4446 decl_specs = build_tree_list (NULL_TREE, list_type);
4447 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4448 build_int_2 (size, 0));
4450 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4451 chainon (field_decl_chain, field_decl);
4453 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4455 return objc_ivar_list_record;
4459 build_ivar_list_initializer (tree type, tree field_decl)
4461 tree initlist = NULL_TREE;
4465 tree ivar = NULL_TREE;
4468 if (DECL_NAME (field_decl))
4469 ivar = tree_cons (NULL_TREE,
4470 add_objc_string (DECL_NAME (field_decl),
4474 /* Unnamed bit-field ivar (yuck). */
4475 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4478 encode_field_decl (field_decl,
4479 obstack_object_size (&util_obstack),
4480 OBJC_ENCODE_DONT_INLINE_DEFS);
4482 /* Null terminate string. */
4483 obstack_1grow (&util_obstack, 0);
4487 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4490 obstack_free (&util_obstack, util_firstobj);
4493 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4494 initlist = tree_cons (NULL_TREE,
4495 objc_build_constructor (type, nreverse (ivar)),
4498 field_decl = TREE_CHAIN (field_decl);
4499 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4503 return objc_build_constructor (build_array_type (type, 0),
4504 nreverse (initlist));
4508 generate_ivars_list (tree type, const char *name, int size, tree list)
4510 tree sc_spec, decl_specs, decl, initlist;
4512 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4513 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4515 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4516 decl_specs, 1, NULL_TREE);
4518 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4519 initlist = tree_cons (NULL_TREE, list, initlist);
4522 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4528 /* Count only the fields occurring in T. */
4530 ivar_list_length (tree t)
4534 for (; t; t = TREE_CHAIN (t))
4535 if (TREE_CODE (t) == FIELD_DECL)
4542 generate_ivar_lists (void)
4544 tree initlist, ivar_list_template, chain;
4545 tree cast, variable_length_type;
4548 generating_instance_variables = 1;
4550 if (!objc_ivar_template)
4551 objc_ivar_template = build_ivar_template ();
4555 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4556 get_identifier (UTAG_IVAR_LIST))),
4558 variable_length_type = groktypename (cast);
4560 /* Only generate class variables for the root of the inheritance
4561 hierarchy since these will be the same for every class. */
4563 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4564 && (chain = TYPE_FIELDS (objc_class_template)))
4566 size = ivar_list_length (chain);
4568 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4569 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4571 UOBJC_CLASS_VARIABLES_decl
4572 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4574 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4577 UOBJC_CLASS_VARIABLES_decl = 0;
4579 chain = CLASS_IVARS (implementation_template);
4582 size = ivar_list_length (chain);
4583 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4584 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4586 UOBJC_INSTANCE_VARIABLES_decl
4587 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4589 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4592 UOBJC_INSTANCE_VARIABLES_decl = 0;
4594 generating_instance_variables = 0;
4598 build_dispatch_table_initializer (tree type, tree entries)
4600 tree initlist = NULL_TREE;
4604 tree elemlist = NULL_TREE;
4606 elemlist = tree_cons (NULL_TREE,
4607 build_selector (METHOD_SEL_NAME (entries)),
4610 /* Generate the method encoding if we don't have one already. */
4611 if (! METHOD_ENCODING (entries))
4612 METHOD_ENCODING (entries) =
4613 encode_method_prototype (entries);
4615 elemlist = tree_cons (NULL_TREE,
4616 add_objc_string (METHOD_ENCODING (entries),
4620 elemlist = tree_cons (NULL_TREE,
4621 build_unary_op (ADDR_EXPR,
4622 METHOD_DEFINITION (entries), 1),
4625 initlist = tree_cons (NULL_TREE,
4626 objc_build_constructor (type, nreverse (elemlist)),
4629 entries = TREE_CHAIN (entries);
4633 return objc_build_constructor (build_array_type (type, 0),
4634 nreverse (initlist));
4637 /* To accomplish method prototyping without generating all kinds of
4638 inane warnings, the definition of the dispatch table entries were
4641 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4643 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4646 build_method_template (void)
4649 tree decl_specs, field_decl, field_decl_chain;
4651 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4653 /* struct objc_selector *_cmd; */
4654 decl_specs = tree_cons (NULL_TREE,
4655 xref_tag (RECORD_TYPE,
4656 get_identifier (TAG_SELECTOR)),
4658 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4660 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4661 field_decl_chain = field_decl;
4663 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4664 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4665 get_identifier ("method_types"));
4666 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4667 chainon (field_decl_chain, field_decl);
4671 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4672 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4673 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4674 chainon (field_decl_chain, field_decl);
4676 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4683 generate_dispatch_table (tree type, const char *name, int size, tree list)
4685 tree sc_spec, decl_specs, decl, initlist;
4687 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4688 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4690 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4691 decl_specs, 1, NULL_TREE);
4693 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4694 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4695 initlist = tree_cons (NULL_TREE, list, initlist);
4698 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4705 mark_referenced_methods (void)
4707 struct imp_entry *impent;
4710 for (impent = imp_list; impent; impent = impent->next)
4712 chain = CLASS_CLS_METHODS (impent->imp_context);
4715 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4716 chain = TREE_CHAIN (chain);
4719 chain = CLASS_NST_METHODS (impent->imp_context);
4722 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4723 chain = TREE_CHAIN (chain);
4729 generate_dispatch_tables (void)
4731 tree initlist, chain, method_list_template;
4732 tree cast, variable_length_type;
4735 if (!objc_method_template)
4736 objc_method_template = build_method_template ();
4740 (build_tree_list (NULL_TREE,
4741 xref_tag (RECORD_TYPE,
4742 get_identifier (UTAG_METHOD_LIST))),
4745 variable_length_type = groktypename (cast);
4747 chain = CLASS_CLS_METHODS (objc_implementation_context);
4750 size = list_length (chain);
4752 method_list_template
4753 = build_method_list_template (objc_method_template, size);
4755 = build_dispatch_table_initializer (objc_method_template, chain);
4757 UOBJC_CLASS_METHODS_decl
4758 = generate_dispatch_table (method_list_template,
4759 ((TREE_CODE (objc_implementation_context)
4760 == CLASS_IMPLEMENTATION_TYPE)
4761 ? "_OBJC_CLASS_METHODS"
4762 : "_OBJC_CATEGORY_CLASS_METHODS"),
4764 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4767 UOBJC_CLASS_METHODS_decl = 0;
4769 chain = CLASS_NST_METHODS (objc_implementation_context);
4772 size = list_length (chain);
4774 method_list_template
4775 = build_method_list_template (objc_method_template, size);
4777 = build_dispatch_table_initializer (objc_method_template, chain);
4779 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4780 UOBJC_INSTANCE_METHODS_decl
4781 = generate_dispatch_table (method_list_template,
4782 "_OBJC_INSTANCE_METHODS",
4785 /* We have a category. */
4786 UOBJC_INSTANCE_METHODS_decl
4787 = generate_dispatch_table (method_list_template,
4788 "_OBJC_CATEGORY_INSTANCE_METHODS",
4790 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4793 UOBJC_INSTANCE_METHODS_decl = 0;
4797 generate_protocol_list (tree i_or_p)
4799 tree initlist, decl_specs, sc_spec;
4800 tree refs_decl, expr_decl, lproto, e, plist;
4804 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4805 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4806 plist = CLASS_PROTOCOL_LIST (i_or_p);
4807 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4808 plist = PROTOCOL_LIST (i_or_p);
4812 cast_type = groktypename
4814 (build_tree_list (NULL_TREE,
4815 xref_tag (RECORD_TYPE,
4816 get_identifier (UTAG_PROTOCOL))),
4817 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4820 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4821 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4822 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4825 /* Build initializer. */
4826 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4828 e = build_int_2 (size, 0);
4829 TREE_TYPE (e) = cast_type;
4830 initlist = tree_cons (NULL_TREE, e, initlist);
4832 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4834 tree pval = TREE_VALUE (lproto);
4836 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4837 && PROTOCOL_FORWARD_DECL (pval))
4839 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4840 initlist = tree_cons (NULL_TREE, e, initlist);
4844 /* static struct objc_protocol *refs[n]; */
4846 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4847 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4848 get_identifier (UTAG_PROTOCOL)),
4851 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4852 expr_decl = build_nt (ARRAY_REF,
4853 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4855 build_int_2 (size + 2, 0));
4856 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4857 expr_decl = build_nt (ARRAY_REF,
4858 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4860 build_int_2 (size + 2, 0));
4861 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4863 = build_nt (ARRAY_REF,
4864 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4866 build_int_2 (size + 2, 0));
4870 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4872 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4873 DECL_CONTEXT (refs_decl) = NULL_TREE;
4875 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4876 nreverse (initlist)),
4883 build_category_initializer (tree type, tree cat_name, tree class_name,
4884 tree instance_methods, tree class_methods,
4887 tree initlist = NULL_TREE, expr;
4889 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4890 initlist = tree_cons (NULL_TREE, class_name, initlist);
4892 if (!instance_methods)
4893 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4896 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4897 initlist = tree_cons (NULL_TREE, expr, initlist);
4900 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4903 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4904 initlist = tree_cons (NULL_TREE, expr, initlist);
4907 /* protocol_list = */
4909 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4912 tree cast_type2 = groktypename
4914 (build_tree_list (NULL_TREE,
4915 xref_tag (RECORD_TYPE,
4916 get_identifier (UTAG_PROTOCOL))),
4917 build1 (INDIRECT_REF, NULL_TREE,
4918 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4920 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4921 TREE_TYPE (expr) = cast_type2;
4922 initlist = tree_cons (NULL_TREE, expr, initlist);
4925 return objc_build_constructor (type, nreverse (initlist));
4928 /* struct objc_class {
4929 struct objc_class *isa;
4930 struct objc_class *super_class;
4935 struct objc_ivar_list *ivars;
4936 struct objc_method_list *methods;
4937 if (flag_next_runtime)
4938 struct objc_cache *cache;
4940 struct sarray *dtable;
4941 struct objc_class *subclass_list;
4942 struct objc_class *sibling_class;
4944 struct objc_protocol_list *protocols;
4945 if (flag_next_runtime)
4947 void *gc_object_type;
4951 build_shared_structure_initializer (tree type, tree isa, tree super,
4952 tree name, tree size, int status,
4953 tree dispatch_table, tree ivar_list,
4956 tree initlist = NULL_TREE, expr;
4959 initlist = tree_cons (NULL_TREE, isa, initlist);
4962 initlist = tree_cons (NULL_TREE, super, initlist);
4965 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4968 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4971 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4973 /* instance_size = */
4974 initlist = tree_cons (NULL_TREE, size, initlist);
4976 /* objc_ivar_list = */
4978 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4981 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4982 initlist = tree_cons (NULL_TREE, expr, initlist);
4985 /* objc_method_list = */
4986 if (!dispatch_table)
4987 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4990 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4991 initlist = tree_cons (NULL_TREE, expr, initlist);
4994 if (flag_next_runtime)
4995 /* method_cache = */
4996 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5000 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5002 /* subclass_list = */
5003 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5005 /* sibling_class = */
5006 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5009 /* protocol_list = */
5010 if (! protocol_list)
5011 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5017 (build_tree_list (NULL_TREE,
5018 xref_tag (RECORD_TYPE,
5019 get_identifier (UTAG_PROTOCOL))),
5020 build1 (INDIRECT_REF, NULL_TREE,
5021 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5023 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5024 TREE_TYPE (expr) = cast_type2;
5025 initlist = tree_cons (NULL_TREE, expr, initlist);
5028 if (flag_next_runtime)
5030 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5032 /* gc_object_type = NULL */
5033 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5035 return objc_build_constructor (type, nreverse (initlist));
5038 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5041 lookup_category (tree class, tree cat_name)
5043 tree category = CLASS_CATEGORY_LIST (class);
5045 while (category && CLASS_SUPER_NAME (category) != cat_name)
5046 category = CLASS_CATEGORY_LIST (category);
5050 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5053 generate_category (tree cat)
5055 tree sc_spec, decl_specs, decl;
5056 tree initlist, cat_name_expr, class_name_expr;
5057 tree protocol_decl, category;
5059 add_class_reference (CLASS_NAME (cat));
5060 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5062 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5064 category = lookup_category (implementation_template,
5065 CLASS_SUPER_NAME (cat));
5067 if (category && CLASS_PROTOCOL_LIST (category))
5069 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5070 protocol_decl = generate_protocol_list (category);
5075 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5076 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5078 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5079 objc_implementation_context),
5080 decl_specs, 1, NULL_TREE);
5082 initlist = build_category_initializer (TREE_TYPE (decl),
5083 cat_name_expr, class_name_expr,
5084 UOBJC_INSTANCE_METHODS_decl,
5085 UOBJC_CLASS_METHODS_decl,
5088 finish_decl (decl, initlist, NULL_TREE);
5091 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5092 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5095 generate_shared_structures (void)
5097 tree sc_spec, decl_specs, decl;
5098 tree name_expr, super_expr, root_expr;
5099 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5100 tree cast_type, initlist, protocol_decl;
5102 my_super_id = CLASS_SUPER_NAME (implementation_template);
5105 add_class_reference (my_super_id);
5107 /* Compute "my_root_id" - this is required for code generation.
5108 the "isa" for all meta class structures points to the root of
5109 the inheritance hierarchy (e.g. "__Object")... */
5110 my_root_id = my_super_id;
5113 tree my_root_int = lookup_interface (my_root_id);
5115 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5116 my_root_id = CLASS_SUPER_NAME (my_root_int);
5123 /* No super class. */
5124 my_root_id = CLASS_NAME (implementation_template);
5127 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5128 objc_class_template),
5129 build1 (INDIRECT_REF,
5130 NULL_TREE, NULL_TREE)));
5132 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5135 /* Install class `isa' and `super' pointers at runtime. */
5138 super_expr = add_objc_string (my_super_id, class_names);
5139 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5142 super_expr = build_int_2 (0, 0);
5144 root_expr = add_objc_string (my_root_id, class_names);
5145 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5147 if (CLASS_PROTOCOL_LIST (implementation_template))
5149 generate_protocol_references
5150 (CLASS_PROTOCOL_LIST (implementation_template));
5151 protocol_decl = generate_protocol_list (implementation_template);
5156 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5158 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5159 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5161 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5165 = build_shared_structure_initializer
5167 root_expr, super_expr, name_expr,
5168 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5170 UOBJC_CLASS_METHODS_decl,
5171 UOBJC_CLASS_VARIABLES_decl,
5174 finish_decl (decl, initlist, NULL_TREE);
5176 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5178 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5182 = build_shared_structure_initializer
5184 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5185 super_expr, name_expr,
5186 convert (integer_type_node,
5187 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5188 (implementation_template))),
5190 UOBJC_INSTANCE_METHODS_decl,
5191 UOBJC_INSTANCE_VARIABLES_decl,
5194 finish_decl (decl, initlist, NULL_TREE);
5198 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5201 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5202 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5204 const char *const class_name
5205 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5206 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5207 sprintf (string, "%s_%s", preamble,
5208 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5210 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5211 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5213 /* We have a category. */
5214 const char *const class_name
5215 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5216 const char *const class_super_name
5217 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5218 string = (char *) alloca (strlen (preamble)
5219 + strlen (class_name)
5220 + strlen (class_super_name)
5222 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5224 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5226 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5228 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5229 sprintf (string, "%s_%s", preamble, protocol_name);
5234 return get_identifier (string);
5238 is_objc_type_qualifier (tree node)
5240 return (TREE_CODE (node) == IDENTIFIER_NODE
5241 && (node == ridpointers [(int) RID_CONST]
5242 || node == ridpointers [(int) RID_VOLATILE]
5243 || node == ridpointers [(int) RID_IN]
5244 || node == ridpointers [(int) RID_OUT]
5245 || node == ridpointers [(int) RID_INOUT]
5246 || node == ridpointers [(int) RID_BYCOPY]
5247 || node == ridpointers [(int) RID_BYREF]
5248 || node == ridpointers [(int) RID_ONEWAY]));
5251 /* If type is empty or only type qualifiers are present, add default
5252 type of id (otherwise grokdeclarator will default to int). */
5255 adjust_type_for_id_default (tree type)
5257 tree declspecs, chain;
5260 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5261 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5263 declspecs = TREE_PURPOSE (type);
5265 /* Determine if a typespec is present. */
5266 for (chain = declspecs;
5268 chain = TREE_CHAIN (chain))
5270 if (TYPED_OBJECT (TREE_VALUE (chain))
5271 && !(TREE_VALUE (type)
5272 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5273 error ("can not use an object as parameter to a method\n");
5274 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5278 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5280 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5285 selector ':' '(' typename ')' identifier
5288 Transform an Objective-C keyword argument into
5289 the C equivalent parameter declarator.
5291 In: key_name, an "identifier_node" (optional).
5292 arg_type, a "tree_list" (optional).
5293 arg_name, an "identifier_node".
5295 Note: It would be really nice to strongly type the preceding
5296 arguments in the function prototype; however, then I
5297 could not use the "accessor" macros defined in "tree.h".
5299 Out: an instance of "keyword_decl". */
5302 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5306 /* If no type is specified, default to "id". */
5307 arg_type = adjust_type_for_id_default (arg_type);
5309 keyword_decl = make_node (KEYWORD_DECL);
5311 TREE_TYPE (keyword_decl) = arg_type;
5312 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5313 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5315 return keyword_decl;
5318 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5321 build_keyword_selector (tree selector)
5324 tree key_chain, key_name;
5327 /* Scan the selector to see how much space we'll need. */
5328 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5330 if (TREE_CODE (selector) == KEYWORD_DECL)
5331 key_name = KEYWORD_KEY_NAME (key_chain);
5332 else if (TREE_CODE (selector) == TREE_LIST)
5333 key_name = TREE_PURPOSE (key_chain);
5338 len += IDENTIFIER_LENGTH (key_name) + 1;
5340 /* Just a ':' arg. */
5344 buf = (char *) alloca (len + 1);
5345 /* Start the buffer out as an empty string. */
5348 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5350 if (TREE_CODE (selector) == KEYWORD_DECL)
5351 key_name = KEYWORD_KEY_NAME (key_chain);
5352 else if (TREE_CODE (selector) == TREE_LIST)
5354 key_name = TREE_PURPOSE (key_chain);
5355 /* The keyword decl chain will later be used as a function argument
5356 chain. Unhook the selector itself so as to not confuse other
5357 parts of the compiler. */
5358 TREE_PURPOSE (key_chain) = NULL_TREE;
5364 strcat (buf, IDENTIFIER_POINTER (key_name));
5368 return get_identifier (buf);
5371 /* Used for declarations and definitions. */
5374 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5379 /* If no type is specified, default to "id". */
5380 ret_type = adjust_type_for_id_default (ret_type);
5382 method_decl = make_node (code);
5383 TREE_TYPE (method_decl) = ret_type;
5385 /* If we have a keyword selector, create an identifier_node that
5386 represents the full selector name (`:' included)... */
5387 if (TREE_CODE (selector) == KEYWORD_DECL)
5389 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5390 METHOD_SEL_ARGS (method_decl) = selector;
5391 METHOD_ADD_ARGS (method_decl) = add_args;
5395 METHOD_SEL_NAME (method_decl) = selector;
5396 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5397 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5403 #define METHOD_DEF 0
5404 #define METHOD_REF 1
5406 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5407 an argument list for method METH. CONTEXT is either METHOD_DEF or
5408 METHOD_REF, saying whether we are trying to define a method or call
5409 one. SUPERFLAG says this is for a send to super; this makes a
5410 difference for the NeXT calling sequence in which the lookup and
5411 the method call are done together. If METH is null, user-defined
5412 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5415 get_arg_type_list (tree meth, int context, int superflag)
5419 /* Receiver type. */
5420 if (flag_next_runtime && superflag)
5421 arglist = build_tree_list (NULL_TREE, super_type);
5422 else if (context == METHOD_DEF)
5423 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5425 arglist = build_tree_list (NULL_TREE, id_type);
5427 /* Selector type - will eventually change to `int'. */
5428 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
5430 /* No actual method prototype given -- assume that remaining arguments
5435 /* Build a list of argument types. */
5436 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5438 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5439 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5442 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5443 /* We have a `, ...' immediately following the selector,
5444 finalize the arglist...simulate get_parm_info (true). */
5446 else if (METHOD_ADD_ARGS (meth))
5448 /* we have a variable length selector */
5449 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5450 chainon (arglist, add_arg_list);
5453 /* finalize the arglist...simulate get_parm_info (false) */
5454 chainon (arglist, void_list_node);
5460 check_duplicates (hash hsh, int methods, int is_class)
5462 tree meth = NULL_TREE;
5470 /* We have two or more methods with the same name but
5474 warning ("multiple %s named `%c%s' found",
5475 methods ? "methods" : "selectors",
5476 (is_class ? '+' : '-'),
5477 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5479 warn_with_method (methods ? "using" : "found",
5480 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5484 for (loop = hsh->list; loop; loop = loop->next)
5485 warn_with_method ("also found",
5486 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5495 /* If RECEIVER is a class reference, return the identifier node for
5496 the referenced class. RECEIVER is created by get_class_reference,
5497 so we check the exact form created depending on which runtimes are
5501 receiver_is_class_object (tree receiver, int self, int super)
5503 tree chain, exp, arg;
5505 /* The receiver is 'self' or 'super' in the context of a class method. */
5506 if (objc_method_context
5507 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5510 ? CLASS_SUPER_NAME (implementation_template)
5511 : CLASS_NAME (implementation_template));
5513 if (flag_next_runtime)
5515 /* The receiver is a variable created by
5516 build_class_reference_decl. */
5517 if (TREE_CODE (receiver) == VAR_DECL
5518 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5519 /* Look up the identifier. */
5520 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5521 if (TREE_PURPOSE (chain) == receiver)
5522 return TREE_VALUE (chain);
5525 /* The receiver is a function call that returns an id. Check if
5526 it is a call to objc_getClass, if so, pick up the class name. */
5527 if (TREE_CODE (receiver) == CALL_EXPR
5528 && (exp = TREE_OPERAND (receiver, 0))
5529 && TREE_CODE (exp) == ADDR_EXPR
5530 && (exp = TREE_OPERAND (exp, 0))
5531 && TREE_CODE (exp) == FUNCTION_DECL
5532 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5533 prototypes for objc_get_class(). Thankfully, they seem to share the
5534 same function type. */
5535 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5536 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5537 /* We have a call to objc_get_class/objc_getClass! */
5538 && (arg = TREE_OPERAND (receiver, 1))
5539 && TREE_CODE (arg) == TREE_LIST
5540 && (arg = TREE_VALUE (arg)))
5543 if (TREE_CODE (arg) == ADDR_EXPR
5544 && (arg = TREE_OPERAND (arg, 0))
5545 && TREE_CODE (arg) == STRING_CST)
5546 /* Finally, we have the class name. */
5547 return get_identifier (TREE_STRING_POINTER (arg));
5552 /* If we are currently building a message expr, this holds
5553 the identifier of the selector of the message. This is
5554 used when printing warnings about argument mismatches. */
5556 static tree current_objc_message_selector = 0;
5559 objc_message_selector (void)
5561 return current_objc_message_selector;
5564 /* Construct an expression for sending a message.
5565 MESS has the object to send to in TREE_PURPOSE
5566 and the argument list (including selector) in TREE_VALUE.
5568 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5569 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5572 build_message_expr (tree mess)
5574 tree receiver = TREE_PURPOSE (mess);
5576 tree args = TREE_VALUE (mess);
5577 tree method_params = NULL_TREE;
5579 if (TREE_CODE (receiver) == ERROR_MARK)
5580 return error_mark_node;
5582 /* Obtain the full selector name. */
5583 if (TREE_CODE (args) == IDENTIFIER_NODE)
5584 /* A unary selector. */
5586 else if (TREE_CODE (args) == TREE_LIST)
5587 sel_name = build_keyword_selector (args);
5591 /* Build the parameter list to give to the method. */
5592 if (TREE_CODE (args) == TREE_LIST)
5594 tree chain = args, prev = NULL_TREE;
5596 /* We have a keyword selector--check for comma expressions. */
5599 tree element = TREE_VALUE (chain);
5601 /* We have a comma expression, must collapse... */
5602 if (TREE_CODE (element) == TREE_LIST)
5605 TREE_CHAIN (prev) = element;
5610 chain = TREE_CHAIN (chain);
5612 method_params = args;
5616 if (processing_template_decl)
5617 /* Must wait until template instantiation time. */
5618 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5622 return finish_message_expr (receiver, sel_name, method_params);
5625 /* Look up method SEL_NAME that would be suitable for receiver
5626 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5627 nonzero), and report on any duplicates. */
5630 lookup_method_in_hash_lists (tree sel_name, int is_class)
5632 hash method_prototype = NULL;
5635 method_prototype = hash_lookup (nst_method_hash_list,
5638 if (!method_prototype)
5640 method_prototype = hash_lookup (cls_method_hash_list,
5645 return check_duplicates (method_prototype, 1, is_class);
5648 /* The 'finish_message_expr' routine is called from within
5649 'build_message_expr' for non-template functions. In the case of
5650 C++ template functions, it is called from 'build_expr_from_tree'
5651 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5654 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5656 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5657 tree selector, retval, is_class;
5658 int self, super, have_cast;
5660 /* Extract the receiver of the message, as well as its type
5661 (where the latter may take the form of a cast or be inferred
5662 from the implementation context). */
5664 while (TREE_CODE (rtype) == COMPOUND_EXPR
5665 || TREE_CODE (rtype) == MODIFY_EXPR
5666 || TREE_CODE (rtype) == NOP_EXPR
5667 || TREE_CODE (rtype) == COMPONENT_REF)
5668 rtype = TREE_OPERAND (rtype, 0);
5669 self = (rtype == self_decl);
5670 super = (rtype == UOBJC_SUPER_decl);
5671 rtype = TREE_TYPE (receiver);
5672 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5673 || (TREE_CODE (receiver) == COMPOUND_EXPR
5674 && !IS_SUPER (rtype)));
5676 /* If the receiver is a class object, retrieve the corresponding
5677 @interface, if one exists. */
5678 is_class = receiver_is_class_object (receiver, self, super);
5680 /* Now determine the receiver type (if an explicit cast has not been
5685 rtype = lookup_interface (is_class);
5686 /* Handle `self' and `super'. */
5689 if (!CLASS_SUPER_NAME (implementation_template))
5691 error ("no super class declared in @interface for `%s'",
5692 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5693 return error_mark_node;
5695 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5698 rtype = lookup_interface (CLASS_NAME (implementation_template));
5701 /* If receiver is of type `id' or `Class' (or if the @interface for a
5702 class is not visible), we shall be satisfied with the existence of
5703 any instance or class method. */
5704 if (!rtype || IS_ID (rtype)
5705 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5708 rtype = xref_tag (RECORD_TYPE, is_class);
5709 else if (IS_ID (rtype))
5711 rprotos = TYPE_PROTOCOL_LIST (rtype);
5715 is_class = TYPE_NAME (rtype) = get_identifier ("Class");
5719 = lookup_method_in_protocol_list (rprotos, sel_name,
5720 is_class != NULL_TREE);
5721 if (!method_prototype && !rprotos)
5723 = lookup_method_in_hash_lists (sel_name,
5724 is_class != NULL_TREE);
5728 tree orig_rtype = rtype, saved_rtype;
5730 if (TREE_CODE (rtype) == POINTER_TYPE)
5731 rtype = TREE_TYPE (rtype);
5732 /* Traverse typedef aliases */
5733 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5734 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5735 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5736 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5737 saved_rtype = rtype;
5738 if (TYPED_OBJECT (rtype))
5740 rprotos = TYPE_PROTOCOL_LIST (rtype);
5741 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5743 /* If we could not find an @interface declaration, we must have
5744 only seen a @class declaration; so, we cannot say anything
5745 more intelligent about which methods the receiver will
5748 rtype = saved_rtype;
5749 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5750 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5752 /* We have a valid ObjC class name. Look up the method name
5753 in the published @interface for the class (and its
5756 = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
5758 /* If the method was not found in the @interface, it may still
5759 exist locally as part of the @implementation. */
5760 if (!method_prototype && objc_implementation_context
5761 && CLASS_NAME (objc_implementation_context)
5762 == OBJC_TYPE_NAME (rtype))
5766 ? CLASS_CLS_METHODS (objc_implementation_context)
5767 : CLASS_NST_METHODS (objc_implementation_context)),
5770 /* If we haven't found a candidate method by now, try looking for
5771 it in the protocol list. */
5772 if (!method_prototype && rprotos)
5774 = lookup_method_in_protocol_list (rprotos, sel_name,
5775 is_class != NULL_TREE);
5779 warning ("invalid receiver type `%s'",
5780 gen_declaration (orig_rtype, errbuf));
5781 rtype = rprotos = NULL_TREE;
5785 if (!method_prototype)
5787 static bool warn_missing_methods = false;
5790 warning ("`%s' may not respond to `%c%s'",
5791 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5792 (is_class ? '+' : '-'),
5793 IDENTIFIER_POINTER (sel_name));
5795 warning ("`%c%s' not implemented by protocol(s)",
5796 (is_class ? '+' : '-'),
5797 IDENTIFIER_POINTER (sel_name));
5798 if (!warn_missing_methods)
5800 warning ("(Messages without a matching method signature");
5801 warning ("will be assumed to return `id' and accept");
5802 warning ("`...' as arguments.)");
5803 warn_missing_methods = true;
5807 /* Save the selector name for printing error messages. */
5808 current_objc_message_selector = sel_name;
5810 /* Build the parameters list for looking up the method.
5811 These are the object itself and the selector. */
5813 if (flag_typed_selectors)
5814 selector = build_typed_selector_reference (sel_name, method_prototype);
5816 selector = build_selector_reference (sel_name);
5818 retval = build_objc_method_call (super, method_prototype,
5820 selector, method_params);
5822 current_objc_message_selector = 0;
5827 /* Build a tree expression to send OBJECT the operation SELECTOR,
5828 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5829 assuming the method has prototype METHOD_PROTOTYPE.
5830 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5831 Use METHOD_PARAMS as list of args to pass to the method.
5832 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5835 build_objc_method_call (int super_flag, tree method_prototype,
5836 tree lookup_object, tree selector,
5839 tree sender = (super_flag ? umsg_super_decl :
5840 (!flag_next_runtime || flag_nil_receivers
5842 : umsg_nonnil_decl));
5843 tree rcv_p = (super_flag ? super_type : id_type);
5845 /* If a prototype for the method to be called exists, then cast
5846 the sender's return type and arguments to match that of the method.
5847 Otherwise, leave sender as is. */
5850 ? groktypename (TREE_TYPE (method_prototype))
5853 = build_pointer_type
5854 (build_function_type
5857 (method_prototype, METHOD_REF, super_flag)));
5859 lookup_object = build_c_cast (rcv_p, lookup_object);
5861 if (flag_next_runtime)
5863 /* If we are returning a struct in memory, and the address
5864 of that memory location is passed as a hidden first
5865 argument, then change which messenger entry point this
5866 expr will call. NB: Note that sender_cast remains
5867 unchanged (it already has a struct return type). */
5868 if (!targetm.calls.struct_value_rtx (0, 0)
5869 && (TREE_CODE (ret_type) == RECORD_TYPE
5870 || TREE_CODE (ret_type) == UNION_TYPE)
5871 && targetm.calls.return_in_memory (ret_type, 0))
5872 sender = (super_flag ? umsg_super_stret_decl :
5873 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5875 method_params = tree_cons (NULL_TREE, lookup_object,
5876 tree_cons (NULL_TREE, selector,
5878 TREE_USED (sender) = 1;
5879 assemble_external (sender);
5880 /* We want to cast the sender, not convert it. */
5881 return build_function_call (build_c_cast (sender_cast, sender),
5886 /* This is the portable (GNU) way. */
5887 tree method, object;
5889 /* First, call the lookup function to get a pointer to the method,
5890 then cast the pointer, then call it with the method arguments.
5891 Use SAVE_EXPR to avoid evaluating the receiver twice. */
5892 lookup_object = save_expr (lookup_object);
5893 object = (super_flag ? self_decl : lookup_object);
5894 TREE_USED (sender) = 1;
5895 assemble_external (sender);
5897 = build_function_call (sender,
5898 tree_cons (NULL_TREE, lookup_object,
5899 tree_cons (NULL_TREE, selector,
5902 /* Pass the object to the method. */
5903 TREE_USED (method) = 1;
5904 assemble_external (method);
5905 return build_function_call
5906 (build_c_cast (sender_cast, method),
5907 tree_cons (NULL_TREE, object,
5908 tree_cons (NULL_TREE, selector, method_params)));
5913 build_protocol_reference (tree p)
5915 tree decl, ident, ptype;
5917 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5919 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5921 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5922 objc_protocol_template),
5925 if (identifier_global_value (ident))
5926 decl = identifier_global_value (ident); /* Set by pushdecl. */
5929 decl = build_decl (VAR_DECL, ident, ptype);
5930 DECL_EXTERNAL (decl) = 1;
5931 TREE_PUBLIC (decl) = 0;
5932 TREE_USED (decl) = 1;
5933 DECL_ARTIFICIAL (decl) = 1;
5935 make_decl_rtl (decl, 0);
5936 pushdecl_top_level (decl);
5939 PROTOCOL_FORWARD_DECL (p) = decl;
5942 /* This function is called by the parser when (and only when) a
5943 @protocol() expression is found, in order to compile it. */
5945 build_protocol_expr (tree protoname)
5948 tree p = lookup_protocol (protoname);
5952 error ("cannot find protocol declaration for `%s'",
5953 IDENTIFIER_POINTER (protoname));
5954 return error_mark_node;
5957 if (!PROTOCOL_FORWARD_DECL (p))
5958 build_protocol_reference (p);
5960 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5962 /* ??? Ideally we'd build the reference with protocol_type directly,
5963 if we have it, rather than converting it here. */
5964 expr = convert (protocol_type, expr);
5966 /* The @protocol() expression is being compiled into a pointer to a
5967 statically allocated instance of the Protocol class. To become
5968 usable at runtime, the 'isa' pointer of the instance need to be
5969 fixed up at runtime by the runtime library, to point to the
5970 actual 'Protocol' class. */
5972 /* For the GNU runtime, put the static Protocol instance in the list
5973 of statically allocated instances, so that we make sure that its
5974 'isa' pointer is fixed up at runtime by the GNU runtime library
5975 to point to the Protocol class (at runtime, when loading the
5976 module, the GNU runtime library loops on the statically allocated
5977 instances (as found in the defs field in objc_symtab) and fixups
5978 all the 'isa' pointers of those objects). */
5979 if (! flag_next_runtime)
5981 /* This type is a struct containing the fields of a Protocol
5982 object. (Cfr. protocol_type instead is the type of a pointer
5983 to such a struct). */
5984 tree protocol_struct_type = xref_tag
5985 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5988 /* Look for the list of Protocol statically allocated instances
5989 to fixup at runtime. Create a new list to hold Protocol
5990 statically allocated instances, if the list is not found. At
5991 present there is only another list, holding NSConstantString
5992 static instances to be fixed up at runtime. */
5993 for (chain = &objc_static_instances;
5994 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5995 chain = &TREE_CHAIN (*chain));
5998 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5999 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6003 /* Add this statically allocated instance to the Protocol list. */
6004 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6005 PROTOCOL_FORWARD_DECL (p),
6006 TREE_PURPOSE (*chain));
6013 /* This function is called by the parser when a @selector() expression
6014 is found, in order to compile it. It is only called by the parser
6015 and only to compile a @selector(). */
6017 build_selector_expr (tree selnamelist)
6021 /* Obtain the full selector name. */
6022 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6023 /* A unary selector. */
6024 selname = selnamelist;
6025 else if (TREE_CODE (selnamelist) == TREE_LIST)
6026 selname = build_keyword_selector (selnamelist);
6030 /* If we are required to check @selector() expressions as they
6031 are found, check that the selector has been declared. */
6032 if (warn_undeclared_selector)
6034 /* Look the selector up in the list of all known class and
6035 instance methods (up to this line) to check that the selector
6039 /* First try with instance methods. */
6040 hsh = hash_lookup (nst_method_hash_list, selname);
6042 /* If not found, try with class methods. */
6045 hsh = hash_lookup (cls_method_hash_list, selname);
6048 /* If still not found, print out a warning. */
6051 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6056 if (flag_typed_selectors)
6057 return build_typed_selector_reference (selname, 0);
6059 return build_selector_reference (selname);
6063 build_encode_expr (tree type)
6068 encode_type (type, obstack_object_size (&util_obstack),
6069 OBJC_ENCODE_INLINE_DEFS);
6070 obstack_1grow (&util_obstack, 0); /* null terminate string */
6071 string = obstack_finish (&util_obstack);
6073 /* Synthesize a string that represents the encoded struct/union. */
6074 result = my_build_string (strlen (string) + 1, string);
6075 obstack_free (&util_obstack, util_firstobj);
6080 build_ivar_reference (tree id)
6082 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6084 /* Historically, a class method that produced objects (factory
6085 method) would assign `self' to the instance that it
6086 allocated. This would effectively turn the class method into
6087 an instance method. Following this assignment, the instance
6088 variables could be accessed. That practice, while safe,
6089 violates the simple rule that a class method should not refer
6090 to an instance variable. It's better to catch the cases
6091 where this is done unknowingly than to support the above
6093 warning ("instance variable `%s' accessed in class method",
6094 IDENTIFIER_POINTER (id));
6095 TREE_TYPE (self_decl) = instance_type; /* cast */
6098 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6101 /* Compute a hash value for a given method SEL_NAME. */
6104 hash_func (tree sel_name)
6106 const unsigned char *s
6107 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6111 h = h * 67 + *s++ - 113;
6118 nst_method_hash_list
6119 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6120 cls_method_hash_list
6121 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6124 /* WARNING!!!! hash_enter is called with a method, and will peek
6125 inside to find its selector! But hash_lookup is given a selector
6126 directly, and looks for the selector that's inside the found
6127 entry's key (method) for comparison. */
6130 hash_enter (hash *hashlist, tree method)
6133 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6135 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6137 obj->next = hashlist[slot];
6140 hashlist[slot] = obj; /* append to front */
6144 hash_lookup (hash *hashlist, tree sel_name)
6148 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6152 if (sel_name == METHOD_SEL_NAME (target->key))
6155 target = target->next;
6161 hash_add_attr (hash entry, tree value)
6165 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6166 obj->next = entry->list;
6169 entry->list = obj; /* append to front */
6173 lookup_method (tree mchain, tree method)
6177 if (TREE_CODE (method) == IDENTIFIER_NODE)
6180 key = METHOD_SEL_NAME (method);
6184 if (METHOD_SEL_NAME (mchain) == key)
6187 mchain = TREE_CHAIN (mchain);
6193 lookup_method_static (tree interface, tree ident, int is_class)
6195 tree meth = NULL_TREE, root_inter = NULL_TREE;
6196 tree inter = interface;
6200 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6201 tree category = inter;
6203 /* First, look up the method in the class itself. */
6204 if ((meth = lookup_method (chain, ident)))
6207 /* Failing that, look for the method in each category of the class. */
6208 while ((category = CLASS_CATEGORY_LIST (category)))
6210 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6212 /* Check directly in each category. */
6213 if ((meth = lookup_method (chain, ident)))
6216 /* Failing that, check in each category's protocols. */
6217 if (CLASS_PROTOCOL_LIST (category))
6219 if ((meth = (lookup_method_in_protocol_list
6220 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6225 /* If not found in categories, check in protocols of the main class. */
6226 if (CLASS_PROTOCOL_LIST (inter))
6228 if ((meth = (lookup_method_in_protocol_list
6229 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6233 /* Failing that, climb up the inheritance hierarchy. */
6235 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6239 /* If no class (factory) method was found, check if an _instance_
6240 method of the same name exists in the root class. This is what
6241 the Objective-C runtime will do. If an instance method was not
6243 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6246 /* Add the method to the hash list if it doesn't contain an identical
6249 add_method_to_hash_list (hash *hash_list, tree method)
6253 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6255 /* Install on a global chain. */
6256 hash_enter (hash_list, method);
6260 /* Check types against those; if different, add to a list. */
6262 int already_there = comp_proto_with_proto (method, hsh->key);
6263 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6264 already_there |= comp_proto_with_proto (method, loop->value);
6266 hash_add_attr (hsh, method);
6271 objc_add_method (tree class, tree method, int is_class)
6275 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6277 /* put method on list in reverse order */
6280 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6281 CLASS_CLS_METHODS (class) = method;
6285 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6286 CLASS_NST_METHODS (class) = method;
6291 /* When processing an @interface for a class or category, give hard
6292 errors on methods with identical selectors but differing argument
6293 and/or return types. We do not do this for @implementations, because
6294 C/C++ will do it for us (i.e., there will be duplicate function
6295 definition errors). */
6296 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6297 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6298 && !comp_proto_with_proto (method, mth))
6299 error ("duplicate declaration of method `%c%s'",
6300 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6304 add_method_to_hash_list (cls_method_hash_list, method);
6307 add_method_to_hash_list (nst_method_hash_list, method);
6309 /* Instance methods in root classes (and categories thereof)
6310 may acts as class methods as a last resort. */
6311 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6312 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6313 class = lookup_interface (CLASS_NAME (class));
6315 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6316 && !CLASS_SUPER_NAME (class))
6317 add_method_to_hash_list (cls_method_hash_list, method);
6324 add_class (tree class)
6326 /* Put interfaces on list in reverse order. */
6327 TREE_CHAIN (class) = interface_chain;
6328 interface_chain = class;
6329 return interface_chain;
6333 add_category (tree class, tree category)
6335 /* Put categories on list in reverse order. */
6336 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6340 warning ("duplicate interface declaration for category `%s(%s)'",
6341 IDENTIFIER_POINTER (CLASS_NAME (class)),
6342 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6346 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6347 CLASS_CATEGORY_LIST (class) = category;
6351 /* Called after parsing each instance variable declaration. Necessary to
6352 preserve typedefs and implement public/private...
6354 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6357 add_instance_variable (tree class, int public, tree declarator,
6358 tree declspecs, tree width)
6360 tree field_decl = grokfield (declarator, declspecs, width);
6361 tree field_type = TREE_TYPE (field_decl);
6362 const char *ivar_name = DECL_NAME (field_decl)
6363 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6368 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6370 error ("illegal reference type specified for instance variable `%s'",
6372 /* Return class as is without adding this ivar. */
6377 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6378 || TYPE_SIZE (field_type) == error_mark_node
6379 /* 'type[0]' is allowed, but 'type[]' is not! */
6381 || (TYPE_SIZE (field_type) == bitsize_zero_node
6382 && !TREE_OPERAND (declarator, 1))
6386 error ("instance variable `%s' has unknown size", ivar_name);
6387 /* Return class as is without adding this ivar. */
6392 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6393 cannot be ivars; ditto for classes with vtables. */
6394 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6395 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6397 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6398 if(TYPE_POLYMORPHIC_P (field_type)) {
6399 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6400 error ("type `%s' has virtual member functions", type_name);
6401 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6402 type_name, ivar_name);
6403 /* Return class as is without adding this ivar. */
6406 /* user-defined constructors and destructors are not known to Obj-C and
6407 hence will not be called. This may or may not be a problem. */
6408 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6409 warning ("type `%s' has a user-defined constructor", type_name);
6410 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6411 warning ("type `%s' has a user-defined destructor", type_name);
6412 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6416 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6420 TREE_PUBLIC (field_decl) = 0;
6421 TREE_PRIVATE (field_decl) = 0;
6422 TREE_PROTECTED (field_decl) = 1;
6426 TREE_PUBLIC (field_decl) = 1;
6427 TREE_PRIVATE (field_decl) = 0;
6428 TREE_PROTECTED (field_decl) = 0;
6432 TREE_PUBLIC (field_decl) = 0;
6433 TREE_PRIVATE (field_decl) = 1;
6434 TREE_PROTECTED (field_decl) = 0;
6439 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6440 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6441 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6446 is_ivar (tree decl_chain, tree ident)
6448 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6449 if (DECL_NAME (decl_chain) == ident)
6454 /* True if the ivar is private and we are not in its implementation. */
6457 is_private (tree decl)
6459 return (TREE_PRIVATE (decl)
6460 && ! is_ivar (CLASS_IVARS (implementation_template),
6464 /* We have an instance variable reference;, check to see if it is public. */
6467 objc_is_public (tree expr, tree identifier)
6469 tree basetype = TREE_TYPE (expr);
6470 enum tree_code code = TREE_CODE (basetype);
6473 if (code == RECORD_TYPE)
6475 if (TREE_STATIC_TEMPLATE (basetype))
6477 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6479 error ("cannot find interface declaration for `%s'",
6480 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6484 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6486 if (TREE_PUBLIC (decl))
6489 /* Important difference between the Stepstone translator:
6490 all instance variables should be public within the context
6491 of the implementation. */
6492 if (objc_implementation_context
6493 && (((TREE_CODE (objc_implementation_context)
6494 == CLASS_IMPLEMENTATION_TYPE)
6495 || (TREE_CODE (objc_implementation_context)
6496 == CATEGORY_IMPLEMENTATION_TYPE))
6497 && (CLASS_NAME (objc_implementation_context)
6498 == OBJC_TYPE_NAME (basetype))))
6500 int private = is_private (decl);
6503 error ("instance variable `%s' is declared private",
6504 IDENTIFIER_POINTER (DECL_NAME (decl)));
6508 /* The 2.95.2 compiler sometimes allowed C functions to access
6509 non-@public ivars. We will let this slide for now... */
6510 if (!objc_method_context)
6512 warning ("instance variable `%s' is %s; "
6513 "this will be a hard error in the future",
6514 IDENTIFIER_POINTER (identifier),
6515 TREE_PRIVATE (decl) ? "@private" : "@protected");
6519 error ("instance variable `%s' is declared %s",
6520 IDENTIFIER_POINTER (identifier),
6521 TREE_PRIVATE (decl) ? "private" : "protected");
6526 else if (objc_implementation_context && (basetype == objc_object_reference))
6528 TREE_TYPE (expr) = uprivate_record;
6529 warning ("static access to object of type `id'");
6536 /* Make sure all entries in CHAIN are also in LIST. */
6539 check_methods (tree chain, tree list, int mtype)
6545 if (!lookup_method (list, chain))
6549 if (TREE_CODE (objc_implementation_context)
6550 == CLASS_IMPLEMENTATION_TYPE)
6551 warning ("incomplete implementation of class `%s'",
6552 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6553 else if (TREE_CODE (objc_implementation_context)
6554 == CATEGORY_IMPLEMENTATION_TYPE)
6555 warning ("incomplete implementation of category `%s'",
6556 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6560 warning ("method definition for `%c%s' not found",
6561 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6564 chain = TREE_CHAIN (chain);
6570 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6573 conforms_to_protocol (tree class, tree protocol)
6575 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6577 tree p = CLASS_PROTOCOL_LIST (class);
6578 while (p && TREE_VALUE (p) != protocol)
6583 tree super = (CLASS_SUPER_NAME (class)
6584 ? lookup_interface (CLASS_SUPER_NAME (class))
6586 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6595 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6596 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6599 check_methods_accessible (tree chain, tree context, int mtype)
6603 tree base_context = context;
6607 context = base_context;
6611 list = CLASS_CLS_METHODS (context);
6613 list = CLASS_NST_METHODS (context);
6615 if (lookup_method (list, chain))
6618 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6619 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6620 context = (CLASS_SUPER_NAME (context)
6621 ? lookup_interface (CLASS_SUPER_NAME (context))
6624 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6625 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6626 context = (CLASS_NAME (context)
6627 ? lookup_interface (CLASS_NAME (context))
6633 if (context == NULL_TREE)
6637 if (TREE_CODE (objc_implementation_context)
6638 == CLASS_IMPLEMENTATION_TYPE)
6639 warning ("incomplete implementation of class `%s'",
6641 (CLASS_NAME (objc_implementation_context)));
6642 else if (TREE_CODE (objc_implementation_context)
6643 == CATEGORY_IMPLEMENTATION_TYPE)
6644 warning ("incomplete implementation of category `%s'",
6646 (CLASS_SUPER_NAME (objc_implementation_context)));
6649 warning ("method definition for `%c%s' not found",
6650 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6653 chain = TREE_CHAIN (chain); /* next method... */
6658 /* Check whether the current interface (accessible via
6659 'objc_implementation_context') actually implements protocol P, along
6660 with any protocols that P inherits. */
6663 check_protocol (tree p, const char *type, const char *name)
6665 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6669 /* Ensure that all protocols have bodies! */
6672 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6673 CLASS_CLS_METHODS (objc_implementation_context),
6675 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6676 CLASS_NST_METHODS (objc_implementation_context),
6681 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6682 objc_implementation_context,
6684 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6685 objc_implementation_context,
6690 warning ("%s `%s' does not fully implement the `%s' protocol",
6691 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6694 /* Check protocols recursively. */
6695 if (PROTOCOL_LIST (p))
6697 tree subs = PROTOCOL_LIST (p);
6699 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6703 tree sub = TREE_VALUE (subs);
6705 /* If the superclass does not conform to the protocols
6706 inherited by P, then we must! */
6707 if (!super_class || !conforms_to_protocol (super_class, sub))
6708 check_protocol (sub, type, name);
6709 subs = TREE_CHAIN (subs);
6714 /* Check whether the current interface (accessible via
6715 'objc_implementation_context') actually implements the protocols listed
6719 check_protocols (tree proto_list, const char *type, const char *name)
6721 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6723 tree p = TREE_VALUE (proto_list);
6725 check_protocol (p, type, name);
6729 /* Make sure that the class CLASS_NAME is defined
6730 CODE says which kind of thing CLASS_NAME ought to be.
6731 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6732 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6735 start_class (enum tree_code code, tree class_name, tree super_name,
6741 if (current_namespace != global_namespace) {
6742 error ("Objective-C declarations may only appear in global scope");
6744 #endif /* OBJCPLUS */
6746 if (objc_implementation_context)
6748 warning ("`@end' missing in implementation context");
6749 finish_class (objc_implementation_context);
6750 objc_ivar_chain = NULL_TREE;
6751 objc_implementation_context = NULL_TREE;
6754 class = make_node (code);
6755 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6757 CLASS_NAME (class) = class_name;
6758 CLASS_SUPER_NAME (class) = super_name;
6759 CLASS_CLS_METHODS (class) = NULL_TREE;
6761 if (! is_class_name (class_name)
6762 && (decl = lookup_name (class_name)))
6764 error ("`%s' redeclared as different kind of symbol",
6765 IDENTIFIER_POINTER (class_name));
6766 error ("%Jprevious declaration of '%D'",
6770 if (code == CLASS_IMPLEMENTATION_TYPE)
6775 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6776 if (TREE_VALUE (chain) == class_name)
6778 error ("reimplementation of class `%s'",
6779 IDENTIFIER_POINTER (class_name));
6780 return error_mark_node;
6782 implemented_classes = tree_cons (NULL_TREE, class_name,
6783 implemented_classes);
6786 /* Reset for multiple classes per file. */
6789 objc_implementation_context = class;
6791 /* Lookup the interface for this implementation. */
6793 if (!(implementation_template = lookup_interface (class_name)))
6795 warning ("cannot find interface declaration for `%s'",
6796 IDENTIFIER_POINTER (class_name));
6797 add_class (implementation_template = objc_implementation_context);
6800 /* If a super class has been specified in the implementation,
6801 insure it conforms to the one specified in the interface. */
6804 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6806 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6807 const char *const name =
6808 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6809 error ("conflicting super class name `%s'",
6810 IDENTIFIER_POINTER (super_name));
6811 error ("previous declaration of `%s'", name);
6814 else if (! super_name)
6816 CLASS_SUPER_NAME (objc_implementation_context)
6817 = CLASS_SUPER_NAME (implementation_template);
6821 else if (code == CLASS_INTERFACE_TYPE)
6823 if (lookup_interface (class_name))
6825 error ("duplicate interface declaration for class `%s'",
6827 warning ("duplicate interface declaration for class `%s'",
6829 IDENTIFIER_POINTER (class_name));
6834 CLASS_PROTOCOL_LIST (class)
6835 = lookup_and_install_protocols (protocol_list);
6838 else if (code == CATEGORY_INTERFACE_TYPE)
6840 tree class_category_is_assoc_with;
6842 /* For a category, class_name is really the name of the class that
6843 the following set of methods will be associated with. We must
6844 find the interface so that can derive the objects template. */
6846 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6848 error ("cannot find interface declaration for `%s'",
6849 IDENTIFIER_POINTER (class_name));
6850 exit (FATAL_EXIT_CODE);
6853 add_category (class_category_is_assoc_with, class);
6856 CLASS_PROTOCOL_LIST (class)
6857 = lookup_and_install_protocols (protocol_list);
6860 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6862 /* Reset for multiple classes per file. */
6865 objc_implementation_context = class;
6867 /* For a category, class_name is really the name of the class that
6868 the following set of methods will be associated with. We must
6869 find the interface so that can derive the objects template. */
6871 if (!(implementation_template = lookup_interface (class_name)))
6873 error ("cannot find interface declaration for `%s'",
6874 IDENTIFIER_POINTER (class_name));
6875 exit (FATAL_EXIT_CODE);
6882 continue_class (tree class)
6884 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6885 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6887 struct imp_entry *imp_entry;
6890 /* Check consistency of the instance variables. */
6892 if (CLASS_IVARS (class))
6893 check_ivars (implementation_template, class);
6895 /* code generation */
6897 ivar_context = build_private_template (implementation_template);
6899 if (!objc_class_template)
6900 build_class_template ();
6902 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6904 imp_entry->next = imp_list;
6905 imp_entry->imp_context = class;
6906 imp_entry->imp_template = implementation_template;
6908 synth_forward_declarations ();
6909 imp_entry->class_decl = UOBJC_CLASS_decl;
6910 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6912 /* Append to front and increment count. */
6913 imp_list = imp_entry;
6914 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6919 return ivar_context;
6922 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6924 if (!CLASS_STATIC_TEMPLATE (class))
6926 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6927 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6928 CLASS_STATIC_TEMPLATE (class) = record;
6930 /* Mark this record as a class template for static typing. */
6931 TREE_STATIC_TEMPLATE (record) = 1;
6938 return error_mark_node;
6941 /* This is called once we see the "@end" in an interface/implementation. */
6944 finish_class (tree class)
6946 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6948 /* All code generation is done in finish_objc. */
6950 if (implementation_template != objc_implementation_context)
6952 /* Ensure that all method listed in the interface contain bodies. */
6953 check_methods (CLASS_CLS_METHODS (implementation_template),
6954 CLASS_CLS_METHODS (objc_implementation_context), '+');
6955 check_methods (CLASS_NST_METHODS (implementation_template),
6956 CLASS_NST_METHODS (objc_implementation_context), '-');
6958 if (CLASS_PROTOCOL_LIST (implementation_template))
6959 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6961 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6965 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6967 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6971 /* Ensure all method listed in the interface contain bodies. */
6972 check_methods (CLASS_CLS_METHODS (category),
6973 CLASS_CLS_METHODS (objc_implementation_context), '+');
6974 check_methods (CLASS_NST_METHODS (category),
6975 CLASS_NST_METHODS (objc_implementation_context), '-');
6977 if (CLASS_PROTOCOL_LIST (category))
6978 check_protocols (CLASS_PROTOCOL_LIST (category),
6980 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6984 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6987 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6988 char *string = (char *) alloca (strlen (class_name) + 3);
6990 /* extern struct objc_object *_<my_name>; */
6992 sprintf (string, "_%s", class_name);
6994 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6995 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6996 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7002 add_protocol (tree protocol)
7004 /* Put protocol on list in reverse order. */
7005 TREE_CHAIN (protocol) = protocol_chain;
7006 protocol_chain = protocol;
7007 return protocol_chain;
7011 lookup_protocol (tree ident)
7015 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7016 if (ident == PROTOCOL_NAME (chain))
7022 /* This function forward declares the protocols named by NAMES. If
7023 they are already declared or defined, the function has no effect. */
7026 objc_declare_protocols (tree names)
7031 if (current_namespace != global_namespace) {
7032 error ("Objective-C declarations may only appear in global scope");
7034 #endif /* OBJCPLUS */
7036 for (list = names; list; list = TREE_CHAIN (list))
7038 tree name = TREE_VALUE (list);
7040 if (lookup_protocol (name) == NULL_TREE)
7042 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7044 TYPE_BINFO (protocol) = make_tree_vec (2);
7045 PROTOCOL_NAME (protocol) = name;
7046 PROTOCOL_LIST (protocol) = NULL_TREE;
7047 add_protocol (protocol);
7048 PROTOCOL_DEFINED (protocol) = 0;
7049 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7055 start_protocol (enum tree_code code, tree name, tree list)
7060 if (current_namespace != global_namespace) {
7061 error ("Objective-C declarations may only appear in global scope");
7063 #endif /* OBJCPLUS */
7065 /* This is as good a place as any. Need to invoke
7066 push_tag_toplevel. */
7067 if (!objc_protocol_template)
7068 objc_protocol_template = build_protocol_template ();
7070 protocol = lookup_protocol (name);
7074 protocol = make_node (code);
7075 TYPE_BINFO (protocol) = make_tree_vec (2);
7077 PROTOCOL_NAME (protocol) = name;
7078 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7079 add_protocol (protocol);
7080 PROTOCOL_DEFINED (protocol) = 1;
7081 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7083 check_protocol_recursively (protocol, list);
7085 else if (! PROTOCOL_DEFINED (protocol))
7087 PROTOCOL_DEFINED (protocol) = 1;
7088 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7090 check_protocol_recursively (protocol, list);
7094 warning ("duplicate declaration for protocol `%s'",
7095 IDENTIFIER_POINTER (name));
7101 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7106 /* "Encode" a data type into a string, which grows in util_obstack.
7107 ??? What is the FORMAT? Someone please document this! */
7110 encode_type_qualifiers (tree declspecs)
7114 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7116 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7117 obstack_1grow (&util_obstack, 'r');
7118 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7119 obstack_1grow (&util_obstack, 'n');
7120 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7121 obstack_1grow (&util_obstack, 'N');
7122 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7123 obstack_1grow (&util_obstack, 'o');
7124 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7125 obstack_1grow (&util_obstack, 'O');
7126 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7127 obstack_1grow (&util_obstack, 'R');
7128 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7129 obstack_1grow (&util_obstack, 'V');
7133 /* Encode a pointer type. */
7136 encode_pointer (tree type, int curtype, int format)
7138 tree pointer_to = TREE_TYPE (type);
7140 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7142 if (OBJC_TYPE_NAME (pointer_to)
7143 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7145 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7147 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7149 obstack_1grow (&util_obstack, '@');
7152 else if (TREE_STATIC_TEMPLATE (pointer_to))
7154 if (generating_instance_variables)
7156 obstack_1grow (&util_obstack, '@');
7157 obstack_1grow (&util_obstack, '"');
7158 obstack_grow (&util_obstack, name, strlen (name));
7159 obstack_1grow (&util_obstack, '"');
7164 obstack_1grow (&util_obstack, '@');
7168 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7170 obstack_1grow (&util_obstack, '#');
7173 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7175 obstack_1grow (&util_obstack, ':');
7180 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7181 && TYPE_MODE (pointer_to) == QImode)
7183 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7184 ? OBJC_TYPE_NAME (pointer_to)
7185 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7187 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7189 obstack_1grow (&util_obstack, '*');
7194 /* We have a type that does not get special treatment. */
7196 /* NeXT extension */
7197 obstack_1grow (&util_obstack, '^');
7198 encode_type (pointer_to, curtype, format);
7202 encode_array (tree type, int curtype, int format)
7204 tree an_int_cst = TYPE_SIZE (type);
7205 tree array_of = TREE_TYPE (type);
7208 /* An incomplete array is treated like a pointer. */
7209 if (an_int_cst == NULL)
7211 encode_pointer (type, curtype, format);
7215 sprintf (buffer, "[%ld",
7216 (long) (TREE_INT_CST_LOW (an_int_cst)
7217 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7219 obstack_grow (&util_obstack, buffer, strlen (buffer));
7220 encode_type (array_of, curtype, format);
7221 obstack_1grow (&util_obstack, ']');
7226 encode_aggregate_within (tree type, int curtype, int format, int left,
7230 /* NB: aggregates that are pointed to have slightly different encoding
7231 rules in that you never encode the names of instance variables. */
7233 = (obstack_object_size (&util_obstack) > 0
7234 && *(obstack_next_free (&util_obstack) - 1) == '^');
7236 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7237 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7239 /* Traverse struct aliases; it is important to get the
7240 original struct and its tag name (if any). */
7241 type = TYPE_MAIN_VARIANT (type);
7242 name = OBJC_TYPE_NAME (type);
7243 /* Open parenth/bracket. */
7244 obstack_1grow (&util_obstack, left);
7246 /* Encode the struct/union tag name, or '?' if a tag was
7247 not provided. Typedef aliases do not qualify. */
7248 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7250 /* Did this struct have a tag? */
7251 && !TYPE_WAS_ANONYMOUS (type)
7254 obstack_grow (&util_obstack,
7255 IDENTIFIER_POINTER (name),
7256 strlen (IDENTIFIER_POINTER (name)));
7258 obstack_1grow (&util_obstack, '?');
7260 /* Encode the types (and possibly names) of the inner fields,
7262 if (inline_contents)
7264 tree fields = TYPE_FIELDS (type);
7266 obstack_1grow (&util_obstack, '=');
7267 for (; fields; fields = TREE_CHAIN (fields))
7270 /* C++ static members, and things that are not fields at all,
7271 should not appear in the encoding. */
7272 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7275 if (generating_instance_variables && !pointed_to)
7277 tree fname = DECL_NAME (fields);
7279 obstack_1grow (&util_obstack, '"');
7280 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7281 obstack_grow (&util_obstack,
7282 IDENTIFIER_POINTER (fname),
7283 strlen (IDENTIFIER_POINTER (fname)));
7284 obstack_1grow (&util_obstack, '"');
7286 encode_field_decl (fields, curtype, format);
7289 /* Close parenth/bracket. */
7290 obstack_1grow (&util_obstack, right);
7294 encode_aggregate (tree type, int curtype, int format)
7296 enum tree_code code = TREE_CODE (type);
7302 encode_aggregate_within (type, curtype, format, '{', '}');
7307 encode_aggregate_within (type, curtype, format, '(', ')');
7312 obstack_1grow (&util_obstack, 'i');
7320 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7324 encode_next_bitfield (int width)
7327 sprintf (buffer, "b%d", width);
7328 obstack_grow (&util_obstack, buffer, strlen (buffer));
7331 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7333 encode_type (tree type, int curtype, int format)
7335 enum tree_code code = TREE_CODE (type);
7338 if (code == INTEGER_TYPE)
7340 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7342 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7343 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7345 if (type == long_unsigned_type_node
7346 || type == long_integer_type_node)
7347 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7349 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7351 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7354 obstack_1grow (&util_obstack, c);
7357 else if (code == REAL_TYPE)
7359 /* Floating point types. */
7360 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7362 case 32: c = 'f'; break;
7364 case 128: c = 'd'; break;
7367 obstack_1grow (&util_obstack, c);
7370 else if (code == VOID_TYPE)
7371 obstack_1grow (&util_obstack, 'v');
7373 else if (code == BOOLEAN_TYPE)
7374 obstack_1grow (&util_obstack, 'B');
7376 else if (code == ARRAY_TYPE)
7377 encode_array (type, curtype, format);
7379 else if (code == POINTER_TYPE)
7380 encode_pointer (type, curtype, format);
7382 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7383 encode_aggregate (type, curtype, format);
7385 else if (code == FUNCTION_TYPE) /* '?' */
7386 obstack_1grow (&util_obstack, '?');
7390 encode_gnu_bitfield (int position, tree type, int size)
7392 enum tree_code code = TREE_CODE (type);
7394 char charType = '?';
7396 if (code == INTEGER_TYPE)
7398 if (integer_zerop (TYPE_MIN_VALUE (type)))
7400 /* Unsigned integer types. */
7402 if (TYPE_MODE (type) == QImode)
7404 else if (TYPE_MODE (type) == HImode)
7406 else if (TYPE_MODE (type) == SImode)
7408 if (type == long_unsigned_type_node)
7413 else if (TYPE_MODE (type) == DImode)
7418 /* Signed integer types. */
7420 if (TYPE_MODE (type) == QImode)
7422 else if (TYPE_MODE (type) == HImode)
7424 else if (TYPE_MODE (type) == SImode)
7426 if (type == long_integer_type_node)
7432 else if (TYPE_MODE (type) == DImode)
7436 else if (code == ENUMERAL_TYPE)
7441 sprintf (buffer, "b%d%c%d", position, charType, size);
7442 obstack_grow (&util_obstack, buffer, strlen (buffer));
7446 encode_field_decl (tree field_decl, int curtype, int format)
7451 /* C++ static members, and things that are not fields at all,
7452 should not appear in the encoding. */
7453 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7457 type = TREE_TYPE (field_decl);
7459 /* Generate the bitfield typing information, if needed. Note the difference
7460 between GNU and NeXT runtimes. */
7461 if (DECL_BIT_FIELD_TYPE (field_decl))
7463 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7465 if (flag_next_runtime)
7466 encode_next_bitfield (size);
7468 encode_gnu_bitfield (int_bit_position (field_decl),
7469 DECL_BIT_FIELD_TYPE (field_decl), size);
7472 encode_type (TREE_TYPE (field_decl), curtype, format);
7476 objc_expr_last (tree complex_expr)
7481 while ((next = TREE_OPERAND (complex_expr, 0)))
7482 complex_expr = next;
7484 return complex_expr;
7488 synth_self_and_ucmd_args (void)
7492 if (objc_method_context
7493 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7494 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7496 /* Really a `struct objc_class *'. However, we allow people to
7497 assign to self, which changes its type midstream. */
7498 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7500 push_parm_decl (build_tree_list
7501 (build_tree_list (decl_specs,
7502 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7505 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (selector_type));
7506 push_parm_decl (build_tree_list
7507 (build_tree_list (decl_specs,
7508 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7512 /* Transform a method definition into a function definition as follows:
7513 - synthesize the first two arguments, "self" and "_cmd". */
7516 start_method_def (tree method)
7518 /* Required to implement _msgSuper. */
7519 objc_method_context = method;
7520 UOBJC_SUPER_decl = NULL_TREE;
7522 /* Must be called BEFORE start_function. */
7524 declare_parm_level ();
7526 /* Generate prototype declarations for arguments..."new-style". */
7527 synth_self_and_ucmd_args ();
7529 /* Generate argument declarations if a keyword_decl. */
7530 if (METHOD_SEL_ARGS (method))
7532 tree arglist = METHOD_SEL_ARGS (method);
7535 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7536 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7540 tree last_expr = objc_expr_last (arg_decl);
7542 /* Unite the abstract decl with its name. */
7543 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7544 push_parm_decl (build_tree_list
7545 (build_tree_list (arg_spec, arg_decl),
7549 /* Unhook: restore the abstract declarator. */
7550 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7555 push_parm_decl (build_tree_list
7556 (build_tree_list (arg_spec,
7557 KEYWORD_ARG_NAME (arglist)),
7560 arglist = TREE_CHAIN (arglist);
7565 if (METHOD_ADD_ARGS (method) != NULL_TREE
7566 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7568 /* We have a variable length selector - in "prototype" format. */
7569 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7572 /* This must be done prior to calling pushdecl. pushdecl is
7573 going to change our chain on us. */
7574 tree nextkey = TREE_CHAIN (akey);
7582 warn_with_method (const char *message, int mtype, tree method)
7584 /* Add a readable method name to the warning. */
7585 warning ("%J%s `%c%s'", method,
7586 message, mtype, gen_method_decl (method, errbuf));
7589 /* Return 1 if METHOD is consistent with PROTO. */
7592 comp_method_with_proto (tree method, tree proto)
7594 /* Create a function template node at most once. */
7595 if (!function1_template)
7596 function1_template = make_node (FUNCTION_TYPE);
7598 /* Install argument types - normally set by build_function_type. */
7599 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7601 /* install return type */
7602 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7604 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
7607 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7610 objc_types_are_equivalent (tree type1, tree type2)
7614 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7616 type1 = TYPE_PROTOCOL_LIST (type1);
7617 type2 = TYPE_PROTOCOL_LIST (type2);
7618 if (list_length (type1) == list_length (type2))
7620 for (; type2; type2 = TREE_CHAIN (type2))
7621 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7628 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7631 comp_proto_with_proto (tree proto1, tree proto2)
7635 /* The following test is needed in case there are hashing
7637 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7640 /* Compare return types. */
7641 type1 = groktypename (TREE_TYPE (proto1));
7642 type2 = groktypename (TREE_TYPE (proto2));
7644 if (!objc_types_are_equivalent (type1, type2))
7647 /* Compare argument types. */
7648 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7649 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7651 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7653 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7657 return (!type1 && !type2);
7660 /* - Generate an identifier for the function. the format is "_n_cls",
7661 where 1 <= n <= nMethods, and cls is the name the implementation we
7663 - Install the return type from the method declaration.
7664 - If we have a prototype, check for type consistency. */
7667 really_start_method (tree method, tree parmlist)
7669 tree sc_spec, ret_spec, ret_decl, decl_specs;
7670 tree method_decl, method_id;
7671 const char *sel_name, *class_name, *cat_name;
7674 /* Synth the storage class & assemble the return type. */
7675 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7676 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7677 decl_specs = chainon (sc_spec, ret_spec);
7679 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7680 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7681 cat_name = ((TREE_CODE (objc_implementation_context)
7682 == CLASS_IMPLEMENTATION_TYPE)
7684 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7687 /* Make sure this is big enough for any plausible method label. */
7688 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7689 + (cat_name ? strlen (cat_name) : 0));
7691 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7692 class_name, cat_name, sel_name, method_slot);
7694 method_id = get_identifier (buf);
7697 /* Objective-C methods cannot be overloaded, so we don't need
7698 the type encoding appended. It looks bad anyway... */
7699 push_lang_context (lang_name_c);
7702 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7704 /* Check the declarator portion of the return type for the method. */
7705 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7707 /* Unite the complex decl (specified in the abstract decl) with the
7708 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7709 tree save_expr = objc_expr_last (ret_decl);
7711 TREE_OPERAND (save_expr, 0) = method_decl;
7712 method_decl = ret_decl;
7714 /* Fool the parser into thinking it is starting a function. */
7715 start_function (decl_specs, method_decl, NULL_TREE);
7717 /* Unhook: this has the effect of restoring the abstract declarator. */
7718 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7723 TREE_VALUE (TREE_TYPE (method)) = method_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_VALUE (TREE_TYPE (method)) = NULL_TREE;
7733 /* set self_decl from the first argument...this global is used by
7734 * build_ivar_reference().build_indirect_ref().
7736 self_decl = DECL_ARGUMENTS (current_function_decl);
7738 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7739 * the following: warning:unused parameter `struct objc_selector * _cmd'
7741 TREE_USED (self_decl) = 1;
7742 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7743 /* Ditto for the underlying (static) C function. */
7744 TREE_USED (current_function_decl) = 1;
7745 pop_lang_context ();
7748 METHOD_DEFINITION (method) = current_function_decl;
7750 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7752 if (implementation_template != objc_implementation_context)
7755 = lookup_method_static (implementation_template,
7756 METHOD_SEL_NAME (method),
7757 TREE_CODE (method) == CLASS_METHOD_DECL);
7761 if (!comp_method_with_proto (method, proto))
7763 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7765 warn_with_method ("conflicting types for", type, method);
7766 warn_with_method ("previous declaration of", type, proto);
7771 /* We have a method @implementation even though we did not
7772 see a corresponding @interface declaration (which is allowed
7773 by Objective-C rules). Go ahead and place the method in
7774 the @interface anyway, so that message dispatch lookups
7776 tree interface = implementation_template;
7778 if (TREE_CODE (objc_implementation_context)
7779 == CATEGORY_IMPLEMENTATION_TYPE)
7780 interface = lookup_category
7782 CLASS_SUPER_NAME (objc_implementation_context));
7785 objc_add_method (interface, copy_node (method),
7786 TREE_CODE (method) == CLASS_METHOD_DECL);
7791 /* The following routine is always called...this "architecture" is to
7792 accommodate "old-style" variable length selectors.
7794 - a:a b:b // prototype ; id c; id d; // old-style. */
7797 continue_method_def (void)
7801 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7802 /* We have a `, ...' immediately following the selector. */
7803 parmlist = get_parm_info (/*ellipsis=*/true);
7805 parmlist = get_parm_info (/*ellipsis=*/false);
7808 /* Set self_decl from the first argument...this global is used by
7809 build_ivar_reference calling build_indirect_ref. */
7810 self_decl = TREE_PURPOSE (parmlist);
7811 #endif /* !OBJCPLUS */
7814 really_start_method (objc_method_context, parmlist);
7815 store_parm_decls ();
7818 static void *UOBJC_SUPER_scope = 0;
7820 /* _n_Method (id self, SEL sel, ...)
7822 struct objc_super _S;
7823 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7827 get_super_receiver (void)
7829 if (objc_method_context)
7831 tree super_expr, super_expr_list;
7833 if (!UOBJC_SUPER_decl)
7835 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7836 build_tree_list (NULL_TREE,
7837 objc_super_template),
7840 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7842 /* This prevents `unused variable' warnings when compiling with -Wall. */
7843 TREE_USED (UOBJC_SUPER_decl) = 1;
7844 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7846 UOBJC_SUPER_scope = get_current_scope ();
7849 /* Set receiver to self. */
7850 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7851 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7852 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7854 /* Set class to begin searching. */
7856 super_expr = build_component_ref (UOBJC_SUPER_decl,
7857 get_identifier ("super_class"));
7859 super_expr = build_component_ref (UOBJC_SUPER_decl,
7860 get_identifier ("class"));
7863 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7865 /* [_cls, __cls]Super are "pre-built" in
7866 synth_forward_declarations. */
7868 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7869 ((TREE_CODE (objc_method_context)
7870 == INSTANCE_METHOD_DECL)
7872 : uucls_super_ref));
7876 /* We have a category. */
7878 tree super_name = CLASS_SUPER_NAME (implementation_template);
7881 /* Barf if super used in a category of Object. */
7884 error ("no super class declared in interface for `%s'",
7885 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7886 return error_mark_node;
7889 if (flag_next_runtime && !flag_zero_link)
7891 super_class = get_class_reference (super_name);
7892 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7893 /* If we are in a class method, we must retrieve the
7894 _metaclass_ for the current class, pointed at by
7895 the class's "isa" pointer. The following assumes that
7896 "isa" is the first ivar in a class (which it must be). */
7898 = build_indirect_ref
7899 (build_c_cast (build_pointer_type (objc_class_type),
7900 super_class), "unary *");
7904 add_class_reference (super_name);
7905 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7906 ? objc_get_class_decl : objc_get_meta_class_decl);
7907 assemble_external (super_class);
7909 = build_function_call
7913 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7914 IDENTIFIER_POINTER (super_name))));
7918 = build_modify_expr (super_expr, NOP_EXPR,
7919 build_c_cast (TREE_TYPE (super_expr),
7923 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7925 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7926 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7928 return build_compound_expr (super_expr_list);
7932 error ("[super ...] must appear in a method context");
7933 return error_mark_node;
7937 /* When exiting a scope, sever links to a 'super' declaration (if any)
7938 therein contained. */
7941 objc_clear_super_receiver (void)
7943 if (objc_method_context
7944 && UOBJC_SUPER_scope == get_current_scope ()) {
7945 UOBJC_SUPER_decl = 0;
7946 UOBJC_SUPER_scope = 0;
7951 objc_expand_function_end (void)
7953 /* This routine may also get called for C functions, including those
7954 nested within ObjC methods. In such cases, method encoding is
7956 if (objc_method_context == NULL_TREE
7957 || DECL_INITIAL (objc_method_context) != current_function_decl)
7960 METHOD_ENCODING (objc_method_context)
7961 = encode_method_prototype (objc_method_context);
7965 finish_method_def (void)
7967 lang_expand_function_end = objc_expand_function_end;
7968 /* We cannot validly inline ObjC methods, at least not without a language
7969 extension to declare that a method need not be dynamically
7970 dispatched, so suppress all thoughts of doing so. */
7971 DECL_INLINE (current_function_decl) = 0;
7972 DECL_UNINLINABLE (current_function_decl) = 1;
7975 lang_expand_function_end = NULL;
7977 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7978 since the optimizer may find "may be used before set" errors. */
7979 objc_method_context = NULL_TREE;
7984 lang_report_error_function (tree decl)
7986 if (objc_method_context)
7988 fprintf (stderr, "In method `%s'\n",
7989 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7999 is_complex_decl (tree type)
8001 return (TREE_CODE (type) == ARRAY_TYPE
8002 || TREE_CODE (type) == FUNCTION_TYPE
8003 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8007 /* Code to convert a decl node into text for a declaration in C. */
8009 static char tmpbuf[256];
8012 adorn_decl (tree decl, char *str)
8014 enum tree_code code = TREE_CODE (decl);
8016 if (code == ARRAY_REF)
8018 tree an_int_cst = TREE_OPERAND (decl, 1);
8020 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8021 sprintf (str + strlen (str), "[%ld]",
8022 (long) TREE_INT_CST_LOW (an_int_cst));
8027 else if (code == ARRAY_TYPE)
8029 tree an_int_cst = TYPE_SIZE (decl);
8030 tree array_of = TREE_TYPE (decl);
8032 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8033 sprintf (str + strlen (str), "[%ld]",
8034 (long) (TREE_INT_CST_LOW (an_int_cst)
8035 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8040 else if (code == CALL_EXPR)
8042 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8047 gen_declaration_1 (chain, str);
8048 chain = TREE_CHAIN (chain);
8055 else if (code == FUNCTION_TYPE)
8057 tree chain = TYPE_ARG_TYPES (decl);
8060 while (chain && TREE_VALUE (chain) != void_type_node)
8062 gen_declaration_1 (TREE_VALUE (chain), str);
8063 chain = TREE_CHAIN (chain);
8064 if (chain && TREE_VALUE (chain) != void_type_node)
8070 else if (code == INDIRECT_REF)
8072 strcpy (tmpbuf, "*");
8073 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8077 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8079 chain = TREE_CHAIN (chain))
8081 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8083 strcat (tmpbuf, " ");
8084 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8088 strcat (tmpbuf, " ");
8090 strcat (tmpbuf, str);
8091 strcpy (str, tmpbuf);
8094 else if (code == POINTER_TYPE)
8096 strcpy (tmpbuf, "*");
8097 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8099 if (TYPE_READONLY (decl))
8100 strcat (tmpbuf, " const");
8101 if (TYPE_VOLATILE (decl))
8102 strcat (tmpbuf, " volatile");
8104 strcat (tmpbuf, " ");
8106 strcat (tmpbuf, str);
8107 strcpy (str, tmpbuf);
8112 gen_declarator (tree decl, char *buf, const char *name)
8116 enum tree_code code = TREE_CODE (decl);
8126 op = TREE_OPERAND (decl, 0);
8128 /* We have a pointer to a function or array...(*)(), (*)[] */
8129 if ((code == ARRAY_REF || code == CALL_EXPR)
8130 && op && TREE_CODE (op) == INDIRECT_REF)
8133 str = gen_declarator (op, buf, name);
8137 strcpy (tmpbuf, "(");
8138 strcat (tmpbuf, str);
8139 strcat (tmpbuf, ")");
8140 strcpy (str, tmpbuf);
8143 adorn_decl (decl, str);
8152 /* This clause is done iteratively rather than recursively. */
8155 op = (is_complex_decl (TREE_TYPE (decl))
8156 ? TREE_TYPE (decl) : NULL_TREE);
8158 adorn_decl (decl, str);
8160 /* We have a pointer to a function or array...(*)(), (*)[] */
8161 if (code == POINTER_TYPE
8162 && op && (TREE_CODE (op) == FUNCTION_TYPE
8163 || TREE_CODE (op) == ARRAY_TYPE))
8165 strcpy (tmpbuf, "(");
8166 strcat (tmpbuf, str);
8167 strcat (tmpbuf, ")");
8168 strcpy (str, tmpbuf);
8171 decl = (is_complex_decl (TREE_TYPE (decl))
8172 ? TREE_TYPE (decl) : NULL_TREE);
8175 while (decl && (code = TREE_CODE (decl)))
8180 case IDENTIFIER_NODE:
8181 /* Will only happen if we are processing a "raw" expr-decl. */
8182 strcpy (buf, IDENTIFIER_POINTER (decl));
8193 /* We have an abstract declarator or a _DECL node. */
8201 gen_declspecs (tree declspecs, char *buf, int raw)
8207 for (chain = nreverse (copy_list (declspecs));
8208 chain; chain = TREE_CHAIN (chain))
8210 tree aspec = TREE_VALUE (chain);
8212 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8213 strcat (buf, IDENTIFIER_POINTER (aspec));
8214 else if (TREE_CODE (aspec) == RECORD_TYPE)
8216 if (OBJC_TYPE_NAME (aspec))
8218 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8220 if (! TREE_STATIC_TEMPLATE (aspec))
8221 strcat (buf, "struct ");
8222 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8227 tree chain = protocol_list;
8234 (PROTOCOL_NAME (TREE_VALUE (chain))));
8235 chain = TREE_CHAIN (chain);
8244 strcat (buf, "untagged struct");
8247 else if (TREE_CODE (aspec) == UNION_TYPE)
8249 if (OBJC_TYPE_NAME (aspec))
8251 if (! TREE_STATIC_TEMPLATE (aspec))
8252 strcat (buf, "union ");
8253 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8256 strcat (buf, "untagged union");
8259 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8261 if (OBJC_TYPE_NAME (aspec))
8263 if (! TREE_STATIC_TEMPLATE (aspec))
8264 strcat (buf, "enum ");
8265 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8268 strcat (buf, "untagged enum");
8271 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8272 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8274 else if (IS_ID (aspec))
8276 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8281 tree chain = protocol_list;
8288 (PROTOCOL_NAME (TREE_VALUE (chain))));
8289 chain = TREE_CHAIN (chain);
8296 if (TREE_CHAIN (chain))
8302 /* Type qualifiers. */
8303 if (TYPE_READONLY (declspecs))
8304 strcat (buf, "const ");
8305 if (TYPE_VOLATILE (declspecs))
8306 strcat (buf, "volatile ");
8308 switch (TREE_CODE (declspecs))
8310 /* Type specifiers. */
8313 declspecs = TYPE_MAIN_VARIANT (declspecs);
8315 /* Signed integer types. */
8317 if (declspecs == short_integer_type_node)
8318 strcat (buf, "short int ");
8319 else if (declspecs == integer_type_node)
8320 strcat (buf, "int ");
8321 else if (declspecs == long_integer_type_node)
8322 strcat (buf, "long int ");
8323 else if (declspecs == long_long_integer_type_node)
8324 strcat (buf, "long long int ");
8325 else if (declspecs == signed_char_type_node
8326 || declspecs == char_type_node)
8327 strcat (buf, "char ");
8329 /* Unsigned integer types. */
8331 else if (declspecs == short_unsigned_type_node)
8332 strcat (buf, "unsigned short ");
8333 else if (declspecs == unsigned_type_node)
8334 strcat (buf, "unsigned int ");
8335 else if (declspecs == long_unsigned_type_node)
8336 strcat (buf, "unsigned long ");
8337 else if (declspecs == long_long_unsigned_type_node)
8338 strcat (buf, "unsigned long long ");
8339 else if (declspecs == unsigned_char_type_node)
8340 strcat (buf, "unsigned char ");
8344 declspecs = TYPE_MAIN_VARIANT (declspecs);
8346 if (declspecs == float_type_node)
8347 strcat (buf, "float ");
8348 else if (declspecs == double_type_node)
8349 strcat (buf, "double ");
8350 else if (declspecs == long_double_type_node)
8351 strcat (buf, "long double ");
8355 if (OBJC_TYPE_NAME (declspecs)
8356 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8358 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8360 if (! TREE_STATIC_TEMPLATE (declspecs))
8361 strcat (buf, "struct ");
8362 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8366 tree chain = protocol_list;
8373 (PROTOCOL_NAME (TREE_VALUE (chain))));
8374 chain = TREE_CHAIN (chain);
8383 strcat (buf, "untagged struct");
8389 if (OBJC_TYPE_NAME (declspecs)
8390 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8392 strcat (buf, "union ");
8393 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8398 strcat (buf, "untagged union ");
8402 if (OBJC_TYPE_NAME (declspecs)
8403 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8405 strcat (buf, "enum ");
8406 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8411 strcat (buf, "untagged enum ");
8415 strcat (buf, "void ");
8420 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8425 tree chain = protocol_list;
8432 (PROTOCOL_NAME (TREE_VALUE (chain))));
8433 chain = TREE_CHAIN (chain);
8449 /* Given a tree node, produce a printable description of it in the given
8450 buffer, overwriting the buffer. */
8453 gen_declaration (tree atype_or_adecl, char *buf)
8456 gen_declaration_1 (atype_or_adecl, buf);
8460 /* Given a tree node, append a printable description to the end of the
8464 gen_declaration_1 (tree atype_or_adecl, char *buf)
8468 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8470 tree declspecs; /* "identifier_node", "record_type" */
8471 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8472 tree width = NULL_TREE; /* for bitfields */
8474 /* We have a "raw", abstract declarator (typename). */
8475 declarator = TREE_VALUE (atype_or_adecl);
8476 /* In the case of raw ivars, the declarator itself is a list,
8477 and contains bitfield widths. */
8478 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8480 width = TREE_VALUE (declarator);
8481 declarator = TREE_PURPOSE (declarator);
8483 declspecs = TREE_PURPOSE (atype_or_adecl);
8485 gen_declspecs (declspecs, buf, 1);
8489 strcat (buf, gen_declarator (declarator, declbuf, ""));
8492 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8493 TREE_INT_CST_LOW (width));
8499 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8500 tree declarator; /* "array_type", "function_type", "pointer_type". */
8502 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8503 || TREE_CODE (atype_or_adecl) == PARM_DECL
8504 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8505 atype = TREE_TYPE (atype_or_adecl);
8507 /* Assume we have a *_type node. */
8508 atype = atype_or_adecl;
8510 if (is_complex_decl (atype))
8514 /* Get the declaration specifier; it is at the end of the list. */
8515 declarator = chain = atype;
8517 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8518 while (is_complex_decl (chain));
8525 declarator = NULL_TREE;
8528 gen_declspecs (declspecs, buf, 0);
8530 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8531 || TREE_CODE (atype_or_adecl) == PARM_DECL
8532 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8534 const char *const decl_name =
8535 (DECL_NAME (atype_or_adecl)
8536 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8541 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8544 else if (decl_name[0])
8547 strcat (buf, decl_name);
8550 else if (declarator)
8553 strcat (buf, gen_declarator (declarator, declbuf, ""));
8558 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8560 /* Given a method tree, put a printable description into the given
8561 buffer (overwriting) and return a pointer to the buffer. */
8564 gen_method_decl (tree method, char *buf)
8569 if (RAW_TYPESPEC (method) != objc_object_reference)
8572 gen_declaration_1 (TREE_TYPE (method), buf);
8576 chain = METHOD_SEL_ARGS (method);
8579 /* We have a chain of keyword_decls. */
8582 if (KEYWORD_KEY_NAME (chain))
8583 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8586 if (RAW_TYPESPEC (chain) != objc_object_reference)
8589 gen_declaration_1 (TREE_TYPE (chain), buf);
8593 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8594 if ((chain = TREE_CHAIN (chain)))
8599 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8600 strcat (buf, ", ...");
8601 else if (METHOD_ADD_ARGS (method))
8603 /* We have a tree list node as generate by get_parm_info. */
8604 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8606 /* Know we have a chain of parm_decls. */
8610 gen_declaration_1 (chain, buf);
8611 chain = TREE_CHAIN (chain);
8617 /* We have a unary selector. */
8618 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8626 /* Dump an @interface declaration of the supplied class CHAIN to the
8627 supplied file FP. Used to implement the -gen-decls option (which
8628 prints out an @interface declaration of all classes compiled in
8629 this run); potentially useful for debugging the compiler too. */
8631 dump_interface (FILE *fp, tree chain)
8633 /* FIXME: A heap overflow here whenever a method (or ivar)
8634 declaration is so long that it doesn't fit in the buffer. The
8635 code and all the related functions should be rewritten to avoid
8636 using fixed size buffers. */
8637 char *buf = (char *) xmalloc (1024 * 10);
8638 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8639 tree ivar_decls = CLASS_RAW_IVARS (chain);
8640 tree nst_methods = CLASS_NST_METHODS (chain);
8641 tree cls_methods = CLASS_CLS_METHODS (chain);
8643 fprintf (fp, "\n@interface %s", my_name);
8645 /* CLASS_SUPER_NAME is used to store the superclass name for
8646 classes, and the category name for categories. */
8647 if (CLASS_SUPER_NAME (chain))
8649 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8651 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8652 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8654 fprintf (fp, " (%s)\n", name);
8658 fprintf (fp, " : %s\n", name);
8664 /* FIXME - the following doesn't seem to work at the moment. */
8667 fprintf (fp, "{\n");
8670 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8671 ivar_decls = TREE_CHAIN (ivar_decls);
8674 fprintf (fp, "}\n");
8679 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8680 nst_methods = TREE_CHAIN (nst_methods);
8685 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8686 cls_methods = TREE_CHAIN (cls_methods);
8689 fprintf (fp, "@end\n");
8692 /* Demangle function for Objective-C */
8694 objc_demangle (const char *mangled)
8696 char *demangled, *cp;
8698 if (mangled[0] == '_' &&
8699 (mangled[1] == 'i' || mangled[1] == 'c') &&
8702 cp = demangled = xmalloc(strlen(mangled) + 2);
8703 if (mangled[1] == 'i')
8704 *cp++ = '-'; /* for instance method */
8706 *cp++ = '+'; /* for class method */
8707 *cp++ = '['; /* opening left brace */
8708 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8709 while (*cp && *cp == '_')
8710 cp++; /* skip any initial underbars in class name */
8711 cp = strchr(cp, '_'); /* find first non-initial underbar */
8714 free(demangled); /* not mangled name */
8717 if (cp[1] == '_') /* easy case: no category name */
8719 *cp++ = ' '; /* replace two '_' with one ' ' */
8720 strcpy(cp, mangled + (cp - demangled) + 2);
8724 *cp++ = '('; /* less easy case: category name */
8725 cp = strchr(cp, '_');
8728 free(demangled); /* not mangled name */
8732 *cp++ = ' '; /* overwriting 1st char of method name... */
8733 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8735 while (*cp && *cp == '_')
8736 cp++; /* skip any initial underbars in method name */
8739 *cp = ':'; /* replace remaining '_' with ':' */
8740 *cp++ = ']'; /* closing right brace */
8741 *cp++ = 0; /* string terminator */
8745 return mangled; /* not an objc mangled name */
8749 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8751 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8757 gcc_obstack_init (&util_obstack);
8758 util_firstobj = (char *) obstack_finish (&util_obstack);
8760 errbuf = (char *) xmalloc (BUFSIZE);
8762 synth_module_prologue ();
8768 struct imp_entry *impent;
8770 /* The internally generated initializers appear to have missing braces.
8771 Don't warn about this. */
8772 int save_warn_missing_braces = warn_missing_braces;
8773 warn_missing_braces = 0;
8775 /* A missing @end may not be detected by the parser. */
8776 if (objc_implementation_context)
8778 warning ("`@end' missing in implementation context");
8779 finish_class (objc_implementation_context);
8780 objc_ivar_chain = NULL_TREE;
8781 objc_implementation_context = NULL_TREE;
8784 /* Process the static instances here because initialization of objc_symtab
8786 if (objc_static_instances)
8787 generate_static_references ();
8789 if (imp_list || class_names_chain
8790 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8791 generate_objc_symtab_decl ();
8793 for (impent = imp_list; impent; impent = impent->next)
8795 objc_implementation_context = impent->imp_context;
8796 implementation_template = impent->imp_template;
8798 UOBJC_CLASS_decl = impent->class_decl;
8799 UOBJC_METACLASS_decl = impent->meta_decl;
8801 /* Dump the @interface of each class as we compile it, if the
8802 -gen-decls option is in use. TODO: Dump the classes in the
8803 order they were found, rather than in reverse order as we
8805 if (flag_gen_declaration)
8807 dump_interface (gen_declaration_file, objc_implementation_context);
8810 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8812 /* all of the following reference the string pool... */
8813 generate_ivar_lists ();
8814 generate_dispatch_tables ();
8815 generate_shared_structures ();
8819 generate_dispatch_tables ();
8820 generate_category (objc_implementation_context);
8824 /* If we are using an array of selectors, we must always
8825 finish up the array decl even if no selectors were used. */
8826 if (! flag_next_runtime || sel_ref_chain)
8827 build_selector_translation_table ();
8830 generate_protocols ();
8832 if (flag_replace_objc_classes && imp_list)
8833 generate_objc_image_info ();
8835 if (objc_implementation_context || class_names_chain || objc_static_instances
8836 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8838 /* Arrange for ObjC data structures to be initialized at run time. */
8839 rtx init_sym = build_module_descriptor ();
8840 if (init_sym && targetm.have_ctors_dtors)
8841 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8844 /* Dump the class references. This forces the appropriate classes
8845 to be linked into the executable image, preserving unix archive
8846 semantics. This can be removed when we move to a more dynamically
8847 linked environment. */
8849 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8851 handle_class_ref (chain);
8852 if (TREE_PURPOSE (chain))
8853 generate_classref_translation_entry (chain);
8856 for (impent = imp_list; impent; impent = impent->next)
8857 handle_impent (impent);
8859 /* Dump the string table last. */
8861 generate_strings ();
8868 /* Run through the selector hash tables and print a warning for any
8869 selector which has multiple methods. */
8871 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8873 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8874 check_duplicates (hsh, 0, 1);
8875 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8876 check_duplicates (hsh, 0, 1);
8880 warn_missing_braces = save_warn_missing_braces;
8883 /* Subroutines of finish_objc. */
8886 generate_classref_translation_entry (tree chain)
8888 tree expr, name, decl_specs, decl, sc_spec;
8891 type = TREE_TYPE (TREE_PURPOSE (chain));
8893 expr = add_objc_string (TREE_VALUE (chain), class_names);
8894 expr = build_c_cast (type, expr); /* cast! */
8896 name = DECL_NAME (TREE_PURPOSE (chain));
8898 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8900 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8901 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8903 /* The decl that is returned from start_decl is the one that we
8904 forward declared in build_class_reference. */
8905 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8906 DECL_CONTEXT (decl) = NULL_TREE;
8907 finish_decl (decl, expr, NULL_TREE);
8912 handle_class_ref (tree chain)
8914 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8915 char *string = (char *) alloca (strlen (name) + 30);
8919 sprintf (string, "%sobjc_class_name_%s",
8920 (flag_next_runtime ? "." : "__"), name);
8922 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8923 if (flag_next_runtime)
8925 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8930 /* Make a decl for this name, so we can use its address in a tree. */
8931 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8932 DECL_EXTERNAL (decl) = 1;
8933 TREE_PUBLIC (decl) = 1;
8936 rest_of_decl_compilation (decl, 0, 0, 0);
8938 /* Make a decl for the address. */
8939 sprintf (string, "%sobjc_class_ref_%s",
8940 (flag_next_runtime ? "." : "__"), name);
8941 exp = build1 (ADDR_EXPR, string_type_node, decl);
8942 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8943 DECL_INITIAL (decl) = exp;
8944 TREE_STATIC (decl) = 1;
8945 TREE_USED (decl) = 1;
8948 rest_of_decl_compilation (decl, 0, 0, 0);
8952 handle_impent (struct imp_entry *impent)
8956 objc_implementation_context = impent->imp_context;
8957 implementation_template = impent->imp_template;
8959 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8961 const char *const class_name =
8962 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8964 string = (char *) alloca (strlen (class_name) + 30);
8966 sprintf (string, "%sobjc_class_name_%s",
8967 (flag_next_runtime ? "." : "__"), class_name);
8969 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8971 const char *const class_name =
8972 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8973 const char *const class_super_name =
8974 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8976 string = (char *) alloca (strlen (class_name)
8977 + strlen (class_super_name) + 30);
8979 /* Do the same for categories. Even though no references to
8980 these symbols are generated automatically by the compiler, it
8981 gives you a handle to pull them into an archive by hand. */
8982 sprintf (string, "*%sobjc_category_name_%s_%s",
8983 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8988 #ifdef ASM_DECLARE_CLASS_REFERENCE
8989 if (flag_next_runtime)
8991 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8999 init = build_int_2 (0, 0);
9000 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
9001 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9002 TREE_PUBLIC (decl) = 1;
9003 TREE_READONLY (decl) = 1;
9004 TREE_USED (decl) = 1;
9005 TREE_CONSTANT (decl) = 1;
9006 DECL_CONTEXT (decl) = 0;
9007 DECL_ARTIFICIAL (decl) = 1;
9008 DECL_INITIAL (decl) = init;
9009 assemble_variable (decl, 1, 0, 0);
9013 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9014 later requires that ObjC translation units participating in F&C be
9015 specially marked. The following routine accomplishes this. */
9017 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9020 generate_objc_image_info (void)
9022 tree sc_spec, decl, initlist;
9024 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9026 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9027 tree_cons (NULL_TREE,
9030 build_index_type (build_int_2 (1, 0))),
9035 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9036 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9037 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9039 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9040 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9041 finish_decl (decl, initlist, NULL_TREE);
9044 /* Look up ID as an instance variable. */
9047 lookup_objc_ivar (tree id)
9051 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9052 /* We have a message to super. */
9053 return get_super_receiver ();
9054 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9056 if (is_private (decl))
9059 return build_ivar_reference (id);
9065 #include "gt-objc-objc-act.h"
9066 #include "gtype-objc.h"