1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
53 #include "langhooks.h"
64 #include "diagnostic.h"
67 /* This is the default way of generating a method name. */
68 /* I am not sure it is really correct.
69 Perhaps there's a danger that it will make name conflicts
70 if method names contain underscores. -- rms. */
71 #ifndef OBJC_GEN_METHOD_LABEL
72 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
75 sprintf ((BUF), "_%s_%s_%s_%s", \
76 ((IS_INST) ? "i" : "c"), \
78 ((CAT_NAME)? (CAT_NAME) : ""), \
80 for (temp = (BUF); *temp; temp++) \
81 if (*temp == ':') *temp = '_'; \
85 /* These need specifying. */
86 #ifndef OBJC_FORWARDING_STACK_OFFSET
87 #define OBJC_FORWARDING_STACK_OFFSET 0
90 #ifndef OBJC_FORWARDING_MIN_OFFSET
91 #define OBJC_FORWARDING_MIN_OFFSET 0
94 /* Set up for use of obstacks. */
98 /* This obstack is used to accumulate the encoding of a data type. */
99 static struct obstack util_obstack;
101 /* This points to the beginning of obstack contents, so we can free
102 the whole contents. */
105 /* The version identifies which language generation and runtime
106 the module (file) was compiled for, and is recorded in the
107 module descriptor. */
109 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
110 #define PROTOCOL_VERSION 2
112 /* (Decide if these can ever be validly changed.) */
113 #define OBJC_ENCODE_INLINE_DEFS 0
114 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
116 /*** Private Interface (procedures) ***/
118 /* Used by compile_file. */
120 static void init_objc (void);
121 static void finish_objc (void);
123 /* Code generation. */
125 static void synth_module_prologue (void);
126 static tree objc_build_constructor (tree, tree);
127 static rtx build_module_descriptor (void);
128 static tree init_module_descriptor (tree);
129 static tree build_objc_method_call (int, tree, tree, tree, tree);
130 static void generate_strings (void);
131 static tree get_proto_encoding (tree);
132 static void build_selector_translation_table (void);
134 static tree objc_add_static_instance (tree, tree);
136 static void build_objc_exception_stuff (void);
137 static tree objc_declare_variable (enum rid, tree, tree, tree);
138 static tree objc_enter_block (void);
139 static tree objc_exit_block (void);
140 static void objc_build_try_enter_fragment (void);
141 static void objc_build_try_exit_fragment (void);
142 static void objc_build_extract_fragment (void);
143 static tree objc_build_extract_expr (void);
145 static tree build_ivar_template (void);
146 static tree build_method_template (void);
147 static tree build_private_template (tree);
148 static void build_class_template (void);
149 static void build_selector_template (void);
150 static void build_category_template (void);
151 static tree lookup_method_in_hash_lists (tree, int);
152 static void build_super_template (void);
153 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
154 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
155 static void synth_forward_declarations (void);
156 static int ivar_list_length (tree);
157 static tree get_class_ivars (tree, int);
158 static void generate_ivar_lists (void);
159 static void generate_dispatch_tables (void);
160 static void generate_shared_structures (void);
161 static tree generate_protocol_list (tree);
162 static void build_protocol_reference (tree);
164 static tree build_keyword_selector (tree);
165 static tree synth_id_with_class_suffix (const char *, tree);
167 static void generate_static_references (void);
168 static int check_methods_accessible (tree, tree, int);
169 static void encode_aggregate_within (tree, int, int, int, int);
170 static const char *objc_demangle (const char *);
171 static void objc_expand_function_end (void);
173 /* Hash tables to manage the global pool of method prototypes. */
175 hash *nst_method_hash_list = 0;
176 hash *cls_method_hash_list = 0;
178 static size_t hash_func (tree);
179 static void hash_init (void);
180 static void hash_enter (hash *, tree);
181 static hash hash_lookup (hash *, tree);
182 static void hash_add_attr (hash, tree);
183 static tree lookup_method (tree, tree);
184 static tree lookup_method_static (tree, tree, int);
185 static void add_method_to_hash_list (hash *, tree);
186 static tree add_class (tree);
187 static void add_category (tree, tree);
188 static inline tree lookup_category (tree, tree);
192 class_names, /* class, category, protocol, module names */
193 meth_var_names, /* method and variable names */
194 meth_var_types /* method and variable type descriptors */
197 static tree add_objc_string (tree, enum string_section);
198 static tree get_objc_string_decl (tree, enum string_section);
199 static tree build_objc_string_decl (enum string_section);
200 static tree build_selector_reference_decl (void);
202 /* Protocol additions. */
204 static tree add_protocol (tree);
205 static tree lookup_protocol (tree);
206 static void check_protocol_recursively (tree, tree);
207 static tree lookup_and_install_protocols (tree);
211 static void encode_type_qualifiers (tree);
212 static void encode_pointer (tree, int, int);
213 static void encode_array (tree, int, int);
214 static void encode_aggregate (tree, int, int);
215 static void encode_next_bitfield (int);
216 static void encode_gnu_bitfield (int, tree, int);
217 static void encode_type (tree, int, int);
218 static void encode_field_decl (tree, int, int);
220 static void really_start_method (tree, tree);
221 static int comp_method_with_proto (tree, tree);
222 static int objc_types_are_equivalent (tree, tree);
223 static int comp_proto_with_proto (tree, tree);
224 static tree get_arg_type_list (tree, int, int);
225 static tree objc_expr_last (tree);
226 static void synth_self_and_ucmd_args (void);
228 /* Utilities for debugging and error diagnostics. */
230 static void warn_with_method (const char *, int, tree);
231 static void error_with_ivar (const char *, tree, tree);
232 static char *gen_method_decl (tree, char *);
233 static char *gen_declaration (tree, char *);
234 static void gen_declaration_1 (tree, char *);
235 static char *gen_declarator (tree, char *, const char *);
236 static int is_complex_decl (tree);
237 static void adorn_decl (tree, char *);
238 static void dump_interface (FILE *, tree);
240 /* Everything else. */
242 static tree define_decl (tree, tree);
243 static tree lookup_method_in_protocol_list (tree, tree, int);
244 static tree lookup_protocol_in_reflist (tree, tree);
245 static tree create_builtin_decl (enum tree_code, tree, const char *);
246 static void setup_string_decl (void);
247 static int check_string_class_template (void);
248 static tree my_build_string (int, const char *);
249 static void build_objc_symtab_template (void);
250 static tree init_def_list (tree);
251 static tree init_objc_symtab (tree);
252 static tree build_metadata_decl (const char *, tree);
253 static void forward_declare_categories (void);
254 static void generate_objc_symtab_decl (void);
255 static tree build_selector (tree);
256 static tree build_typed_selector_reference (tree, tree);
257 static tree build_selector_reference (tree);
258 static tree build_class_reference_decl (void);
259 static void add_class_reference (tree);
260 static tree build_protocol_template (void);
261 static tree build_descriptor_table_initializer (tree, tree);
262 static tree build_method_prototype_list_template (tree, int);
263 static tree build_method_prototype_template (void);
264 static tree objc_method_parm_type (tree);
265 static int objc_encoded_type_size (tree);
266 static tree encode_method_prototype (tree);
267 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
268 static void generate_method_descriptors (tree);
269 static void generate_protocol_references (tree);
270 static void generate_protocols (void);
271 static void check_ivars (tree, tree);
272 static tree build_ivar_list_template (tree, int);
273 static tree build_method_list_template (tree, int);
274 static tree build_ivar_list_initializer (tree, tree);
275 static tree generate_ivars_list (tree, const char *, int, tree);
276 static tree build_dispatch_table_initializer (tree, tree);
277 static tree generate_dispatch_table (tree, const char *, int, tree);
278 static tree build_shared_structure_initializer (tree, tree, tree, tree,
279 tree, int, tree, tree, tree);
280 static void generate_category (tree);
281 static int is_objc_type_qualifier (tree);
282 static tree adjust_type_for_id_default (tree);
283 static tree check_duplicates (hash, int, int);
284 static tree receiver_is_class_object (tree, int, int);
285 static int check_methods (tree, tree, int);
286 static int conforms_to_protocol (tree, tree);
287 static void check_protocol (tree, const char *, const char *);
288 static void check_protocols (tree, const char *, const char *);
289 static void gen_declspecs (tree, char *, int);
290 static void generate_classref_translation_entry (tree);
291 static void handle_class_ref (tree);
292 static void generate_struct_by_value_array (void)
294 static void mark_referenced_methods (void);
295 static void generate_objc_image_info (void);
297 /*** Private Interface (data) ***/
299 /* Reserved tag definitions. */
302 #define TAG_OBJECT "objc_object"
303 #define TAG_CLASS "objc_class"
304 #define TAG_SUPER "objc_super"
305 #define TAG_SELECTOR "objc_selector"
307 #define UTAG_CLASS "_objc_class"
308 #define UTAG_IVAR "_objc_ivar"
309 #define UTAG_IVAR_LIST "_objc_ivar_list"
310 #define UTAG_METHOD "_objc_method"
311 #define UTAG_METHOD_LIST "_objc_method_list"
312 #define UTAG_CATEGORY "_objc_category"
313 #define UTAG_MODULE "_objc_module"
314 #define UTAG_SYMTAB "_objc_symtab"
315 #define UTAG_SUPER "_objc_super"
316 #define UTAG_SELECTOR "_objc_selector"
318 #define UTAG_PROTOCOL "_objc_protocol"
319 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
320 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
322 /* Note that the string object global name is only needed for the
324 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
326 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
328 static const char *TAG_GETCLASS;
329 static const char *TAG_GETMETACLASS;
330 static const char *TAG_MSGSEND;
331 static const char *TAG_MSGSENDSUPER;
332 /* The NeXT Objective-C messenger may have two extra entry points, for use
333 when returning a structure. */
334 static const char *TAG_MSGSEND_STRET;
335 static const char *TAG_MSGSENDSUPER_STRET;
336 static const char *TAG_EXECCLASS;
337 static const char *default_constant_string_class_name;
339 /* Runtime metadata flags. */
340 #define CLS_FACTORY 0x0001L
341 #define CLS_META 0x0002L
343 #define OBJC_MODIFIER_STATIC 0x00000001
344 #define OBJC_MODIFIER_FINAL 0x00000002
345 #define OBJC_MODIFIER_PUBLIC 0x00000004
346 #define OBJC_MODIFIER_PRIVATE 0x00000008
347 #define OBJC_MODIFIER_PROTECTED 0x00000010
348 #define OBJC_MODIFIER_NATIVE 0x00000020
349 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
350 #define OBJC_MODIFIER_ABSTRACT 0x00000080
351 #define OBJC_MODIFIER_VOLATILE 0x00000100
352 #define OBJC_MODIFIER_TRANSIENT 0x00000200
353 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
355 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
356 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
357 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
358 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
359 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
360 #define TAG_EXCEPTIONMATCH "objc_exception_match"
361 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
362 #define TAG_SYNCENTER "objc_sync_enter"
363 #define TAG_SYNCEXIT "objc_sync_exit"
364 #define TAG_SETJMP "_setjmp"
365 #define TAG_RETURN_STRUCT "objc_return_struct"
367 #define UTAG_EXCDATA "_objc_exception_data"
368 #define UTAG_EXCDATA_VAR "_stackExceptionData"
369 #define UTAG_CAUGHTEXC_VAR "_caughtException"
370 #define UTAG_RETHROWEXC_VAR "_rethrowException"
371 #define UTAG_EVALONCE_VAR "_eval_once"
375 struct val_stack *next;
377 static struct val_stack *catch_count_stack, *exc_binding_stack;
379 /* useful for debugging */
380 static int if_nesting_count;
381 static int blk_nesting_count;
383 static void val_stack_push (struct val_stack **, long);
384 static void val_stack_pop (struct val_stack **);
386 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
387 tree objc_global_trees[OCTI_MAX];
389 static void handle_impent (struct imp_entry *);
391 struct imp_entry *imp_list = 0;
392 int imp_count = 0; /* `@implementation' */
393 int cat_count = 0; /* `@category' */
395 /* Use to generate method labels. */
396 static int method_slot = 0;
400 static char *errbuf; /* Buffer for error diagnostics */
402 /* Data imported from tree.c. */
404 extern enum debug_info_type write_symbols;
406 /* Data imported from toplev.c. */
408 extern const char *dump_base_name;
410 static int flag_typed_selectors;
412 FILE *gen_declaration_file;
414 /* Tells "encode_pointer/encode_aggregate" whether we are generating
415 type descriptors for instance variables (as opposed to methods).
416 Type descriptors for instance variables contain more information
417 than methods (for static typing and embedded structures). */
419 static int generating_instance_variables = 0;
421 /* Some platforms pass small structures through registers versus
422 through an invisible pointer. Determine at what size structure is
423 the transition point between the two possibilities. */
426 generate_struct_by_value_array (void)
429 tree field_decl, field_decl_chain;
431 int aggregate_in_mem[32];
434 /* Presumably no platform passes 32 byte structures in a register. */
435 for (i = 1; i < 32; i++)
439 /* Create an unnamed struct that has `i' character components */
440 type = start_struct (RECORD_TYPE, NULL_TREE);
442 strcpy (buffer, "c1");
443 field_decl = create_builtin_decl (FIELD_DECL,
446 field_decl_chain = field_decl;
448 for (j = 1; j < i; j++)
450 sprintf (buffer, "c%d", j + 1);
451 field_decl = create_builtin_decl (FIELD_DECL,
454 chainon (field_decl_chain, field_decl);
456 finish_struct (type, field_decl_chain, NULL_TREE);
458 aggregate_in_mem[i] = aggregate_value_p (type, 0);
459 if (!aggregate_in_mem[i])
463 /* We found some structures that are returned in registers instead of memory
464 so output the necessary data. */
467 for (i = 31; i >= 0; i--)
468 if (!aggregate_in_mem[i])
470 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
472 /* The first member of the structure is always 0 because we don't handle
473 structures with 0 members */
474 printf ("static int struct_forward_array[] = {\n 0");
476 for (j = 1; j <= i; j++)
477 printf (", %d", aggregate_in_mem[j]);
487 if (c_objc_common_init () == false)
490 /* Force the line number back to 0; check_newline will have
491 raised it to 1, which will make the builtin functions appear
492 not to be built in. */
495 /* If gen_declaration desired, open the output file. */
496 if (flag_gen_declaration)
498 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
499 gen_declaration_file = fopen (dumpname, "w");
500 if (gen_declaration_file == 0)
501 fatal_error ("can't open %s: %m", dumpname);
505 if (flag_next_runtime)
507 TAG_GETCLASS = "objc_getClass";
508 TAG_GETMETACLASS = "objc_getMetaClass";
509 TAG_MSGSEND = "objc_msgSend";
510 TAG_MSGSENDSUPER = "objc_msgSendSuper";
511 TAG_MSGSEND_STRET = "objc_msgSend_stret";
512 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
513 TAG_EXECCLASS = "__objc_execClass";
514 default_constant_string_class_name = "NSConstantString";
518 TAG_GETCLASS = "objc_get_class";
519 TAG_GETMETACLASS = "objc_get_meta_class";
520 TAG_MSGSEND = "objc_msg_lookup";
521 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
522 /* GNU runtime does not provide special functions to support
523 structure-returning methods. */
524 TAG_EXECCLASS = "__objc_exec_class";
525 default_constant_string_class_name = "NXConstantString";
526 flag_typed_selectors = 1;
529 objc_ellipsis_node = make_node (ERROR_MARK);
533 if (print_struct_values)
534 generate_struct_by_value_array ();
542 mark_referenced_methods ();
543 c_objc_common_finish_file ();
545 /* Finalize Objective-C runtime data. No need to generate tables
546 and code if only checking syntax. */
547 if (!flag_syntax_only)
550 if (gen_declaration_file)
551 fclose (gen_declaration_file);
555 define_decl (tree declarator, tree declspecs)
557 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
558 finish_decl (decl, NULL_TREE, NULL_TREE);
563 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
569 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
571 p = TREE_VALUE (rproto);
573 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
575 if ((fnd = lookup_method (class_meth
576 ? PROTOCOL_CLS_METHODS (p)
577 : PROTOCOL_NST_METHODS (p), sel_name)))
579 else if (PROTOCOL_LIST (p))
580 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
581 sel_name, class_meth);
585 ; /* An identifier...if we could not find a protocol. */
596 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
600 /* Make sure the protocol is supported by the object on the rhs. */
601 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
604 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
606 p = TREE_VALUE (rproto);
608 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
613 else if (PROTOCOL_LIST (p))
614 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
623 ; /* An identifier...if we could not find a protocol. */
629 /* Return 1 if LHS and RHS are compatible types for assignment or
630 various other operations. Return 0 if they are incompatible, and
631 return -1 if we choose to not decide (because the types are really
632 just C types, not ObjC specific ones). When the operation is
633 REFLEXIVE (typically comparisons), check for compatibility in
634 either direction; when it's not (typically assignments), don't.
636 This function is called in two cases: when both lhs and rhs are
637 pointers to records (in which case we check protocols too), and
638 when both lhs and rhs are records (in which case we check class
641 Warnings about classes/protocols not implementing a protocol are
642 emitted here (multiple of those warnings might be emitted for a
643 single line!); generic warnings about incompatible assignments and
644 lacks of casts in comparisons are/must be emitted by the caller if
649 objc_comptypes (tree lhs, tree rhs, int reflexive)
651 /* New clause for protocols. */
653 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
654 manage the ObjC ones, and leave the rest to the C code. */
655 if (TREE_CODE (lhs) == POINTER_TYPE
656 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
657 && TREE_CODE (rhs) == POINTER_TYPE
658 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
660 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
661 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
665 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
666 tree rproto, rproto_list;
669 /* <Protocol> = <Protocol> */
672 rproto_list = TYPE_PROTOCOL_LIST (rhs);
676 /* An assignment between objects of type 'id
677 <Protocol>'; make sure the protocol on the lhs is
678 supported by the object on the rhs. */
679 for (lproto = lproto_list; lproto;
680 lproto = TREE_CHAIN (lproto))
682 p = TREE_VALUE (lproto);
683 rproto = lookup_protocol_in_reflist (rproto_list, p);
687 ("object does not conform to the `%s' protocol",
688 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
694 /* Obscure case - a comparison between two objects
695 of type 'id <Protocol>'. Check that either the
696 protocol on the lhs is supported by the object on
697 the rhs, or viceversa. */
699 /* Check if the protocol on the lhs is supported by the
700 object on the rhs. */
701 for (lproto = lproto_list; lproto;
702 lproto = TREE_CHAIN (lproto))
704 p = TREE_VALUE (lproto);
705 rproto = lookup_protocol_in_reflist (rproto_list, p);
709 /* Check failed - check if the protocol on the rhs
710 is supported by the object on the lhs. */
711 for (rproto = rproto_list; rproto;
712 rproto = TREE_CHAIN (rproto))
714 p = TREE_VALUE (rproto);
715 lproto = lookup_protocol_in_reflist (lproto_list,
720 /* This check failed too: incompatible */
730 /* <Protocol> = <class> * */
731 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
733 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
736 /* Make sure the protocol is supported by the object on
738 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
740 p = TREE_VALUE (lproto);
742 rinter = lookup_interface (rname);
744 while (rinter && !rproto)
748 rproto_list = CLASS_PROTOCOL_LIST (rinter);
749 rproto = lookup_protocol_in_reflist (rproto_list, p);
750 /* If the underlying ObjC class does not have
751 the protocol we're looking for, check for "one-off"
752 protocols (e.g., `NSObject<MyProt> *foo;') attached
756 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
757 rproto = lookup_protocol_in_reflist (rproto_list, p);
760 /* Check for protocols adopted by categories. */
761 cat = CLASS_CATEGORY_LIST (rinter);
762 while (cat && !rproto)
764 rproto_list = CLASS_PROTOCOL_LIST (cat);
765 rproto = lookup_protocol_in_reflist (rproto_list, p);
766 cat = CLASS_CATEGORY_LIST (cat);
769 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
773 warning ("class `%s' does not implement the `%s' protocol",
774 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
775 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
779 /* <Protocol> = id */
780 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
784 /* <Protocol> = Class */
785 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
789 /* <Protocol> = ?? : let comptypes decide. */
792 else if (rhs_is_proto)
794 /* <class> * = <Protocol> */
795 if (TYPED_OBJECT (TREE_TYPE (lhs)))
799 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
801 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
803 /* Make sure the protocol is supported by the object on
805 for (rproto = rproto_list; rproto;
806 rproto = TREE_CHAIN (rproto))
808 tree p = TREE_VALUE (rproto);
810 rinter = lookup_interface (rname);
812 while (rinter && !lproto)
816 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
817 lproto = lookup_protocol_in_reflist (lproto_list, p);
818 /* If the underlying ObjC class does not
819 have the protocol we're looking for,
820 check for "one-off" protocols (e.g.,
821 `NSObject<MyProt> *foo;') attached to the
825 lproto_list = TYPE_PROTOCOL_LIST
827 lproto = lookup_protocol_in_reflist
831 /* Check for protocols adopted by categories. */
832 cat = CLASS_CATEGORY_LIST (rinter);
833 while (cat && !lproto)
835 lproto_list = CLASS_PROTOCOL_LIST (cat);
836 lproto = lookup_protocol_in_reflist (lproto_list,
838 cat = CLASS_CATEGORY_LIST (cat);
841 rinter = lookup_interface (CLASS_SUPER_NAME
846 warning ("class `%s' does not implement the `%s' protocol",
847 IDENTIFIER_POINTER (OBJC_TYPE_NAME
849 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
856 /* id = <Protocol> */
857 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
861 /* Class = <Protocol> */
862 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
866 /* ??? = <Protocol> : let comptypes decide */
874 /* Attention: we shouldn't defer to comptypes here. One bad
875 side effect would be that we might loose the REFLEXIVE
878 lhs = TREE_TYPE (lhs);
879 rhs = TREE_TYPE (rhs);
883 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
885 /* Nothing to do with ObjC - let immediately comptypes take
886 responsibility for checking. */
890 /* `id' = `<class> *' `<class> *' = `id': always allow it.
892 'Object *o = [[Object alloc] init]; falls
893 in the case <class> * = `id'.
895 if ((OBJC_TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
896 || (OBJC_TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
899 /* `id' = `Class', `Class' = `id' */
901 else if ((OBJC_TYPE_NAME (lhs) == objc_object_id
902 && OBJC_TYPE_NAME (rhs) == objc_class_id)
903 || (OBJC_TYPE_NAME (lhs) == objc_class_id
904 && OBJC_TYPE_NAME (rhs) == objc_object_id))
907 /* `Class' != `<class> *' && `<class> *' != `Class'! */
908 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
909 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
912 /* `<class> *' = `<class> *' */
914 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
916 tree lname = OBJC_TYPE_NAME (lhs);
917 tree rname = OBJC_TYPE_NAME (rhs);
923 /* If the left hand side is a super class of the right hand side,
925 for (inter = lookup_interface (rname); inter;
926 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
927 if (lname == CLASS_SUPER_NAME (inter))
930 /* Allow the reverse when reflexive. */
932 for (inter = lookup_interface (lname); inter;
933 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
934 if (rname == CLASS_SUPER_NAME (inter))
940 /* Not an ObjC type - let comptypes do the check. */
944 /* Called from finish_decl. */
947 objc_check_decl (tree decl)
949 tree type = TREE_TYPE (decl);
951 if (TREE_CODE (type) != RECORD_TYPE)
953 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
954 error ("statically allocated instance of Objective-C class `%s'",
955 IDENTIFIER_POINTER (type));
958 /* Implement static typing. At this point, we know we have an interface. */
961 get_static_reference (tree interface, tree protocols)
963 tree type = xref_tag (RECORD_TYPE, interface);
967 tree t, m = TYPE_MAIN_VARIANT (type);
969 t = copy_node (type);
971 /* Add this type to the chain of variants of TYPE. */
972 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
973 TYPE_NEXT_VARIANT (m) = t;
975 /* Look up protocols and install in lang specific list. Note
976 that the protocol list can have a different lifetime than T! */
977 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
979 /* This forces a new pointer type to be created later
980 (in build_pointer_type)...so that the new template
981 we just created will actually be used...what a hack! */
982 if (TYPE_POINTER_TO (t))
983 TYPE_POINTER_TO (t) = NULL_TREE;
992 get_object_reference (tree protocols)
994 tree type_decl = lookup_name (objc_id_id);
997 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
999 type = TREE_TYPE (type_decl);
1000 if (TYPE_MAIN_VARIANT (type) != id_type)
1001 warning ("unexpected type for `id' (%s)",
1002 gen_declaration (type, errbuf));
1006 error ("undefined type `id', please import <objc/objc.h>");
1007 return error_mark_node;
1010 /* This clause creates a new pointer type that is qualified with
1011 the protocol specification...this info is used later to do more
1012 elaborate type checking. */
1016 tree t, m = TYPE_MAIN_VARIANT (type);
1018 t = copy_node (type);
1020 /* Add this type to the chain of variants of TYPE. */
1021 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1022 TYPE_NEXT_VARIANT (m) = t;
1024 /* Look up protocols...and install in lang specific list */
1025 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1027 /* This forces a new pointer type to be created later
1028 (in build_pointer_type)...so that the new template
1029 we just created will actually be used...what a hack! */
1030 if (TYPE_POINTER_TO (t))
1031 TYPE_POINTER_TO (t) = NULL_TREE;
1038 /* Check for circular dependencies in protocols. The arguments are
1039 PROTO, the protocol to check, and LIST, a list of protocol it
1043 check_protocol_recursively (tree proto, tree list)
1047 for (p = list; p; p = TREE_CHAIN (p))
1049 tree pp = TREE_VALUE (p);
1051 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1052 pp = lookup_protocol (pp);
1055 fatal_error ("protocol `%s' has circular dependency",
1056 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1058 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1062 /* Look up PROTOCOLS, and return a list of those that are found.
1063 If none are found, return NULL. */
1066 lookup_and_install_protocols (tree protocols)
1069 tree return_value = NULL_TREE;
1071 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1073 tree ident = TREE_VALUE (proto);
1074 tree p = lookup_protocol (ident);
1077 error ("cannot find protocol declaration for `%s'",
1078 IDENTIFIER_POINTER (ident));
1080 return_value = chainon (return_value,
1081 build_tree_list (NULL_TREE, p));
1084 return return_value;
1087 /* Create and push a decl for a built-in external variable or field NAME.
1089 TYPE is its data type. */
1092 create_builtin_decl (enum tree_code code, tree type, const char *name)
1094 tree decl = build_decl (code, get_identifier (name), type);
1096 if (code == VAR_DECL)
1098 TREE_STATIC (decl) = 1;
1099 make_decl_rtl (decl, 0);
1101 DECL_ARTIFICIAL (decl) = 1;
1107 /* Find the decl for the constant string class. */
1110 setup_string_decl (void)
1112 if (!string_class_decl)
1114 if (!constant_string_global_id)
1118 /* %s in format will provide room for terminating null */
1119 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1120 + strlen (constant_string_class_name);
1121 name = xmalloc (length);
1122 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1123 constant_string_class_name);
1124 constant_string_global_id = get_identifier (name);
1126 string_class_decl = lookup_name (constant_string_global_id);
1130 /* Purpose: "play" parser, creating/installing representations
1131 of the declarations that are required by Objective-C.
1135 type_spec--------->sc_spec
1136 (tree_list) (tree_list)
1139 identifier_node identifier_node */
1142 synth_module_prologue (void)
1146 /* Defined in `objc.h' */
1147 objc_object_id = get_identifier (TAG_OBJECT);
1149 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1151 id_type = build_pointer_type (objc_object_reference);
1153 objc_id_id = get_identifier (TYPE_ID);
1154 objc_class_id = get_identifier (TAG_CLASS);
1156 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1157 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1158 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1159 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1162 /* Declare type of selector-objects that represent an operation name. */
1164 if (flag_next_runtime)
1165 /* `struct objc_selector *' */
1167 = build_pointer_type (xref_tag (RECORD_TYPE,
1168 get_identifier (TAG_SELECTOR)));
1170 /* `const struct objc_selector *' */
1172 = build_pointer_type
1173 (build_qualified_type (xref_tag (RECORD_TYPE,
1174 get_identifier (TAG_SELECTOR)),
1177 /* Declare receiver type used for dispatching messages to 'super'. */
1179 /* `struct objc_super *' */
1180 super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1181 get_identifier (TAG_SUPER)));
1183 if (flag_next_runtime)
1185 /* NB: In order to call one of the ..._stret (struct-returning)
1186 functions, the function *MUST* first be cast to a signature that
1187 corresponds to the actual ObjC method being invoked. This is
1188 what is done by the build_objc_method_call() routine below. */
1190 /* id objc_msgSend (id, SEL, ...); */
1191 /* id objc_msgSendNonNil (id, SEL, ...); */
1192 /* id objc_msgSend_stret (id, SEL, ...); */
1193 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1195 = build_function_type (id_type,
1196 tree_cons (NULL_TREE, id_type,
1197 tree_cons (NULL_TREE, selector_type,
1199 umsg_decl = builtin_function (TAG_MSGSEND,
1200 temp_type, 0, NOT_BUILT_IN,
1202 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1203 temp_type, 0, NOT_BUILT_IN,
1205 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1206 temp_type, 0, NOT_BUILT_IN,
1208 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1209 temp_type, 0, NOT_BUILT_IN,
1212 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1213 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1215 = build_function_type (id_type,
1216 tree_cons (NULL_TREE, super_type,
1217 tree_cons (NULL_TREE, selector_type,
1219 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1220 temp_type, 0, NOT_BUILT_IN,
1222 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1223 temp_type, 0, NOT_BUILT_IN, 0,
1228 /* GNU runtime messenger entry points. */
1230 /* typedef id (*IMP)(id, SEL, ...); */
1232 = build_pointer_type
1233 (build_function_type (id_type,
1234 tree_cons (NULL_TREE, id_type,
1235 tree_cons (NULL_TREE, selector_type,
1238 /* IMP objc_msg_lookup (id, SEL); */
1240 = build_function_type (IMP_type,
1241 tree_cons (NULL_TREE, id_type,
1242 tree_cons (NULL_TREE, selector_type,
1244 umsg_decl = builtin_function (TAG_MSGSEND,
1245 temp_type, 0, NOT_BUILT_IN,
1248 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1250 = build_function_type (IMP_type,
1251 tree_cons (NULL_TREE, super_type,
1252 tree_cons (NULL_TREE, selector_type,
1254 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1255 temp_type, 0, NOT_BUILT_IN,
1259 /* id objc_getClass (const char *); */
1261 temp_type = build_function_type (id_type,
1262 tree_cons (NULL_TREE,
1263 const_string_type_node,
1267 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1270 /* id objc_getMetaClass (const char *); */
1272 objc_get_meta_class_decl
1273 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1275 build_super_template ();
1276 if (flag_next_runtime)
1277 build_objc_exception_stuff ();
1279 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1281 if (! flag_next_runtime)
1283 if (flag_typed_selectors)
1285 /* Suppress outputting debug symbols, because
1286 dbxout_init hasn'r been called yet. */
1287 enum debug_info_type save_write_symbols = write_symbols;
1288 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1289 write_symbols = NO_DEBUG;
1290 debug_hooks = &do_nothing_debug_hooks;
1292 build_selector_template ();
1293 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1295 write_symbols = save_write_symbols;
1296 debug_hooks = save_hooks;
1299 temp_type = build_array_type (selector_type, NULL_TREE);
1301 layout_type (temp_type);
1302 UOBJC_SELECTOR_TABLE_decl
1303 = create_builtin_decl (VAR_DECL, temp_type,
1304 "_OBJC_SELECTOR_TABLE");
1306 /* Avoid warning when not sending messages. */
1307 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1310 /* Forward declare constant_string_id and constant_string_type. */
1311 if (!constant_string_class_name)
1312 constant_string_class_name = default_constant_string_class_name;
1314 constant_string_id = get_identifier (constant_string_class_name);
1315 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1317 /* Pre-build the following entities - for speed/convenience. */
1318 self_id = get_identifier ("self");
1319 ucmd_id = get_identifier ("_cmd");
1321 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1322 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1326 /* Ensure that the ivar list for NSConstantString/NXConstantString
1327 (or whatever was specified via `-fconstant-string-class')
1328 contains fields at least as large as the following three, so that
1329 the runtime can stomp on them with confidence:
1331 struct STRING_OBJECT_CLASS_NAME
1335 unsigned int length;
1339 check_string_class_template (void)
1341 tree field_decl = TYPE_FIELDS (constant_string_type);
1343 #define AT_LEAST_AS_LARGE_AS(F, T) \
1344 (F && TREE_CODE (F) == FIELD_DECL \
1345 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1346 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1348 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1351 field_decl = TREE_CHAIN (field_decl);
1352 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1355 field_decl = TREE_CHAIN (field_decl);
1356 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1358 #undef AT_LEAST_AS_LARGE_AS
1361 /* Avoid calling `check_string_class_template ()' more than once. */
1362 static GTY(()) int string_layout_checked;
1364 /* Custom build_string which sets TREE_TYPE! */
1367 my_build_string (int len, const char *str)
1369 return fix_string_type (build_string (len, str));
1372 /* Given a chain of STRING_CST's, build a static instance of
1373 NXConstantString which points at the concatenation of those
1374 strings. We place the string object in the __string_objects
1375 section of the __OBJC segment. The Objective-C runtime will
1376 initialize the isa pointers of the string objects to point at the
1377 NXConstantString class object. */
1380 build_objc_string_object (tree string)
1382 tree initlist, constructor, constant_string_class;
1386 string = fix_string_type (string);
1388 constant_string_class = lookup_interface (constant_string_id);
1389 if (!constant_string_class
1390 || !(constant_string_type
1391 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1393 error ("cannot find interface declaration for `%s'",
1394 IDENTIFIER_POINTER (constant_string_id));
1395 return error_mark_node;
1398 /* Call to 'combine_strings' has been moved above. */
1399 TREE_SET_CODE (string, STRING_CST);
1400 length = TREE_STRING_LENGTH (string) - 1;
1402 if (!string_layout_checked)
1404 /* The NSConstantString/NXConstantString ivar layout is now
1406 if (!check_string_class_template ())
1408 error ("interface `%s' does not have valid constant string layout",
1409 IDENTIFIER_POINTER (constant_string_id));
1410 return error_mark_node;
1412 add_class_reference (constant_string_id);
1414 fields = TYPE_FIELDS (constant_string_type);
1416 /* & ((NXConstantString) { NULL, string, length }) */
1418 if (flag_next_runtime)
1420 /* For the NeXT runtime, we can generate a literal reference
1421 to the string class, don't need to run a constructor. */
1422 setup_string_decl ();
1423 if (string_class_decl == NULL_TREE)
1425 error ("cannot find reference tag for class `%s'",
1426 IDENTIFIER_POINTER (constant_string_id));
1427 return error_mark_node;
1429 initlist = build_tree_list
1431 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1435 initlist = build_tree_list (fields, build_int_2 (0, 0));
1438 fields = TREE_CHAIN (fields);
1441 = tree_cons (fields, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1444 fields = TREE_CHAIN (fields);
1446 initlist = tree_cons (fields, build_int_2 (length, 0), initlist);
1447 constructor = objc_build_constructor (constant_string_type,
1448 nreverse (initlist));
1450 if (!flag_next_runtime)
1453 = objc_add_static_instance (constructor, constant_string_type);
1456 return (build_unary_op (ADDR_EXPR, constructor, 1));
1459 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1461 static GTY(()) int num_static_inst;
1464 objc_add_static_instance (tree constructor, tree class_decl)
1469 /* Find the list of static instances for the CLASS_DECL. Create one if
1471 for (chain = &objc_static_instances;
1472 *chain && TREE_VALUE (*chain) != class_decl;
1473 chain = &TREE_CHAIN (*chain));
1476 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1477 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1480 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1481 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1482 DECL_COMMON (decl) = 1;
1483 TREE_STATIC (decl) = 1;
1484 DECL_ARTIFICIAL (decl) = 1;
1485 DECL_INITIAL (decl) = constructor;
1487 /* We may be writing something else just now.
1488 Postpone till end of input. */
1489 DECL_DEFER_OUTPUT (decl) = 1;
1490 pushdecl_top_level (decl);
1491 rest_of_decl_compilation (decl, 0, 1, 0);
1493 /* Add the DECL to the head of this CLASS' list. */
1494 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1499 /* Build a static constant CONSTRUCTOR
1500 with type TYPE and elements ELTS. */
1503 objc_build_constructor (tree type, tree elts)
1505 tree constructor, f, e;
1507 /* ??? Most of the places that we build constructors, we don't fill in
1508 the type of integers properly. Convert them all en masse. */
1509 if (TREE_CODE (type) == ARRAY_TYPE)
1511 f = TREE_TYPE (type);
1512 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1513 for (e = elts; e ; e = TREE_CHAIN (e))
1514 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1518 f = TYPE_FIELDS (type);
1519 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1520 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1521 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1522 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1525 constructor = build_constructor (type, elts);
1526 TREE_CONSTANT (constructor) = 1;
1527 TREE_STATIC (constructor) = 1;
1528 TREE_READONLY (constructor) = 1;
1531 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1532 build_unary_op (wasn't true in 2.7.2.1 days) */
1533 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1538 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1540 /* Predefine the following data type:
1548 void *defs[cls_def_cnt + cat_def_cnt];
1552 build_objc_symtab_template (void)
1554 tree field_decl, field_decl_chain;
1556 objc_symtab_template
1557 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1559 /* long sel_ref_cnt; */
1561 field_decl = create_builtin_decl (FIELD_DECL,
1562 long_integer_type_node,
1564 field_decl_chain = field_decl;
1568 field_decl = create_builtin_decl (FIELD_DECL,
1569 build_pointer_type (selector_type),
1571 chainon (field_decl_chain, field_decl);
1573 /* short cls_def_cnt; */
1575 field_decl = create_builtin_decl (FIELD_DECL,
1576 short_integer_type_node,
1578 chainon (field_decl_chain, field_decl);
1580 /* short cat_def_cnt; */
1582 field_decl = create_builtin_decl (FIELD_DECL,
1583 short_integer_type_node,
1585 chainon (field_decl_chain, field_decl);
1587 if (imp_count || cat_count || !flag_next_runtime)
1589 /* void *defs[imp_count + cat_count (+ 1)]; */
1590 /* NB: The index is one less than the size of the array. */
1591 int index = imp_count + cat_count
1592 + (flag_next_runtime? -1: 0);
1593 field_decl = create_builtin_decl
1597 build_index_type (build_int_2 (index, 0))),
1599 chainon (field_decl_chain, field_decl);
1602 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1605 /* Create the initial value for the `defs' field of _objc_symtab.
1606 This is a CONSTRUCTOR. */
1609 init_def_list (tree type)
1611 tree expr, initlist = NULL_TREE;
1612 struct imp_entry *impent;
1615 for (impent = imp_list; impent; impent = impent->next)
1617 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1619 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1620 initlist = tree_cons (NULL_TREE, expr, initlist);
1625 for (impent = imp_list; impent; impent = impent->next)
1627 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1629 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1630 initlist = tree_cons (NULL_TREE, expr, initlist);
1634 if (!flag_next_runtime)
1636 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1639 if (static_instances_decl)
1640 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1642 expr = build_int_2 (0, 0);
1644 initlist = tree_cons (NULL_TREE, expr, initlist);
1647 return objc_build_constructor (type, nreverse (initlist));
1650 /* Construct the initial value for all of _objc_symtab. */
1653 init_objc_symtab (tree type)
1657 /* sel_ref_cnt = { ..., 5, ... } */
1659 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1661 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1663 if (flag_next_runtime || ! sel_ref_chain)
1664 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1666 initlist = tree_cons (NULL_TREE,
1667 build_unary_op (ADDR_EXPR,
1668 UOBJC_SELECTOR_TABLE_decl, 1),
1671 /* cls_def_cnt = { ..., 5, ... } */
1673 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1675 /* cat_def_cnt = { ..., 5, ... } */
1677 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1679 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1681 if (imp_count || cat_count || !flag_next_runtime)
1684 tree field = TYPE_FIELDS (type);
1685 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1687 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1691 return objc_build_constructor (type, nreverse (initlist));
1694 /* Generate forward declarations for metadata such as
1695 'OBJC_CLASS_...'. */
1698 build_metadata_decl (const char *name, tree type)
1700 tree decl, decl_specs;
1701 /* extern struct TYPE NAME_<name>; */
1702 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1703 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1704 decl = define_decl (synth_id_with_class_suffix
1706 objc_implementation_context),
1708 TREE_USED (decl) = 1;
1709 DECL_ARTIFICIAL (decl) = 1;
1710 TREE_PUBLIC (decl) = 0;
1714 /* Push forward-declarations of all the categories so that
1715 init_def_list can use them in a CONSTRUCTOR. */
1718 forward_declare_categories (void)
1720 struct imp_entry *impent;
1721 tree sav = objc_implementation_context;
1723 for (impent = imp_list; impent; impent = impent->next)
1725 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1727 /* Set an invisible arg to synth_id_with_class_suffix. */
1728 objc_implementation_context = impent->imp_context;
1729 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1730 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1731 objc_category_template);
1734 objc_implementation_context = sav;
1737 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1738 and initialized appropriately. */
1741 generate_objc_symtab_decl (void)
1745 if (!objc_category_template)
1746 build_category_template ();
1748 /* forward declare categories */
1750 forward_declare_categories ();
1752 if (!objc_symtab_template)
1753 build_objc_symtab_template ();
1755 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1757 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1758 tree_cons (NULL_TREE,
1759 objc_symtab_template, sc_spec),
1763 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1764 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1765 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1766 finish_decl (UOBJC_SYMBOLS_decl,
1767 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1772 init_module_descriptor (tree type)
1774 tree initlist, expr;
1776 /* version = { 1, ... } */
1778 expr = build_int_2 (OBJC_VERSION, 0);
1779 initlist = build_tree_list (NULL_TREE, expr);
1781 /* size = { ..., sizeof (struct objc_module), ... } */
1783 expr = size_in_bytes (objc_module_template);
1784 initlist = tree_cons (NULL_TREE, expr, initlist);
1786 /* name = { ..., "foo.m", ... } */
1788 expr = add_objc_string (get_identifier (input_filename), class_names);
1789 initlist = tree_cons (NULL_TREE, expr, initlist);
1791 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1793 if (UOBJC_SYMBOLS_decl)
1794 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1796 expr = build_int_2 (0, 0);
1797 initlist = tree_cons (NULL_TREE, expr, initlist);
1799 return objc_build_constructor (type, nreverse (initlist));
1802 /* Write out the data structures to describe Objective C classes defined.
1803 If appropriate, compile and output a setup function to initialize them.
1804 Return a symbol_ref to the function to call to initialize the Objective C
1805 data structures for this file (and perhaps for other files also).
1807 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1810 build_module_descriptor (void)
1812 tree decl_specs, field_decl, field_decl_chain;
1814 objc_module_template
1815 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1819 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1820 field_decl = get_identifier ("version");
1821 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1822 field_decl_chain = field_decl;
1826 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1827 field_decl = get_identifier ("size");
1828 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1829 chainon (field_decl_chain, field_decl);
1833 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1834 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1835 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1836 chainon (field_decl_chain, field_decl);
1838 /* struct objc_symtab *symtab; */
1840 decl_specs = get_identifier (UTAG_SYMTAB);
1841 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1842 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1843 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1844 chainon (field_decl_chain, field_decl);
1846 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1848 /* Create an instance of "objc_module". */
1850 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1851 build_tree_list (NULL_TREE,
1852 ridpointers[(int) RID_STATIC]));
1854 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1855 decl_specs, 1, NULL_TREE);
1857 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1858 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1859 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1861 finish_decl (UOBJC_MODULES_decl,
1862 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1865 /* Mark the decl to avoid "defined but not used" warning. */
1866 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1868 /* Generate a constructor call for the module descriptor.
1869 This code was generated by reading the grammar rules
1870 of c-parse.in; Therefore, it may not be the most efficient
1871 way of generating the requisite code. */
1873 if (flag_next_runtime)
1877 tree parms, execclass_decl, decelerator, void_list_node_1;
1878 tree init_function_name, init_function_decl;
1880 /* Declare void __objc_execClass (void *); */
1882 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1883 execclass_decl = build_decl (FUNCTION_DECL,
1884 get_identifier (TAG_EXECCLASS),
1885 build_function_type (void_type_node,
1886 tree_cons (NULL_TREE, ptr_type_node,
1889 DECL_EXTERNAL (execclass_decl) = 1;
1890 DECL_ARTIFICIAL (execclass_decl) = 1;
1891 TREE_PUBLIC (execclass_decl) = 1;
1892 pushdecl (execclass_decl);
1893 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1894 assemble_external (execclass_decl);
1896 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1898 init_function_name = get_file_function_name ('I');
1899 start_function (void_list_node_1,
1900 build_nt (CALL_EXPR, init_function_name,
1901 tree_cons (NULL_TREE, NULL_TREE,
1905 store_parm_decls ();
1907 init_function_decl = current_function_decl;
1908 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1909 TREE_USED (init_function_decl) = 1;
1910 /* Don't let this one be deferred. */
1911 DECL_INLINE (init_function_decl) = 0;
1912 DECL_UNINLINABLE (init_function_decl) = 1;
1913 current_function_cannot_inline
1914 = "static constructors and destructors cannot be inlined";
1917 = build_tree_list (NULL_TREE,
1918 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1919 decelerator = build_function_call (execclass_decl, parms);
1921 c_expand_expr_stmt (decelerator);
1925 return XEXP (DECL_RTL (init_function_decl), 0);
1929 /* Return the DECL of the string IDENT in the SECTION. */
1932 get_objc_string_decl (tree ident, enum string_section section)
1936 if (section == class_names)
1937 chain = class_names_chain;
1938 else if (section == meth_var_names)
1939 chain = meth_var_names_chain;
1940 else if (section == meth_var_types)
1941 chain = meth_var_types_chain;
1945 for (; chain != 0; chain = TREE_CHAIN (chain))
1946 if (TREE_VALUE (chain) == ident)
1947 return (TREE_PURPOSE (chain));
1953 /* Output references to all statically allocated objects. Return the DECL
1954 for the array built. */
1957 generate_static_references (void)
1959 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1960 tree class_name, class, decl, initlist;
1961 tree cl_chain, in_chain, type;
1962 int num_inst, num_class;
1965 if (flag_next_runtime)
1968 for (cl_chain = objc_static_instances, num_class = 0;
1969 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1971 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1972 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1974 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1975 ident = get_identifier (buf);
1977 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1978 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1979 build_tree_list (NULL_TREE,
1980 ridpointers[(int) RID_STATIC]));
1981 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1982 DECL_CONTEXT (decl) = 0;
1983 DECL_ARTIFICIAL (decl) = 1;
1985 /* Output {class_name, ...}. */
1986 class = TREE_VALUE (cl_chain);
1987 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
1988 initlist = build_tree_list (NULL_TREE,
1989 build_unary_op (ADDR_EXPR, class_name, 1));
1991 /* Output {..., instance, ...}. */
1992 for (in_chain = TREE_PURPOSE (cl_chain);
1993 in_chain; in_chain = TREE_CHAIN (in_chain))
1995 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1996 initlist = tree_cons (NULL_TREE, expr, initlist);
1999 /* Output {..., NULL}. */
2000 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2002 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2003 finish_decl (decl, expr, NULL_TREE);
2004 TREE_USED (decl) = 1;
2006 type = build_array_type (build_pointer_type (void_type_node), 0);
2007 decl = build_decl (VAR_DECL, ident, type);
2008 TREE_USED (decl) = 1;
2009 TREE_STATIC (decl) = 1;
2011 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2014 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2015 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2016 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2017 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2018 build_tree_list (NULL_TREE,
2019 ridpointers[(int) RID_STATIC]));
2020 static_instances_decl
2021 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2022 TREE_USED (static_instances_decl) = 1;
2023 DECL_CONTEXT (static_instances_decl) = 0;
2024 DECL_ARTIFICIAL (static_instances_decl) = 1;
2025 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2027 finish_decl (static_instances_decl, expr, NULL_TREE);
2030 /* Output all strings. */
2033 generate_strings (void)
2035 tree sc_spec, decl_specs, expr_decl;
2036 tree chain, string_expr;
2039 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2041 string = TREE_VALUE (chain);
2042 decl = TREE_PURPOSE (chain);
2044 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2045 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2046 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2047 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2048 DECL_CONTEXT (decl) = NULL_TREE;
2049 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2050 IDENTIFIER_POINTER (string));
2051 finish_decl (decl, string_expr, NULL_TREE);
2054 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2056 string = TREE_VALUE (chain);
2057 decl = TREE_PURPOSE (chain);
2059 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2060 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2061 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2062 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2063 DECL_CONTEXT (decl) = NULL_TREE;
2064 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2065 IDENTIFIER_POINTER (string));
2066 finish_decl (decl, string_expr, NULL_TREE);
2069 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2071 string = TREE_VALUE (chain);
2072 decl = TREE_PURPOSE (chain);
2074 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2075 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2076 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2077 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2078 DECL_CONTEXT (decl) = NULL_TREE;
2079 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2080 IDENTIFIER_POINTER (string));
2081 finish_decl (decl, string_expr, NULL_TREE);
2085 static GTY(()) int selector_reference_idx;
2088 build_selector_reference_decl (void)
2093 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2095 ident = get_identifier (buf);
2097 decl = build_decl (VAR_DECL, ident, selector_type);
2098 DECL_EXTERNAL (decl) = 1;
2099 TREE_PUBLIC (decl) = 0;
2100 TREE_USED (decl) = 1;
2101 DECL_ARTIFICIAL (decl) = 1;
2102 DECL_CONTEXT (decl) = 0;
2104 make_decl_rtl (decl, 0);
2105 pushdecl_top_level (decl);
2110 /* Just a handy wrapper for add_objc_string. */
2113 build_selector (tree ident)
2115 tree expr = add_objc_string (ident, meth_var_names);
2116 if (flag_typed_selectors)
2119 return build_c_cast (selector_type, expr); /* cast! */
2123 build_selector_translation_table (void)
2125 tree sc_spec, decl_specs;
2126 tree chain, initlist = NULL_TREE;
2128 tree decl = NULL_TREE, var_decl, name;
2130 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2134 if (warn_selector && objc_implementation_context)
2138 for (method_chain = meth_var_names_chain;
2140 method_chain = TREE_CHAIN (method_chain))
2142 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2150 /* Adjust line number for warning message. */
2151 int save_lineno = input_line;
2152 if (flag_next_runtime && TREE_PURPOSE (chain))
2153 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2154 warning ("creating selector for non existant method %s",
2155 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2156 input_line = save_lineno;
2160 expr = build_selector (TREE_VALUE (chain));
2162 if (flag_next_runtime)
2164 name = DECL_NAME (TREE_PURPOSE (chain));
2166 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2168 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2169 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2173 /* The `decl' that is returned from start_decl is the one that we
2174 forward declared in `build_selector_reference' */
2175 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2178 /* add one for the '\0' character */
2179 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2181 if (flag_next_runtime)
2182 finish_decl (decl, expr, NULL_TREE);
2185 if (flag_typed_selectors)
2187 tree eltlist = NULL_TREE;
2188 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2189 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2190 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2191 expr = objc_build_constructor (objc_selector_template,
2192 nreverse (eltlist));
2194 initlist = tree_cons (NULL_TREE, expr, initlist);
2199 if (! flag_next_runtime)
2201 /* Cause the variable and its initial value to be actually output. */
2202 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2203 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2204 /* NULL terminate the list and fix the decl for output. */
2205 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2206 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2207 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2208 nreverse (initlist));
2209 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2210 current_function_decl = NULL_TREE;
2215 get_proto_encoding (tree proto)
2220 if (! METHOD_ENCODING (proto))
2222 encoding = encode_method_prototype (proto);
2223 METHOD_ENCODING (proto) = encoding;
2226 encoding = METHOD_ENCODING (proto);
2228 return add_objc_string (encoding, meth_var_types);
2231 return build_int_2 (0, 0);
2234 /* sel_ref_chain is a list whose "value" fields will be instances of
2235 identifier_node that represent the selector. */
2238 build_typed_selector_reference (tree ident, tree prototype)
2240 tree *chain = &sel_ref_chain;
2246 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2247 goto return_at_index;
2250 chain = &TREE_CHAIN (*chain);
2253 *chain = tree_cons (prototype, ident, NULL_TREE);
2256 expr = build_unary_op (ADDR_EXPR,
2257 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2258 build_int_2 (index, 0)),
2260 return build_c_cast (selector_type, expr);
2264 build_selector_reference (tree ident)
2266 tree *chain = &sel_ref_chain;
2272 if (TREE_VALUE (*chain) == ident)
2273 return (flag_next_runtime
2274 ? TREE_PURPOSE (*chain)
2275 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2276 build_int_2 (index, 0)));
2279 chain = &TREE_CHAIN (*chain);
2282 expr = build_selector_reference_decl ();
2284 *chain = tree_cons (expr, ident, NULL_TREE);
2286 return (flag_next_runtime
2288 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2289 build_int_2 (index, 0)));
2292 static GTY(()) int class_reference_idx;
2295 build_class_reference_decl (void)
2300 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2302 ident = get_identifier (buf);
2304 decl = build_decl (VAR_DECL, ident, objc_class_type);
2305 DECL_EXTERNAL (decl) = 1;
2306 TREE_PUBLIC (decl) = 0;
2307 TREE_USED (decl) = 1;
2308 DECL_CONTEXT (decl) = 0;
2309 DECL_ARTIFICIAL (decl) = 1;
2311 make_decl_rtl (decl, 0);
2312 pushdecl_top_level (decl);
2317 /* Create a class reference, but don't create a variable to reference
2321 add_class_reference (tree ident)
2325 if ((chain = cls_ref_chain))
2330 if (ident == TREE_VALUE (chain))
2334 chain = TREE_CHAIN (chain);
2338 /* Append to the end of the list */
2339 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2342 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2345 /* Get a class reference, creating it if necessary. Also create the
2346 reference variable. */
2349 get_class_reference (tree ident)
2354 if (processing_template_decl)
2355 /* Must wait until template instantiation time. */
2356 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2357 if (TREE_CODE (ident) == TYPE_DECL)
2358 ident = DECL_NAME (ident);
2362 if (!(ident = is_class_name (ident)))
2364 error ("`%s' is not an Objective-C class name or alias",
2365 IDENTIFIER_POINTER (orig_ident));
2366 return error_mark_node;
2369 if (flag_next_runtime && !flag_zero_link)
2374 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2375 if (TREE_VALUE (*chain) == ident)
2377 if (! TREE_PURPOSE (*chain))
2378 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2380 return TREE_PURPOSE (*chain);
2383 decl = build_class_reference_decl ();
2384 *chain = tree_cons (decl, ident, NULL_TREE);
2391 add_class_reference (ident);
2393 params = build_tree_list (NULL_TREE,
2394 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2395 IDENTIFIER_POINTER (ident)));
2397 assemble_external (objc_get_class_decl);
2398 return build_function_call (objc_get_class_decl, params);
2402 /* For each string section we have a chain which maps identifier nodes
2403 to decls for the strings. */
2406 add_objc_string (tree ident, enum string_section section)
2410 if (section == class_names)
2411 chain = &class_names_chain;
2412 else if (section == meth_var_names)
2413 chain = &meth_var_names_chain;
2414 else if (section == meth_var_types)
2415 chain = &meth_var_types_chain;
2421 if (TREE_VALUE (*chain) == ident)
2422 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2424 chain = &TREE_CHAIN (*chain);
2427 decl = build_objc_string_decl (section);
2429 *chain = tree_cons (decl, ident, NULL_TREE);
2431 return build_unary_op (ADDR_EXPR, decl, 1);
2434 static GTY(()) int class_names_idx;
2435 static GTY(()) int meth_var_names_idx;
2436 static GTY(()) int meth_var_types_idx;
2439 build_objc_string_decl (enum string_section section)
2444 if (section == class_names)
2445 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2446 else if (section == meth_var_names)
2447 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2448 else if (section == meth_var_types)
2449 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2451 ident = get_identifier (buf);
2453 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2454 DECL_EXTERNAL (decl) = 1;
2455 TREE_PUBLIC (decl) = 0;
2456 TREE_USED (decl) = 1;
2457 TREE_CONSTANT (decl) = 1;
2458 DECL_CONTEXT (decl) = 0;
2459 DECL_ARTIFICIAL (decl) = 1;
2461 make_decl_rtl (decl, 0);
2462 pushdecl_top_level (decl);
2469 objc_declare_alias (tree alias_ident, tree class_ident)
2471 tree underlying_class;
2474 if (current_namespace != global_namespace) {
2475 error ("Objective-C declarations may only appear in global scope");
2477 #endif /* OBJCPLUS */
2479 if (!(underlying_class = is_class_name (class_ident)))
2480 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2481 else if (is_class_name (alias_ident))
2482 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2484 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2488 objc_declare_class (tree ident_list)
2492 if (current_namespace != global_namespace) {
2493 error ("Objective-C declarations may only appear in global scope");
2495 #endif /* OBJCPLUS */
2497 for (list = ident_list; list; list = TREE_CHAIN (list))
2499 tree ident = TREE_VALUE (list);
2501 if (! is_class_name (ident))
2503 tree record = lookup_name (ident);
2505 if (record && ! TREE_STATIC_TEMPLATE (record))
2507 error ("`%s' redeclared as different kind of symbol",
2508 IDENTIFIER_POINTER (ident));
2509 error ("%Jprevious declaration of '%D'",
2513 record = xref_tag (RECORD_TYPE, ident);
2514 TREE_STATIC_TEMPLATE (record) = 1;
2515 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2521 is_class_name (tree ident)
2525 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2526 && identifier_global_value (ident))
2527 ident = identifier_global_value (ident);
2528 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2529 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2532 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2533 ident = TYPE_NAME (ident);
2534 if (ident && TREE_CODE (ident) == TYPE_DECL)
2535 ident = DECL_NAME (ident);
2537 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2540 if (lookup_interface (ident))
2543 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2545 if (ident == TREE_VALUE (chain))
2549 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2551 if (ident == TREE_VALUE (chain))
2552 return TREE_PURPOSE (chain);
2558 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2559 class instance. This is needed by other parts of the compiler to
2560 handle ObjC types gracefully. */
2563 objc_is_object_ptr (tree type)
2565 type = TYPE_MAIN_VARIANT (type);
2566 if (!type || TREE_CODE (type) != POINTER_TYPE)
2568 /* NB: This function may be called before the ObjC front-end has
2569 been initialized, in which case ID_TYPE will be NULL. */
2570 if (id_type && type && TYPE_P (type)
2572 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2574 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2578 lookup_interface (tree ident)
2583 if (ident && TREE_CODE (ident) == TYPE_DECL)
2584 ident = DECL_NAME (ident);
2586 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2588 if (ident == CLASS_NAME (chain))
2594 /* Implement @defs (<classname>) within struct bodies. */
2597 get_class_ivars_from_name (tree class_name)
2599 tree interface = lookup_interface (class_name);
2600 tree field, fields = NULL_TREE;
2604 tree raw_ivar = get_class_ivars (interface, 1);
2606 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2607 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2609 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2610 TREE_PURPOSE (raw_ivar),
2611 TREE_VALUE (TREE_VALUE (raw_ivar)));
2613 finish_member_declaration (field);
2615 fields = chainon (fields, field);
2620 error ("cannot find interface declaration for `%s'",
2621 IDENTIFIER_POINTER (class_name));
2626 /* Used by: build_private_template, continue_class,
2627 and for @defs constructs. */
2630 get_class_ivars (tree interface, int raw)
2632 tree my_name, super_name, ivar_chain;
2634 my_name = CLASS_NAME (interface);
2635 super_name = CLASS_SUPER_NAME (interface);
2637 ivar_chain = CLASS_RAW_IVARS (interface);
2640 ivar_chain = CLASS_IVARS (interface);
2641 /* Save off a pristine copy of the leaf ivars (i.e, those not
2642 inherited from a super class). */
2643 if (!CLASS_OWN_IVARS (interface))
2644 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2650 tree super_interface = lookup_interface (super_name);
2652 if (!super_interface)
2654 /* fatal did not work with 2 args...should fix */
2655 error ("cannot find interface declaration for `%s', superclass of `%s'",
2656 IDENTIFIER_POINTER (super_name),
2657 IDENTIFIER_POINTER (my_name));
2658 exit (FATAL_EXIT_CODE);
2661 if (super_interface == interface)
2662 fatal_error ("circular inheritance in interface declaration for `%s'",
2663 IDENTIFIER_POINTER (super_name));
2665 interface = super_interface;
2666 my_name = CLASS_NAME (interface);
2667 super_name = CLASS_SUPER_NAME (interface);
2669 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2672 tree head = copy_list (op1);
2674 /* Prepend super class ivars...make a copy of the list, we
2675 do not want to alter the original. */
2676 chainon (head, ivar_chain);
2685 objc_enter_block (void)
2690 block = begin_compound_stmt (0);
2692 block = c_begin_compound_stmt ();
2695 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
2698 objc_exception_block_stack = tree_cons (NULL_TREE, block,
2699 objc_exception_block_stack);
2701 blk_nesting_count++;
2706 objc_exit_block (void)
2708 tree block = TREE_VALUE (objc_exception_block_stack);
2710 tree scope_stmt, inner;
2713 objc_clear_super_receiver ();
2715 finish_compound_stmt (0, block);
2717 scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
2718 inner = pop_scope ();
2720 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
2721 = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
2723 RECHAIN_STMTS (block, COMPOUND_BODY (block));
2725 last_expr_type = NULL_TREE;
2726 objc_exception_block_stack = TREE_CHAIN (objc_exception_block_stack);
2728 blk_nesting_count--;
2733 objc_declare_variable (enum rid scspec, tree name, tree type, tree init)
2737 type = tree_cons (NULL_TREE, type,
2738 tree_cons (NULL_TREE, ridpointers[(int) scspec],
2740 TREE_STATIC (type) = 1;
2741 decl = start_decl (name, type, (init != NULL_TREE), NULL_TREE);
2742 finish_decl (decl, init, NULL_TREE);
2743 /* This prevents `unused variable' warnings when compiling with -Wall. */
2744 TREE_USED (decl) = 1;
2745 DECL_ARTIFICIAL (decl) = 1;
2750 objc_build_throw_stmt (tree throw_expr)
2754 if (!flag_objc_exceptions)
2755 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2757 if (!throw_expr && objc_caught_exception)
2758 throw_expr = TREE_VALUE (objc_caught_exception);
2762 error ("`@throw;' (rethrow) used outside of a `@catch' block");
2763 return error_mark_node;
2766 func_params = tree_cons (NULL_TREE, throw_expr, NULL_TREE);
2768 assemble_external (objc_exception_throw_decl);
2769 return c_expand_expr_stmt (build_function_call (objc_exception_throw_decl,
2774 val_stack_push (struct val_stack **nc, long val)
2776 struct val_stack *new_elem = xmalloc (sizeof (struct val_stack));
2777 new_elem->val = val;
2778 new_elem->next = *nc;
2783 val_stack_pop (struct val_stack **nc)
2785 struct val_stack *old_elem = *nc;
2786 *nc = old_elem->next;
2791 objc_build_try_enter_fragment (void)
2793 /* objc_exception_try_enter(&_stackExceptionData);
2794 if (!_setjmp(&_stackExceptionData.buf)) { */
2796 tree func_params, if_stmt, cond;
2799 = tree_cons (NULL_TREE,
2800 build_unary_op (ADDR_EXPR,
2801 TREE_VALUE (objc_stack_exception_data),
2805 assemble_external (objc_exception_try_enter_decl);
2806 c_expand_expr_stmt (build_function_call
2807 (objc_exception_try_enter_decl, func_params));
2809 if_stmt = c_begin_if_stmt ();
2811 /* If <setjmp.h> has been included, the _setjmp prototype has
2812 acquired a real, breathing type for its parameter. Cast our
2813 argument to that type. */
2815 = tree_cons (NULL_TREE,
2816 build_c_cast (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))
2817 ? TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
2821 build_component_ref (TREE_VALUE (objc_stack_exception_data),
2822 get_identifier ("buf")), 0)),
2824 assemble_external (objc_setjmp_decl);
2825 cond = build_unary_op (TRUTH_NOT_EXPR,
2826 build_function_call (objc_setjmp_decl, func_params),
2828 c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (cond),
2830 objc_enter_block ();
2834 objc_build_extract_expr (void)
2836 /* ... = objc_exception_extract(&_stackExceptionData); */
2839 = tree_cons (NULL_TREE,
2840 build_unary_op (ADDR_EXPR,
2841 TREE_VALUE (objc_stack_exception_data), 0),
2844 assemble_external (objc_exception_extract_decl);
2845 return build_function_call (objc_exception_extract_decl, func_params);
2849 objc_build_try_exit_fragment (void)
2851 /* objc_exception_try_exit(&_stackExceptionData); */
2854 = tree_cons (NULL_TREE,
2855 build_unary_op (ADDR_EXPR,
2856 TREE_VALUE (objc_stack_exception_data), 0),
2859 assemble_external (objc_exception_try_exit_decl);
2860 c_expand_expr_stmt (build_function_call (objc_exception_try_exit_decl,
2865 objc_build_extract_fragment (void)
2868 _rethrowException = objc_exception_extract(&_stackExceptionData);
2874 c_expand_start_else ();
2875 objc_enter_block ();
2876 c_expand_expr_stmt (build_modify_expr
2877 (TREE_VALUE (objc_rethrow_exception),
2879 objc_build_extract_expr ()));
2882 c_expand_end_cond ();
2887 objc_build_try_prologue (void)
2890 struct _objc_exception_data _stackExceptionData;
2891 volatile id _rethrowException = nil;
2892 { // begin TRY-CATCH scope
2893 objc_exception_try_enter(&_stackExceptionData);
2894 if (!_setjmp(&_stackExceptionData.buf)) { */
2896 tree try_catch_block;
2898 if (!flag_objc_exceptions)
2899 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2901 objc_mark_locals_volatile ((void *)(exc_binding_stack
2902 ? exc_binding_stack->val
2904 objc_enter_block ();
2905 objc_stack_exception_data
2906 = tree_cons (NULL_TREE,
2907 objc_declare_variable (RID_AUTO,
2908 get_identifier (UTAG_EXCDATA_VAR),
2909 xref_tag (RECORD_TYPE,
2910 get_identifier (UTAG_EXCDATA)),
2912 objc_stack_exception_data);
2913 objc_rethrow_exception = tree_cons (NULL_TREE,
2914 objc_declare_variable (RID_VOLATILE,
2915 get_identifier (UTAG_RETHROWEXC_VAR),
2917 build_int_2 (0, 0)),
2918 objc_rethrow_exception);
2920 try_catch_block = objc_enter_block ();
2921 val_stack_push (&exc_binding_stack, (long) get_current_scope ());
2922 objc_build_try_enter_fragment ();
2924 return try_catch_block;
2928 objc_build_try_epilogue (int also_catch_prologue)
2930 if (also_catch_prologue)
2933 register id _caughtException = objc_exception_extract( &_stackExceptionData);
2934 objc_exception_try_enter(&_stackExceptionData);
2935 if(!_setjmp(&_stackExceptionData.buf)) {
2943 c_expand_start_else ();
2944 objc_enter_block ();
2945 objc_caught_exception
2946 = tree_cons (NULL_TREE,
2947 objc_declare_variable (RID_REGISTER,
2948 get_identifier (UTAG_CAUGHTEXC_VAR),
2950 objc_build_extract_expr ()),
2951 objc_caught_exception);
2952 objc_build_try_enter_fragment ();
2953 val_stack_push (&catch_count_stack, 1);
2954 if_stmt = c_begin_if_stmt ();
2956 c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (boolean_false_node),
2958 objc_enter_block ();
2960 /* Start a new chain of @catch statements for this @try. */
2961 objc_catch_type = tree_cons (objc_catch_type, NULL_TREE, NULL_TREE);
2964 { /* !also_catch_prologue */
2967 _rethrowException = objc_exception_extract( &_stackExceptionData);
2970 objc_build_extract_fragment ();
2976 objc_build_catch_stmt (tree catch_expr)
2978 /* } else if (objc_exception_match(objc_get_class("SomeClass"), _caughtException)) {
2979 register SomeClass *e = _caughtException; */
2981 tree if_stmt, cond, func_params, prev_catch, var_name, var_type;
2985 /* Yet another C/C++ impedance mismatch. */
2986 catch_expr = TREE_PURPOSE (catch_expr);
2989 var_name = TREE_VALUE (catch_expr);
2990 var_type = TREE_VALUE (TREE_PURPOSE (catch_expr));
2991 if (TREE_CODE (var_name) == INDIRECT_REF)
2992 var_name = TREE_OPERAND (var_name, 0);
2993 if (TREE_CODE (var_type) == TYPE_DECL
2994 || TREE_CODE (var_type) == POINTER_TYPE)
2995 var_type = TREE_TYPE (var_type);
2996 catch_id = (var_type == TREE_TYPE (id_type));
2998 if (!flag_objc_exceptions)
2999 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3001 if (!(catch_id || TYPED_OBJECT (var_type)))
3002 fatal_error ("`@catch' parameter is not a known Objective-C class type");
3004 /* Examine previous @catch clauses for the current @try block for
3005 superclasses of the 'var_type' class. */
3006 for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch);
3007 prev_catch = TREE_CHAIN (prev_catch))
3009 if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
3011 warning ("Exception already handled by preceding `@catch(id)'");
3015 && objc_comptypes (TREE_VALUE (prev_catch), var_type, 0) == 1)
3016 warning ("Exception of type `%s *' already handled by `@catch (%s *)'",
3017 IDENTIFIER_POINTER (OBJC_TYPE_NAME (var_type)),
3018 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_VALUE (prev_catch))));
3021 objc_catch_type = tree_cons (NULL_TREE, var_type, objc_catch_type);
3026 c_expand_start_else ();
3027 catch_count_stack->val++;
3028 if_stmt = c_begin_if_stmt ();
3032 cond = integer_one_node;
3035 cond = get_class_reference (OBJC_TYPE_NAME (var_type));
3038 = tree_cons (NULL_TREE, cond,
3039 tree_cons (NULL_TREE,
3040 TREE_VALUE (objc_caught_exception),
3042 assemble_external (objc_exception_match_decl);
3043 cond = build_function_call (objc_exception_match_decl, func_params);
3046 c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (cond),
3048 objc_enter_block ();
3049 objc_declare_variable (RID_REGISTER, var_name,
3050 build_pointer_type (var_type),
3051 TREE_VALUE (objc_caught_exception));
3055 objc_build_catch_epilogue (void)
3058 _rethrowException = _caughtException;
3059 objc_exception_try_exit(&_stackExceptionData);
3062 _rethrowException = objc_exception_extract(&_stackExceptionData);
3065 } // end TRY-CATCH scope
3071 c_expand_start_else ();
3072 objc_enter_block ();
3075 (TREE_VALUE (objc_rethrow_exception),
3077 TREE_VALUE (objc_caught_exception)));
3078 objc_build_try_exit_fragment ();
3080 while (catch_count_stack->val--)
3082 c_finish_else (); /* close off all the nested ifs ! */
3083 c_expand_end_cond ();
3086 val_stack_pop (&catch_count_stack);
3087 objc_caught_exception = TREE_CHAIN (objc_caught_exception);
3089 objc_build_extract_fragment ();
3093 c_expand_end_cond ();
3097 /* Return to enclosing chain of @catch statements (if any). */
3098 while (TREE_VALUE (objc_catch_type))
3099 objc_catch_type = TREE_CHAIN (objc_catch_type);
3100 objc_catch_type = TREE_PURPOSE (objc_catch_type);
3104 objc_build_finally_prologue (void)
3106 /* { // begin FINALLY scope
3107 if (!_rethrowException) {
3108 objc_exception_try_exit(&_stackExceptionData);
3111 tree blk = objc_enter_block ();
3113 tree if_stmt = c_begin_if_stmt ();
3116 c_expand_start_cond ((*lang_hooks.truthvalue_conversion)
3119 TREE_VALUE (objc_rethrow_exception), 0)),
3121 objc_enter_block ();
3122 objc_build_try_exit_fragment ();
3125 c_expand_end_cond ();
3132 objc_build_finally_epilogue (void)
3134 /* if (_rethrowException) {
3135 objc_exception_throw(_rethrowException);
3137 } // end FINALLY scope
3140 tree if_stmt = c_begin_if_stmt ();
3144 ((*lang_hooks.truthvalue_conversion) (TREE_VALUE (objc_rethrow_exception)),
3146 objc_enter_block ();
3147 objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception));
3150 c_expand_end_cond ();
3154 objc_rethrow_exception = TREE_CHAIN (objc_rethrow_exception);
3155 objc_stack_exception_data = TREE_CHAIN (objc_stack_exception_data);
3157 val_stack_pop (&exc_binding_stack);
3158 return objc_exit_block ();
3162 objc_build_try_catch_finally_stmt (int has_catch, int has_finally)
3164 /* NB: The operative assumption here is that TRY_FINALLY_EXPR will
3165 deal with all exits from 'try_catch_blk' and route them through
3167 tree outer_blk = objc_build_finally_epilogue ();
3168 tree prec_stmt = TREE_CHAIN (TREE_CHAIN (COMPOUND_BODY (outer_blk)));
3169 tree try_catch_blk = TREE_CHAIN (prec_stmt), try_catch_expr;
3170 tree finally_blk = TREE_CHAIN (try_catch_blk), finally_expr;
3171 tree succ_stmt = TREE_CHAIN (finally_blk);
3172 tree try_finally_stmt, try_finally_expr;
3174 if (!flag_objc_exceptions)
3175 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3177 /* It is an error to have a @try block without a @catch and/or @finally
3178 (even though sensible code can be generated nonetheless). */
3180 if (!has_catch && !has_finally)
3181 error ("`@try' without `@catch' or `@finally'");
3183 /* We shall now do something truly disgusting. We shall remove the
3184 'try_catch_blk' and 'finally_blk' from the 'outer_blk' statement
3185 chain, and replace them with a TRY_FINALLY_EXPR statement! If
3186 this doesn't work, we will have to learn (from Per/gcj) how to
3187 construct the 'outer_blk' lazily. */
3189 TREE_CHAIN (try_catch_blk) = TREE_CHAIN (finally_blk) = NULL_TREE;
3190 try_catch_expr = build1 (STMT_EXPR, void_type_node, try_catch_blk);
3191 TREE_SIDE_EFFECTS (try_catch_expr) = 1;
3192 finally_expr = build1 (STMT_EXPR, void_type_node, finally_blk);
3193 TREE_SIDE_EFFECTS (finally_expr) = 1;
3194 try_finally_expr = build (TRY_FINALLY_EXPR, void_type_node, try_catch_expr,
3196 TREE_SIDE_EFFECTS (try_finally_expr) = 1;
3197 try_finally_stmt = build_stmt (EXPR_STMT, try_finally_expr);
3198 TREE_CHAIN (prec_stmt) = try_finally_stmt;
3199 TREE_CHAIN (try_finally_stmt) = succ_stmt;
3201 return outer_blk; /* the whole enchilada */
3205 objc_build_synchronized_prologue (tree sync_expr)
3208 id _eval_once = <sync_expr>;
3210 objc_sync_enter( _eval_once ); */
3214 if (!flag_objc_exceptions)
3215 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3217 objc_enter_block ();
3219 = tree_cons (NULL_TREE,
3220 objc_declare_variable (RID_AUTO,
3221 get_identifier (UTAG_EVALONCE_VAR),
3225 objc_build_try_prologue ();
3226 objc_enter_block ();
3227 func_params = tree_cons (NULL_TREE,
3228 TREE_VALUE (objc_eval_once),
3231 assemble_external (objc_sync_enter_decl);
3232 c_expand_expr_stmt (build_function_call
3233 (objc_sync_enter_decl, func_params));
3237 objc_build_synchronized_epilogue (void)
3241 objc_sync_exit( _eval_once );
3248 objc_build_try_epilogue (0);
3249 objc_build_finally_prologue ();
3250 func_params = tree_cons (NULL_TREE, TREE_VALUE (objc_eval_once),
3253 assemble_external (objc_sync_exit_decl);
3254 c_expand_expr_stmt (build_function_call (objc_sync_exit_decl,
3256 objc_build_try_catch_finally_stmt (0, 1);
3258 return objc_exit_block ();
3261 /* Predefine the following data type:
3263 struct _objc_exception_data
3269 /* The following yuckiness should prevent users from having to #include
3270 <setjmp.h> in their code... */
3272 #ifdef TARGET_POWERPC
3273 /* snarfed from /usr/include/ppc/setjmp.h */
3274 #define _JBLEN (26 + 36 + 129 + 1)
3276 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3281 build_objc_exception_stuff (void)
3283 tree field_decl, field_decl_chain, index, temp_type;
3285 /* Suppress outputting debug symbols, because
3286 dbxout_init hasn't been called yet. */
3287 enum debug_info_type save_write_symbols = write_symbols;
3288 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3290 write_symbols = NO_DEBUG;
3291 debug_hooks = &do_nothing_debug_hooks;
3292 objc_exception_data_template
3293 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3295 /* int buf[_JBLEN]; */
3297 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3298 field_decl = create_builtin_decl (FIELD_DECL,
3299 build_array_type (integer_type_node, index),
3301 field_decl_chain = field_decl;
3303 /* void *pointers[4]; */
3305 index = build_index_type (build_int_2 (4 - 1, 0));
3306 field_decl = create_builtin_decl (FIELD_DECL,
3307 build_array_type (ptr_type_node, index),
3309 chainon (field_decl_chain, field_decl);
3311 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3313 /* int _setjmp(...); */
3314 /* If the user includes <setjmp.h>, this shall be superseded by
3315 'int _setjmp(jmp_buf);' */
3316 temp_type = build_function_type (integer_type_node, NULL_TREE);
3318 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3320 /* id objc_exception_extract(struct _objc_exception_data *); */
3322 = build_function_type (id_type,
3323 tree_cons (NULL_TREE,
3324 build_pointer_type (objc_exception_data_template),
3326 objc_exception_extract_decl
3327 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3328 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3329 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3331 = build_function_type (void_type_node,
3332 tree_cons (NULL_TREE,
3333 build_pointer_type (objc_exception_data_template),
3335 objc_exception_try_enter_decl
3336 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3337 objc_exception_try_exit_decl
3338 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3339 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3340 /* void objc_sync_enter(id); */
3341 /* void objc_sync_exit(id); */
3342 temp_type = build_function_type (void_type_node,
3343 tree_cons (NULL_TREE, id_type,
3345 objc_exception_throw_decl
3346 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3347 DECL_ATTRIBUTES (objc_exception_throw_decl)
3348 = tree_cons (get_identifier ("noreturn"), NULL_TREE, NULL_TREE);
3349 objc_sync_enter_decl
3350 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3352 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3353 /* int objc_exception_match(id, id); */
3354 temp_type = build_function_type (integer_type_node,
3355 tree_cons (NULL_TREE, id_type,
3356 tree_cons (NULL_TREE, id_type,
3358 objc_exception_match_decl
3359 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3361 write_symbols = save_write_symbols;
3362 debug_hooks = save_hooks;
3365 /* struct <classname> {
3366 struct objc_class *isa;
3371 build_private_template (tree class)
3375 if (CLASS_STATIC_TEMPLATE (class))
3377 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3378 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3382 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3383 ivar_context = get_class_ivars (class, 0);
3385 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3387 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3389 /* mark this record as class template - for class type checking */
3390 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3394 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3396 build1 (INDIRECT_REF, NULL_TREE,
3399 return ivar_context;
3402 /* Begin code generation for protocols... */
3404 /* struct objc_protocol {
3405 char *protocol_name;
3406 struct objc_protocol **protocol_list;
3407 struct objc_method_desc *instance_methods;
3408 struct objc_method_desc *class_methods;
3412 build_protocol_template (void)
3414 tree decl_specs, field_decl, field_decl_chain;
3417 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3419 /* struct objc_class *isa; */
3421 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3422 get_identifier (UTAG_CLASS)));
3423 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3424 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3425 field_decl_chain = field_decl;
3427 /* char *protocol_name; */
3429 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3431 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3432 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3433 chainon (field_decl_chain, field_decl);
3435 /* struct objc_protocol **protocol_list; */
3437 decl_specs = build_tree_list (NULL_TREE, template);
3439 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3440 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3441 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3442 chainon (field_decl_chain, field_decl);
3444 /* struct objc_method_list *instance_methods; */
3447 = build_tree_list (NULL_TREE,
3448 xref_tag (RECORD_TYPE,
3449 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3451 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3452 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3453 chainon (field_decl_chain, field_decl);
3455 /* struct objc_method_list *class_methods; */
3458 = build_tree_list (NULL_TREE,
3459 xref_tag (RECORD_TYPE,
3460 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3462 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3463 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3464 chainon (field_decl_chain, field_decl);
3466 return finish_struct (template, field_decl_chain, NULL_TREE);
3470 build_descriptor_table_initializer (tree type, tree entries)
3472 tree initlist = NULL_TREE;
3476 tree eltlist = NULL_TREE;
3479 = tree_cons (NULL_TREE,
3480 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3482 = tree_cons (NULL_TREE,
3483 add_objc_string (METHOD_ENCODING (entries),
3488 = tree_cons (NULL_TREE,
3489 objc_build_constructor (type, nreverse (eltlist)),
3492 entries = TREE_CHAIN (entries);
3496 return objc_build_constructor (build_array_type (type, 0),
3497 nreverse (initlist));
3500 /* struct objc_method_prototype_list {
3502 struct objc_method_prototype {
3509 build_method_prototype_list_template (tree list_type, int size)
3511 tree objc_ivar_list_record;
3512 tree decl_specs, field_decl, field_decl_chain;
3514 /* Generate an unnamed struct definition. */
3516 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3518 /* int method_count; */
3520 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3521 field_decl = get_identifier ("method_count");
3522 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3523 field_decl_chain = field_decl;
3525 /* struct objc_method method_list[]; */
3527 decl_specs = build_tree_list (NULL_TREE, list_type);
3528 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3529 build_int_2 (size, 0));
3530 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3531 chainon (field_decl_chain, field_decl);
3533 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3535 return objc_ivar_list_record;
3539 build_method_prototype_template (void)
3542 tree decl_specs, field_decl, field_decl_chain;
3545 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3547 /* struct objc_selector *_cmd; */
3548 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3549 get_identifier (TAG_SELECTOR)), NULL_TREE);
3550 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3551 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3552 field_decl_chain = field_decl;
3554 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3556 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3557 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3558 chainon (field_decl_chain, field_decl);
3560 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3562 return proto_record;
3566 objc_method_parm_type (tree type)
3568 type = groktypename (TREE_TYPE (type));
3569 if (TREE_CODE (type) == TYPE_DECL)
3570 type = TREE_TYPE (type);
3571 return TYPE_MAIN_VARIANT (type);
3575 objc_encoded_type_size (tree type)
3577 int sz = int_size_in_bytes (type);
3579 /* Make all integer and enum types at least as large
3581 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3582 || TREE_CODE (type) == BOOLEAN_TYPE
3583 || TREE_CODE (type) == ENUMERAL_TYPE))
3584 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3585 /* Treat arrays as pointers, since that's how they're
3587 else if (TREE_CODE (type) == ARRAY_TYPE)
3588 sz = int_size_in_bytes (ptr_type_node);
3593 encode_method_prototype (tree method_decl)
3600 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3601 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3603 /* Encode return type. */
3604 encode_type (objc_method_parm_type (method_decl),
3605 obstack_object_size (&util_obstack),
3606 OBJC_ENCODE_INLINE_DEFS);
3609 /* The first two arguments (self and _cmd) are pointers; account for
3611 i = int_size_in_bytes (ptr_type_node);
3612 parm_offset = 2 * i;
3613 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3614 parms = TREE_CHAIN (parms))
3616 tree type = objc_method_parm_type (parms);
3617 int sz = objc_encoded_type_size (type);
3619 /* If a type size is not known, bail out. */
3622 error ("%Jtype '%D' does not have a known size",
3624 /* Pretend that the encoding succeeded; the compilation will
3625 fail nevertheless. */
3626 goto finish_encoding;
3631 sprintf (buf, "%d@0:%d", parm_offset, i);
3632 obstack_grow (&util_obstack, buf, strlen (buf));
3634 /* Argument types. */
3635 parm_offset = 2 * i;
3636 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3637 parms = TREE_CHAIN (parms))
3639 tree type = objc_method_parm_type (parms);
3641 /* Process argument qualifiers for user supplied arguments. */
3642 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3645 encode_type (type, obstack_object_size (&util_obstack),
3646 OBJC_ENCODE_INLINE_DEFS);
3648 /* Compute offset. */
3649 sprintf (buf, "%d", parm_offset);
3650 parm_offset += objc_encoded_type_size (type);
3652 obstack_grow (&util_obstack, buf, strlen (buf));
3656 obstack_1grow (&util_obstack, '\0');
3657 result = get_identifier (obstack_finish (&util_obstack));
3658 obstack_free (&util_obstack, util_firstobj);
3663 generate_descriptor_table (tree type, const char *name, int size, tree list,
3666 tree sc_spec, decl_specs, decl, initlist;
3668 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3669 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3671 decl = start_decl (synth_id_with_class_suffix (name, proto),
3672 decl_specs, 1, NULL_TREE);
3673 DECL_CONTEXT (decl) = NULL_TREE;
3675 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3676 initlist = tree_cons (NULL_TREE, list, initlist);
3678 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3685 generate_method_descriptors (tree protocol)
3687 tree initlist, chain, method_list_template;
3688 tree cast, variable_length_type;
3691 if (!objc_method_prototype_template)
3692 objc_method_prototype_template = build_method_prototype_template ();
3694 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3695 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3697 variable_length_type = groktypename (cast);
3699 chain = PROTOCOL_CLS_METHODS (protocol);
3702 size = list_length (chain);
3704 method_list_template
3705 = build_method_prototype_list_template (objc_method_prototype_template,
3709 = build_descriptor_table_initializer (objc_method_prototype_template,
3712 UOBJC_CLASS_METHODS_decl
3713 = generate_descriptor_table (method_list_template,
3714 "_OBJC_PROTOCOL_CLASS_METHODS",
3715 size, initlist, protocol);
3716 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3719 UOBJC_CLASS_METHODS_decl = 0;
3721 chain = PROTOCOL_NST_METHODS (protocol);
3724 size = list_length (chain);
3726 method_list_template
3727 = build_method_prototype_list_template (objc_method_prototype_template,
3730 = build_descriptor_table_initializer (objc_method_prototype_template,
3733 UOBJC_INSTANCE_METHODS_decl
3734 = generate_descriptor_table (method_list_template,
3735 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3736 size, initlist, protocol);
3737 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3740 UOBJC_INSTANCE_METHODS_decl = 0;
3744 generate_protocol_references (tree plist)
3748 /* Forward declare protocols referenced. */
3749 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3751 tree proto = TREE_VALUE (lproto);
3753 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3754 && PROTOCOL_NAME (proto))
3756 if (! PROTOCOL_FORWARD_DECL (proto))
3757 build_protocol_reference (proto);
3759 if (PROTOCOL_LIST (proto))
3760 generate_protocol_references (PROTOCOL_LIST (proto));
3765 /* For each protocol which was referenced either from a @protocol()
3766 expression, or because a class/category implements it (then a
3767 pointer to the protocol is stored in the struct describing the
3768 class/category), we create a statically allocated instance of the
3769 Protocol class. The code is written in such a way as to generate
3770 as few Protocol objects as possible; we generate a unique Protocol
3771 instance for each protocol, and we don't generate a Protocol
3772 instance if the protocol is never referenced (either from a
3773 @protocol() or from a class/category implementation). These
3774 statically allocated objects can be referred to via the static
3775 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3777 The statically allocated Protocol objects that we generate here
3778 need to be fixed up at runtime in order to be used: the 'isa'
3779 pointer of the objects need to be set up to point to the 'Protocol'
3780 class, as known at runtime.
3782 The NeXT runtime fixes up all protocols at program startup time,
3783 before main() is entered. It uses a low-level trick to look up all
3784 those symbols, then loops on them and fixes them up.
3786 The GNU runtime as well fixes up all protocols before user code
3787 from the module is executed; it requires pointers to those symbols
3788 to be put in the objc_symtab (which is then passed as argument to
3789 the function __objc_exec_class() which the compiler sets up to be
3790 executed automatically when the module is loaded); setup of those
3791 Protocol objects happen in two ways in the GNU runtime: all
3792 Protocol objects referred to by a class or category implementation
3793 are fixed up when the class/category is loaded; all Protocol
3794 objects referred to by a @protocol() expression are added by the
3795 compiler to the list of statically allocated instances to fixup
3796 (the same list holding the statically allocated constant string
3797 objects). Because, as explained above, the compiler generates as
3798 few Protocol objects as possible, some Protocol object might end up
3799 being referenced multiple times when compiled with the GNU runtime,
3800 and end up being fixed up multiple times at runtime inizialization.
3801 But that doesn't hurt, it's just a little inefficient. */
3804 generate_protocols (void)
3807 tree sc_spec, decl_specs, decl;
3808 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3811 if (! objc_protocol_template)
3812 objc_protocol_template = build_protocol_template ();
3814 /* If a protocol was directly referenced, pull in indirect references. */
3815 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3816 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3817 generate_protocol_references (PROTOCOL_LIST (p));
3819 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3821 tree nst_methods = PROTOCOL_NST_METHODS (p);
3822 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3824 /* If protocol wasn't referenced, don't generate any code. */
3825 if (! PROTOCOL_FORWARD_DECL (p))
3828 /* Make sure we link in the Protocol class. */
3829 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3833 if (! METHOD_ENCODING (nst_methods))
3835 encoding = encode_method_prototype (nst_methods);
3836 METHOD_ENCODING (nst_methods) = encoding;
3838 nst_methods = TREE_CHAIN (nst_methods);
3843 if (! METHOD_ENCODING (cls_methods))
3845 encoding = encode_method_prototype (cls_methods);
3846 METHOD_ENCODING (cls_methods) = encoding;
3849 cls_methods = TREE_CHAIN (cls_methods);
3851 generate_method_descriptors (p);
3853 if (PROTOCOL_LIST (p))
3854 refs_decl = generate_protocol_list (p);
3858 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3860 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3862 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3864 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3865 decl_specs, 1, NULL_TREE);
3867 DECL_CONTEXT (decl) = NULL_TREE;
3869 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3875 (build_tree_list (build_tree_list (NULL_TREE,
3876 objc_protocol_template),
3877 build1 (INDIRECT_REF, NULL_TREE,
3878 build1 (INDIRECT_REF, NULL_TREE,
3881 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3882 TREE_TYPE (refs_expr) = cast_type2;
3885 refs_expr = build_int_2 (0, 0);
3887 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3888 by generate_method_descriptors, which is called above. */
3889 initlist = build_protocol_initializer (TREE_TYPE (decl),
3890 protocol_name_expr, refs_expr,
3891 UOBJC_INSTANCE_METHODS_decl,
3892 UOBJC_CLASS_METHODS_decl);
3893 finish_decl (decl, initlist, NULL_TREE);
3895 /* Mark the decl as used to avoid "defined but not used" warning. */
3896 TREE_USED (decl) = 1;
3901 build_protocol_initializer (tree type, tree protocol_name,
3902 tree protocol_list, tree instance_methods,
3905 tree initlist = NULL_TREE, expr;
3908 cast_type = groktypename
3910 (build_tree_list (NULL_TREE,
3911 xref_tag (RECORD_TYPE,
3912 get_identifier (UTAG_CLASS))),
3913 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3915 /* Filling the "isa" in with one allows the runtime system to
3916 detect that the version change...should remove before final release. */
3918 expr = build_int_2 (PROTOCOL_VERSION, 0);
3919 TREE_TYPE (expr) = cast_type;
3920 initlist = tree_cons (NULL_TREE, expr, initlist);
3921 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3922 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3924 if (!instance_methods)
3925 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3928 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3929 initlist = tree_cons (NULL_TREE, expr, initlist);
3933 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3936 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3937 initlist = tree_cons (NULL_TREE, expr, initlist);
3940 return objc_build_constructor (type, nreverse (initlist));
3943 /* struct objc_category {
3944 char *category_name;
3946 struct objc_method_list *instance_methods;
3947 struct objc_method_list *class_methods;
3948 struct objc_protocol_list *protocols;
3952 build_category_template (void)
3954 tree decl_specs, field_decl, field_decl_chain;
3956 objc_category_template = start_struct (RECORD_TYPE,
3957 get_identifier (UTAG_CATEGORY));
3958 /* char *category_name; */
3960 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3962 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3963 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3964 field_decl_chain = field_decl;
3966 /* char *class_name; */
3968 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3969 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3970 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3971 chainon (field_decl_chain, field_decl);
3973 /* struct objc_method_list *instance_methods; */
3975 decl_specs = build_tree_list (NULL_TREE,
3976 xref_tag (RECORD_TYPE,
3977 get_identifier (UTAG_METHOD_LIST)));
3979 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3980 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3981 chainon (field_decl_chain, field_decl);
3983 /* struct objc_method_list *class_methods; */
3985 decl_specs = build_tree_list (NULL_TREE,
3986 xref_tag (RECORD_TYPE,
3987 get_identifier (UTAG_METHOD_LIST)));
3989 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3990 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3991 chainon (field_decl_chain, field_decl);
3993 /* struct objc_protocol **protocol_list; */
3995 decl_specs = build_tree_list (NULL_TREE,
3996 xref_tag (RECORD_TYPE,
3997 get_identifier (UTAG_PROTOCOL)));
3999 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4000 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4001 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4002 chainon (field_decl_chain, field_decl);
4004 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4007 /* struct objc_selector {
4013 build_selector_template (void)
4016 tree decl_specs, field_decl, field_decl_chain;
4018 objc_selector_template
4019 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4023 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4024 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4025 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4026 field_decl_chain = field_decl;
4028 /* char *sel_type; */
4030 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4031 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4032 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4033 chainon (field_decl_chain, field_decl);
4035 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4038 /* struct objc_class {
4039 struct objc_class *isa;
4040 struct objc_class *super_class;
4045 struct objc_ivar_list *ivars;
4046 struct objc_method_list *methods;
4047 if (flag_next_runtime)
4048 struct objc_cache *cache;
4050 struct sarray *dtable;
4051 struct objc_class *subclass_list;
4052 struct objc_class *sibling_class;
4054 struct objc_protocol_list *protocols;
4055 if (flag_next_runtime)
4057 void *gc_object_type;
4060 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4061 the NeXT/Apple runtime; still, the compiler must generate them to
4062 maintain backward binary compatibility (and to allow for future
4066 build_class_template (void)
4068 tree decl_specs, field_decl, field_decl_chain;
4071 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4073 /* struct objc_class *isa; */
4075 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4076 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4077 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4078 field_decl_chain = field_decl;
4080 /* struct objc_class *super_class; */
4082 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4084 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4085 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4086 chainon (field_decl_chain, field_decl);
4090 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4091 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4092 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4093 chainon (field_decl_chain, field_decl);
4097 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4098 field_decl = get_identifier ("version");
4099 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4100 chainon (field_decl_chain, field_decl);
4104 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4105 field_decl = get_identifier ("info");
4106 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4107 chainon (field_decl_chain, field_decl);
4109 /* long instance_size; */
4111 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4112 field_decl = get_identifier ("instance_size");
4113 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4114 chainon (field_decl_chain, field_decl);
4116 /* struct objc_ivar_list *ivars; */
4118 decl_specs = build_tree_list (NULL_TREE,
4119 xref_tag (RECORD_TYPE,
4120 get_identifier (UTAG_IVAR_LIST)));
4121 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4122 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4123 chainon (field_decl_chain, field_decl);
4125 /* struct objc_method_list *methods; */
4127 decl_specs = build_tree_list (NULL_TREE,
4128 xref_tag (RECORD_TYPE,
4129 get_identifier (UTAG_METHOD_LIST)));
4130 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4131 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4132 chainon (field_decl_chain, field_decl);
4134 if (flag_next_runtime)
4136 /* struct objc_cache *cache; */
4138 decl_specs = build_tree_list (NULL_TREE,
4139 xref_tag (RECORD_TYPE,
4140 get_identifier ("objc_cache")));
4141 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4142 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4143 chainon (field_decl_chain, field_decl);
4147 /* struct sarray *dtable; */
4149 decl_specs = build_tree_list (NULL_TREE,
4150 xref_tag (RECORD_TYPE,
4151 get_identifier ("sarray")));
4152 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4153 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4154 chainon (field_decl_chain, field_decl);
4156 /* struct objc_class *subclass_list; */
4158 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4160 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4161 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4162 chainon (field_decl_chain, field_decl);
4164 /* struct objc_class *sibling_class; */
4166 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4168 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4169 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4170 chainon (field_decl_chain, field_decl);
4173 /* struct objc_protocol **protocol_list; */
4175 decl_specs = build_tree_list (NULL_TREE,
4176 xref_tag (RECORD_TYPE,
4177 get_identifier (UTAG_PROTOCOL)));
4179 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4181 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4182 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4183 chainon (field_decl_chain, field_decl);
4185 if (flag_next_runtime)
4189 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4190 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4192 = grokfield (field_decl, decl_specs, NULL_TREE);
4193 chainon (field_decl_chain, field_decl);
4196 /* void *gc_object_type; */
4198 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4199 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4200 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4201 chainon (field_decl_chain, field_decl);
4203 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4206 /* Generate appropriate forward declarations for an implementation. */
4209 synth_forward_declarations (void)
4213 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4214 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4215 objc_class_template);
4217 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4218 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4219 objc_class_template);
4221 /* Pre-build the following entities - for speed/convenience. */
4223 an_id = get_identifier ("super_class");
4224 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4225 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4229 error_with_ivar (const char *message, tree decl, tree rawdecl)
4231 error ("%J%s `%s'", decl,
4232 message, gen_declaration (rawdecl, errbuf));
4237 check_ivars (tree inter, tree imp)
4239 tree intdecls = CLASS_IVARS (inter);
4240 tree impdecls = CLASS_IVARS (imp);
4241 tree rawintdecls = CLASS_RAW_IVARS (inter);
4242 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4249 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4250 intdecls = TREE_CHAIN (intdecls);
4252 if (intdecls == 0 && impdecls == 0)
4254 if (intdecls == 0 || impdecls == 0)
4256 error ("inconsistent instance variable specification");
4260 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4262 if (!comptypes (t1, t2, false)
4263 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4264 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4266 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4268 error_with_ivar ("conflicting instance variable type",
4269 impdecls, rawimpdecls);
4270 error_with_ivar ("previous declaration of",
4271 intdecls, rawintdecls);
4273 else /* both the type and the name don't match */
4275 error ("inconsistent instance variable specification");
4280 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4282 error_with_ivar ("conflicting instance variable name",
4283 impdecls, rawimpdecls);
4284 error_with_ivar ("previous declaration of",
4285 intdecls, rawintdecls);
4288 intdecls = TREE_CHAIN (intdecls);
4289 impdecls = TREE_CHAIN (impdecls);
4290 rawintdecls = TREE_CHAIN (rawintdecls);
4291 rawimpdecls = TREE_CHAIN (rawimpdecls);
4295 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4296 This needs to be done just once per compilation. */
4299 build_super_template (void)
4301 tree decl_specs, field_decl, field_decl_chain;
4303 /* Suppress outputting debug symbols, because
4304 dbxout_init hasn't been called yet. */
4305 enum debug_info_type save_write_symbols = write_symbols;
4306 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4308 write_symbols = NO_DEBUG;
4309 debug_hooks = &do_nothing_debug_hooks;
4311 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4313 /* struct objc_object *self; */
4315 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4316 field_decl = get_identifier ("self");
4317 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4318 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4319 field_decl_chain = field_decl;
4322 /* struct objc_class *super_class; */
4324 /* struct objc_class *class; */
4327 decl_specs = get_identifier (UTAG_CLASS);
4328 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4330 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4332 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4335 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4336 chainon (field_decl_chain, field_decl);
4338 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4340 write_symbols = save_write_symbols;
4341 debug_hooks = save_hooks;
4344 /* struct objc_ivar {
4351 build_ivar_template (void)
4353 tree objc_ivar_id, objc_ivar_record;
4354 tree decl_specs, field_decl, field_decl_chain;
4356 objc_ivar_id = get_identifier (UTAG_IVAR);
4357 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4359 /* char *ivar_name; */
4361 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4362 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4364 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4365 field_decl_chain = field_decl;
4367 /* char *ivar_type; */
4369 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4370 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4372 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4373 chainon (field_decl_chain, field_decl);
4375 /* int ivar_offset; */
4377 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4378 field_decl = get_identifier ("ivar_offset");
4380 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4381 chainon (field_decl_chain, field_decl);
4383 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4385 return objc_ivar_record;
4390 struct objc_ivar ivar_list[ivar_count];
4394 build_ivar_list_template (tree list_type, int size)
4396 tree objc_ivar_list_record;
4397 tree decl_specs, field_decl, field_decl_chain;
4399 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4401 /* int ivar_count; */
4403 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4404 field_decl = get_identifier ("ivar_count");
4406 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4407 field_decl_chain = field_decl;
4409 /* struct objc_ivar ivar_list[]; */
4411 decl_specs = build_tree_list (NULL_TREE, list_type);
4412 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4413 build_int_2 (size, 0));
4415 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4416 chainon (field_decl_chain, field_decl);
4418 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4420 return objc_ivar_list_record;
4426 struct objc_method method_list[method_count];
4430 build_method_list_template (tree list_type, int size)
4432 tree objc_ivar_list_record;
4433 tree decl_specs, field_decl, field_decl_chain;
4435 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4437 /* int method_next; */
4442 xref_tag (RECORD_TYPE,
4443 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4445 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4446 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4447 field_decl_chain = field_decl;
4449 /* int method_count; */
4451 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4452 field_decl = get_identifier ("method_count");
4454 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4455 chainon (field_decl_chain, field_decl);
4457 /* struct objc_method method_list[]; */
4459 decl_specs = build_tree_list (NULL_TREE, list_type);
4460 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4461 build_int_2 (size, 0));
4463 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4464 chainon (field_decl_chain, field_decl);
4466 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4468 return objc_ivar_list_record;
4472 build_ivar_list_initializer (tree type, tree field_decl)
4474 tree initlist = NULL_TREE;
4478 tree ivar = NULL_TREE;
4481 if (DECL_NAME (field_decl))
4482 ivar = tree_cons (NULL_TREE,
4483 add_objc_string (DECL_NAME (field_decl),
4487 /* Unnamed bit-field ivar (yuck). */
4488 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4491 encode_field_decl (field_decl,
4492 obstack_object_size (&util_obstack),
4493 OBJC_ENCODE_DONT_INLINE_DEFS);
4495 /* Null terminate string. */
4496 obstack_1grow (&util_obstack, 0);
4500 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4503 obstack_free (&util_obstack, util_firstobj);
4506 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4507 initlist = tree_cons (NULL_TREE,
4508 objc_build_constructor (type, nreverse (ivar)),
4511 field_decl = TREE_CHAIN (field_decl);
4512 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4516 return objc_build_constructor (build_array_type (type, 0),
4517 nreverse (initlist));
4521 generate_ivars_list (tree type, const char *name, int size, tree list)
4523 tree sc_spec, decl_specs, decl, initlist;
4525 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4526 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4528 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4529 decl_specs, 1, NULL_TREE);
4531 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4532 initlist = tree_cons (NULL_TREE, list, initlist);
4535 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4541 /* Count only the fields occurring in T. */
4543 ivar_list_length (tree t)
4547 for (; t; t = TREE_CHAIN (t))
4548 if (TREE_CODE (t) == FIELD_DECL)
4555 generate_ivar_lists (void)
4557 tree initlist, ivar_list_template, chain;
4558 tree cast, variable_length_type;
4561 generating_instance_variables = 1;
4563 if (!objc_ivar_template)
4564 objc_ivar_template = build_ivar_template ();
4568 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4569 get_identifier (UTAG_IVAR_LIST))),
4571 variable_length_type = groktypename (cast);
4573 /* Only generate class variables for the root of the inheritance
4574 hierarchy since these will be the same for every class. */
4576 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4577 && (chain = TYPE_FIELDS (objc_class_template)))
4579 size = ivar_list_length (chain);
4581 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4582 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4584 UOBJC_CLASS_VARIABLES_decl
4585 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4587 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4590 UOBJC_CLASS_VARIABLES_decl = 0;
4592 chain = CLASS_IVARS (implementation_template);
4595 size = ivar_list_length (chain);
4596 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4597 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4599 UOBJC_INSTANCE_VARIABLES_decl
4600 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4602 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4605 UOBJC_INSTANCE_VARIABLES_decl = 0;
4607 generating_instance_variables = 0;
4611 build_dispatch_table_initializer (tree type, tree entries)
4613 tree initlist = NULL_TREE;
4617 tree elemlist = NULL_TREE;
4619 elemlist = tree_cons (NULL_TREE,
4620 build_selector (METHOD_SEL_NAME (entries)),
4623 /* Generate the method encoding if we don't have one already. */
4624 if (! METHOD_ENCODING (entries))
4625 METHOD_ENCODING (entries) =
4626 encode_method_prototype (entries);
4628 elemlist = tree_cons (NULL_TREE,
4629 add_objc_string (METHOD_ENCODING (entries),
4633 elemlist = tree_cons (NULL_TREE,
4634 build_unary_op (ADDR_EXPR,
4635 METHOD_DEFINITION (entries), 1),
4638 initlist = tree_cons (NULL_TREE,
4639 objc_build_constructor (type, nreverse (elemlist)),
4642 entries = TREE_CHAIN (entries);
4646 return objc_build_constructor (build_array_type (type, 0),
4647 nreverse (initlist));
4650 /* To accomplish method prototyping without generating all kinds of
4651 inane warnings, the definition of the dispatch table entries were
4654 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4656 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4659 build_method_template (void)
4662 tree decl_specs, field_decl, field_decl_chain;
4664 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4666 /* struct objc_selector *_cmd; */
4667 decl_specs = tree_cons (NULL_TREE,
4668 xref_tag (RECORD_TYPE,
4669 get_identifier (TAG_SELECTOR)),
4671 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4673 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4674 field_decl_chain = field_decl;
4676 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4677 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4678 get_identifier ("method_types"));
4679 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4680 chainon (field_decl_chain, field_decl);
4684 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4685 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4686 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4687 chainon (field_decl_chain, field_decl);
4689 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4696 generate_dispatch_table (tree type, const char *name, int size, tree list)
4698 tree sc_spec, decl_specs, decl, initlist;
4700 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4701 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4703 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4704 decl_specs, 1, NULL_TREE);
4706 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4707 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4708 initlist = tree_cons (NULL_TREE, list, initlist);
4711 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4718 mark_referenced_methods (void)
4720 struct imp_entry *impent;
4723 for (impent = imp_list; impent; impent = impent->next)
4725 chain = CLASS_CLS_METHODS (impent->imp_context);
4728 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4729 chain = TREE_CHAIN (chain);
4732 chain = CLASS_NST_METHODS (impent->imp_context);
4735 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4736 chain = TREE_CHAIN (chain);
4742 generate_dispatch_tables (void)
4744 tree initlist, chain, method_list_template;
4745 tree cast, variable_length_type;
4748 if (!objc_method_template)
4749 objc_method_template = build_method_template ();
4753 (build_tree_list (NULL_TREE,
4754 xref_tag (RECORD_TYPE,
4755 get_identifier (UTAG_METHOD_LIST))),
4758 variable_length_type = groktypename (cast);
4760 chain = CLASS_CLS_METHODS (objc_implementation_context);
4763 size = list_length (chain);
4765 method_list_template
4766 = build_method_list_template (objc_method_template, size);
4768 = build_dispatch_table_initializer (objc_method_template, chain);
4770 UOBJC_CLASS_METHODS_decl
4771 = generate_dispatch_table (method_list_template,
4772 ((TREE_CODE (objc_implementation_context)
4773 == CLASS_IMPLEMENTATION_TYPE)
4774 ? "_OBJC_CLASS_METHODS"
4775 : "_OBJC_CATEGORY_CLASS_METHODS"),
4777 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4780 UOBJC_CLASS_METHODS_decl = 0;
4782 chain = CLASS_NST_METHODS (objc_implementation_context);
4785 size = list_length (chain);
4787 method_list_template
4788 = build_method_list_template (objc_method_template, size);
4790 = build_dispatch_table_initializer (objc_method_template, chain);
4792 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4793 UOBJC_INSTANCE_METHODS_decl
4794 = generate_dispatch_table (method_list_template,
4795 "_OBJC_INSTANCE_METHODS",
4798 /* We have a category. */
4799 UOBJC_INSTANCE_METHODS_decl
4800 = generate_dispatch_table (method_list_template,
4801 "_OBJC_CATEGORY_INSTANCE_METHODS",
4803 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4806 UOBJC_INSTANCE_METHODS_decl = 0;
4810 generate_protocol_list (tree i_or_p)
4812 tree initlist, decl_specs, sc_spec;
4813 tree refs_decl, expr_decl, lproto, e, plist;
4817 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4818 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4819 plist = CLASS_PROTOCOL_LIST (i_or_p);
4820 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4821 plist = PROTOCOL_LIST (i_or_p);
4825 cast_type = groktypename
4827 (build_tree_list (NULL_TREE,
4828 xref_tag (RECORD_TYPE,
4829 get_identifier (UTAG_PROTOCOL))),
4830 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4833 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4834 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4835 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4838 /* Build initializer. */
4839 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4841 e = build_int_2 (size, 0);
4842 TREE_TYPE (e) = cast_type;
4843 initlist = tree_cons (NULL_TREE, e, initlist);
4845 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4847 tree pval = TREE_VALUE (lproto);
4849 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4850 && PROTOCOL_FORWARD_DECL (pval))
4852 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4853 initlist = tree_cons (NULL_TREE, e, initlist);
4857 /* static struct objc_protocol *refs[n]; */
4859 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4860 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4861 get_identifier (UTAG_PROTOCOL)),
4864 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4865 expr_decl = build_nt (ARRAY_REF,
4866 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4868 build_int_2 (size + 2, 0));
4869 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4870 expr_decl = build_nt (ARRAY_REF,
4871 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4873 build_int_2 (size + 2, 0));
4874 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4876 = build_nt (ARRAY_REF,
4877 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4879 build_int_2 (size + 2, 0));
4883 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4885 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4886 DECL_CONTEXT (refs_decl) = NULL_TREE;
4888 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4889 nreverse (initlist)),
4896 build_category_initializer (tree type, tree cat_name, tree class_name,
4897 tree instance_methods, tree class_methods,
4900 tree initlist = NULL_TREE, expr;
4902 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4903 initlist = tree_cons (NULL_TREE, class_name, initlist);
4905 if (!instance_methods)
4906 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4909 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4910 initlist = tree_cons (NULL_TREE, expr, initlist);
4913 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4916 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4917 initlist = tree_cons (NULL_TREE, expr, initlist);
4920 /* protocol_list = */
4922 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4925 tree cast_type2 = groktypename
4927 (build_tree_list (NULL_TREE,
4928 xref_tag (RECORD_TYPE,
4929 get_identifier (UTAG_PROTOCOL))),
4930 build1 (INDIRECT_REF, NULL_TREE,
4931 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4933 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4934 TREE_TYPE (expr) = cast_type2;
4935 initlist = tree_cons (NULL_TREE, expr, initlist);
4938 return objc_build_constructor (type, nreverse (initlist));
4941 /* struct objc_class {
4942 struct objc_class *isa;
4943 struct objc_class *super_class;
4948 struct objc_ivar_list *ivars;
4949 struct objc_method_list *methods;
4950 if (flag_next_runtime)
4951 struct objc_cache *cache;
4953 struct sarray *dtable;
4954 struct objc_class *subclass_list;
4955 struct objc_class *sibling_class;
4957 struct objc_protocol_list *protocols;
4958 if (flag_next_runtime)
4960 void *gc_object_type;
4964 build_shared_structure_initializer (tree type, tree isa, tree super,
4965 tree name, tree size, int status,
4966 tree dispatch_table, tree ivar_list,
4969 tree initlist = NULL_TREE, expr;
4972 initlist = tree_cons (NULL_TREE, isa, initlist);
4975 initlist = tree_cons (NULL_TREE, super, initlist);
4978 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4981 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4984 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4986 /* instance_size = */
4987 initlist = tree_cons (NULL_TREE, size, initlist);
4989 /* objc_ivar_list = */
4991 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4994 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4995 initlist = tree_cons (NULL_TREE, expr, initlist);
4998 /* objc_method_list = */
4999 if (!dispatch_table)
5000 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5003 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
5004 initlist = tree_cons (NULL_TREE, expr, initlist);
5007 if (flag_next_runtime)
5008 /* method_cache = */
5009 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5013 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5015 /* subclass_list = */
5016 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5018 /* sibling_class = */
5019 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5022 /* protocol_list = */
5023 if (! protocol_list)
5024 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5030 (build_tree_list (NULL_TREE,
5031 xref_tag (RECORD_TYPE,
5032 get_identifier (UTAG_PROTOCOL))),
5033 build1 (INDIRECT_REF, NULL_TREE,
5034 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5036 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5037 TREE_TYPE (expr) = cast_type2;
5038 initlist = tree_cons (NULL_TREE, expr, initlist);
5041 if (flag_next_runtime)
5043 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5045 /* gc_object_type = NULL */
5046 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5048 return objc_build_constructor (type, nreverse (initlist));
5051 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5054 lookup_category (tree class, tree cat_name)
5056 tree category = CLASS_CATEGORY_LIST (class);
5058 while (category && CLASS_SUPER_NAME (category) != cat_name)
5059 category = CLASS_CATEGORY_LIST (category);
5063 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5066 generate_category (tree cat)
5068 tree sc_spec, decl_specs, decl;
5069 tree initlist, cat_name_expr, class_name_expr;
5070 tree protocol_decl, category;
5072 add_class_reference (CLASS_NAME (cat));
5073 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5075 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5077 category = lookup_category (implementation_template,
5078 CLASS_SUPER_NAME (cat));
5080 if (category && CLASS_PROTOCOL_LIST (category))
5082 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5083 protocol_decl = generate_protocol_list (category);
5088 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5089 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5091 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5092 objc_implementation_context),
5093 decl_specs, 1, NULL_TREE);
5095 initlist = build_category_initializer (TREE_TYPE (decl),
5096 cat_name_expr, class_name_expr,
5097 UOBJC_INSTANCE_METHODS_decl,
5098 UOBJC_CLASS_METHODS_decl,
5101 finish_decl (decl, initlist, NULL_TREE);
5104 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5105 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5108 generate_shared_structures (void)
5110 tree sc_spec, decl_specs, decl;
5111 tree name_expr, super_expr, root_expr;
5112 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5113 tree cast_type, initlist, protocol_decl;
5115 my_super_id = CLASS_SUPER_NAME (implementation_template);
5118 add_class_reference (my_super_id);
5120 /* Compute "my_root_id" - this is required for code generation.
5121 the "isa" for all meta class structures points to the root of
5122 the inheritance hierarchy (e.g. "__Object")... */
5123 my_root_id = my_super_id;
5126 tree my_root_int = lookup_interface (my_root_id);
5128 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5129 my_root_id = CLASS_SUPER_NAME (my_root_int);
5136 /* No super class. */
5137 my_root_id = CLASS_NAME (implementation_template);
5140 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5141 objc_class_template),
5142 build1 (INDIRECT_REF,
5143 NULL_TREE, NULL_TREE)));
5145 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5148 /* Install class `isa' and `super' pointers at runtime. */
5151 super_expr = add_objc_string (my_super_id, class_names);
5152 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5155 super_expr = build_int_2 (0, 0);
5157 root_expr = add_objc_string (my_root_id, class_names);
5158 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5160 if (CLASS_PROTOCOL_LIST (implementation_template))
5162 generate_protocol_references
5163 (CLASS_PROTOCOL_LIST (implementation_template));
5164 protocol_decl = generate_protocol_list (implementation_template);
5169 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5171 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5172 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5174 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5178 = build_shared_structure_initializer
5180 root_expr, super_expr, name_expr,
5181 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5183 UOBJC_CLASS_METHODS_decl,
5184 UOBJC_CLASS_VARIABLES_decl,
5187 finish_decl (decl, initlist, NULL_TREE);
5189 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5191 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5195 = build_shared_structure_initializer
5197 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5198 super_expr, name_expr,
5199 convert (integer_type_node,
5200 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5201 (implementation_template))),
5203 UOBJC_INSTANCE_METHODS_decl,
5204 UOBJC_INSTANCE_VARIABLES_decl,
5207 finish_decl (decl, initlist, NULL_TREE);
5211 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5214 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5215 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5217 const char *const class_name
5218 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5219 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5220 sprintf (string, "%s_%s", preamble,
5221 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5223 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5224 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5226 /* We have a category. */
5227 const char *const class_name
5228 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5229 const char *const class_super_name
5230 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5231 string = (char *) alloca (strlen (preamble)
5232 + strlen (class_name)
5233 + strlen (class_super_name)
5235 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5237 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5239 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5241 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5242 sprintf (string, "%s_%s", preamble, protocol_name);
5247 return get_identifier (string);
5251 is_objc_type_qualifier (tree node)
5253 return (TREE_CODE (node) == IDENTIFIER_NODE
5254 && (node == ridpointers [(int) RID_CONST]
5255 || node == ridpointers [(int) RID_VOLATILE]
5256 || node == ridpointers [(int) RID_IN]
5257 || node == ridpointers [(int) RID_OUT]
5258 || node == ridpointers [(int) RID_INOUT]
5259 || node == ridpointers [(int) RID_BYCOPY]
5260 || node == ridpointers [(int) RID_BYREF]
5261 || node == ridpointers [(int) RID_ONEWAY]));
5264 /* If type is empty or only type qualifiers are present, add default
5265 type of id (otherwise grokdeclarator will default to int). */
5268 adjust_type_for_id_default (tree type)
5270 tree declspecs, chain;
5273 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5274 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5276 declspecs = TREE_PURPOSE (type);
5278 /* Determine if a typespec is present. */
5279 for (chain = declspecs;
5281 chain = TREE_CHAIN (chain))
5283 if (TYPED_OBJECT (TREE_VALUE (chain))
5284 && !(TREE_VALUE (type)
5285 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5286 error ("can not use an object as parameter to a method\n");
5287 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5291 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5293 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5298 selector ':' '(' typename ')' identifier
5301 Transform an Objective-C keyword argument into
5302 the C equivalent parameter declarator.
5304 In: key_name, an "identifier_node" (optional).
5305 arg_type, a "tree_list" (optional).
5306 arg_name, an "identifier_node".
5308 Note: It would be really nice to strongly type the preceding
5309 arguments in the function prototype; however, then I
5310 could not use the "accessor" macros defined in "tree.h".
5312 Out: an instance of "keyword_decl". */
5315 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5319 /* If no type is specified, default to "id". */
5320 arg_type = adjust_type_for_id_default (arg_type);
5322 keyword_decl = make_node (KEYWORD_DECL);
5324 TREE_TYPE (keyword_decl) = arg_type;
5325 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5326 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5328 return keyword_decl;
5331 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5334 build_keyword_selector (tree selector)
5337 tree key_chain, key_name;
5340 /* Scan the selector to see how much space we'll need. */
5341 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5343 if (TREE_CODE (selector) == KEYWORD_DECL)
5344 key_name = KEYWORD_KEY_NAME (key_chain);
5345 else if (TREE_CODE (selector) == TREE_LIST)
5346 key_name = TREE_PURPOSE (key_chain);
5351 len += IDENTIFIER_LENGTH (key_name) + 1;
5353 /* Just a ':' arg. */
5357 buf = (char *) alloca (len + 1);
5358 /* Start the buffer out as an empty string. */
5361 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5363 if (TREE_CODE (selector) == KEYWORD_DECL)
5364 key_name = KEYWORD_KEY_NAME (key_chain);
5365 else if (TREE_CODE (selector) == TREE_LIST)
5367 key_name = TREE_PURPOSE (key_chain);
5368 /* The keyword decl chain will later be used as a function argument
5369 chain. Unhook the selector itself so as to not confuse other
5370 parts of the compiler. */
5371 TREE_PURPOSE (key_chain) = NULL_TREE;
5377 strcat (buf, IDENTIFIER_POINTER (key_name));
5381 return get_identifier (buf);
5384 /* Used for declarations and definitions. */
5387 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5392 /* If no type is specified, default to "id". */
5393 ret_type = adjust_type_for_id_default (ret_type);
5395 method_decl = make_node (code);
5396 TREE_TYPE (method_decl) = ret_type;
5398 /* If we have a keyword selector, create an identifier_node that
5399 represents the full selector name (`:' included)... */
5400 if (TREE_CODE (selector) == KEYWORD_DECL)
5402 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5403 METHOD_SEL_ARGS (method_decl) = selector;
5404 METHOD_ADD_ARGS (method_decl) = add_args;
5408 METHOD_SEL_NAME (method_decl) = selector;
5409 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5410 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5416 #define METHOD_DEF 0
5417 #define METHOD_REF 1
5419 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5420 an argument list for method METH. CONTEXT is either METHOD_DEF or
5421 METHOD_REF, saying whether we are trying to define a method or call
5422 one. SUPERFLAG says this is for a send to super; this makes a
5423 difference for the NeXT calling sequence in which the lookup and
5424 the method call are done together. If METH is null, user-defined
5425 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5428 get_arg_type_list (tree meth, int context, int superflag)
5432 /* Receiver type. */
5433 if (flag_next_runtime && superflag)
5434 arglist = build_tree_list (NULL_TREE, super_type);
5435 else if (context == METHOD_DEF)
5436 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5438 arglist = build_tree_list (NULL_TREE, id_type);
5440 /* Selector type - will eventually change to `int'. */
5441 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
5443 /* No actual method prototype given -- assume that remaining arguments
5448 /* Build a list of argument types. */
5449 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5451 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5452 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5455 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5456 /* We have a `, ...' immediately following the selector,
5457 finalize the arglist...simulate get_parm_info (true). */
5459 else if (METHOD_ADD_ARGS (meth))
5461 /* we have a variable length selector */
5462 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5463 chainon (arglist, add_arg_list);
5466 /* finalize the arglist...simulate get_parm_info (false) */
5467 chainon (arglist, void_list_node);
5473 check_duplicates (hash hsh, int methods, int is_class)
5475 tree meth = NULL_TREE;
5483 /* We have two or more methods with the same name but
5487 warning ("multiple %s named `%c%s' found",
5488 methods ? "methods" : "selectors",
5489 (is_class ? '+' : '-'),
5490 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5492 warn_with_method (methods ? "using" : "found",
5493 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5497 for (loop = hsh->list; loop; loop = loop->next)
5498 warn_with_method ("also found",
5499 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5508 /* If RECEIVER is a class reference, return the identifier node for
5509 the referenced class. RECEIVER is created by get_class_reference,
5510 so we check the exact form created depending on which runtimes are
5514 receiver_is_class_object (tree receiver, int self, int super)
5516 tree chain, exp, arg;
5518 /* The receiver is 'self' or 'super' in the context of a class method. */
5519 if (objc_method_context
5520 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5523 ? CLASS_SUPER_NAME (implementation_template)
5524 : CLASS_NAME (implementation_template));
5526 if (flag_next_runtime)
5528 /* The receiver is a variable created by
5529 build_class_reference_decl. */
5530 if (TREE_CODE (receiver) == VAR_DECL
5531 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5532 /* Look up the identifier. */
5533 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5534 if (TREE_PURPOSE (chain) == receiver)
5535 return TREE_VALUE (chain);
5538 /* The receiver is a function call that returns an id. Check if
5539 it is a call to objc_getClass, if so, pick up the class name. */
5540 if (TREE_CODE (receiver) == CALL_EXPR
5541 && (exp = TREE_OPERAND (receiver, 0))
5542 && TREE_CODE (exp) == ADDR_EXPR
5543 && (exp = TREE_OPERAND (exp, 0))
5544 && TREE_CODE (exp) == FUNCTION_DECL
5545 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5546 prototypes for objc_get_class(). Thankfully, they seem to share the
5547 same function type. */
5548 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5549 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5550 /* We have a call to objc_get_class/objc_getClass! */
5551 && (arg = TREE_OPERAND (receiver, 1))
5552 && TREE_CODE (arg) == TREE_LIST
5553 && (arg = TREE_VALUE (arg)))
5556 if (TREE_CODE (arg) == ADDR_EXPR
5557 && (arg = TREE_OPERAND (arg, 0))
5558 && TREE_CODE (arg) == STRING_CST)
5559 /* Finally, we have the class name. */
5560 return get_identifier (TREE_STRING_POINTER (arg));
5565 /* If we are currently building a message expr, this holds
5566 the identifier of the selector of the message. This is
5567 used when printing warnings about argument mismatches. */
5569 static tree current_objc_message_selector = 0;
5572 objc_message_selector (void)
5574 return current_objc_message_selector;
5577 /* Construct an expression for sending a message.
5578 MESS has the object to send to in TREE_PURPOSE
5579 and the argument list (including selector) in TREE_VALUE.
5581 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5582 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5585 build_message_expr (tree mess)
5587 tree receiver = TREE_PURPOSE (mess);
5589 tree args = TREE_VALUE (mess);
5590 tree method_params = NULL_TREE;
5592 if (TREE_CODE (receiver) == ERROR_MARK)
5593 return error_mark_node;
5595 /* Obtain the full selector name. */
5596 if (TREE_CODE (args) == IDENTIFIER_NODE)
5597 /* A unary selector. */
5599 else if (TREE_CODE (args) == TREE_LIST)
5600 sel_name = build_keyword_selector (args);
5604 /* Build the parameter list to give to the method. */
5605 if (TREE_CODE (args) == TREE_LIST)
5607 tree chain = args, prev = NULL_TREE;
5609 /* We have a keyword selector--check for comma expressions. */
5612 tree element = TREE_VALUE (chain);
5614 /* We have a comma expression, must collapse... */
5615 if (TREE_CODE (element) == TREE_LIST)
5618 TREE_CHAIN (prev) = element;
5623 chain = TREE_CHAIN (chain);
5625 method_params = args;
5629 if (processing_template_decl)
5630 /* Must wait until template instantiation time. */
5631 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5635 return finish_message_expr (receiver, sel_name, method_params);
5638 /* Look up method SEL_NAME that would be suitable for receiver
5639 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5640 nonzero), and report on any duplicates. */
5643 lookup_method_in_hash_lists (tree sel_name, int is_class)
5645 hash method_prototype = NULL;
5648 method_prototype = hash_lookup (nst_method_hash_list,
5651 if (!method_prototype)
5653 method_prototype = hash_lookup (cls_method_hash_list,
5658 return check_duplicates (method_prototype, 1, is_class);
5661 /* The 'finish_message_expr' routine is called from within
5662 'build_message_expr' for non-template functions. In the case of
5663 C++ template functions, it is called from 'build_expr_from_tree'
5664 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5667 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5669 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5670 tree selector, retval, is_class;
5671 int self, super, have_cast;
5673 /* Extract the receiver of the message, as well as its type
5674 (where the latter may take the form of a cast or be inferred
5675 from the implementation context). */
5677 while (TREE_CODE (rtype) == COMPOUND_EXPR
5678 || TREE_CODE (rtype) == MODIFY_EXPR
5679 || TREE_CODE (rtype) == NOP_EXPR
5680 || TREE_CODE (rtype) == COMPONENT_REF)
5681 rtype = TREE_OPERAND (rtype, 0);
5682 self = (rtype == self_decl);
5683 super = (rtype == UOBJC_SUPER_decl);
5684 rtype = TREE_TYPE (receiver);
5685 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5686 || (TREE_CODE (receiver) == COMPOUND_EXPR
5687 && !IS_SUPER (rtype)));
5689 /* If the receiver is a class object, retrieve the corresponding
5690 @interface, if one exists. */
5691 is_class = receiver_is_class_object (receiver, self, super);
5693 /* Now determine the receiver type (if an explicit cast has not been
5698 rtype = lookup_interface (is_class);
5699 /* Handle `self' and `super'. */
5702 if (!CLASS_SUPER_NAME (implementation_template))
5704 error ("no super class declared in @interface for `%s'",
5705 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5706 return error_mark_node;
5708 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5711 rtype = lookup_interface (CLASS_NAME (implementation_template));
5714 /* If receiver is of type `id' or `Class' (or if the @interface for a
5715 class is not visible), we shall be satisfied with the existence of
5716 any instance or class method. */
5717 if (!rtype || IS_ID (rtype)
5718 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5721 rtype = xref_tag (RECORD_TYPE, is_class);
5722 else if (IS_ID (rtype))
5724 rprotos = TYPE_PROTOCOL_LIST (rtype);
5728 is_class = TYPE_NAME (rtype) = get_identifier ("Class");
5732 = lookup_method_in_protocol_list (rprotos, sel_name,
5733 is_class != NULL_TREE);
5734 if (!method_prototype && !rprotos)
5736 = lookup_method_in_hash_lists (sel_name,
5737 is_class != NULL_TREE);
5741 tree orig_rtype = rtype, saved_rtype;
5743 if (TREE_CODE (rtype) == POINTER_TYPE)
5744 rtype = TREE_TYPE (rtype);
5745 /* Traverse typedef aliases */
5746 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5747 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5748 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5749 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5750 saved_rtype = rtype;
5751 if (TYPED_OBJECT (rtype))
5753 rprotos = TYPE_PROTOCOL_LIST (rtype);
5754 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5756 /* If we could not find an @interface declaration, we must have
5757 only seen a @class declaration; so, we cannot say anything
5758 more intelligent about which methods the receiver will
5761 rtype = saved_rtype;
5762 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5763 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5765 /* We have a valid ObjC class name. Look up the method name
5766 in the published @interface for the class (and its
5769 = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
5771 /* If the method was not found in the @interface, it may still
5772 exist locally as part of the @implementation. */
5773 if (!method_prototype && objc_implementation_context
5774 && CLASS_NAME (objc_implementation_context)
5775 == OBJC_TYPE_NAME (rtype))
5779 ? CLASS_CLS_METHODS (objc_implementation_context)
5780 : CLASS_NST_METHODS (objc_implementation_context)),
5783 /* If we haven't found a candidate method by now, try looking for
5784 it in the protocol list. */
5785 if (!method_prototype && rprotos)
5787 = lookup_method_in_protocol_list (rprotos, sel_name,
5788 is_class != NULL_TREE);
5792 warning ("invalid receiver type `%s'",
5793 gen_declaration (orig_rtype, errbuf));
5794 rtype = rprotos = NULL_TREE;
5798 if (!method_prototype)
5800 static bool warn_missing_methods = false;
5803 warning ("`%s' may not respond to `%c%s'",
5804 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5805 (is_class ? '+' : '-'),
5806 IDENTIFIER_POINTER (sel_name));
5808 warning ("`%c%s' not implemented by protocol(s)",
5809 (is_class ? '+' : '-'),
5810 IDENTIFIER_POINTER (sel_name));
5811 if (!warn_missing_methods)
5813 warning ("(Messages without a matching method signature");
5814 warning ("will be assumed to return `id' and accept");
5815 warning ("`...' as arguments.)");
5816 warn_missing_methods = true;
5820 /* Save the selector name for printing error messages. */
5821 current_objc_message_selector = sel_name;
5823 /* Build the parameters list for looking up the method.
5824 These are the object itself and the selector. */
5826 if (flag_typed_selectors)
5827 selector = build_typed_selector_reference (sel_name, method_prototype);
5829 selector = build_selector_reference (sel_name);
5831 retval = build_objc_method_call (super, method_prototype,
5833 selector, method_params);
5835 current_objc_message_selector = 0;
5840 /* Build a tree expression to send OBJECT the operation SELECTOR,
5841 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5842 assuming the method has prototype METHOD_PROTOTYPE.
5843 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5844 Use METHOD_PARAMS as list of args to pass to the method.
5845 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5848 build_objc_method_call (int super_flag, tree method_prototype,
5849 tree lookup_object, tree selector,
5852 tree sender = (super_flag ? umsg_super_decl :
5853 (!flag_next_runtime || flag_nil_receivers
5855 : umsg_nonnil_decl));
5856 tree rcv_p = (super_flag ? super_type : id_type);
5858 /* If a prototype for the method to be called exists, then cast
5859 the sender's return type and arguments to match that of the method.
5860 Otherwise, leave sender as is. */
5863 ? groktypename (TREE_TYPE (method_prototype))
5866 = build_pointer_type
5867 (build_function_type
5870 (method_prototype, METHOD_REF, super_flag)));
5872 lookup_object = build_c_cast (rcv_p, lookup_object);
5874 if (flag_next_runtime)
5876 /* If we are returning a struct in memory, and the address
5877 of that memory location is passed as a hidden first
5878 argument, then change which messenger entry point this
5879 expr will call. NB: Note that sender_cast remains
5880 unchanged (it already has a struct return type). */
5881 if (!targetm.calls.struct_value_rtx (0, 0)
5882 && (TREE_CODE (ret_type) == RECORD_TYPE
5883 || TREE_CODE (ret_type) == UNION_TYPE)
5884 && targetm.calls.return_in_memory (ret_type, 0))
5885 sender = (super_flag ? umsg_super_stret_decl :
5886 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5888 method_params = tree_cons (NULL_TREE, lookup_object,
5889 tree_cons (NULL_TREE, selector,
5891 TREE_USED (sender) = 1;
5892 assemble_external (sender);
5893 /* We want to cast the sender, not convert it. */
5894 return build_function_call (build_c_cast (sender_cast, sender),
5899 /* This is the portable (GNU) way. */
5900 tree method, object;
5902 /* First, call the lookup function to get a pointer to the method,
5903 then cast the pointer, then call it with the method arguments.
5904 Use SAVE_EXPR to avoid evaluating the receiver twice. */
5905 lookup_object = save_expr (lookup_object);
5906 object = (super_flag ? self_decl : lookup_object);
5907 TREE_USED (sender) = 1;
5908 assemble_external (sender);
5910 = build_function_call (sender,
5911 tree_cons (NULL_TREE, lookup_object,
5912 tree_cons (NULL_TREE, selector,
5915 /* Pass the object to the method. */
5916 TREE_USED (method) = 1;
5917 assemble_external (method);
5918 return build_function_call
5919 (build_c_cast (sender_cast, method),
5920 tree_cons (NULL_TREE, object,
5921 tree_cons (NULL_TREE, selector, method_params)));
5926 build_protocol_reference (tree p)
5928 tree decl, ident, ptype;
5930 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5932 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5934 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5935 objc_protocol_template),
5938 if (identifier_global_value (ident))
5939 decl = identifier_global_value (ident); /* Set by pushdecl. */
5942 decl = build_decl (VAR_DECL, ident, ptype);
5943 DECL_EXTERNAL (decl) = 1;
5944 TREE_PUBLIC (decl) = 0;
5945 TREE_USED (decl) = 1;
5946 DECL_ARTIFICIAL (decl) = 1;
5948 make_decl_rtl (decl, 0);
5949 pushdecl_top_level (decl);
5952 PROTOCOL_FORWARD_DECL (p) = decl;
5955 /* This function is called by the parser when (and only when) a
5956 @protocol() expression is found, in order to compile it. */
5958 build_protocol_expr (tree protoname)
5961 tree p = lookup_protocol (protoname);
5965 error ("cannot find protocol declaration for `%s'",
5966 IDENTIFIER_POINTER (protoname));
5967 return error_mark_node;
5970 if (!PROTOCOL_FORWARD_DECL (p))
5971 build_protocol_reference (p);
5973 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5975 /* ??? Ideally we'd build the reference with protocol_type directly,
5976 if we have it, rather than converting it here. */
5977 expr = convert (protocol_type, expr);
5979 /* The @protocol() expression is being compiled into a pointer to a
5980 statically allocated instance of the Protocol class. To become
5981 usable at runtime, the 'isa' pointer of the instance need to be
5982 fixed up at runtime by the runtime library, to point to the
5983 actual 'Protocol' class. */
5985 /* For the GNU runtime, put the static Protocol instance in the list
5986 of statically allocated instances, so that we make sure that its
5987 'isa' pointer is fixed up at runtime by the GNU runtime library
5988 to point to the Protocol class (at runtime, when loading the
5989 module, the GNU runtime library loops on the statically allocated
5990 instances (as found in the defs field in objc_symtab) and fixups
5991 all the 'isa' pointers of those objects). */
5992 if (! flag_next_runtime)
5994 /* This type is a struct containing the fields of a Protocol
5995 object. (Cfr. protocol_type instead is the type of a pointer
5996 to such a struct). */
5997 tree protocol_struct_type = xref_tag
5998 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6001 /* Look for the list of Protocol statically allocated instances
6002 to fixup at runtime. Create a new list to hold Protocol
6003 statically allocated instances, if the list is not found. At
6004 present there is only another list, holding NSConstantString
6005 static instances to be fixed up at runtime. */
6006 for (chain = &objc_static_instances;
6007 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6008 chain = &TREE_CHAIN (*chain));
6011 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6012 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6016 /* Add this statically allocated instance to the Protocol list. */
6017 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6018 PROTOCOL_FORWARD_DECL (p),
6019 TREE_PURPOSE (*chain));
6026 /* This function is called by the parser when a @selector() expression
6027 is found, in order to compile it. It is only called by the parser
6028 and only to compile a @selector(). */
6030 build_selector_expr (tree selnamelist)
6034 /* Obtain the full selector name. */
6035 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6036 /* A unary selector. */
6037 selname = selnamelist;
6038 else if (TREE_CODE (selnamelist) == TREE_LIST)
6039 selname = build_keyword_selector (selnamelist);
6043 /* If we are required to check @selector() expressions as they
6044 are found, check that the selector has been declared. */
6045 if (warn_undeclared_selector)
6047 /* Look the selector up in the list of all known class and
6048 instance methods (up to this line) to check that the selector
6052 /* First try with instance methods. */
6053 hsh = hash_lookup (nst_method_hash_list, selname);
6055 /* If not found, try with class methods. */
6058 hsh = hash_lookup (cls_method_hash_list, selname);
6061 /* If still not found, print out a warning. */
6064 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6069 if (flag_typed_selectors)
6070 return build_typed_selector_reference (selname, 0);
6072 return build_selector_reference (selname);
6076 build_encode_expr (tree type)
6081 encode_type (type, obstack_object_size (&util_obstack),
6082 OBJC_ENCODE_INLINE_DEFS);
6083 obstack_1grow (&util_obstack, 0); /* null terminate string */
6084 string = obstack_finish (&util_obstack);
6086 /* Synthesize a string that represents the encoded struct/union. */
6087 result = my_build_string (strlen (string) + 1, string);
6088 obstack_free (&util_obstack, util_firstobj);
6093 build_ivar_reference (tree id)
6095 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6097 /* Historically, a class method that produced objects (factory
6098 method) would assign `self' to the instance that it
6099 allocated. This would effectively turn the class method into
6100 an instance method. Following this assignment, the instance
6101 variables could be accessed. That practice, while safe,
6102 violates the simple rule that a class method should not refer
6103 to an instance variable. It's better to catch the cases
6104 where this is done unknowingly than to support the above
6106 warning ("instance variable `%s' accessed in class method",
6107 IDENTIFIER_POINTER (id));
6108 TREE_TYPE (self_decl) = instance_type; /* cast */
6111 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6114 /* Compute a hash value for a given method SEL_NAME. */
6117 hash_func (tree sel_name)
6119 const unsigned char *s
6120 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6124 h = h * 67 + *s++ - 113;
6131 nst_method_hash_list
6132 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6133 cls_method_hash_list
6134 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6137 /* WARNING!!!! hash_enter is called with a method, and will peek
6138 inside to find its selector! But hash_lookup is given a selector
6139 directly, and looks for the selector that's inside the found
6140 entry's key (method) for comparison. */
6143 hash_enter (hash *hashlist, tree method)
6146 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6148 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6150 obj->next = hashlist[slot];
6153 hashlist[slot] = obj; /* append to front */
6157 hash_lookup (hash *hashlist, tree sel_name)
6161 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6165 if (sel_name == METHOD_SEL_NAME (target->key))
6168 target = target->next;
6174 hash_add_attr (hash entry, tree value)
6178 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6179 obj->next = entry->list;
6182 entry->list = obj; /* append to front */
6186 lookup_method (tree mchain, tree method)
6190 if (TREE_CODE (method) == IDENTIFIER_NODE)
6193 key = METHOD_SEL_NAME (method);
6197 if (METHOD_SEL_NAME (mchain) == key)
6200 mchain = TREE_CHAIN (mchain);
6206 lookup_method_static (tree interface, tree ident, int is_class)
6208 tree meth = NULL_TREE, root_inter = NULL_TREE;
6209 tree inter = interface;
6213 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6214 tree category = inter;
6216 /* First, look up the method in the class itself. */
6217 if ((meth = lookup_method (chain, ident)))
6220 /* Failing that, look for the method in each category of the class. */
6221 while ((category = CLASS_CATEGORY_LIST (category)))
6223 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6225 /* Check directly in each category. */
6226 if ((meth = lookup_method (chain, ident)))
6229 /* Failing that, check in each category's protocols. */
6230 if (CLASS_PROTOCOL_LIST (category))
6232 if ((meth = (lookup_method_in_protocol_list
6233 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6238 /* If not found in categories, check in protocols of the main class. */
6239 if (CLASS_PROTOCOL_LIST (inter))
6241 if ((meth = (lookup_method_in_protocol_list
6242 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6246 /* Failing that, climb up the inheritance hierarchy. */
6248 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6252 /* If no class (factory) method was found, check if an _instance_
6253 method of the same name exists in the root class. This is what
6254 the Objective-C runtime will do. If an instance method was not
6256 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6259 /* Add the method to the hash list if it doesn't contain an identical
6262 add_method_to_hash_list (hash *hash_list, tree method)
6266 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6268 /* Install on a global chain. */
6269 hash_enter (hash_list, method);
6273 /* Check types against those; if different, add to a list. */
6275 int already_there = comp_proto_with_proto (method, hsh->key);
6276 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6277 already_there |= comp_proto_with_proto (method, loop->value);
6279 hash_add_attr (hsh, method);
6284 objc_add_method (tree class, tree method, int is_class)
6288 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6290 /* put method on list in reverse order */
6293 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6294 CLASS_CLS_METHODS (class) = method;
6298 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6299 CLASS_NST_METHODS (class) = method;
6304 /* When processing an @interface for a class or category, give hard
6305 errors on methods with identical selectors but differing argument
6306 and/or return types. We do not do this for @implementations, because
6307 C/C++ will do it for us (i.e., there will be duplicate function
6308 definition errors). */
6309 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6310 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6311 && !comp_proto_with_proto (method, mth))
6312 error ("duplicate declaration of method `%c%s'",
6313 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6317 add_method_to_hash_list (cls_method_hash_list, method);
6320 add_method_to_hash_list (nst_method_hash_list, method);
6322 /* Instance methods in root classes (and categories thereof)
6323 may acts as class methods as a last resort. */
6324 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6325 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6326 class = lookup_interface (CLASS_NAME (class));
6328 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6329 && !CLASS_SUPER_NAME (class))
6330 add_method_to_hash_list (cls_method_hash_list, method);
6337 add_class (tree class)
6339 /* Put interfaces on list in reverse order. */
6340 TREE_CHAIN (class) = interface_chain;
6341 interface_chain = class;
6342 return interface_chain;
6346 add_category (tree class, tree category)
6348 /* Put categories on list in reverse order. */
6349 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6353 warning ("duplicate interface declaration for category `%s(%s)'",
6354 IDENTIFIER_POINTER (CLASS_NAME (class)),
6355 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6359 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6360 CLASS_CATEGORY_LIST (class) = category;
6364 /* Called after parsing each instance variable declaration. Necessary to
6365 preserve typedefs and implement public/private...
6367 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6370 add_instance_variable (tree class, int public, tree declarator,
6371 tree declspecs, tree width)
6373 tree field_decl = grokfield (declarator, declspecs, width);
6374 tree field_type = TREE_TYPE (field_decl);
6375 const char *ivar_name = DECL_NAME (field_decl)
6376 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6381 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6383 error ("illegal reference type specified for instance variable `%s'",
6385 /* Return class as is without adding this ivar. */
6390 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6391 || TYPE_SIZE (field_type) == error_mark_node
6392 /* 'type[0]' is allowed, but 'type[]' is not! */
6394 || (TYPE_SIZE (field_type) == bitsize_zero_node
6395 && !TREE_OPERAND (declarator, 1))
6399 error ("instance variable `%s' has unknown size", ivar_name);
6400 /* Return class as is without adding this ivar. */
6405 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6406 cannot be ivars; ditto for classes with vtables. */
6407 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6408 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6410 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6411 if(TYPE_POLYMORPHIC_P (field_type)) {
6412 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6413 error ("type `%s' has virtual member functions", type_name);
6414 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6415 type_name, ivar_name);
6416 /* Return class as is without adding this ivar. */
6419 /* user-defined constructors and destructors are not known to Obj-C and
6420 hence will not be called. This may or may not be a problem. */
6421 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6422 warning ("type `%s' has a user-defined constructor", type_name);
6423 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6424 warning ("type `%s' has a user-defined destructor", type_name);
6425 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6429 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6433 TREE_PUBLIC (field_decl) = 0;
6434 TREE_PRIVATE (field_decl) = 0;
6435 TREE_PROTECTED (field_decl) = 1;
6439 TREE_PUBLIC (field_decl) = 1;
6440 TREE_PRIVATE (field_decl) = 0;
6441 TREE_PROTECTED (field_decl) = 0;
6445 TREE_PUBLIC (field_decl) = 0;
6446 TREE_PRIVATE (field_decl) = 1;
6447 TREE_PROTECTED (field_decl) = 0;
6452 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6453 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6454 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6459 is_ivar (tree decl_chain, tree ident)
6461 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6462 if (DECL_NAME (decl_chain) == ident)
6467 /* True if the ivar is private and we are not in its implementation. */
6470 is_private (tree decl)
6472 if (TREE_PRIVATE (decl)
6473 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
6475 error ("instance variable `%s' is declared private",
6476 IDENTIFIER_POINTER (DECL_NAME (decl)));
6483 /* We have an instance variable reference;, check to see if it is public. */
6486 is_public (tree expr, tree identifier)
6488 tree basetype = TREE_TYPE (expr);
6489 enum tree_code code = TREE_CODE (basetype);
6492 if (code == RECORD_TYPE)
6494 if (TREE_STATIC_TEMPLATE (basetype))
6496 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6498 error ("cannot find interface declaration for `%s'",
6499 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6503 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6505 if (TREE_PUBLIC (decl))
6508 /* Important difference between the Stepstone translator:
6509 all instance variables should be public within the context
6510 of the implementation. */
6511 if (objc_implementation_context
6512 && (((TREE_CODE (objc_implementation_context)
6513 == CLASS_IMPLEMENTATION_TYPE)
6514 || (TREE_CODE (objc_implementation_context)
6515 == CATEGORY_IMPLEMENTATION_TYPE))
6516 && (CLASS_NAME (objc_implementation_context)
6517 == OBJC_TYPE_NAME (basetype))))
6518 return ! is_private (decl);
6520 /* The 2.95.2 compiler sometimes allowed C functions to access
6521 non-@public ivars. We will let this slide for now... */
6522 if (!objc_method_context)
6524 warning ("instance variable `%s' is %s; "
6525 "this will be a hard error in the future",
6526 IDENTIFIER_POINTER (identifier),
6527 TREE_PRIVATE (decl) ? "@private" : "@protected");
6531 error ("instance variable `%s' is declared %s",
6532 IDENTIFIER_POINTER (identifier),
6533 TREE_PRIVATE (decl) ? "private" : "protected");
6538 else if (objc_implementation_context && (basetype == objc_object_reference))
6540 TREE_TYPE (expr) = uprivate_record;
6541 warning ("static access to object of type `id'");
6548 /* Make sure all entries in CHAIN are also in LIST. */
6551 check_methods (tree chain, tree list, int mtype)
6557 if (!lookup_method (list, chain))
6561 if (TREE_CODE (objc_implementation_context)
6562 == CLASS_IMPLEMENTATION_TYPE)
6563 warning ("incomplete implementation of class `%s'",
6564 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6565 else if (TREE_CODE (objc_implementation_context)
6566 == CATEGORY_IMPLEMENTATION_TYPE)
6567 warning ("incomplete implementation of category `%s'",
6568 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6572 warning ("method definition for `%c%s' not found",
6573 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6576 chain = TREE_CHAIN (chain);
6582 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6585 conforms_to_protocol (tree class, tree protocol)
6587 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6589 tree p = CLASS_PROTOCOL_LIST (class);
6590 while (p && TREE_VALUE (p) != protocol)
6595 tree super = (CLASS_SUPER_NAME (class)
6596 ? lookup_interface (CLASS_SUPER_NAME (class))
6598 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6607 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6608 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6611 check_methods_accessible (tree chain, tree context, int mtype)
6615 tree base_context = context;
6619 context = base_context;
6623 list = CLASS_CLS_METHODS (context);
6625 list = CLASS_NST_METHODS (context);
6627 if (lookup_method (list, chain))
6630 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6631 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6632 context = (CLASS_SUPER_NAME (context)
6633 ? lookup_interface (CLASS_SUPER_NAME (context))
6636 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6637 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6638 context = (CLASS_NAME (context)
6639 ? lookup_interface (CLASS_NAME (context))
6645 if (context == NULL_TREE)
6649 if (TREE_CODE (objc_implementation_context)
6650 == CLASS_IMPLEMENTATION_TYPE)
6651 warning ("incomplete implementation of class `%s'",
6653 (CLASS_NAME (objc_implementation_context)));
6654 else if (TREE_CODE (objc_implementation_context)
6655 == CATEGORY_IMPLEMENTATION_TYPE)
6656 warning ("incomplete implementation of category `%s'",
6658 (CLASS_SUPER_NAME (objc_implementation_context)));
6661 warning ("method definition for `%c%s' not found",
6662 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6665 chain = TREE_CHAIN (chain); /* next method... */
6670 /* Check whether the current interface (accessible via
6671 'objc_implementation_context') actually implements protocol P, along
6672 with any protocols that P inherits. */
6675 check_protocol (tree p, const char *type, const char *name)
6677 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6681 /* Ensure that all protocols have bodies! */
6684 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6685 CLASS_CLS_METHODS (objc_implementation_context),
6687 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6688 CLASS_NST_METHODS (objc_implementation_context),
6693 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6694 objc_implementation_context,
6696 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6697 objc_implementation_context,
6702 warning ("%s `%s' does not fully implement the `%s' protocol",
6703 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6706 /* Check protocols recursively. */
6707 if (PROTOCOL_LIST (p))
6709 tree subs = PROTOCOL_LIST (p);
6711 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6715 tree sub = TREE_VALUE (subs);
6717 /* If the superclass does not conform to the protocols
6718 inherited by P, then we must! */
6719 if (!super_class || !conforms_to_protocol (super_class, sub))
6720 check_protocol (sub, type, name);
6721 subs = TREE_CHAIN (subs);
6726 /* Check whether the current interface (accessible via
6727 'objc_implementation_context') actually implements the protocols listed
6731 check_protocols (tree proto_list, const char *type, const char *name)
6733 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6735 tree p = TREE_VALUE (proto_list);
6737 check_protocol (p, type, name);
6741 /* Make sure that the class CLASS_NAME is defined
6742 CODE says which kind of thing CLASS_NAME ought to be.
6743 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6744 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6747 start_class (enum tree_code code, tree class_name, tree super_name,
6753 if (current_namespace != global_namespace) {
6754 error ("Objective-C declarations may only appear in global scope");
6756 #endif /* OBJCPLUS */
6758 if (objc_implementation_context)
6760 warning ("`@end' missing in implementation context");
6761 finish_class (objc_implementation_context);
6762 objc_ivar_chain = NULL_TREE;
6763 objc_implementation_context = NULL_TREE;
6766 class = make_node (code);
6767 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6769 CLASS_NAME (class) = class_name;
6770 CLASS_SUPER_NAME (class) = super_name;
6771 CLASS_CLS_METHODS (class) = NULL_TREE;
6773 if (! is_class_name (class_name)
6774 && (decl = lookup_name (class_name)))
6776 error ("`%s' redeclared as different kind of symbol",
6777 IDENTIFIER_POINTER (class_name));
6778 error ("%Jprevious declaration of '%D'",
6782 if (code == CLASS_IMPLEMENTATION_TYPE)
6787 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6788 if (TREE_VALUE (chain) == class_name)
6790 error ("reimplementation of class `%s'",
6791 IDENTIFIER_POINTER (class_name));
6792 return error_mark_node;
6794 implemented_classes = tree_cons (NULL_TREE, class_name,
6795 implemented_classes);
6798 /* Reset for multiple classes per file. */
6801 objc_implementation_context = class;
6803 /* Lookup the interface for this implementation. */
6805 if (!(implementation_template = lookup_interface (class_name)))
6807 warning ("cannot find interface declaration for `%s'",
6808 IDENTIFIER_POINTER (class_name));
6809 add_class (implementation_template = objc_implementation_context);
6812 /* If a super class has been specified in the implementation,
6813 insure it conforms to the one specified in the interface. */
6816 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6818 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6819 const char *const name =
6820 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6821 error ("conflicting super class name `%s'",
6822 IDENTIFIER_POINTER (super_name));
6823 error ("previous declaration of `%s'", name);
6826 else if (! super_name)
6828 CLASS_SUPER_NAME (objc_implementation_context)
6829 = CLASS_SUPER_NAME (implementation_template);
6833 else if (code == CLASS_INTERFACE_TYPE)
6835 if (lookup_interface (class_name))
6837 error ("duplicate interface declaration for class `%s'",
6839 warning ("duplicate interface declaration for class `%s'",
6841 IDENTIFIER_POINTER (class_name));
6846 CLASS_PROTOCOL_LIST (class)
6847 = lookup_and_install_protocols (protocol_list);
6850 else if (code == CATEGORY_INTERFACE_TYPE)
6852 tree class_category_is_assoc_with;
6854 /* For a category, class_name is really the name of the class that
6855 the following set of methods will be associated with. We must
6856 find the interface so that can derive the objects template. */
6858 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6860 error ("cannot find interface declaration for `%s'",
6861 IDENTIFIER_POINTER (class_name));
6862 exit (FATAL_EXIT_CODE);
6865 add_category (class_category_is_assoc_with, class);
6868 CLASS_PROTOCOL_LIST (class)
6869 = lookup_and_install_protocols (protocol_list);
6872 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6874 /* Reset for multiple classes per file. */
6877 objc_implementation_context = class;
6879 /* For a category, class_name is really the name of the class that
6880 the following set of methods will be associated with. We must
6881 find the interface so that can derive the objects template. */
6883 if (!(implementation_template = lookup_interface (class_name)))
6885 error ("cannot find interface declaration for `%s'",
6886 IDENTIFIER_POINTER (class_name));
6887 exit (FATAL_EXIT_CODE);
6894 continue_class (tree class)
6896 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6897 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6899 struct imp_entry *imp_entry;
6902 /* Check consistency of the instance variables. */
6904 if (CLASS_IVARS (class))
6905 check_ivars (implementation_template, class);
6907 /* code generation */
6909 ivar_context = build_private_template (implementation_template);
6911 if (!objc_class_template)
6912 build_class_template ();
6914 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6916 imp_entry->next = imp_list;
6917 imp_entry->imp_context = class;
6918 imp_entry->imp_template = implementation_template;
6920 synth_forward_declarations ();
6921 imp_entry->class_decl = UOBJC_CLASS_decl;
6922 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6924 /* Append to front and increment count. */
6925 imp_list = imp_entry;
6926 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6931 return ivar_context;
6934 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6936 if (!CLASS_STATIC_TEMPLATE (class))
6938 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6939 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6940 CLASS_STATIC_TEMPLATE (class) = record;
6942 /* Mark this record as a class template for static typing. */
6943 TREE_STATIC_TEMPLATE (record) = 1;
6950 return error_mark_node;
6953 /* This is called once we see the "@end" in an interface/implementation. */
6956 finish_class (tree class)
6958 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6960 /* All code generation is done in finish_objc. */
6962 if (implementation_template != objc_implementation_context)
6964 /* Ensure that all method listed in the interface contain bodies. */
6965 check_methods (CLASS_CLS_METHODS (implementation_template),
6966 CLASS_CLS_METHODS (objc_implementation_context), '+');
6967 check_methods (CLASS_NST_METHODS (implementation_template),
6968 CLASS_NST_METHODS (objc_implementation_context), '-');
6970 if (CLASS_PROTOCOL_LIST (implementation_template))
6971 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6973 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6977 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6979 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6983 /* Ensure all method listed in the interface contain bodies. */
6984 check_methods (CLASS_CLS_METHODS (category),
6985 CLASS_CLS_METHODS (objc_implementation_context), '+');
6986 check_methods (CLASS_NST_METHODS (category),
6987 CLASS_NST_METHODS (objc_implementation_context), '-');
6989 if (CLASS_PROTOCOL_LIST (category))
6990 check_protocols (CLASS_PROTOCOL_LIST (category),
6992 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6996 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6999 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
7000 char *string = (char *) alloca (strlen (class_name) + 3);
7002 /* extern struct objc_object *_<my_name>; */
7004 sprintf (string, "_%s", class_name);
7006 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
7007 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
7008 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7014 add_protocol (tree protocol)
7016 /* Put protocol on list in reverse order. */
7017 TREE_CHAIN (protocol) = protocol_chain;
7018 protocol_chain = protocol;
7019 return protocol_chain;
7023 lookup_protocol (tree ident)
7027 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7028 if (ident == PROTOCOL_NAME (chain))
7034 /* This function forward declares the protocols named by NAMES. If
7035 they are already declared or defined, the function has no effect. */
7038 objc_declare_protocols (tree names)
7043 if (current_namespace != global_namespace) {
7044 error ("Objective-C declarations may only appear in global scope");
7046 #endif /* OBJCPLUS */
7048 for (list = names; list; list = TREE_CHAIN (list))
7050 tree name = TREE_VALUE (list);
7052 if (lookup_protocol (name) == NULL_TREE)
7054 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7056 TYPE_BINFO (protocol) = make_tree_vec (2);
7057 PROTOCOL_NAME (protocol) = name;
7058 PROTOCOL_LIST (protocol) = NULL_TREE;
7059 add_protocol (protocol);
7060 PROTOCOL_DEFINED (protocol) = 0;
7061 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7067 start_protocol (enum tree_code code, tree name, tree list)
7072 if (current_namespace != global_namespace) {
7073 error ("Objective-C declarations may only appear in global scope");
7075 #endif /* OBJCPLUS */
7077 /* This is as good a place as any. Need to invoke
7078 push_tag_toplevel. */
7079 if (!objc_protocol_template)
7080 objc_protocol_template = build_protocol_template ();
7082 protocol = lookup_protocol (name);
7086 protocol = make_node (code);
7087 TYPE_BINFO (protocol) = make_tree_vec (2);
7089 PROTOCOL_NAME (protocol) = name;
7090 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7091 add_protocol (protocol);
7092 PROTOCOL_DEFINED (protocol) = 1;
7093 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7095 check_protocol_recursively (protocol, list);
7097 else if (! PROTOCOL_DEFINED (protocol))
7099 PROTOCOL_DEFINED (protocol) = 1;
7100 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7102 check_protocol_recursively (protocol, list);
7106 warning ("duplicate declaration for protocol `%s'",
7107 IDENTIFIER_POINTER (name));
7113 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7118 /* "Encode" a data type into a string, which grows in util_obstack.
7119 ??? What is the FORMAT? Someone please document this! */
7122 encode_type_qualifiers (tree declspecs)
7126 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7128 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7129 obstack_1grow (&util_obstack, 'r');
7130 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7131 obstack_1grow (&util_obstack, 'n');
7132 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7133 obstack_1grow (&util_obstack, 'N');
7134 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7135 obstack_1grow (&util_obstack, 'o');
7136 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7137 obstack_1grow (&util_obstack, 'O');
7138 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7139 obstack_1grow (&util_obstack, 'R');
7140 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7141 obstack_1grow (&util_obstack, 'V');
7145 /* Encode a pointer type. */
7148 encode_pointer (tree type, int curtype, int format)
7150 tree pointer_to = TREE_TYPE (type);
7152 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7154 if (OBJC_TYPE_NAME (pointer_to)
7155 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7157 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7159 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7161 obstack_1grow (&util_obstack, '@');
7164 else if (TREE_STATIC_TEMPLATE (pointer_to))
7166 if (generating_instance_variables)
7168 obstack_1grow (&util_obstack, '@');
7169 obstack_1grow (&util_obstack, '"');
7170 obstack_grow (&util_obstack, name, strlen (name));
7171 obstack_1grow (&util_obstack, '"');
7176 obstack_1grow (&util_obstack, '@');
7180 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7182 obstack_1grow (&util_obstack, '#');
7185 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7187 obstack_1grow (&util_obstack, ':');
7192 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7193 && TYPE_MODE (pointer_to) == QImode)
7195 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7196 ? OBJC_TYPE_NAME (pointer_to)
7197 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7199 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7201 obstack_1grow (&util_obstack, '*');
7206 /* We have a type that does not get special treatment. */
7208 /* NeXT extension */
7209 obstack_1grow (&util_obstack, '^');
7210 encode_type (pointer_to, curtype, format);
7214 encode_array (tree type, int curtype, int format)
7216 tree an_int_cst = TYPE_SIZE (type);
7217 tree array_of = TREE_TYPE (type);
7220 /* An incomplete array is treated like a pointer. */
7221 if (an_int_cst == NULL)
7223 encode_pointer (type, curtype, format);
7227 sprintf (buffer, "[%ld",
7228 (long) (TREE_INT_CST_LOW (an_int_cst)
7229 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7231 obstack_grow (&util_obstack, buffer, strlen (buffer));
7232 encode_type (array_of, curtype, format);
7233 obstack_1grow (&util_obstack, ']');
7238 encode_aggregate_within (tree type, int curtype, int format, int left,
7242 /* NB: aggregates that are pointed to have slightly different encoding
7243 rules in that you never encode the names of instance variables. */
7245 = (obstack_object_size (&util_obstack) > 0
7246 && *(obstack_next_free (&util_obstack) - 1) == '^');
7248 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7249 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7251 /* Traverse struct aliases; it is important to get the
7252 original struct and its tag name (if any). */
7253 type = TYPE_MAIN_VARIANT (type);
7254 name = OBJC_TYPE_NAME (type);
7255 /* Open parenth/bracket. */
7256 obstack_1grow (&util_obstack, left);
7258 /* Encode the struct/union tag name, or '?' if a tag was
7259 not provided. Typedef aliases do not qualify. */
7260 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7262 /* Did this struct have a tag? */
7263 && !TYPE_WAS_ANONYMOUS (type)
7266 obstack_grow (&util_obstack,
7267 IDENTIFIER_POINTER (name),
7268 strlen (IDENTIFIER_POINTER (name)));
7270 obstack_1grow (&util_obstack, '?');
7272 /* Encode the types (and possibly names) of the inner fields,
7274 if (inline_contents)
7276 tree fields = TYPE_FIELDS (type);
7278 obstack_1grow (&util_obstack, '=');
7279 for (; fields; fields = TREE_CHAIN (fields))
7282 /* C++ static members, and things that are not fields at all,
7283 should not appear in the encoding. */
7284 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7287 if (generating_instance_variables && !pointed_to)
7289 tree fname = DECL_NAME (fields);
7291 obstack_1grow (&util_obstack, '"');
7292 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7293 obstack_grow (&util_obstack,
7294 IDENTIFIER_POINTER (fname),
7295 strlen (IDENTIFIER_POINTER (fname)));
7296 obstack_1grow (&util_obstack, '"');
7298 encode_field_decl (fields, curtype, format);
7301 /* Close parenth/bracket. */
7302 obstack_1grow (&util_obstack, right);
7306 encode_aggregate (tree type, int curtype, int format)
7308 enum tree_code code = TREE_CODE (type);
7314 encode_aggregate_within (type, curtype, format, '{', '}');
7319 encode_aggregate_within (type, curtype, format, '(', ')');
7324 obstack_1grow (&util_obstack, 'i');
7332 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7336 encode_next_bitfield (int width)
7339 sprintf (buffer, "b%d", width);
7340 obstack_grow (&util_obstack, buffer, strlen (buffer));
7343 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7345 encode_type (tree type, int curtype, int format)
7347 enum tree_code code = TREE_CODE (type);
7350 if (code == INTEGER_TYPE)
7352 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7354 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7355 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7357 if (type == long_unsigned_type_node
7358 || type == long_integer_type_node)
7359 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7361 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7363 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7366 obstack_1grow (&util_obstack, c);
7369 else if (code == REAL_TYPE)
7371 /* Floating point types. */
7372 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7374 case 32: c = 'f'; break;
7376 case 128: c = 'd'; break;
7379 obstack_1grow (&util_obstack, c);
7382 else if (code == VOID_TYPE)
7383 obstack_1grow (&util_obstack, 'v');
7385 else if (code == BOOLEAN_TYPE)
7386 obstack_1grow (&util_obstack, 'B');
7388 else if (code == ARRAY_TYPE)
7389 encode_array (type, curtype, format);
7391 else if (code == POINTER_TYPE)
7392 encode_pointer (type, curtype, format);
7394 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7395 encode_aggregate (type, curtype, format);
7397 else if (code == FUNCTION_TYPE) /* '?' */
7398 obstack_1grow (&util_obstack, '?');
7402 encode_gnu_bitfield (int position, tree type, int size)
7404 enum tree_code code = TREE_CODE (type);
7406 char charType = '?';
7408 if (code == INTEGER_TYPE)
7410 if (integer_zerop (TYPE_MIN_VALUE (type)))
7412 /* Unsigned integer types. */
7414 if (TYPE_MODE (type) == QImode)
7416 else if (TYPE_MODE (type) == HImode)
7418 else if (TYPE_MODE (type) == SImode)
7420 if (type == long_unsigned_type_node)
7425 else if (TYPE_MODE (type) == DImode)
7430 /* Signed integer types. */
7432 if (TYPE_MODE (type) == QImode)
7434 else if (TYPE_MODE (type) == HImode)
7436 else if (TYPE_MODE (type) == SImode)
7438 if (type == long_integer_type_node)
7444 else if (TYPE_MODE (type) == DImode)
7448 else if (code == ENUMERAL_TYPE)
7453 sprintf (buffer, "b%d%c%d", position, charType, size);
7454 obstack_grow (&util_obstack, buffer, strlen (buffer));
7458 encode_field_decl (tree field_decl, int curtype, int format)
7463 /* C++ static members, and things that are not fields at all,
7464 should not appear in the encoding. */
7465 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7469 type = TREE_TYPE (field_decl);
7471 /* Generate the bitfield typing information, if needed. Note the difference
7472 between GNU and NeXT runtimes. */
7473 if (DECL_BIT_FIELD_TYPE (field_decl))
7475 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7477 if (flag_next_runtime)
7478 encode_next_bitfield (size);
7480 encode_gnu_bitfield (int_bit_position (field_decl),
7481 DECL_BIT_FIELD_TYPE (field_decl), size);
7484 encode_type (TREE_TYPE (field_decl), curtype, format);
7488 objc_expr_last (tree complex_expr)
7493 while ((next = TREE_OPERAND (complex_expr, 0)))
7494 complex_expr = next;
7496 return complex_expr;
7500 synth_self_and_ucmd_args (void)
7504 if (objc_method_context
7505 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7506 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7508 /* Really a `struct objc_class *'. However, we allow people to
7509 assign to self, which changes its type midstream. */
7510 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7512 push_parm_decl (build_tree_list
7513 (build_tree_list (decl_specs,
7514 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7517 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (selector_type));
7518 push_parm_decl (build_tree_list
7519 (build_tree_list (decl_specs,
7520 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7524 /* Transform a method definition into a function definition as follows:
7525 - synthesize the first two arguments, "self" and "_cmd". */
7528 start_method_def (tree method)
7530 /* Required to implement _msgSuper. */
7531 objc_method_context = method;
7532 UOBJC_SUPER_decl = NULL_TREE;
7534 /* Must be called BEFORE start_function. */
7536 declare_parm_level ();
7538 /* Generate prototype declarations for arguments..."new-style". */
7539 synth_self_and_ucmd_args ();
7541 /* Generate argument declarations if a keyword_decl. */
7542 if (METHOD_SEL_ARGS (method))
7544 tree arglist = METHOD_SEL_ARGS (method);
7547 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7548 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7552 tree last_expr = objc_expr_last (arg_decl);
7554 /* Unite the abstract decl with its name. */
7555 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7556 push_parm_decl (build_tree_list
7557 (build_tree_list (arg_spec, arg_decl),
7561 /* Unhook: restore the abstract declarator. */
7562 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7567 push_parm_decl (build_tree_list
7568 (build_tree_list (arg_spec,
7569 KEYWORD_ARG_NAME (arglist)),
7572 arglist = TREE_CHAIN (arglist);
7577 if (METHOD_ADD_ARGS (method) != NULL_TREE
7578 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7580 /* We have a variable length selector - in "prototype" format. */
7581 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7584 /* This must be done prior to calling pushdecl. pushdecl is
7585 going to change our chain on us. */
7586 tree nextkey = TREE_CHAIN (akey);
7594 warn_with_method (const char *message, int mtype, tree method)
7596 /* Add a readable method name to the warning. */
7597 warning ("%J%s `%c%s'", method,
7598 message, mtype, gen_method_decl (method, errbuf));
7601 /* Return 1 if METHOD is consistent with PROTO. */
7604 comp_method_with_proto (tree method, tree proto)
7606 /* Create a function template node at most once. */
7607 if (!function1_template)
7608 function1_template = make_node (FUNCTION_TYPE);
7610 /* Install argument types - normally set by build_function_type. */
7611 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7613 /* install return type */
7614 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7616 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
7620 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7623 objc_types_are_equivalent (tree type1, tree type2)
7627 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7629 type1 = TYPE_PROTOCOL_LIST (type1);
7630 type2 = TYPE_PROTOCOL_LIST (type2);
7631 if (list_length (type1) == list_length (type2))
7633 for (; type2; type2 = TREE_CHAIN (type2))
7634 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7641 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7644 comp_proto_with_proto (tree proto1, tree proto2)
7648 /* The following test is needed in case there are hashing
7650 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7653 /* Compare return types. */
7654 type1 = groktypename (TREE_TYPE (proto1));
7655 type2 = groktypename (TREE_TYPE (proto2));
7657 if (!objc_types_are_equivalent (type1, type2))
7660 /* Compare argument types. */
7661 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7662 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7664 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7666 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7670 return (!type1 && !type2);
7673 /* - Generate an identifier for the function. the format is "_n_cls",
7674 where 1 <= n <= nMethods, and cls is the name the implementation we
7676 - Install the return type from the method declaration.
7677 - If we have a prototype, check for type consistency. */
7680 really_start_method (tree method, tree parmlist)
7682 tree sc_spec, ret_spec, ret_decl, decl_specs;
7683 tree method_decl, method_id;
7684 const char *sel_name, *class_name, *cat_name;
7687 /* Synth the storage class & assemble the return type. */
7688 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7689 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7690 decl_specs = chainon (sc_spec, ret_spec);
7692 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7693 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7694 cat_name = ((TREE_CODE (objc_implementation_context)
7695 == CLASS_IMPLEMENTATION_TYPE)
7697 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7700 /* Make sure this is big enough for any plausible method label. */
7701 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7702 + (cat_name ? strlen (cat_name) : 0));
7704 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7705 class_name, cat_name, sel_name, method_slot);
7707 method_id = get_identifier (buf);
7710 /* Objective-C methods cannot be overloaded, so we don't need
7711 the type encoding appended. It looks bad anyway... */
7712 push_lang_context (lang_name_c);
7715 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7717 /* Check the declarator portion of the return type for the method. */
7718 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7720 /* Unite the complex decl (specified in the abstract decl) with the
7721 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7722 tree save_expr = objc_expr_last (ret_decl);
7724 TREE_OPERAND (save_expr, 0) = method_decl;
7725 method_decl = ret_decl;
7727 /* Fool the parser into thinking it is starting a function. */
7728 start_function (decl_specs, method_decl, NULL_TREE);
7730 /* Unhook: this has the effect of restoring the abstract declarator. */
7731 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7736 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7738 /* Fool the parser into thinking it is starting a function. */
7739 start_function (decl_specs, method_decl, NULL_TREE);
7741 /* Unhook: this has the effect of restoring the abstract declarator. */
7742 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7746 /* set self_decl from the first argument...this global is used by
7747 * build_ivar_reference().build_indirect_ref().
7749 self_decl = DECL_ARGUMENTS (current_function_decl);
7751 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7752 * the following: warning:unused parameter `struct objc_selector * _cmd'
7754 TREE_USED (self_decl) = 1;
7755 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7756 /* Ditto for the underlying (static) C function. */
7757 TREE_USED (current_function_decl) = 1;
7758 pop_lang_context ();
7761 METHOD_DEFINITION (method) = current_function_decl;
7763 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7765 if (implementation_template != objc_implementation_context)
7768 = lookup_method_static (implementation_template,
7769 METHOD_SEL_NAME (method),
7770 TREE_CODE (method) == CLASS_METHOD_DECL);
7774 if (!comp_method_with_proto (method, proto))
7776 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7778 warn_with_method ("conflicting types for", type, method);
7779 warn_with_method ("previous declaration of", type, proto);
7784 /* We have a method @implementation even though we did not
7785 see a corresponding @interface declaration (which is allowed
7786 by Objective-C rules). Go ahead and place the method in
7787 the @interface anyway, so that message dispatch lookups
7789 tree interface = implementation_template;
7791 if (TREE_CODE (objc_implementation_context)
7792 == CATEGORY_IMPLEMENTATION_TYPE)
7793 interface = lookup_category
7795 CLASS_SUPER_NAME (objc_implementation_context));
7798 objc_add_method (interface, copy_node (method),
7799 TREE_CODE (method) == CLASS_METHOD_DECL);
7804 /* The following routine is always called...this "architecture" is to
7805 accommodate "old-style" variable length selectors.
7807 - a:a b:b // prototype ; id c; id d; // old-style. */
7810 continue_method_def (void)
7814 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7815 /* We have a `, ...' immediately following the selector. */
7816 parmlist = get_parm_info (/*ellipsis=*/true);
7818 parmlist = get_parm_info (/*ellipsis=*/false);
7821 /* Set self_decl from the first argument...this global is used by
7822 build_ivar_reference calling build_indirect_ref. */
7823 self_decl = TREE_PURPOSE (parmlist);
7824 #endif /* !OBJCPLUS */
7827 really_start_method (objc_method_context, parmlist);
7828 store_parm_decls ();
7831 static void *UOBJC_SUPER_scope = 0;
7833 /* _n_Method (id self, SEL sel, ...)
7835 struct objc_super _S;
7836 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7840 get_super_receiver (void)
7842 if (objc_method_context)
7844 tree super_expr, super_expr_list;
7846 if (!UOBJC_SUPER_decl)
7848 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7849 build_tree_list (NULL_TREE,
7850 objc_super_template),
7853 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7855 /* This prevents `unused variable' warnings when compiling with -Wall. */
7856 TREE_USED (UOBJC_SUPER_decl) = 1;
7857 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7859 UOBJC_SUPER_scope = get_current_scope ();
7862 /* Set receiver to self. */
7863 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7864 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7865 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7867 /* Set class to begin searching. */
7869 super_expr = build_component_ref (UOBJC_SUPER_decl,
7870 get_identifier ("super_class"));
7872 super_expr = build_component_ref (UOBJC_SUPER_decl,
7873 get_identifier ("class"));
7876 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7878 /* [_cls, __cls]Super are "pre-built" in
7879 synth_forward_declarations. */
7881 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7882 ((TREE_CODE (objc_method_context)
7883 == INSTANCE_METHOD_DECL)
7885 : uucls_super_ref));
7889 /* We have a category. */
7891 tree super_name = CLASS_SUPER_NAME (implementation_template);
7894 /* Barf if super used in a category of Object. */
7897 error ("no super class declared in interface for `%s'",
7898 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7899 return error_mark_node;
7902 if (flag_next_runtime && !flag_zero_link)
7904 super_class = get_class_reference (super_name);
7905 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7906 /* If we are in a class method, we must retrieve the
7907 _metaclass_ for the current class, pointed at by
7908 the class's "isa" pointer. The following assumes that
7909 "isa" is the first ivar in a class (which it must be). */
7911 = build_indirect_ref
7912 (build_c_cast (build_pointer_type (objc_class_type),
7913 super_class), "unary *");
7917 add_class_reference (super_name);
7918 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7919 ? objc_get_class_decl : objc_get_meta_class_decl);
7920 assemble_external (super_class);
7922 = build_function_call
7926 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7927 IDENTIFIER_POINTER (super_name))));
7931 = build_modify_expr (super_expr, NOP_EXPR,
7932 build_c_cast (TREE_TYPE (super_expr),
7936 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7938 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7939 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7941 return build_compound_expr (super_expr_list);
7945 error ("[super ...] must appear in a method context");
7946 return error_mark_node;
7950 /* When exiting a scope, sever links to a 'super' declaration (if any)
7951 therein contained. */
7954 objc_clear_super_receiver (void)
7956 if (objc_method_context
7957 && UOBJC_SUPER_scope == get_current_scope ()) {
7958 UOBJC_SUPER_decl = 0;
7959 UOBJC_SUPER_scope = 0;
7964 objc_expand_function_end (void)
7966 /* This routine may also get called for C functions, including those
7967 nested within ObjC methods. In such cases, method encoding is
7969 if (objc_method_context == NULL_TREE
7970 || DECL_INITIAL (objc_method_context) != current_function_decl)
7973 METHOD_ENCODING (objc_method_context)
7974 = encode_method_prototype (objc_method_context);
7978 finish_method_def (void)
7980 lang_expand_function_end = objc_expand_function_end;
7981 /* We cannot validly inline ObjC methods, at least not without a language
7982 extension to declare that a method need not be dynamically
7983 dispatched, so suppress all thoughts of doing so. */
7984 DECL_INLINE (current_function_decl) = 0;
7985 DECL_UNINLINABLE (current_function_decl) = 1;
7986 current_function_cannot_inline = "methods cannot be inlined";
7989 lang_expand_function_end = NULL;
7991 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7992 since the optimizer may find "may be used before set" errors. */
7993 objc_method_context = NULL_TREE;
7998 lang_report_error_function (tree decl)
8000 if (objc_method_context)
8002 fprintf (stderr, "In method `%s'\n",
8003 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8013 is_complex_decl (tree type)
8015 return (TREE_CODE (type) == ARRAY_TYPE
8016 || TREE_CODE (type) == FUNCTION_TYPE
8017 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8021 /* Code to convert a decl node into text for a declaration in C. */
8023 static char tmpbuf[256];
8026 adorn_decl (tree decl, char *str)
8028 enum tree_code code = TREE_CODE (decl);
8030 if (code == ARRAY_REF)
8032 tree an_int_cst = TREE_OPERAND (decl, 1);
8034 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8035 sprintf (str + strlen (str), "[%ld]",
8036 (long) TREE_INT_CST_LOW (an_int_cst));
8041 else if (code == ARRAY_TYPE)
8043 tree an_int_cst = TYPE_SIZE (decl);
8044 tree array_of = TREE_TYPE (decl);
8046 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8047 sprintf (str + strlen (str), "[%ld]",
8048 (long) (TREE_INT_CST_LOW (an_int_cst)
8049 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8054 else if (code == CALL_EXPR)
8056 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8061 gen_declaration_1 (chain, str);
8062 chain = TREE_CHAIN (chain);
8069 else if (code == FUNCTION_TYPE)
8071 tree chain = TYPE_ARG_TYPES (decl);
8074 while (chain && TREE_VALUE (chain) != void_type_node)
8076 gen_declaration_1 (TREE_VALUE (chain), str);
8077 chain = TREE_CHAIN (chain);
8078 if (chain && TREE_VALUE (chain) != void_type_node)
8084 else if (code == INDIRECT_REF)
8086 strcpy (tmpbuf, "*");
8087 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8091 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8093 chain = TREE_CHAIN (chain))
8095 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8097 strcat (tmpbuf, " ");
8098 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8102 strcat (tmpbuf, " ");
8104 strcat (tmpbuf, str);
8105 strcpy (str, tmpbuf);
8108 else if (code == POINTER_TYPE)
8110 strcpy (tmpbuf, "*");
8111 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8113 if (TYPE_READONLY (decl))
8114 strcat (tmpbuf, " const");
8115 if (TYPE_VOLATILE (decl))
8116 strcat (tmpbuf, " volatile");
8118 strcat (tmpbuf, " ");
8120 strcat (tmpbuf, str);
8121 strcpy (str, tmpbuf);
8126 gen_declarator (tree decl, char *buf, const char *name)
8130 enum tree_code code = TREE_CODE (decl);
8140 op = TREE_OPERAND (decl, 0);
8142 /* We have a pointer to a function or array...(*)(), (*)[] */
8143 if ((code == ARRAY_REF || code == CALL_EXPR)
8144 && op && TREE_CODE (op) == INDIRECT_REF)
8147 str = gen_declarator (op, buf, name);
8151 strcpy (tmpbuf, "(");
8152 strcat (tmpbuf, str);
8153 strcat (tmpbuf, ")");
8154 strcpy (str, tmpbuf);
8157 adorn_decl (decl, str);
8166 /* This clause is done iteratively rather than recursively. */
8169 op = (is_complex_decl (TREE_TYPE (decl))
8170 ? TREE_TYPE (decl) : NULL_TREE);
8172 adorn_decl (decl, str);
8174 /* We have a pointer to a function or array...(*)(), (*)[] */
8175 if (code == POINTER_TYPE
8176 && op && (TREE_CODE (op) == FUNCTION_TYPE
8177 || TREE_CODE (op) == ARRAY_TYPE))
8179 strcpy (tmpbuf, "(");
8180 strcat (tmpbuf, str);
8181 strcat (tmpbuf, ")");
8182 strcpy (str, tmpbuf);
8185 decl = (is_complex_decl (TREE_TYPE (decl))
8186 ? TREE_TYPE (decl) : NULL_TREE);
8189 while (decl && (code = TREE_CODE (decl)))
8194 case IDENTIFIER_NODE:
8195 /* Will only happen if we are processing a "raw" expr-decl. */
8196 strcpy (buf, IDENTIFIER_POINTER (decl));
8207 /* We have an abstract declarator or a _DECL node. */
8215 gen_declspecs (tree declspecs, char *buf, int raw)
8221 for (chain = nreverse (copy_list (declspecs));
8222 chain; chain = TREE_CHAIN (chain))
8224 tree aspec = TREE_VALUE (chain);
8226 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8227 strcat (buf, IDENTIFIER_POINTER (aspec));
8228 else if (TREE_CODE (aspec) == RECORD_TYPE)
8230 if (OBJC_TYPE_NAME (aspec))
8232 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8234 if (! TREE_STATIC_TEMPLATE (aspec))
8235 strcat (buf, "struct ");
8236 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8241 tree chain = protocol_list;
8248 (PROTOCOL_NAME (TREE_VALUE (chain))));
8249 chain = TREE_CHAIN (chain);
8258 strcat (buf, "untagged struct");
8261 else if (TREE_CODE (aspec) == UNION_TYPE)
8263 if (OBJC_TYPE_NAME (aspec))
8265 if (! TREE_STATIC_TEMPLATE (aspec))
8266 strcat (buf, "union ");
8267 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8270 strcat (buf, "untagged union");
8273 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8275 if (OBJC_TYPE_NAME (aspec))
8277 if (! TREE_STATIC_TEMPLATE (aspec))
8278 strcat (buf, "enum ");
8279 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8282 strcat (buf, "untagged enum");
8285 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8286 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8288 else if (IS_ID (aspec))
8290 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8295 tree chain = protocol_list;
8302 (PROTOCOL_NAME (TREE_VALUE (chain))));
8303 chain = TREE_CHAIN (chain);
8310 if (TREE_CHAIN (chain))
8316 /* Type qualifiers. */
8317 if (TYPE_READONLY (declspecs))
8318 strcat (buf, "const ");
8319 if (TYPE_VOLATILE (declspecs))
8320 strcat (buf, "volatile ");
8322 switch (TREE_CODE (declspecs))
8324 /* Type specifiers. */
8327 declspecs = TYPE_MAIN_VARIANT (declspecs);
8329 /* Signed integer types. */
8331 if (declspecs == short_integer_type_node)
8332 strcat (buf, "short int ");
8333 else if (declspecs == integer_type_node)
8334 strcat (buf, "int ");
8335 else if (declspecs == long_integer_type_node)
8336 strcat (buf, "long int ");
8337 else if (declspecs == long_long_integer_type_node)
8338 strcat (buf, "long long int ");
8339 else if (declspecs == signed_char_type_node
8340 || declspecs == char_type_node)
8341 strcat (buf, "char ");
8343 /* Unsigned integer types. */
8345 else if (declspecs == short_unsigned_type_node)
8346 strcat (buf, "unsigned short ");
8347 else if (declspecs == unsigned_type_node)
8348 strcat (buf, "unsigned int ");
8349 else if (declspecs == long_unsigned_type_node)
8350 strcat (buf, "unsigned long ");
8351 else if (declspecs == long_long_unsigned_type_node)
8352 strcat (buf, "unsigned long long ");
8353 else if (declspecs == unsigned_char_type_node)
8354 strcat (buf, "unsigned char ");
8358 declspecs = TYPE_MAIN_VARIANT (declspecs);
8360 if (declspecs == float_type_node)
8361 strcat (buf, "float ");
8362 else if (declspecs == double_type_node)
8363 strcat (buf, "double ");
8364 else if (declspecs == long_double_type_node)
8365 strcat (buf, "long double ");
8369 if (OBJC_TYPE_NAME (declspecs)
8370 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8372 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8374 if (! TREE_STATIC_TEMPLATE (declspecs))
8375 strcat (buf, "struct ");
8376 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8380 tree chain = protocol_list;
8387 (PROTOCOL_NAME (TREE_VALUE (chain))));
8388 chain = TREE_CHAIN (chain);
8397 strcat (buf, "untagged struct");
8403 if (OBJC_TYPE_NAME (declspecs)
8404 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8406 strcat (buf, "union ");
8407 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8412 strcat (buf, "untagged union ");
8416 if (OBJC_TYPE_NAME (declspecs)
8417 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8419 strcat (buf, "enum ");
8420 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8425 strcat (buf, "untagged enum ");
8429 strcat (buf, "void ");
8434 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8439 tree chain = protocol_list;
8446 (PROTOCOL_NAME (TREE_VALUE (chain))));
8447 chain = TREE_CHAIN (chain);
8463 /* Given a tree node, produce a printable description of it in the given
8464 buffer, overwriting the buffer. */
8467 gen_declaration (tree atype_or_adecl, char *buf)
8470 gen_declaration_1 (atype_or_adecl, buf);
8474 /* Given a tree node, append a printable description to the end of the
8478 gen_declaration_1 (tree atype_or_adecl, char *buf)
8482 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8484 tree declspecs; /* "identifier_node", "record_type" */
8485 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8486 tree width = NULL_TREE; /* for bitfields */
8488 /* We have a "raw", abstract declarator (typename). */
8489 declarator = TREE_VALUE (atype_or_adecl);
8490 /* In the case of raw ivars, the declarator itself is a list,
8491 and contains bitfield widths. */
8492 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8494 width = TREE_VALUE (declarator);
8495 declarator = TREE_PURPOSE (declarator);
8497 declspecs = TREE_PURPOSE (atype_or_adecl);
8499 gen_declspecs (declspecs, buf, 1);
8503 strcat (buf, gen_declarator (declarator, declbuf, ""));
8506 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8507 TREE_INT_CST_LOW (width));
8513 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8514 tree declarator; /* "array_type", "function_type", "pointer_type". */
8516 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8517 || TREE_CODE (atype_or_adecl) == PARM_DECL
8518 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8519 atype = TREE_TYPE (atype_or_adecl);
8521 /* Assume we have a *_type node. */
8522 atype = atype_or_adecl;
8524 if (is_complex_decl (atype))
8528 /* Get the declaration specifier; it is at the end of the list. */
8529 declarator = chain = atype;
8531 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8532 while (is_complex_decl (chain));
8539 declarator = NULL_TREE;
8542 gen_declspecs (declspecs, buf, 0);
8544 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8545 || TREE_CODE (atype_or_adecl) == PARM_DECL
8546 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8548 const char *const decl_name =
8549 (DECL_NAME (atype_or_adecl)
8550 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8555 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8558 else if (decl_name[0])
8561 strcat (buf, decl_name);
8564 else if (declarator)
8567 strcat (buf, gen_declarator (declarator, declbuf, ""));
8572 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8574 /* Given a method tree, put a printable description into the given
8575 buffer (overwriting) and return a pointer to the buffer. */
8578 gen_method_decl (tree method, char *buf)
8583 if (RAW_TYPESPEC (method) != objc_object_reference)
8586 gen_declaration_1 (TREE_TYPE (method), buf);
8590 chain = METHOD_SEL_ARGS (method);
8593 /* We have a chain of keyword_decls. */
8596 if (KEYWORD_KEY_NAME (chain))
8597 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8600 if (RAW_TYPESPEC (chain) != objc_object_reference)
8603 gen_declaration_1 (TREE_TYPE (chain), buf);
8607 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8608 if ((chain = TREE_CHAIN (chain)))
8613 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8614 strcat (buf, ", ...");
8615 else if (METHOD_ADD_ARGS (method))
8617 /* We have a tree list node as generate by get_parm_info. */
8618 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8620 /* Know we have a chain of parm_decls. */
8624 gen_declaration_1 (chain, buf);
8625 chain = TREE_CHAIN (chain);
8631 /* We have a unary selector. */
8632 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8640 /* Dump an @interface declaration of the supplied class CHAIN to the
8641 supplied file FP. Used to implement the -gen-decls option (which
8642 prints out an @interface declaration of all classes compiled in
8643 this run); potentially useful for debugging the compiler too. */
8645 dump_interface (FILE *fp, tree chain)
8647 /* FIXME: A heap overflow here whenever a method (or ivar)
8648 declaration is so long that it doesn't fit in the buffer. The
8649 code and all the related functions should be rewritten to avoid
8650 using fixed size buffers. */
8651 char *buf = (char *) xmalloc (1024 * 10);
8652 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8653 tree ivar_decls = CLASS_RAW_IVARS (chain);
8654 tree nst_methods = CLASS_NST_METHODS (chain);
8655 tree cls_methods = CLASS_CLS_METHODS (chain);
8657 fprintf (fp, "\n@interface %s", my_name);
8659 /* CLASS_SUPER_NAME is used to store the superclass name for
8660 classes, and the category name for categories. */
8661 if (CLASS_SUPER_NAME (chain))
8663 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8665 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8666 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8668 fprintf (fp, " (%s)\n", name);
8672 fprintf (fp, " : %s\n", name);
8678 /* FIXME - the following doesn't seem to work at the moment. */
8681 fprintf (fp, "{\n");
8684 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8685 ivar_decls = TREE_CHAIN (ivar_decls);
8688 fprintf (fp, "}\n");
8693 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8694 nst_methods = TREE_CHAIN (nst_methods);
8699 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8700 cls_methods = TREE_CHAIN (cls_methods);
8703 fprintf (fp, "@end\n");
8706 /* Demangle function for Objective-C */
8708 objc_demangle (const char *mangled)
8710 char *demangled, *cp;
8712 if (mangled[0] == '_' &&
8713 (mangled[1] == 'i' || mangled[1] == 'c') &&
8716 cp = demangled = xmalloc(strlen(mangled) + 2);
8717 if (mangled[1] == 'i')
8718 *cp++ = '-'; /* for instance method */
8720 *cp++ = '+'; /* for class method */
8721 *cp++ = '['; /* opening left brace */
8722 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8723 while (*cp && *cp == '_')
8724 cp++; /* skip any initial underbars in class name */
8725 cp = strchr(cp, '_'); /* find first non-initial underbar */
8728 free(demangled); /* not mangled name */
8731 if (cp[1] == '_') /* easy case: no category name */
8733 *cp++ = ' '; /* replace two '_' with one ' ' */
8734 strcpy(cp, mangled + (cp - demangled) + 2);
8738 *cp++ = '('; /* less easy case: category name */
8739 cp = strchr(cp, '_');
8742 free(demangled); /* not mangled name */
8746 *cp++ = ' '; /* overwriting 1st char of method name... */
8747 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8749 while (*cp && *cp == '_')
8750 cp++; /* skip any initial underbars in method name */
8753 *cp = ':'; /* replace remaining '_' with ':' */
8754 *cp++ = ']'; /* closing right brace */
8755 *cp++ = 0; /* string terminator */
8759 return mangled; /* not an objc mangled name */
8763 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8765 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8771 gcc_obstack_init (&util_obstack);
8772 util_firstobj = (char *) obstack_finish (&util_obstack);
8774 errbuf = (char *) xmalloc (BUFSIZE);
8776 synth_module_prologue ();
8782 struct imp_entry *impent;
8784 /* The internally generated initializers appear to have missing braces.
8785 Don't warn about this. */
8786 int save_warn_missing_braces = warn_missing_braces;
8787 warn_missing_braces = 0;
8789 /* A missing @end may not be detected by the parser. */
8790 if (objc_implementation_context)
8792 warning ("`@end' missing in implementation context");
8793 finish_class (objc_implementation_context);
8794 objc_ivar_chain = NULL_TREE;
8795 objc_implementation_context = NULL_TREE;
8798 /* Process the static instances here because initialization of objc_symtab
8800 if (objc_static_instances)
8801 generate_static_references ();
8803 if (imp_list || class_names_chain
8804 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8805 generate_objc_symtab_decl ();
8807 for (impent = imp_list; impent; impent = impent->next)
8809 objc_implementation_context = impent->imp_context;
8810 implementation_template = impent->imp_template;
8812 UOBJC_CLASS_decl = impent->class_decl;
8813 UOBJC_METACLASS_decl = impent->meta_decl;
8815 /* Dump the @interface of each class as we compile it, if the
8816 -gen-decls option is in use. TODO: Dump the classes in the
8817 order they were found, rather than in reverse order as we
8819 if (flag_gen_declaration)
8821 dump_interface (gen_declaration_file, objc_implementation_context);
8824 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8826 /* all of the following reference the string pool... */
8827 generate_ivar_lists ();
8828 generate_dispatch_tables ();
8829 generate_shared_structures ();
8833 generate_dispatch_tables ();
8834 generate_category (objc_implementation_context);
8838 /* If we are using an array of selectors, we must always
8839 finish up the array decl even if no selectors were used. */
8840 if (! flag_next_runtime || sel_ref_chain)
8841 build_selector_translation_table ();
8844 generate_protocols ();
8846 if (flag_replace_objc_classes && imp_list)
8847 generate_objc_image_info ();
8849 if (objc_implementation_context || class_names_chain || objc_static_instances
8850 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8852 /* Arrange for ObjC data structures to be initialized at run time. */
8853 rtx init_sym = build_module_descriptor ();
8854 if (init_sym && targetm.have_ctors_dtors)
8855 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8858 /* Dump the class references. This forces the appropriate classes
8859 to be linked into the executable image, preserving unix archive
8860 semantics. This can be removed when we move to a more dynamically
8861 linked environment. */
8863 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8865 handle_class_ref (chain);
8866 if (TREE_PURPOSE (chain))
8867 generate_classref_translation_entry (chain);
8870 for (impent = imp_list; impent; impent = impent->next)
8871 handle_impent (impent);
8873 /* Dump the string table last. */
8875 generate_strings ();
8882 /* Run through the selector hash tables and print a warning for any
8883 selector which has multiple methods. */
8885 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8887 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8888 check_duplicates (hsh, 0, 1);
8889 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8890 check_duplicates (hsh, 0, 1);
8894 warn_missing_braces = save_warn_missing_braces;
8897 /* Subroutines of finish_objc. */
8900 generate_classref_translation_entry (tree chain)
8902 tree expr, name, decl_specs, decl, sc_spec;
8905 type = TREE_TYPE (TREE_PURPOSE (chain));
8907 expr = add_objc_string (TREE_VALUE (chain), class_names);
8908 expr = build_c_cast (type, expr); /* cast! */
8910 name = DECL_NAME (TREE_PURPOSE (chain));
8912 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8914 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8915 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8917 /* The decl that is returned from start_decl is the one that we
8918 forward declared in build_class_reference. */
8919 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8920 DECL_CONTEXT (decl) = NULL_TREE;
8921 finish_decl (decl, expr, NULL_TREE);
8926 handle_class_ref (tree chain)
8928 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8929 char *string = (char *) alloca (strlen (name) + 30);
8933 sprintf (string, "%sobjc_class_name_%s",
8934 (flag_next_runtime ? "." : "__"), name);
8936 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8937 if (flag_next_runtime)
8939 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8944 /* Make a decl for this name, so we can use its address in a tree. */
8945 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8946 DECL_EXTERNAL (decl) = 1;
8947 TREE_PUBLIC (decl) = 1;
8950 rest_of_decl_compilation (decl, 0, 0, 0);
8952 /* Make a decl for the address. */
8953 sprintf (string, "%sobjc_class_ref_%s",
8954 (flag_next_runtime ? "." : "__"), name);
8955 exp = build1 (ADDR_EXPR, string_type_node, decl);
8956 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8957 DECL_INITIAL (decl) = exp;
8958 TREE_STATIC (decl) = 1;
8959 TREE_USED (decl) = 1;
8962 rest_of_decl_compilation (decl, 0, 0, 0);
8966 handle_impent (struct imp_entry *impent)
8970 objc_implementation_context = impent->imp_context;
8971 implementation_template = impent->imp_template;
8973 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8975 const char *const class_name =
8976 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8978 string = (char *) alloca (strlen (class_name) + 30);
8980 sprintf (string, "%sobjc_class_name_%s",
8981 (flag_next_runtime ? "." : "__"), class_name);
8983 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8985 const char *const class_name =
8986 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8987 const char *const class_super_name =
8988 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8990 string = (char *) alloca (strlen (class_name)
8991 + strlen (class_super_name) + 30);
8993 /* Do the same for categories. Even though no references to
8994 these symbols are generated automatically by the compiler, it
8995 gives you a handle to pull them into an archive by hand. */
8996 sprintf (string, "*%sobjc_category_name_%s_%s",
8997 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9002 #ifdef ASM_DECLARE_CLASS_REFERENCE
9003 if (flag_next_runtime)
9005 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9013 init = build_int_2 (0, 0);
9014 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
9015 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9016 TREE_PUBLIC (decl) = 1;
9017 TREE_READONLY (decl) = 1;
9018 TREE_USED (decl) = 1;
9019 TREE_CONSTANT (decl) = 1;
9020 DECL_CONTEXT (decl) = 0;
9021 DECL_ARTIFICIAL (decl) = 1;
9022 DECL_INITIAL (decl) = init;
9023 assemble_variable (decl, 1, 0, 0);
9027 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9028 later requires that ObjC translation units participating in F&C be
9029 specially marked. The following routine accomplishes this. */
9031 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9034 generate_objc_image_info (void)
9036 tree sc_spec, decl, initlist;
9038 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9040 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9041 tree_cons (NULL_TREE,
9044 build_index_type (build_int_2 (1, 0))),
9049 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9050 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9051 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9053 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9054 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9055 finish_decl (decl, initlist, NULL_TREE);
9058 /* Look up ID as an instance variable. */
9061 lookup_objc_ivar (tree id)
9065 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9066 /* We have a message to super. */
9067 return get_super_receiver ();
9068 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9070 if (is_private (decl))
9071 return error_mark_node;
9073 return build_ivar_reference (id);
9079 #include "gt-objc-objc-act.h"
9080 #include "gtype-objc.h"