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"
62 #include "diagnostic.h"
65 #define OBJC_VOID_AT_END build_tree_list (NULL_TREE, void_type_node)
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);
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 generate_forward_declaration_to_string_table (void);
163 static void build_protocol_reference (tree);
165 static tree build_keyword_selector (tree);
166 static tree synth_id_with_class_suffix (const char *, tree);
168 static void generate_static_references (void);
169 static int check_methods_accessible (tree, tree, int);
170 static void encode_aggregate_within (tree, int, int, int, int);
171 static const char *objc_demangle (const char *);
172 static void objc_expand_function_end (void);
174 /* Hash tables to manage the global pool of method prototypes. */
176 hash *nst_method_hash_list = 0;
177 hash *cls_method_hash_list = 0;
179 static size_t hash_func (tree);
180 static void hash_init (void);
181 static void hash_enter (hash *, tree);
182 static hash hash_lookup (hash *, tree);
183 static void hash_add_attr (hash, tree);
184 static tree lookup_method (tree, tree);
185 static tree lookup_method_static (tree, tree, int);
186 static tree add_class (tree);
187 static void add_category (tree, tree);
191 class_names, /* class, category, protocol, module names */
192 meth_var_names, /* method and variable names */
193 meth_var_types /* method and variable type descriptors */
196 static tree add_objc_string (tree, enum string_section);
197 static tree get_objc_string_decl (tree, enum string_section);
198 static tree build_objc_string_decl (enum string_section);
199 static tree build_selector_reference_decl (void);
201 /* Protocol additions. */
203 static tree add_protocol (tree);
204 static tree lookup_protocol (tree);
205 static void check_protocol_recursively (tree, tree);
206 static tree lookup_and_install_protocols (tree);
210 static void encode_type_qualifiers (tree);
211 static void encode_pointer (tree, int, int);
212 static void encode_array (tree, int, int);
213 static void encode_aggregate (tree, int, int);
214 static void encode_next_bitfield (int);
215 static void encode_gnu_bitfield (int, tree, int);
216 static void encode_type (tree, int, int);
217 static void encode_field_decl (tree, int, int);
219 static void really_start_method (tree, tree);
220 static int comp_method_with_proto (tree, tree);
221 static int objc_types_are_equivalent (tree, tree);
222 static int comp_proto_with_proto (tree, tree);
223 static tree get_arg_type_list (tree, int, int);
224 static tree objc_expr_last (tree);
225 static void synth_self_and_ucmd_args (void);
227 /* Utilities for debugging and error diagnostics. */
229 static void warn_with_method (const char *, int, tree);
230 static void error_with_ivar (const char *, tree, tree);
231 static char *gen_method_decl (tree, char *);
232 static char *gen_declaration (tree, char *);
233 static void gen_declaration_1 (tree, char *);
234 static char *gen_declarator (tree, char *, const char *);
235 static int is_complex_decl (tree);
236 static void adorn_decl (tree, char *);
237 static void dump_interface (FILE *, tree);
239 /* Everything else. */
241 static tree define_decl (tree, tree);
242 static tree lookup_method_in_protocol_list (tree, tree, int);
243 static tree lookup_protocol_in_reflist (tree, tree);
244 static tree create_builtin_decl (enum tree_code, tree, const char *);
245 static void setup_string_decl (void);
246 static int check_string_class_template (void);
247 static tree my_build_string (int, const char *);
248 static void build_objc_symtab_template (void);
249 static tree init_def_list (tree);
250 static tree init_objc_symtab (tree);
251 static tree build_metadata_decl (const char *, tree);
252 static void forward_declare_categories (void);
253 static void generate_objc_symtab_decl (void);
254 static tree build_selector (tree);
255 static tree build_typed_selector_reference (tree, tree);
256 static tree build_selector_reference (tree);
257 static tree build_class_reference_decl (void);
258 static void add_class_reference (tree);
259 static tree build_protocol_template (void);
260 static tree build_descriptor_table_initializer (tree, tree);
261 static tree build_method_prototype_list_template (tree, int);
262 static tree build_method_prototype_template (void);
263 static tree objc_method_parm_type (tree);
264 static int objc_encoded_type_size (tree);
265 static tree encode_method_prototype (tree);
266 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
267 static void generate_method_descriptors (tree);
268 static void generate_protocol_references (tree);
269 static void generate_protocols (void);
270 static void check_ivars (tree, tree);
271 static tree build_ivar_list_template (tree, int);
272 static tree build_method_list_template (tree, int);
273 static tree build_ivar_list_initializer (tree, tree);
274 static tree generate_ivars_list (tree, const char *, int, tree);
275 static tree build_dispatch_table_initializer (tree, tree);
276 static tree generate_dispatch_table (tree, const char *, int, tree);
277 static tree build_shared_structure_initializer (tree, tree, tree, tree,
278 tree, int, tree, tree, tree);
279 static void generate_category (tree);
280 static int is_objc_type_qualifier (tree);
281 static tree adjust_type_for_id_default (tree);
282 static tree check_duplicates (hash, int);
283 static tree receiver_is_class_object (tree, int, int);
284 static int check_methods (tree, tree, int);
285 static int conforms_to_protocol (tree, tree);
286 static void check_protocol (tree, const char *, const char *);
287 static void check_protocols (tree, const char *, const char *);
288 static void gen_declspecs (tree, char *, int);
289 static void generate_classref_translation_entry (tree);
290 static void handle_class_ref (tree);
291 static void generate_struct_by_value_array (void)
293 static void mark_referenced_methods (void);
294 static void generate_objc_image_info (void);
296 /*** Private Interface (data) ***/
298 /* Reserved tag definitions. */
301 #define TAG_OBJECT "objc_object"
302 #define TAG_CLASS "objc_class"
303 #define TAG_SUPER "objc_super"
304 #define TAG_SELECTOR "objc_selector"
306 #define UTAG_CLASS "_objc_class"
307 #define UTAG_IVAR "_objc_ivar"
308 #define UTAG_IVAR_LIST "_objc_ivar_list"
309 #define UTAG_METHOD "_objc_method"
310 #define UTAG_METHOD_LIST "_objc_method_list"
311 #define UTAG_CATEGORY "_objc_category"
312 #define UTAG_MODULE "_objc_module"
313 #define UTAG_SYMTAB "_objc_symtab"
314 #define UTAG_SUPER "_objc_super"
315 #define UTAG_SELECTOR "_objc_selector"
317 #define UTAG_PROTOCOL "_objc_protocol"
318 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
319 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
321 /* Note that the string object global name is only needed for the
323 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
325 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
327 static const char *TAG_GETCLASS;
328 static const char *TAG_GETMETACLASS;
329 static const char *TAG_MSGSEND;
330 static const char *TAG_MSGSENDSUPER;
331 /* The NeXT Objective-C messenger may have two extra entry points, for use
332 when returning a structure. */
333 static const char *TAG_MSGSEND_STRET;
334 static const char *TAG_MSGSENDSUPER_STRET;
335 static const char *TAG_EXECCLASS;
336 static const char *default_constant_string_class_name;
338 /* Runtime metadata flags. */
339 #define CLS_FACTORY 0x0001L
340 #define CLS_META 0x0002L
342 #define OBJC_MODIFIER_STATIC 0x00000001
343 #define OBJC_MODIFIER_FINAL 0x00000002
344 #define OBJC_MODIFIER_PUBLIC 0x00000004
345 #define OBJC_MODIFIER_PRIVATE 0x00000008
346 #define OBJC_MODIFIER_PROTECTED 0x00000010
347 #define OBJC_MODIFIER_NATIVE 0x00000020
348 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
349 #define OBJC_MODIFIER_ABSTRACT 0x00000080
350 #define OBJC_MODIFIER_VOLATILE 0x00000100
351 #define OBJC_MODIFIER_TRANSIENT 0x00000200
352 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
354 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
355 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
356 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
357 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
358 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
359 #define TAG_EXCEPTIONMATCH "objc_exception_match"
360 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
361 #define TAG_SYNCENTER "objc_sync_enter"
362 #define TAG_SYNCEXIT "objc_sync_exit"
363 #define TAG_SETJMP "_setjmp"
364 #define TAG_RETURN_STRUCT "objc_return_struct"
366 #define UTAG_EXCDATA "_objc_exception_data"
367 #define UTAG_EXCDATA_VAR "_stackExceptionData"
368 #define UTAG_CAUGHTEXC_VAR "_caughtException"
369 #define UTAG_RETHROWEXC_VAR "_rethrowException"
370 #define UTAG_EVALONCE_VAR "_eval_once"
374 struct val_stack *next;
376 static struct val_stack *catch_count_stack, *exc_binding_stack;
378 /* useful for debugging */
379 static int if_nesting_count;
380 static int blk_nesting_count;
382 static void val_stack_push (struct val_stack **, long);
383 static void val_stack_pop (struct val_stack **);
385 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
386 tree objc_global_trees[OCTI_MAX];
388 static void handle_impent (struct imp_entry *);
390 struct imp_entry *imp_list = 0;
391 int imp_count = 0; /* `@implementation' */
392 int cat_count = 0; /* `@category' */
394 /* Use to generate method labels. */
395 static int method_slot = 0;
399 static char *errbuf; /* Buffer for error diagnostics */
401 /* Data imported from tree.c. */
403 extern enum debug_info_type write_symbols;
405 /* Data imported from toplev.c. */
407 extern const char *dump_base_name;
409 static int flag_typed_selectors;
411 FILE *gen_declaration_file;
413 /* Tells "encode_pointer/encode_aggregate" whether we are generating
414 type descriptors for instance variables (as opposed to methods).
415 Type descriptors for instance variables contain more information
416 than methods (for static typing and embedded structures). */
418 static int generating_instance_variables = 0;
420 /* Some platforms pass small structures through registers versus
421 through an invisible pointer. Determine at what size structure is
422 the transition point between the two possibilities. */
425 generate_struct_by_value_array (void)
428 tree field_decl, field_decl_chain;
430 int aggregate_in_mem[32];
433 /* Presumably no platform passes 32 byte structures in a register. */
434 for (i = 1; i < 32; i++)
438 /* Create an unnamed struct that has `i' character components */
439 type = start_struct (RECORD_TYPE, NULL_TREE);
441 strcpy (buffer, "c1");
442 field_decl = create_builtin_decl (FIELD_DECL,
445 field_decl_chain = field_decl;
447 for (j = 1; j < i; j++)
449 sprintf (buffer, "c%d", j + 1);
450 field_decl = create_builtin_decl (FIELD_DECL,
453 chainon (field_decl_chain, field_decl);
455 finish_struct (type, field_decl_chain, NULL_TREE);
457 aggregate_in_mem[i] = aggregate_value_p (type, 0);
458 if (!aggregate_in_mem[i])
462 /* We found some structures that are returned in registers instead of memory
463 so output the necessary data. */
466 for (i = 31; i >= 0; i--)
467 if (!aggregate_in_mem[i])
469 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
471 /* The first member of the structure is always 0 because we don't handle
472 structures with 0 members */
473 printf ("static int struct_forward_array[] = {\n 0");
475 for (j = 1; j <= i; j++)
476 printf (", %d", aggregate_in_mem[j]);
486 if (c_objc_common_init () == false)
489 /* Force the line number back to 0; check_newline will have
490 raised it to 1, which will make the builtin functions appear
491 not to be built in. */
494 /* If gen_declaration desired, open the output file. */
495 if (flag_gen_declaration)
497 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
498 gen_declaration_file = fopen (dumpname, "w");
499 if (gen_declaration_file == 0)
500 fatal_error ("can't open %s: %m", dumpname);
504 if (flag_next_runtime)
506 TAG_GETCLASS = "objc_getClass";
507 TAG_GETMETACLASS = "objc_getMetaClass";
508 TAG_MSGSEND = "objc_msgSend";
509 TAG_MSGSENDSUPER = "objc_msgSendSuper";
510 TAG_MSGSEND_STRET = "objc_msgSend_stret";
511 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
512 TAG_EXECCLASS = "__objc_execClass";
513 default_constant_string_class_name = "NSConstantString";
517 TAG_GETCLASS = "objc_get_class";
518 TAG_GETMETACLASS = "objc_get_meta_class";
519 TAG_MSGSEND = "objc_msg_lookup";
520 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
521 /* GNU runtime does not provide special functions to support
522 structure-returning methods. */
523 TAG_EXECCLASS = "__objc_exec_class";
524 default_constant_string_class_name = "NXConstantString";
525 flag_typed_selectors = 1;
528 objc_ellipsis_node = make_node (ERROR_MARK);
532 if (print_struct_values)
533 generate_struct_by_value_array ();
541 mark_referenced_methods ();
542 c_objc_common_finish_file ();
544 /* Finalize Objective-C runtime data. No need to generate tables
545 and code if only checking syntax. */
546 if (!flag_syntax_only)
549 if (gen_declaration_file)
550 fclose (gen_declaration_file);
554 define_decl (tree declarator, tree declspecs)
556 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
557 finish_decl (decl, NULL_TREE, NULL_TREE);
562 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
568 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
570 p = TREE_VALUE (rproto);
572 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
574 if ((fnd = lookup_method (class_meth
575 ? PROTOCOL_CLS_METHODS (p)
576 : PROTOCOL_NST_METHODS (p), sel_name)))
578 else if (PROTOCOL_LIST (p))
579 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
580 sel_name, class_meth);
584 ; /* An identifier...if we could not find a protocol. */
595 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
599 /* Make sure the protocol is supported by the object on the rhs. */
600 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
603 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
605 p = TREE_VALUE (rproto);
607 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
612 else if (PROTOCOL_LIST (p))
613 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
622 ; /* An identifier...if we could not find a protocol. */
628 /* Return 1 if LHS and RHS are compatible types for assignment or
629 various other operations. Return 0 if they are incompatible, and
630 return -1 if we choose to not decide (because the types are really
631 just C types, not ObjC specific ones). When the operation is
632 REFLEXIVE (typically comparisons), check for compatibility in
633 either direction; when it's not (typically assignments), don't.
635 This function is called in two cases: when both lhs and rhs are
636 pointers to records (in which case we check protocols too), and
637 when both lhs and rhs are records (in which case we check class
640 Warnings about classes/protocols not implementing a protocol are
641 emitted here (multiple of those warnings might be emitted for a
642 single line!); generic warnings about incompatible assignments and
643 lacks of casts in comparisons are/must be emitted by the caller if
648 objc_comptypes (tree lhs, tree rhs, int reflexive)
650 /* New clause for protocols. */
652 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
653 manage the ObjC ones, and leave the rest to the C code. */
654 if (TREE_CODE (lhs) == POINTER_TYPE
655 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
656 && TREE_CODE (rhs) == POINTER_TYPE
657 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
659 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
660 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
664 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
665 tree rproto, rproto_list;
668 /* <Protocol> = <Protocol> */
671 rproto_list = TYPE_PROTOCOL_LIST (rhs);
675 /* An assignment between objects of type 'id
676 <Protocol>'; make sure the protocol on the lhs is
677 supported by the object on the rhs. */
678 for (lproto = lproto_list; lproto;
679 lproto = TREE_CHAIN (lproto))
681 p = TREE_VALUE (lproto);
682 rproto = lookup_protocol_in_reflist (rproto_list, p);
686 ("object does not conform to the `%s' protocol",
687 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
693 /* Obscure case - a comparison between two objects
694 of type 'id <Protocol>'. Check that either the
695 protocol on the lhs is supported by the object on
696 the rhs, or viceversa. */
698 /* Check if the protocol on the lhs is supported by the
699 object on the rhs. */
700 for (lproto = lproto_list; lproto;
701 lproto = TREE_CHAIN (lproto))
703 p = TREE_VALUE (lproto);
704 rproto = lookup_protocol_in_reflist (rproto_list, p);
708 /* Check failed - check if the protocol on the rhs
709 is supported by the object on the lhs. */
710 for (rproto = rproto_list; rproto;
711 rproto = TREE_CHAIN (rproto))
713 p = TREE_VALUE (rproto);
714 lproto = lookup_protocol_in_reflist (lproto_list,
719 /* This check failed too: incompatible */
729 /* <Protocol> = <class> * */
730 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
732 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
735 /* Make sure the protocol is supported by the object on
737 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
739 p = TREE_VALUE (lproto);
741 rinter = lookup_interface (rname);
743 while (rinter && !rproto)
747 rproto_list = CLASS_PROTOCOL_LIST (rinter);
748 rproto = lookup_protocol_in_reflist (rproto_list, p);
749 /* If the underlying ObjC class does not have
750 the protocol we're looking for, check for "one-off"
751 protocols (e.g., `NSObject<MyProt> *foo;') attached
755 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
756 rproto = lookup_protocol_in_reflist (rproto_list, p);
759 /* Check for protocols adopted by categories. */
760 cat = CLASS_CATEGORY_LIST (rinter);
761 while (cat && !rproto)
763 rproto_list = CLASS_PROTOCOL_LIST (cat);
764 rproto = lookup_protocol_in_reflist (rproto_list, p);
765 cat = CLASS_CATEGORY_LIST (cat);
768 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
772 warning ("class `%s' does not implement the `%s' protocol",
773 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
774 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
778 /* <Protocol> = id */
779 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
783 /* <Protocol> = Class */
784 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
788 /* <Protocol> = ?? : let comptypes decide. */
791 else if (rhs_is_proto)
793 /* <class> * = <Protocol> */
794 if (TYPED_OBJECT (TREE_TYPE (lhs)))
798 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
800 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
802 /* Make sure the protocol is supported by the object on
804 for (rproto = rproto_list; rproto;
805 rproto = TREE_CHAIN (rproto))
807 tree p = TREE_VALUE (rproto);
809 rinter = lookup_interface (rname);
811 while (rinter && !lproto)
815 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
816 lproto = lookup_protocol_in_reflist (lproto_list, p);
817 /* If the underlying ObjC class does not
818 have the protocol we're looking for,
819 check for "one-off" protocols (e.g.,
820 `NSObject<MyProt> *foo;') attached to the
824 lproto_list = TYPE_PROTOCOL_LIST
826 lproto = lookup_protocol_in_reflist
830 /* Check for protocols adopted by categories. */
831 cat = CLASS_CATEGORY_LIST (rinter);
832 while (cat && !lproto)
834 lproto_list = CLASS_PROTOCOL_LIST (cat);
835 lproto = lookup_protocol_in_reflist (lproto_list,
837 cat = CLASS_CATEGORY_LIST (cat);
840 rinter = lookup_interface (CLASS_SUPER_NAME
845 warning ("class `%s' does not implement the `%s' protocol",
846 IDENTIFIER_POINTER (OBJC_TYPE_NAME
848 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
855 /* id = <Protocol> */
856 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
860 /* Class = <Protocol> */
861 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
865 /* ??? = <Protocol> : let comptypes decide */
873 /* Attention: we shouldn't defer to comptypes here. One bad
874 side effect would be that we might loose the REFLEXIVE
877 lhs = TREE_TYPE (lhs);
878 rhs = TREE_TYPE (rhs);
882 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
884 /* Nothing to do with ObjC - let immediately comptypes take
885 responsibility for checking. */
889 /* `id' = `<class> *' `<class> *' = `id': always allow it.
891 'Object *o = [[Object alloc] init]; falls
892 in the case <class> * = `id'.
894 if ((OBJC_TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
895 || (OBJC_TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
898 /* `id' = `Class', `Class' = `id' */
900 else if ((OBJC_TYPE_NAME (lhs) == objc_object_id
901 && OBJC_TYPE_NAME (rhs) == objc_class_id)
902 || (OBJC_TYPE_NAME (lhs) == objc_class_id
903 && OBJC_TYPE_NAME (rhs) == objc_object_id))
906 /* `<class> *' = `<class> *' */
908 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
910 tree lname = OBJC_TYPE_NAME (lhs);
911 tree rname = OBJC_TYPE_NAME (rhs);
917 /* If the left hand side is a super class of the right hand side,
919 for (inter = lookup_interface (rname); inter;
920 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
921 if (lname == CLASS_SUPER_NAME (inter))
924 /* Allow the reverse when reflexive. */
926 for (inter = lookup_interface (lname); inter;
927 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
928 if (rname == CLASS_SUPER_NAME (inter))
934 /* Not an ObjC type - let comptypes do the check. */
938 /* Called from finish_decl. */
941 objc_check_decl (tree decl)
943 tree type = TREE_TYPE (decl);
945 if (TREE_CODE (type) != RECORD_TYPE)
947 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type)))
948 && type != constant_string_type)
949 error ("statically allocated instance of Objective-C class `%s'",
950 IDENTIFIER_POINTER (type));
953 /* Implement static typing. At this point, we know we have an interface. */
956 get_static_reference (tree interface, tree protocols)
958 tree type = xref_tag (RECORD_TYPE, interface);
962 tree t, m = TYPE_MAIN_VARIANT (type);
964 t = copy_node (type);
966 /* Add this type to the chain of variants of TYPE. */
967 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
968 TYPE_NEXT_VARIANT (m) = t;
970 /* Look up protocols and install in lang specific list. Note
971 that the protocol list can have a different lifetime than T! */
972 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
974 /* This forces a new pointer type to be created later
975 (in build_pointer_type)...so that the new template
976 we just created will actually be used...what a hack! */
977 if (TYPE_POINTER_TO (t))
978 TYPE_POINTER_TO (t) = NULL_TREE;
987 get_object_reference (tree protocols)
989 tree type_decl = lookup_name (objc_id_id);
992 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
994 type = TREE_TYPE (type_decl);
995 if (TYPE_MAIN_VARIANT (type) != id_type)
996 warning ("unexpected type for `id' (%s)",
997 gen_declaration (type, errbuf));
1001 error ("undefined type `id', please import <objc/objc.h>");
1002 return error_mark_node;
1005 /* This clause creates a new pointer type that is qualified with
1006 the protocol specification...this info is used later to do more
1007 elaborate type checking. */
1011 tree t, m = TYPE_MAIN_VARIANT (type);
1013 t = copy_node (type);
1015 /* Add this type to the chain of variants of TYPE. */
1016 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1017 TYPE_NEXT_VARIANT (m) = t;
1019 /* Look up protocols...and install in lang specific list */
1020 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1022 /* This forces a new pointer type to be created later
1023 (in build_pointer_type)...so that the new template
1024 we just created will actually be used...what a hack! */
1025 if (TYPE_POINTER_TO (t))
1026 TYPE_POINTER_TO (t) = NULL_TREE;
1033 /* Check for circular dependencies in protocols. The arguments are
1034 PROTO, the protocol to check, and LIST, a list of protocol it
1038 check_protocol_recursively (tree proto, tree list)
1042 for (p = list; p; p = TREE_CHAIN (p))
1044 tree pp = TREE_VALUE (p);
1046 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1047 pp = lookup_protocol (pp);
1050 fatal_error ("protocol `%s' has circular dependency",
1051 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1053 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1057 /* Look up PROTOCOLS, and return a list of those that are found.
1058 If none are found, return NULL. */
1061 lookup_and_install_protocols (tree protocols)
1064 tree return_value = NULL_TREE;
1066 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1068 tree ident = TREE_VALUE (proto);
1069 tree p = lookup_protocol (ident);
1072 error ("cannot find protocol declaration for `%s'",
1073 IDENTIFIER_POINTER (ident));
1075 return_value = chainon (return_value,
1076 build_tree_list (NULL_TREE, p));
1079 return return_value;
1082 /* Create and push a decl for a built-in external variable or field NAME.
1084 TYPE is its data type. */
1087 create_builtin_decl (enum tree_code code, tree type, const char *name)
1089 tree decl = build_decl (code, get_identifier (name), type);
1091 if (code == VAR_DECL)
1093 TREE_STATIC (decl) = 1;
1094 make_decl_rtl (decl, 0);
1096 DECL_ARTIFICIAL (decl) = 1;
1102 /* Find the decl for the constant string class. */
1105 setup_string_decl (void)
1107 if (!string_class_decl)
1109 if (!constant_string_global_id)
1113 /* %s in format will provide room for terminating null */
1114 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1115 + strlen (constant_string_class_name);
1116 name = xmalloc (length);
1117 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1118 constant_string_class_name);
1119 constant_string_global_id = get_identifier (name);
1121 string_class_decl = lookup_name (constant_string_global_id);
1125 /* Purpose: "play" parser, creating/installing representations
1126 of the declarations that are required by Objective-C.
1130 type_spec--------->sc_spec
1131 (tree_list) (tree_list)
1134 identifier_node identifier_node */
1137 synth_module_prologue (void)
1141 /* Defined in `objc.h' */
1142 objc_object_id = get_identifier (TAG_OBJECT);
1144 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1146 id_type = build_pointer_type (objc_object_reference);
1148 objc_id_id = get_identifier (TYPE_ID);
1149 objc_class_id = get_identifier (TAG_CLASS);
1151 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1152 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1153 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1154 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1157 /* Declare type of selector-objects that represent an operation name. */
1159 /* `struct objc_selector *' */
1161 = build_pointer_type (xref_tag (RECORD_TYPE,
1162 get_identifier (TAG_SELECTOR)));
1164 /* Forward declare type, or else the prototype for msgSendSuper will
1167 /* `struct objc_super *' */
1168 super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1169 get_identifier (TAG_SUPER)));
1172 /* id objc_msgSend (id, SEL, ...); */
1175 = build_function_type (id_type,
1176 tree_cons (NULL_TREE, id_type,
1177 tree_cons (NULL_TREE, selector_type,
1180 if (! flag_next_runtime)
1182 umsg_decl = build_decl (FUNCTION_DECL,
1183 get_identifier (TAG_MSGSEND), temp_type);
1184 DECL_EXTERNAL (umsg_decl) = 1;
1185 TREE_PUBLIC (umsg_decl) = 1;
1186 DECL_INLINE (umsg_decl) = 1;
1187 DECL_ARTIFICIAL (umsg_decl) = 1;
1189 make_decl_rtl (umsg_decl, NULL);
1190 pushdecl (umsg_decl);
1194 umsg_decl = builtin_function (TAG_MSGSEND,
1195 temp_type, 0, NOT_BUILT_IN,
1197 /* id objc_msgSendNonNil (id, SEL, ...); */
1198 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1199 temp_type, 0, NOT_BUILT_IN,
1203 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1206 = build_function_type (id_type,
1207 tree_cons (NULL_TREE, super_type,
1208 tree_cons (NULL_TREE, selector_type,
1211 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1212 temp_type, 0, NOT_BUILT_IN,
1215 /* The NeXT runtime defines the following additional entry points,
1216 used for dispatching calls to methods returning structs:
1218 #if defined(__cplusplus)
1219 id objc_msgSend_stret(id self, SEL op, ...);
1220 id objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...);
1222 void objc_msgSend_stret(void * stretAddr, id self, SEL op, ...);
1223 void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super,
1227 struct objc_return_struct objc_msgSendNonNil_stret(id self, SEL op, ...);
1229 These prototypes appear in <objc/objc-runtime.h>; however, they
1230 CANNOT BE USED DIRECTLY. In order to call one of the ..._stret
1231 functions, the function must first be cast to a signature that
1232 corresponds to the actual ObjC method being invoked. This is
1233 what is done by the build_objc_method_call() routine below. */
1235 if (flag_next_runtime)
1237 tree objc_return_struct_type
1238 = xref_tag (RECORD_TYPE,
1239 get_identifier (TAG_RETURN_STRUCT));
1241 tree stret_temp_type
1242 = build_function_type (id_type,
1243 tree_cons (NULL_TREE, id_type,
1244 tree_cons (NULL_TREE, selector_type,
1247 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1248 stret_temp_type, 0, NOT_BUILT_IN,
1251 = build_function_type (objc_return_struct_type,
1252 tree_cons (NULL_TREE, id_type,
1253 tree_cons (NULL_TREE, selector_type,
1256 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1257 stret_temp_type, 0, NOT_BUILT_IN,
1261 = build_function_type (id_type,
1262 tree_cons (NULL_TREE, super_type,
1263 tree_cons (NULL_TREE, selector_type,
1266 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1267 stret_temp_type, 0, NOT_BUILT_IN, 0,
1271 /* id objc_getClass (const char *); */
1273 temp_type = build_function_type (id_type,
1274 tree_cons (NULL_TREE,
1275 const_string_type_node,
1279 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1282 /* id objc_getMetaClass (const char *); */
1284 objc_get_meta_class_decl
1285 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1287 build_super_template ();
1288 if (flag_next_runtime)
1289 build_objc_exception_stuff ();
1291 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1293 if (! flag_next_runtime)
1295 if (flag_typed_selectors)
1297 /* Suppress outputting debug symbols, because
1298 dbxout_init hasn'r been called yet. */
1299 enum debug_info_type save_write_symbols = write_symbols;
1300 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1301 write_symbols = NO_DEBUG;
1302 debug_hooks = &do_nothing_debug_hooks;
1304 build_selector_template ();
1305 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1307 write_symbols = save_write_symbols;
1308 debug_hooks = save_hooks;
1311 temp_type = build_array_type (selector_type, NULL_TREE);
1313 layout_type (temp_type);
1314 UOBJC_SELECTOR_TABLE_decl
1315 = create_builtin_decl (VAR_DECL, temp_type,
1316 "_OBJC_SELECTOR_TABLE");
1318 /* Avoid warning when not sending messages. */
1319 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1322 generate_forward_declaration_to_string_table ();
1324 /* Forward declare constant_string_id and constant_string_type. */
1325 if (!constant_string_class_name)
1326 constant_string_class_name = default_constant_string_class_name;
1328 constant_string_id = get_identifier (constant_string_class_name);
1329 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1331 /* Pre-build the following entities - for speed/convenience. */
1332 self_id = get_identifier ("self");
1333 ucmd_id = get_identifier ("_cmd");
1335 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1336 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1340 /* Ensure that the ivar list for NSConstantString/NXConstantString
1341 (or whatever was specified via `-fconstant-string-class')
1342 contains fields at least as large as the following three, so that
1343 the runtime can stomp on them with confidence:
1345 struct STRING_OBJECT_CLASS_NAME
1349 unsigned int length;
1353 check_string_class_template (void)
1355 tree field_decl = TYPE_FIELDS (constant_string_type);
1357 #define AT_LEAST_AS_LARGE_AS(F, T) \
1358 (F && TREE_CODE (F) == FIELD_DECL \
1359 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1360 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1362 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1365 field_decl = TREE_CHAIN (field_decl);
1366 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1369 field_decl = TREE_CHAIN (field_decl);
1370 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1372 #undef AT_LEAST_AS_LARGE_AS
1375 /* Avoid calling `check_string_class_template ()' more than once. */
1376 static GTY(()) int string_layout_checked;
1378 /* Custom build_string which sets TREE_TYPE! */
1381 my_build_string (int len, const char *str)
1383 return fix_string_type (build_string (len, str));
1386 /* Given a chain of STRING_CST's, build a static instance of
1387 NXConstantString which points at the concatenation of those
1388 strings. We place the string object in the __string_objects
1389 section of the __OBJC segment. The Objective-C runtime will
1390 initialize the isa pointers of the string objects to point at the
1391 NXConstantString class object. */
1394 build_objc_string_object (tree string)
1396 tree initlist, constructor, constant_string_class;
1399 string = fix_string_type (string);
1401 constant_string_class = lookup_interface (constant_string_id);
1402 if (!constant_string_class
1403 || !(constant_string_type
1404 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1406 error ("cannot find interface declaration for `%s'",
1407 IDENTIFIER_POINTER (constant_string_id));
1408 return error_mark_node;
1411 /* Call to 'combine_strings' has been moved above. */
1412 TREE_SET_CODE (string, STRING_CST);
1413 length = TREE_STRING_LENGTH (string) - 1;
1415 if (!string_layout_checked)
1417 /* The NSConstantString/NXConstantString ivar layout is now
1419 if (!check_string_class_template ())
1421 error ("interface `%s' does not have valid constant string layout",
1422 IDENTIFIER_POINTER (constant_string_id));
1423 return error_mark_node;
1425 add_class_reference (constant_string_id);
1428 /* & ((NXConstantString) { NULL, string, length }) */
1430 if (flag_next_runtime)
1432 /* For the NeXT runtime, we can generate a literal reference
1433 to the string class, don't need to run a constructor. */
1434 setup_string_decl ();
1435 if (string_class_decl == NULL_TREE)
1437 error ("cannot find reference tag for class `%s'",
1438 IDENTIFIER_POINTER (constant_string_id));
1439 return error_mark_node;
1441 initlist = build_tree_list
1443 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1447 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1451 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1453 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1454 constructor = objc_build_constructor (constant_string_type,
1455 nreverse (initlist));
1457 if (!flag_next_runtime)
1460 = objc_add_static_instance (constructor, constant_string_type);
1463 return (build_unary_op (ADDR_EXPR, constructor, 1));
1466 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1468 static GTY(()) int num_static_inst;
1471 objc_add_static_instance (tree constructor, tree class_decl)
1476 /* Find the list of static instances for the CLASS_DECL. Create one if
1478 for (chain = &objc_static_instances;
1479 *chain && TREE_VALUE (*chain) != class_decl;
1480 chain = &TREE_CHAIN (*chain));
1483 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1484 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1487 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1488 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1489 DECL_COMMON (decl) = 1;
1490 TREE_STATIC (decl) = 1;
1491 DECL_ARTIFICIAL (decl) = 1;
1492 DECL_INITIAL (decl) = constructor;
1494 /* We may be writing something else just now.
1495 Postpone till end of input. */
1496 DECL_DEFER_OUTPUT (decl) = 1;
1497 pushdecl_top_level (decl);
1498 rest_of_decl_compilation (decl, 0, 1, 0);
1500 /* Add the DECL to the head of this CLASS' list. */
1501 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1506 /* Build a static constant CONSTRUCTOR
1507 with type TYPE and elements ELTS. */
1510 objc_build_constructor (tree type, tree elts)
1512 tree constructor, f, e;
1514 /* ??? Most of the places that we build constructors, we don't fill in
1515 the type of integers properly. Convert them all en masse. */
1516 if (TREE_CODE (type) == ARRAY_TYPE)
1518 f = TREE_TYPE (type);
1519 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1520 for (e = elts; e ; e = TREE_CHAIN (e))
1521 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1525 f = TYPE_FIELDS (type);
1526 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1527 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1528 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1529 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1532 constructor = build_constructor (type, elts);
1533 TREE_CONSTANT (constructor) = 1;
1534 TREE_STATIC (constructor) = 1;
1535 TREE_READONLY (constructor) = 1;
1538 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1539 build_unary_op (wasn't true in 2.7.2.1 days) */
1540 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1545 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1547 /* Predefine the following data type:
1555 void *defs[cls_def_cnt + cat_def_cnt];
1559 build_objc_symtab_template (void)
1561 tree field_decl, field_decl_chain;
1563 objc_symtab_template
1564 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1566 /* long sel_ref_cnt; */
1568 field_decl = create_builtin_decl (FIELD_DECL,
1569 long_integer_type_node,
1571 field_decl_chain = field_decl;
1575 field_decl = create_builtin_decl (FIELD_DECL,
1576 build_pointer_type (selector_type),
1578 chainon (field_decl_chain, field_decl);
1580 /* short cls_def_cnt; */
1582 field_decl = create_builtin_decl (FIELD_DECL,
1583 short_integer_type_node,
1585 chainon (field_decl_chain, field_decl);
1587 /* short cat_def_cnt; */
1589 field_decl = create_builtin_decl (FIELD_DECL,
1590 short_integer_type_node,
1592 chainon (field_decl_chain, field_decl);
1594 if (imp_count || cat_count || !flag_next_runtime)
1596 /* void *defs[imp_count + cat_count (+ 1)]; */
1597 /* NB: The index is one less than the size of the array. */
1598 int index = imp_count + cat_count
1599 + (flag_next_runtime? -1: 0);
1600 field_decl = create_builtin_decl
1604 build_index_type (build_int_2 (index, 0))),
1606 chainon (field_decl_chain, field_decl);
1609 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1612 /* Create the initial value for the `defs' field of _objc_symtab.
1613 This is a CONSTRUCTOR. */
1616 init_def_list (tree type)
1618 tree expr, initlist = NULL_TREE;
1619 struct imp_entry *impent;
1622 for (impent = imp_list; impent; impent = impent->next)
1624 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1626 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1627 initlist = tree_cons (NULL_TREE, expr, initlist);
1632 for (impent = imp_list; impent; impent = impent->next)
1634 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1636 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1637 initlist = tree_cons (NULL_TREE, expr, initlist);
1641 if (!flag_next_runtime)
1643 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1646 if (static_instances_decl)
1647 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1649 expr = build_int_2 (0, 0);
1651 initlist = tree_cons (NULL_TREE, expr, initlist);
1654 return objc_build_constructor (type, nreverse (initlist));
1657 /* Construct the initial value for all of _objc_symtab. */
1660 init_objc_symtab (tree type)
1664 /* sel_ref_cnt = { ..., 5, ... } */
1666 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1668 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1670 if (flag_next_runtime || ! sel_ref_chain)
1671 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1673 initlist = tree_cons (NULL_TREE,
1674 build_unary_op (ADDR_EXPR,
1675 UOBJC_SELECTOR_TABLE_decl, 1),
1678 /* cls_def_cnt = { ..., 5, ... } */
1680 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1682 /* cat_def_cnt = { ..., 5, ... } */
1684 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1686 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1688 if (imp_count || cat_count || !flag_next_runtime)
1691 tree field = TYPE_FIELDS (type);
1692 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1694 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1698 return objc_build_constructor (type, nreverse (initlist));
1701 /* Generate forward declarations for metadata such as
1702 'OBJC_CLASS_...'. */
1705 build_metadata_decl (const char *name, tree type)
1707 tree decl, decl_specs;
1708 /* extern struct TYPE NAME_<name>; */
1709 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1710 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1711 decl = define_decl (synth_id_with_class_suffix
1713 objc_implementation_context),
1715 TREE_USED (decl) = 1;
1716 DECL_ARTIFICIAL (decl) = 1;
1717 TREE_PUBLIC (decl) = 0;
1721 /* Push forward-declarations of all the categories so that
1722 init_def_list can use them in a CONSTRUCTOR. */
1725 forward_declare_categories (void)
1727 struct imp_entry *impent;
1728 tree sav = objc_implementation_context;
1730 for (impent = imp_list; impent; impent = impent->next)
1732 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1734 /* Set an invisible arg to synth_id_with_class_suffix. */
1735 objc_implementation_context = impent->imp_context;
1736 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1737 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1738 objc_category_template);
1741 objc_implementation_context = sav;
1744 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1745 and initialized appropriately. */
1748 generate_objc_symtab_decl (void)
1752 if (!objc_category_template)
1753 build_category_template ();
1755 /* forward declare categories */
1757 forward_declare_categories ();
1759 if (!objc_symtab_template)
1760 build_objc_symtab_template ();
1762 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1764 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1765 tree_cons (NULL_TREE,
1766 objc_symtab_template, sc_spec),
1770 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1771 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1772 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1773 finish_decl (UOBJC_SYMBOLS_decl,
1774 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1779 init_module_descriptor (tree type)
1781 tree initlist, expr;
1783 /* version = { 1, ... } */
1785 expr = build_int_2 (OBJC_VERSION, 0);
1786 initlist = build_tree_list (NULL_TREE, expr);
1788 /* size = { ..., sizeof (struct objc_module), ... } */
1790 expr = size_in_bytes (objc_module_template);
1791 initlist = tree_cons (NULL_TREE, expr, initlist);
1793 /* name = { ..., "foo.m", ... } */
1795 expr = add_objc_string (get_identifier (input_filename), class_names);
1796 initlist = tree_cons (NULL_TREE, expr, initlist);
1798 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1800 if (UOBJC_SYMBOLS_decl)
1801 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1803 expr = build_int_2 (0, 0);
1804 initlist = tree_cons (NULL_TREE, expr, initlist);
1806 return objc_build_constructor (type, nreverse (initlist));
1809 /* Write out the data structures to describe Objective C classes defined.
1810 If appropriate, compile and output a setup function to initialize them.
1811 Return a symbol_ref to the function to call to initialize the Objective C
1812 data structures for this file (and perhaps for other files also).
1814 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1817 build_module_descriptor (void)
1819 tree decl_specs, field_decl, field_decl_chain;
1821 objc_module_template
1822 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1826 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1827 field_decl = get_identifier ("version");
1828 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1829 field_decl_chain = field_decl;
1833 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1834 field_decl = get_identifier ("size");
1835 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1836 chainon (field_decl_chain, field_decl);
1840 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1841 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1842 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1843 chainon (field_decl_chain, field_decl);
1845 /* struct objc_symtab *symtab; */
1847 decl_specs = get_identifier (UTAG_SYMTAB);
1848 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1849 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1850 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1851 chainon (field_decl_chain, field_decl);
1853 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1855 /* Create an instance of "objc_module". */
1857 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1858 build_tree_list (NULL_TREE,
1859 ridpointers[(int) RID_STATIC]));
1861 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1862 decl_specs, 1, NULL_TREE);
1864 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1865 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1866 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1868 finish_decl (UOBJC_MODULES_decl,
1869 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1872 /* Mark the decl to avoid "defined but not used" warning. */
1873 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1875 /* Generate a constructor call for the module descriptor.
1876 This code was generated by reading the grammar rules
1877 of c-parse.in; Therefore, it may not be the most efficient
1878 way of generating the requisite code. */
1880 if (flag_next_runtime)
1884 tree parms, execclass_decl, decelerator, void_list_node_1;
1885 tree init_function_name, init_function_decl;
1887 /* Declare void __objc_execClass (void *); */
1889 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1890 execclass_decl = build_decl (FUNCTION_DECL,
1891 get_identifier (TAG_EXECCLASS),
1892 build_function_type (void_type_node,
1893 tree_cons (NULL_TREE, ptr_type_node,
1894 OBJC_VOID_AT_END)));
1896 DECL_EXTERNAL (execclass_decl) = 1;
1897 DECL_ARTIFICIAL (execclass_decl) = 1;
1898 TREE_PUBLIC (execclass_decl) = 1;
1899 pushdecl (execclass_decl);
1900 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1901 assemble_external (execclass_decl);
1903 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1905 init_function_name = get_file_function_name ('I');
1906 start_function (void_list_node_1,
1907 build_nt (CALL_EXPR, init_function_name,
1908 tree_cons (NULL_TREE, NULL_TREE,
1912 store_parm_decls ();
1914 init_function_decl = current_function_decl;
1915 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1916 TREE_USED (init_function_decl) = 1;
1917 /* Don't let this one be deferred. */
1918 DECL_INLINE (init_function_decl) = 0;
1919 DECL_UNINLINABLE (init_function_decl) = 1;
1920 current_function_cannot_inline
1921 = "static constructors and destructors cannot be inlined";
1924 = build_tree_list (NULL_TREE,
1925 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1926 decelerator = build_function_call (execclass_decl, parms);
1928 c_expand_expr_stmt (decelerator);
1932 return XEXP (DECL_RTL (init_function_decl), 0);
1936 /* extern const char _OBJC_STRINGS[]; */
1939 generate_forward_declaration_to_string_table (void)
1941 tree sc_spec, decl_specs, expr_decl;
1943 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
1944 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
1947 = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
1949 UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
1952 /* Return the DECL of the string IDENT in the SECTION. */
1955 get_objc_string_decl (tree ident, enum string_section section)
1959 if (section == class_names)
1960 chain = class_names_chain;
1961 else if (section == meth_var_names)
1962 chain = meth_var_names_chain;
1963 else if (section == meth_var_types)
1964 chain = meth_var_types_chain;
1968 for (; chain != 0; chain = TREE_CHAIN (chain))
1969 if (TREE_VALUE (chain) == ident)
1970 return (TREE_PURPOSE (chain));
1976 /* Output references to all statically allocated objects. Return the DECL
1977 for the array built. */
1980 generate_static_references (void)
1982 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1983 tree class_name, class, decl, initlist;
1984 tree cl_chain, in_chain, type;
1985 int num_inst, num_class;
1988 if (flag_next_runtime)
1991 for (cl_chain = objc_static_instances, num_class = 0;
1992 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1994 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1995 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1997 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1998 ident = get_identifier (buf);
2000 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2001 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2002 build_tree_list (NULL_TREE,
2003 ridpointers[(int) RID_STATIC]));
2004 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2005 DECL_CONTEXT (decl) = 0;
2006 DECL_ARTIFICIAL (decl) = 1;
2008 /* Output {class_name, ...}. */
2009 class = TREE_VALUE (cl_chain);
2010 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2011 initlist = build_tree_list (NULL_TREE,
2012 build_unary_op (ADDR_EXPR, class_name, 1));
2014 /* Output {..., instance, ...}. */
2015 for (in_chain = TREE_PURPOSE (cl_chain);
2016 in_chain; in_chain = TREE_CHAIN (in_chain))
2018 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2019 initlist = tree_cons (NULL_TREE, expr, initlist);
2022 /* Output {..., NULL}. */
2023 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2025 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2026 finish_decl (decl, expr, NULL_TREE);
2027 TREE_USED (decl) = 1;
2029 type = build_array_type (build_pointer_type (void_type_node), 0);
2030 decl = build_decl (VAR_DECL, ident, type);
2031 TREE_USED (decl) = 1;
2032 TREE_STATIC (decl) = 1;
2034 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2037 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2038 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2039 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2040 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2041 build_tree_list (NULL_TREE,
2042 ridpointers[(int) RID_STATIC]));
2043 static_instances_decl
2044 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2045 TREE_USED (static_instances_decl) = 1;
2046 DECL_CONTEXT (static_instances_decl) = 0;
2047 DECL_ARTIFICIAL (static_instances_decl) = 1;
2048 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2050 finish_decl (static_instances_decl, expr, NULL_TREE);
2053 /* Output all strings. */
2056 generate_strings (void)
2058 tree sc_spec, decl_specs, expr_decl;
2059 tree chain, string_expr;
2062 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2064 string = TREE_VALUE (chain);
2065 decl = TREE_PURPOSE (chain);
2067 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2068 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2069 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2070 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2071 DECL_CONTEXT (decl) = NULL_TREE;
2072 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2073 IDENTIFIER_POINTER (string));
2074 finish_decl (decl, string_expr, NULL_TREE);
2077 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2079 string = TREE_VALUE (chain);
2080 decl = TREE_PURPOSE (chain);
2082 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2083 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2084 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2085 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2086 DECL_CONTEXT (decl) = NULL_TREE;
2087 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2088 IDENTIFIER_POINTER (string));
2089 finish_decl (decl, string_expr, NULL_TREE);
2092 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2094 string = TREE_VALUE (chain);
2095 decl = TREE_PURPOSE (chain);
2097 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2098 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2099 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2100 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2101 DECL_CONTEXT (decl) = NULL_TREE;
2102 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2103 IDENTIFIER_POINTER (string));
2104 finish_decl (decl, string_expr, NULL_TREE);
2108 static GTY(()) int selector_reference_idx;
2111 build_selector_reference_decl (void)
2116 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2118 ident = get_identifier (buf);
2120 decl = build_decl (VAR_DECL, ident, selector_type);
2121 DECL_EXTERNAL (decl) = 1;
2122 TREE_PUBLIC (decl) = 0;
2123 TREE_USED (decl) = 1;
2124 DECL_ARTIFICIAL (decl) = 1;
2125 DECL_CONTEXT (decl) = 0;
2127 make_decl_rtl (decl, 0);
2128 pushdecl_top_level (decl);
2133 /* Just a handy wrapper for add_objc_string. */
2136 build_selector (tree ident)
2138 tree expr = add_objc_string (ident, meth_var_names);
2139 if (flag_typed_selectors)
2142 return build_c_cast (selector_type, expr); /* cast! */
2146 build_selector_translation_table (void)
2148 tree sc_spec, decl_specs;
2149 tree chain, initlist = NULL_TREE;
2151 tree decl = NULL_TREE, var_decl, name;
2153 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2157 if (warn_selector && objc_implementation_context)
2161 for (method_chain = meth_var_names_chain;
2163 method_chain = TREE_CHAIN (method_chain))
2165 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2173 /* Adjust line number for warning message. */
2174 int save_lineno = input_line;
2175 if (flag_next_runtime && TREE_PURPOSE (chain))
2176 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2177 warning ("creating selector for non existant method %s",
2178 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2179 input_line = save_lineno;
2183 expr = build_selector (TREE_VALUE (chain));
2185 if (flag_next_runtime)
2187 name = DECL_NAME (TREE_PURPOSE (chain));
2189 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2191 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2192 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2196 /* The `decl' that is returned from start_decl is the one that we
2197 forward declared in `build_selector_reference' */
2198 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2201 /* add one for the '\0' character */
2202 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2204 if (flag_next_runtime)
2205 finish_decl (decl, expr, NULL_TREE);
2208 if (flag_typed_selectors)
2210 tree eltlist = NULL_TREE;
2211 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2212 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2213 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2214 expr = objc_build_constructor (objc_selector_template,
2215 nreverse (eltlist));
2217 initlist = tree_cons (NULL_TREE, expr, initlist);
2222 if (! flag_next_runtime)
2224 /* Cause the variable and its initial value to be actually output. */
2225 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2226 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2227 /* NULL terminate the list and fix the decl for output. */
2228 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2229 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2230 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2231 nreverse (initlist));
2232 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2233 current_function_decl = NULL_TREE;
2238 get_proto_encoding (tree proto)
2243 if (! METHOD_ENCODING (proto))
2245 encoding = encode_method_prototype (proto);
2246 METHOD_ENCODING (proto) = encoding;
2249 encoding = METHOD_ENCODING (proto);
2251 return add_objc_string (encoding, meth_var_types);
2254 return build_int_2 (0, 0);
2257 /* sel_ref_chain is a list whose "value" fields will be instances of
2258 identifier_node that represent the selector. */
2261 build_typed_selector_reference (tree ident, tree prototype)
2263 tree *chain = &sel_ref_chain;
2269 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2270 goto return_at_index;
2273 chain = &TREE_CHAIN (*chain);
2276 *chain = tree_cons (prototype, ident, NULL_TREE);
2279 expr = build_unary_op (ADDR_EXPR,
2280 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2281 build_int_2 (index, 0)),
2283 return build_c_cast (selector_type, expr);
2287 build_selector_reference (tree ident)
2289 tree *chain = &sel_ref_chain;
2295 if (TREE_VALUE (*chain) == ident)
2296 return (flag_next_runtime
2297 ? TREE_PURPOSE (*chain)
2298 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2299 build_int_2 (index, 0)));
2302 chain = &TREE_CHAIN (*chain);
2305 expr = build_selector_reference_decl ();
2307 *chain = tree_cons (expr, ident, NULL_TREE);
2309 return (flag_next_runtime
2311 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2312 build_int_2 (index, 0)));
2315 static GTY(()) int class_reference_idx;
2318 build_class_reference_decl (void)
2323 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2325 ident = get_identifier (buf);
2327 decl = build_decl (VAR_DECL, ident, objc_class_type);
2328 DECL_EXTERNAL (decl) = 1;
2329 TREE_PUBLIC (decl) = 0;
2330 TREE_USED (decl) = 1;
2331 DECL_CONTEXT (decl) = 0;
2332 DECL_ARTIFICIAL (decl) = 1;
2334 make_decl_rtl (decl, 0);
2335 pushdecl_top_level (decl);
2340 /* Create a class reference, but don't create a variable to reference
2344 add_class_reference (tree ident)
2348 if ((chain = cls_ref_chain))
2353 if (ident == TREE_VALUE (chain))
2357 chain = TREE_CHAIN (chain);
2361 /* Append to the end of the list */
2362 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2365 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2368 /* Get a class reference, creating it if necessary. Also create the
2369 reference variable. */
2372 get_class_reference (tree ident)
2377 if (processing_template_decl)
2378 /* Must wait until template instantiation time. */
2379 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2380 if (TREE_CODE (ident) == TYPE_DECL)
2381 ident = DECL_NAME (ident);
2385 if (!(ident = is_class_name (ident)))
2387 error ("`%s' is not an Objective-C class name or alias",
2388 IDENTIFIER_POINTER (orig_ident));
2389 return error_mark_node;
2392 if (flag_next_runtime && !flag_zero_link)
2397 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2398 if (TREE_VALUE (*chain) == ident)
2400 if (! TREE_PURPOSE (*chain))
2401 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2403 return TREE_PURPOSE (*chain);
2406 decl = build_class_reference_decl ();
2407 *chain = tree_cons (decl, ident, NULL_TREE);
2414 add_class_reference (ident);
2416 params = build_tree_list (NULL_TREE,
2417 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2418 IDENTIFIER_POINTER (ident)));
2420 assemble_external (objc_get_class_decl);
2421 return build_function_call (objc_get_class_decl, params);
2425 /* For each string section we have a chain which maps identifier nodes
2426 to decls for the strings. */
2429 add_objc_string (tree ident, enum string_section section)
2433 if (section == class_names)
2434 chain = &class_names_chain;
2435 else if (section == meth_var_names)
2436 chain = &meth_var_names_chain;
2437 else if (section == meth_var_types)
2438 chain = &meth_var_types_chain;
2444 if (TREE_VALUE (*chain) == ident)
2445 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2447 chain = &TREE_CHAIN (*chain);
2450 decl = build_objc_string_decl (section);
2452 *chain = tree_cons (decl, ident, NULL_TREE);
2454 return build_unary_op (ADDR_EXPR, decl, 1);
2457 static GTY(()) int class_names_idx;
2458 static GTY(()) int meth_var_names_idx;
2459 static GTY(()) int meth_var_types_idx;
2462 build_objc_string_decl (enum string_section section)
2467 if (section == class_names)
2468 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2469 else if (section == meth_var_names)
2470 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2471 else if (section == meth_var_types)
2472 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2474 ident = get_identifier (buf);
2476 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2477 DECL_EXTERNAL (decl) = 1;
2478 TREE_PUBLIC (decl) = 0;
2479 TREE_USED (decl) = 1;
2480 TREE_CONSTANT (decl) = 1;
2481 DECL_CONTEXT (decl) = 0;
2482 DECL_ARTIFICIAL (decl) = 1;
2484 make_decl_rtl (decl, 0);
2485 pushdecl_top_level (decl);
2492 objc_declare_alias (tree alias_ident, tree class_ident)
2494 tree underlying_class;
2497 if (current_namespace != global_namespace) {
2498 error ("Objective-C declarations may only appear in global scope");
2500 #endif /* OBJCPLUS */
2502 if (!(underlying_class = is_class_name (class_ident)))
2503 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2504 else if (is_class_name (alias_ident))
2505 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2507 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2511 objc_declare_class (tree ident_list)
2515 if (current_namespace != global_namespace) {
2516 error ("Objective-C declarations may only appear in global scope");
2518 #endif /* OBJCPLUS */
2520 for (list = ident_list; list; list = TREE_CHAIN (list))
2522 tree ident = TREE_VALUE (list);
2524 if (! is_class_name (ident))
2526 tree record = lookup_name (ident);
2528 if (record && ! TREE_STATIC_TEMPLATE (record))
2530 error ("`%s' redeclared as different kind of symbol",
2531 IDENTIFIER_POINTER (ident));
2532 error ("%Jprevious declaration of '%D'",
2536 record = xref_tag (RECORD_TYPE, ident);
2537 TREE_STATIC_TEMPLATE (record) = 1;
2538 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2544 is_class_name (tree ident)
2548 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2549 && identifier_global_value (ident))
2550 ident = identifier_global_value (ident);
2551 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2552 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2555 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2556 ident = TYPE_NAME (ident);
2557 if (ident && TREE_CODE (ident) == TYPE_DECL)
2558 ident = DECL_NAME (ident);
2560 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2563 if (lookup_interface (ident))
2566 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2568 if (ident == TREE_VALUE (chain))
2572 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2574 if (ident == TREE_VALUE (chain))
2575 return TREE_PURPOSE (chain);
2581 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2582 class instance. This is needed by other parts of the compiler to
2583 handle ObjC types gracefully. */
2586 objc_is_object_ptr (tree type)
2588 type = TYPE_MAIN_VARIANT (type);
2589 if (!type || TREE_CODE (type) != POINTER_TYPE)
2591 /* NB: This function may be called before the ObjC front-end has
2592 been initialized, in which case ID_TYPE will be NULL. */
2593 if (id_type && type && TYPE_P (type)
2595 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2597 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2601 lookup_interface (tree ident)
2606 if (ident && TREE_CODE (ident) == TYPE_DECL)
2607 ident = DECL_NAME (ident);
2609 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2611 if (ident == CLASS_NAME (chain))
2617 /* Implement @defs (<classname>) within struct bodies. */
2620 get_class_ivars_from_name (tree class_name)
2622 tree interface = lookup_interface (class_name);
2623 tree field, fields = NULL_TREE;
2627 tree raw_ivar = get_class_ivars (interface, 1);
2629 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2630 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2632 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2633 TREE_PURPOSE (raw_ivar),
2634 TREE_VALUE (TREE_VALUE (raw_ivar)));
2636 finish_member_declaration (field);
2638 fields = chainon (fields, field);
2643 error ("cannot find interface declaration for `%s'",
2644 IDENTIFIER_POINTER (class_name));
2649 /* Used by: build_private_template, continue_class,
2650 and for @defs constructs. */
2653 get_class_ivars (tree interface, int raw)
2655 tree my_name, super_name, ivar_chain;
2657 my_name = CLASS_NAME (interface);
2658 super_name = CLASS_SUPER_NAME (interface);
2660 ivar_chain = CLASS_RAW_IVARS (interface);
2663 ivar_chain = CLASS_IVARS (interface);
2664 /* Save off a pristine copy of the leaf ivars (i.e, those not
2665 inherited from a super class). */
2666 if (!CLASS_OWN_IVARS (interface))
2667 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2673 tree super_interface = lookup_interface (super_name);
2675 if (!super_interface)
2677 /* fatal did not work with 2 args...should fix */
2678 error ("cannot find interface declaration for `%s', superclass of `%s'",
2679 IDENTIFIER_POINTER (super_name),
2680 IDENTIFIER_POINTER (my_name));
2681 exit (FATAL_EXIT_CODE);
2684 if (super_interface == interface)
2685 fatal_error ("circular inheritance in interface declaration for `%s'",
2686 IDENTIFIER_POINTER (super_name));
2688 interface = super_interface;
2689 my_name = CLASS_NAME (interface);
2690 super_name = CLASS_SUPER_NAME (interface);
2692 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2695 tree head = copy_list (op1);
2697 /* Prepend super class ivars...make a copy of the list, we
2698 do not want to alter the original. */
2699 chainon (head, ivar_chain);
2708 objc_enter_block (void)
2713 block = begin_compound_stmt (0);
2715 block = c_begin_compound_stmt ();
2718 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
2721 objc_exception_block_stack = tree_cons (NULL_TREE, block,
2722 objc_exception_block_stack);
2724 blk_nesting_count++;
2729 objc_exit_block (void)
2731 tree block = TREE_VALUE (objc_exception_block_stack);
2733 tree scope_stmt, inner;
2736 objc_clear_super_receiver ();
2738 finish_compound_stmt (0, block);
2740 scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
2741 inner = poplevel (KEEP_MAYBE, 1, 0);
2743 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
2744 = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
2746 RECHAIN_STMTS (block, COMPOUND_BODY (block));
2748 last_expr_type = NULL_TREE;
2749 objc_exception_block_stack = TREE_CHAIN (objc_exception_block_stack);
2751 blk_nesting_count--;
2756 objc_declare_variable (enum rid scspec, tree name, tree type, tree init)
2760 type = tree_cons (NULL_TREE, type,
2761 tree_cons (NULL_TREE, ridpointers[(int) scspec],
2763 TREE_STATIC (type) = 1;
2764 decl = start_decl (name, type, (init != NULL_TREE), NULL_TREE);
2765 finish_decl (decl, init, NULL_TREE);
2766 /* This prevents `unused variable' warnings when compiling with -Wall. */
2767 TREE_USED (decl) = 1;
2768 DECL_ARTIFICIAL (decl) = 1;
2773 objc_build_throw_stmt (tree throw_expr)
2777 if (!flag_objc_exceptions)
2778 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2780 if (!throw_expr && objc_caught_exception)
2781 throw_expr = TREE_VALUE (objc_caught_exception);
2785 error ("`@throw;' (rethrow) used outside of a `@catch' block");
2786 return error_mark_node;
2789 func_params = tree_cons (NULL_TREE, throw_expr, NULL_TREE);
2791 assemble_external (objc_exception_throw_decl);
2792 return c_expand_expr_stmt (build_function_call (objc_exception_throw_decl,
2797 val_stack_push (struct val_stack **nc, long val)
2799 struct val_stack *new_elem = xmalloc (sizeof (struct val_stack));
2800 new_elem->val = val;
2801 new_elem->next = *nc;
2806 val_stack_pop (struct val_stack **nc)
2808 struct val_stack *old_elem = *nc;
2809 *nc = old_elem->next;
2814 objc_build_try_enter_fragment (void)
2816 /* objc_exception_try_enter(&_stackExceptionData);
2817 if (!_setjmp(&_stackExceptionData.buf)) { */
2819 tree func_params, if_stmt, cond;
2822 = tree_cons (NULL_TREE,
2823 build_unary_op (ADDR_EXPR,
2824 TREE_VALUE (objc_stack_exception_data),
2828 assemble_external (objc_exception_try_enter_decl);
2829 c_expand_expr_stmt (build_function_call
2830 (objc_exception_try_enter_decl, func_params));
2832 if_stmt = c_begin_if_stmt ();
2834 /* If <setjmp.h> has been included, the _setjmp prototype has
2835 acquired a real, breathing type for its parameter. Cast our
2836 argument to that type. */
2838 = tree_cons (NULL_TREE,
2839 build_c_cast (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))
2840 ? TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
2844 build_component_ref (TREE_VALUE (objc_stack_exception_data),
2845 get_identifier ("buf")), 0)),
2847 assemble_external (objc_setjmp_decl);
2848 cond = build_unary_op (TRUTH_NOT_EXPR,
2849 build_function_call (objc_setjmp_decl, func_params),
2851 c_expand_start_cond (c_common_truthvalue_conversion (cond),
2853 objc_enter_block ();
2857 objc_build_extract_expr (void)
2859 /* ... = objc_exception_extract(&_stackExceptionData); */
2862 = tree_cons (NULL_TREE,
2863 build_unary_op (ADDR_EXPR,
2864 TREE_VALUE (objc_stack_exception_data), 0),
2867 assemble_external (objc_exception_extract_decl);
2868 return build_function_call (objc_exception_extract_decl, func_params);
2872 objc_build_try_exit_fragment (void)
2874 /* objc_exception_try_exit(&_stackExceptionData); */
2877 = tree_cons (NULL_TREE,
2878 build_unary_op (ADDR_EXPR,
2879 TREE_VALUE (objc_stack_exception_data), 0),
2882 assemble_external (objc_exception_try_exit_decl);
2883 c_expand_expr_stmt (build_function_call (objc_exception_try_exit_decl,
2888 objc_build_extract_fragment (void)
2891 _rethrowException = objc_exception_extract(&_stackExceptionData);
2897 c_expand_start_else ();
2898 objc_enter_block ();
2899 c_expand_expr_stmt (build_modify_expr
2900 (TREE_VALUE (objc_rethrow_exception),
2902 objc_build_extract_expr ()));
2905 c_expand_end_cond ();
2910 objc_build_try_prologue (void)
2913 struct _objc_exception_data _stackExceptionData;
2914 volatile id _rethrowException = nil;
2915 { // begin TRY-CATCH scope
2916 objc_exception_try_enter(&_stackExceptionData);
2917 if (!_setjmp(&_stackExceptionData.buf)) { */
2919 tree try_catch_block;
2921 if (!flag_objc_exceptions)
2922 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2924 objc_mark_locals_volatile ((void *)(exc_binding_stack
2925 ? exc_binding_stack->val
2927 objc_enter_block ();
2928 objc_stack_exception_data
2929 = tree_cons (NULL_TREE,
2930 objc_declare_variable (RID_AUTO,
2931 get_identifier (UTAG_EXCDATA_VAR),
2932 xref_tag (RECORD_TYPE,
2933 get_identifier (UTAG_EXCDATA)),
2935 objc_stack_exception_data);
2936 objc_rethrow_exception = tree_cons (NULL_TREE,
2937 objc_declare_variable (RID_VOLATILE,
2938 get_identifier (UTAG_RETHROWEXC_VAR),
2940 build_int_2 (0, 0)),
2941 objc_rethrow_exception);
2943 try_catch_block = objc_enter_block ();
2944 val_stack_push (&exc_binding_stack, (long) get_current_scope ());
2945 objc_build_try_enter_fragment ();
2947 return try_catch_block;
2951 objc_build_try_epilogue (int also_catch_prologue)
2953 if (also_catch_prologue)
2956 register id _caughtException = objc_exception_extract( &_stackExceptionData);
2957 objc_exception_try_enter(&_stackExceptionData);
2958 if(!_setjmp(&_stackExceptionData.buf)) {
2966 c_expand_start_else ();
2967 objc_enter_block ();
2968 objc_caught_exception
2969 = tree_cons (NULL_TREE,
2970 objc_declare_variable (RID_REGISTER,
2971 get_identifier (UTAG_CAUGHTEXC_VAR),
2973 objc_build_extract_expr ()),
2974 objc_caught_exception);
2975 objc_build_try_enter_fragment ();
2976 val_stack_push (&catch_count_stack, 1);
2977 if_stmt = c_begin_if_stmt ();
2979 c_expand_start_cond (c_common_truthvalue_conversion (boolean_false_node),
2981 objc_enter_block ();
2983 /* Start a new chain of @catch statements for this @try. */
2984 objc_catch_type = tree_cons (objc_catch_type, NULL_TREE, NULL_TREE);
2987 { /* !also_catch_prologue */
2990 _rethrowException = objc_exception_extract( &_stackExceptionData);
2993 objc_build_extract_fragment ();
2999 objc_build_catch_stmt (tree catch_expr)
3001 /* } else if (objc_exception_match(objc_get_class("SomeClass"), _caughtException)) {
3002 register SomeClass *e = _caughtException; */
3004 tree if_stmt, cond, func_params, prev_catch, var_name, var_type;
3008 /* Yet another C/C++ impedance mismatch. */
3009 catch_expr = TREE_PURPOSE (catch_expr);
3012 var_name = TREE_VALUE (catch_expr);
3013 var_type = TREE_VALUE (TREE_PURPOSE (catch_expr));
3014 if (TREE_CODE (var_name) == INDIRECT_REF)
3015 var_name = TREE_OPERAND (var_name, 0);
3016 if (TREE_CODE (var_type) == TYPE_DECL
3017 || TREE_CODE (var_type) == POINTER_TYPE)
3018 var_type = TREE_TYPE (var_type);
3019 catch_id = (var_type == TREE_TYPE (id_type));
3021 if (!flag_objc_exceptions)
3022 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3024 if (!(catch_id || TYPED_OBJECT (var_type)))
3025 fatal_error ("`@catch' parameter is not a known Objective-C class type");
3027 /* Examine previous @catch clauses for the current @try block for
3028 superclasses of the 'var_type' class. */
3029 for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch);
3030 prev_catch = TREE_CHAIN (prev_catch))
3032 if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
3034 warning ("Exception already handled by preceding `@catch(id)'");
3038 && objc_comptypes (TREE_VALUE (prev_catch), var_type, 0) == 1)
3039 warning ("Exception of type `%s *' already handled by `@catch (%s *)'",
3040 IDENTIFIER_POINTER (OBJC_TYPE_NAME (var_type)),
3041 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_VALUE (prev_catch))));
3044 objc_catch_type = tree_cons (NULL_TREE, var_type, objc_catch_type);
3049 c_expand_start_else ();
3050 catch_count_stack->val++;
3051 if_stmt = c_begin_if_stmt ();
3055 cond = integer_one_node;
3058 cond = get_class_reference (OBJC_TYPE_NAME (var_type));
3061 = tree_cons (NULL_TREE, cond,
3062 tree_cons (NULL_TREE,
3063 TREE_VALUE (objc_caught_exception),
3065 assemble_external (objc_exception_match_decl);
3066 cond = build_function_call (objc_exception_match_decl, func_params);
3069 c_expand_start_cond (c_common_truthvalue_conversion (cond),
3071 objc_enter_block ();
3072 objc_declare_variable (RID_REGISTER, var_name,
3073 build_pointer_type (var_type),
3074 TREE_VALUE (objc_caught_exception));
3078 objc_build_catch_epilogue (void)
3081 _rethrowException = _caughtException;
3082 objc_exception_try_exit(&_stackExceptionData);
3085 _rethrowException = objc_exception_extract(&_stackExceptionData);
3088 } // end TRY-CATCH scope
3094 c_expand_start_else ();
3095 objc_enter_block ();
3098 (TREE_VALUE (objc_rethrow_exception),
3100 TREE_VALUE (objc_caught_exception)));
3101 objc_build_try_exit_fragment ();
3103 while (catch_count_stack->val--)
3105 c_finish_else (); /* close off all the nested ifs ! */
3106 c_expand_end_cond ();
3109 val_stack_pop (&catch_count_stack);
3110 objc_caught_exception = TREE_CHAIN (objc_caught_exception);
3112 objc_build_extract_fragment ();
3116 c_expand_end_cond ();
3120 /* Return to enclosing chain of @catch statements (if any). */
3121 while (TREE_VALUE (objc_catch_type))
3122 objc_catch_type = TREE_CHAIN (objc_catch_type);
3123 objc_catch_type = TREE_PURPOSE (objc_catch_type);
3127 objc_build_finally_prologue ()
3129 /* { // begin FINALLY scope
3130 if (!_rethrowException) {
3131 objc_exception_try_exit(&_stackExceptionData);
3134 tree blk = objc_enter_block ();
3136 tree if_stmt = c_begin_if_stmt ();
3139 c_expand_start_cond (c_common_truthvalue_conversion
3142 TREE_VALUE (objc_rethrow_exception), 0)),
3144 objc_enter_block ();
3145 objc_build_try_exit_fragment ();
3148 c_expand_end_cond ();
3155 objc_build_finally_epilogue (void)
3157 /* if (_rethrowException) {
3158 objc_exception_throw(_rethrowException);
3160 } // end FINALLY scope
3163 tree if_stmt = c_begin_if_stmt ();
3167 (c_common_truthvalue_conversion (TREE_VALUE (objc_rethrow_exception)),
3169 objc_enter_block ();
3170 objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception));
3173 c_expand_end_cond ();
3177 objc_rethrow_exception = TREE_CHAIN (objc_rethrow_exception);
3178 objc_stack_exception_data = TREE_CHAIN (objc_stack_exception_data);
3180 val_stack_pop (&exc_binding_stack);
3181 return objc_exit_block ();
3185 objc_build_try_catch_finally_stmt (int has_catch, int has_finally)
3187 /* NB: The operative assumption here is that TRY_FINALLY_EXPR will
3188 deal with all exits from 'try_catch_blk' and route them through
3190 tree outer_blk = objc_build_finally_epilogue ();
3191 tree prec_stmt = TREE_CHAIN (TREE_CHAIN (COMPOUND_BODY (outer_blk)));
3192 tree try_catch_blk = TREE_CHAIN (prec_stmt), try_catch_expr;
3193 tree finally_blk = TREE_CHAIN (try_catch_blk), finally_expr;
3194 tree succ_stmt = TREE_CHAIN (finally_blk);
3195 tree try_finally_stmt, try_finally_expr;
3197 if (!flag_objc_exceptions)
3198 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3200 /* It is an error to have a @try block without a @catch and/or @finally
3201 (even though sensible code can be generated nonetheless). */
3203 if (!has_catch && !has_finally)
3204 error ("`@try' without `@catch' or `@finally'");
3206 /* We shall now do something truly disgusting. We shall remove the
3207 'try_catch_blk' and 'finally_blk' from the 'outer_blk' statement
3208 chain, and replace them with a TRY_FINALLY_EXPR statement! If
3209 this doesn't work, we will have to learn (from Per/gcj) how to
3210 construct the 'outer_blk' lazily. */
3212 TREE_CHAIN (try_catch_blk) = TREE_CHAIN (finally_blk) = NULL_TREE;
3213 try_catch_expr = build1 (STMT_EXPR, void_type_node, try_catch_blk);
3214 TREE_SIDE_EFFECTS (try_catch_expr) = 1;
3215 finally_expr = build1 (STMT_EXPR, void_type_node, finally_blk);
3216 TREE_SIDE_EFFECTS (finally_expr) = 1;
3217 try_finally_expr = build (TRY_FINALLY_EXPR, void_type_node, try_catch_expr,
3219 TREE_SIDE_EFFECTS (try_finally_expr) = 1;
3220 try_finally_stmt = build_stmt (EXPR_STMT, try_finally_expr);
3221 TREE_CHAIN (prec_stmt) = try_finally_stmt;
3222 TREE_CHAIN (try_finally_stmt) = succ_stmt;
3224 return outer_blk; /* the whole enchilada */
3228 objc_build_synchronized_prologue (tree sync_expr)
3231 id _eval_once = <sync_expr>;
3233 objc_sync_enter( _eval_once ); */
3237 if (!flag_objc_exceptions)
3238 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3240 objc_enter_block ();
3242 = tree_cons (NULL_TREE,
3243 objc_declare_variable (RID_AUTO,
3244 get_identifier (UTAG_EVALONCE_VAR),
3248 objc_build_try_prologue ();
3249 objc_enter_block ();
3250 func_params = tree_cons (NULL_TREE,
3251 TREE_VALUE (objc_eval_once),
3254 assemble_external (objc_sync_enter_decl);
3255 c_expand_expr_stmt (build_function_call
3256 (objc_sync_enter_decl, func_params));
3260 objc_build_synchronized_epilogue (void)
3264 objc_sync_exit( _eval_once );
3271 objc_build_try_epilogue (0);
3272 objc_build_finally_prologue ();
3273 func_params = tree_cons (NULL_TREE, TREE_VALUE (objc_eval_once),
3276 assemble_external (objc_sync_exit_decl);
3277 c_expand_expr_stmt (build_function_call (objc_sync_exit_decl,
3279 objc_build_try_catch_finally_stmt (0, 1);
3281 return objc_exit_block ();
3284 /* Predefine the following data type:
3286 struct _objc_exception_data
3292 /* The following yuckiness should prevent users from having to #include
3293 <setjmp.h> in their code... */
3295 #ifdef TARGET_POWERPC
3296 /* snarfed from /usr/include/ppc/setjmp.h */
3297 #define _JBLEN (26 + 36 + 129 + 1)
3299 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3304 build_objc_exception_stuff (void)
3306 tree field_decl, field_decl_chain, index, temp_type;
3308 /* Suppress outputting debug symbols, because
3309 dbxout_init hasn't been called yet. */
3310 enum debug_info_type save_write_symbols = write_symbols;
3311 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3313 write_symbols = NO_DEBUG;
3314 debug_hooks = &do_nothing_debug_hooks;
3315 objc_exception_data_template
3316 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3318 /* int buf[_JBLEN]; */
3320 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3321 field_decl = create_builtin_decl (FIELD_DECL,
3322 build_array_type (integer_type_node, index),
3324 field_decl_chain = field_decl;
3326 /* void *pointers[4]; */
3328 index = build_index_type (build_int_2 (4 - 1, 0));
3329 field_decl = create_builtin_decl (FIELD_DECL,
3330 build_array_type (ptr_type_node, index),
3332 chainon (field_decl_chain, field_decl);
3334 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3336 /* int _setjmp(...); */
3337 /* If the user includes <setjmp.h>, this shall be superceded by
3338 'int _setjmp(jmp_buf);' */
3339 temp_type = build_function_type (integer_type_node, NULL_TREE);
3341 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3343 /* id objc_exception_extract(struct _objc_exception_data *); */
3345 = build_function_type (id_type,
3346 tree_cons (NULL_TREE,
3347 build_pointer_type (objc_exception_data_template),
3349 objc_exception_extract_decl
3350 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3351 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3352 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3354 = build_function_type (void_type_node,
3355 tree_cons (NULL_TREE,
3356 build_pointer_type (objc_exception_data_template),
3358 objc_exception_try_enter_decl
3359 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3360 objc_exception_try_exit_decl
3361 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3362 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3363 /* void objc_sync_enter(id); */
3364 /* void objc_sync_exit(id); */
3365 temp_type = build_function_type (void_type_node,
3366 tree_cons (NULL_TREE, id_type,
3368 objc_exception_throw_decl
3369 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3370 DECL_ATTRIBUTES (objc_exception_throw_decl)
3371 = tree_cons (get_identifier ("noreturn"), NULL_TREE, NULL_TREE);
3372 objc_sync_enter_decl
3373 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3375 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3376 /* int objc_exception_match(id, id); */
3377 temp_type = build_function_type (integer_type_node,
3378 tree_cons (NULL_TREE, id_type,
3379 tree_cons (NULL_TREE, id_type,
3380 OBJC_VOID_AT_END)));
3381 objc_exception_match_decl
3382 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3384 write_symbols = save_write_symbols;
3385 debug_hooks = save_hooks;
3388 /* struct <classname> {
3389 struct objc_class *isa;
3394 build_private_template (tree class)
3398 if (CLASS_STATIC_TEMPLATE (class))
3400 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3401 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3405 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3406 ivar_context = get_class_ivars (class, 0);
3408 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3410 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3412 /* mark this record as class template - for class type checking */
3413 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3417 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3419 build1 (INDIRECT_REF, NULL_TREE,
3422 return ivar_context;
3425 /* Begin code generation for protocols... */
3427 /* struct objc_protocol {
3428 char *protocol_name;
3429 struct objc_protocol **protocol_list;
3430 struct objc_method_desc *instance_methods;
3431 struct objc_method_desc *class_methods;
3435 build_protocol_template (void)
3437 tree decl_specs, field_decl, field_decl_chain;
3440 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3442 /* struct objc_class *isa; */
3444 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3445 get_identifier (UTAG_CLASS)));
3446 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3447 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3448 field_decl_chain = field_decl;
3450 /* char *protocol_name; */
3452 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3454 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3455 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3456 chainon (field_decl_chain, field_decl);
3458 /* struct objc_protocol **protocol_list; */
3460 decl_specs = build_tree_list (NULL_TREE, template);
3462 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3463 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3464 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3465 chainon (field_decl_chain, field_decl);
3467 /* struct objc_method_list *instance_methods; */
3470 = build_tree_list (NULL_TREE,
3471 xref_tag (RECORD_TYPE,
3472 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3474 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3475 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3476 chainon (field_decl_chain, field_decl);
3478 /* struct objc_method_list *class_methods; */
3481 = build_tree_list (NULL_TREE,
3482 xref_tag (RECORD_TYPE,
3483 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3485 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3486 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3487 chainon (field_decl_chain, field_decl);
3489 return finish_struct (template, field_decl_chain, NULL_TREE);
3493 build_descriptor_table_initializer (tree type, tree entries)
3495 tree initlist = NULL_TREE;
3499 tree eltlist = NULL_TREE;
3502 = tree_cons (NULL_TREE,
3503 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3505 = tree_cons (NULL_TREE,
3506 add_objc_string (METHOD_ENCODING (entries),
3511 = tree_cons (NULL_TREE,
3512 objc_build_constructor (type, nreverse (eltlist)),
3515 entries = TREE_CHAIN (entries);
3519 return objc_build_constructor (build_array_type (type, 0),
3520 nreverse (initlist));
3523 /* struct objc_method_prototype_list {
3525 struct objc_method_prototype {
3532 build_method_prototype_list_template (tree list_type, int size)
3534 tree objc_ivar_list_record;
3535 tree decl_specs, field_decl, field_decl_chain;
3537 /* Generate an unnamed struct definition. */
3539 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3541 /* int method_count; */
3543 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3544 field_decl = get_identifier ("method_count");
3545 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3546 field_decl_chain = field_decl;
3548 /* struct objc_method method_list[]; */
3550 decl_specs = build_tree_list (NULL_TREE, list_type);
3551 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3552 build_int_2 (size, 0));
3553 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3554 chainon (field_decl_chain, field_decl);
3556 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3558 return objc_ivar_list_record;
3562 build_method_prototype_template (void)
3565 tree decl_specs, field_decl, field_decl_chain;
3568 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3570 /* struct objc_selector *_cmd; */
3571 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3572 get_identifier (TAG_SELECTOR)), NULL_TREE);
3573 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3574 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3575 field_decl_chain = field_decl;
3577 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3579 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3580 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3581 chainon (field_decl_chain, field_decl);
3583 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3585 return proto_record;
3589 objc_method_parm_type (tree type)
3591 type = groktypename (TREE_TYPE (type));
3592 if (TREE_CODE (type) == TYPE_DECL)
3593 type = TREE_TYPE (type);
3594 return TYPE_MAIN_VARIANT (type);
3598 objc_encoded_type_size (tree type)
3600 int sz = int_size_in_bytes (type);
3602 /* Make all integer and enum types at least as large
3604 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3605 || TREE_CODE (type) == BOOLEAN_TYPE
3606 || TREE_CODE (type) == ENUMERAL_TYPE))
3607 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3608 /* Treat arrays as pointers, since that's how they're
3610 else if (TREE_CODE (type) == ARRAY_TYPE)
3611 sz = int_size_in_bytes (ptr_type_node);
3616 encode_method_prototype (tree method_decl)
3623 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3624 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3626 /* Encode return type. */
3627 encode_type (objc_method_parm_type (method_decl),
3628 obstack_object_size (&util_obstack),
3629 OBJC_ENCODE_INLINE_DEFS);
3632 /* The first two arguments (self and _cmd) are pointers; account for
3634 i = int_size_in_bytes (ptr_type_node);
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);
3640 int sz = objc_encoded_type_size (type);
3642 /* If a type size is not known, bail out. */
3645 error ("%Jtype '%D' does not have a known size",
3647 /* Pretend that the encoding succeeded; the compilation will
3648 fail nevertheless. */
3649 goto finish_encoding;
3654 sprintf (buf, "%d@0:%d", parm_offset, i);
3655 obstack_grow (&util_obstack, buf, strlen (buf));
3657 /* Argument types. */
3658 parm_offset = 2 * i;
3659 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3660 parms = TREE_CHAIN (parms))
3662 tree type = objc_method_parm_type (parms);
3664 /* Process argument qualifiers for user supplied arguments. */
3665 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3668 encode_type (type, obstack_object_size (&util_obstack),
3669 OBJC_ENCODE_INLINE_DEFS);
3671 /* Compute offset. */
3672 sprintf (buf, "%d", parm_offset);
3673 parm_offset += objc_encoded_type_size (type);
3675 obstack_grow (&util_obstack, buf, strlen (buf));
3679 obstack_1grow (&util_obstack, '\0');
3680 result = get_identifier (obstack_finish (&util_obstack));
3681 obstack_free (&util_obstack, util_firstobj);
3686 generate_descriptor_table (tree type, const char *name, int size, tree list,
3689 tree sc_spec, decl_specs, decl, initlist;
3691 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3692 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3694 decl = start_decl (synth_id_with_class_suffix (name, proto),
3695 decl_specs, 1, NULL_TREE);
3696 DECL_CONTEXT (decl) = NULL_TREE;
3698 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3699 initlist = tree_cons (NULL_TREE, list, initlist);
3701 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3708 generate_method_descriptors (tree protocol)
3710 tree initlist, chain, method_list_template;
3711 tree cast, variable_length_type;
3714 if (!objc_method_prototype_template)
3715 objc_method_prototype_template = build_method_prototype_template ();
3717 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3718 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3720 variable_length_type = groktypename (cast);
3722 chain = PROTOCOL_CLS_METHODS (protocol);
3725 size = list_length (chain);
3727 method_list_template
3728 = build_method_prototype_list_template (objc_method_prototype_template,
3732 = build_descriptor_table_initializer (objc_method_prototype_template,
3735 UOBJC_CLASS_METHODS_decl
3736 = generate_descriptor_table (method_list_template,
3737 "_OBJC_PROTOCOL_CLASS_METHODS",
3738 size, initlist, protocol);
3739 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3742 UOBJC_CLASS_METHODS_decl = 0;
3744 chain = PROTOCOL_NST_METHODS (protocol);
3747 size = list_length (chain);
3749 method_list_template
3750 = build_method_prototype_list_template (objc_method_prototype_template,
3753 = build_descriptor_table_initializer (objc_method_prototype_template,
3756 UOBJC_INSTANCE_METHODS_decl
3757 = generate_descriptor_table (method_list_template,
3758 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3759 size, initlist, protocol);
3760 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3763 UOBJC_INSTANCE_METHODS_decl = 0;
3767 generate_protocol_references (tree plist)
3771 /* Forward declare protocols referenced. */
3772 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3774 tree proto = TREE_VALUE (lproto);
3776 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3777 && PROTOCOL_NAME (proto))
3779 if (! PROTOCOL_FORWARD_DECL (proto))
3780 build_protocol_reference (proto);
3782 if (PROTOCOL_LIST (proto))
3783 generate_protocol_references (PROTOCOL_LIST (proto));
3788 /* For each protocol which was referenced either from a @protocol()
3789 expression, or because a class/category implements it (then a
3790 pointer to the protocol is stored in the struct describing the
3791 class/category), we create a statically allocated instance of the
3792 Protocol class. The code is written in such a way as to generate
3793 as few Protocol objects as possible; we generate a unique Protocol
3794 instance for each protocol, and we don't generate a Protocol
3795 instance if the protocol is never referenced (either from a
3796 @protocol() or from a class/category implementation). These
3797 statically allocated objects can be referred to via the static
3798 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3800 The statically allocated Protocol objects that we generate here
3801 need to be fixed up at runtime in order to be used: the 'isa'
3802 pointer of the objects need to be set up to point to the 'Protocol'
3803 class, as known at runtime.
3805 The NeXT runtime fixes up all protocols at program startup time,
3806 before main() is entered. It uses a low-level trick to look up all
3807 those symbols, then loops on them and fixes them up.
3809 The GNU runtime as well fixes up all protocols before user code
3810 from the module is executed; it requires pointers to those symbols
3811 to be put in the objc_symtab (which is then passed as argument to
3812 the function __objc_exec_class() which the compiler sets up to be
3813 executed automatically when the module is loaded); setup of those
3814 Protocol objects happen in two ways in the GNU runtime: all
3815 Protocol objects referred to by a class or category implementation
3816 are fixed up when the class/category is loaded; all Protocol
3817 objects referred to by a @protocol() expression are added by the
3818 compiler to the list of statically allocated instances to fixup
3819 (the same list holding the statically allocated constant string
3820 objects). Because, as explained above, the compiler generates as
3821 few Protocol objects as possible, some Protocol object might end up
3822 being referenced multiple times when compiled with the GNU runtime,
3823 and end up being fixed up multiple times at runtime inizialization.
3824 But that doesn't hurt, it's just a little inefficient. */
3827 generate_protocols (void)
3830 tree sc_spec, decl_specs, decl;
3831 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3834 if (! objc_protocol_template)
3835 objc_protocol_template = build_protocol_template ();
3837 /* If a protocol was directly referenced, pull in indirect references. */
3838 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3839 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3840 generate_protocol_references (PROTOCOL_LIST (p));
3842 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3844 tree nst_methods = PROTOCOL_NST_METHODS (p);
3845 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3847 /* If protocol wasn't referenced, don't generate any code. */
3848 if (! PROTOCOL_FORWARD_DECL (p))
3851 /* Make sure we link in the Protocol class. */
3852 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3856 if (! METHOD_ENCODING (nst_methods))
3858 encoding = encode_method_prototype (nst_methods);
3859 METHOD_ENCODING (nst_methods) = encoding;
3861 nst_methods = TREE_CHAIN (nst_methods);
3866 if (! METHOD_ENCODING (cls_methods))
3868 encoding = encode_method_prototype (cls_methods);
3869 METHOD_ENCODING (cls_methods) = encoding;
3872 cls_methods = TREE_CHAIN (cls_methods);
3874 generate_method_descriptors (p);
3876 if (PROTOCOL_LIST (p))
3877 refs_decl = generate_protocol_list (p);
3881 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3883 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3885 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3887 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3888 decl_specs, 1, NULL_TREE);
3890 DECL_CONTEXT (decl) = NULL_TREE;
3892 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3898 (build_tree_list (build_tree_list (NULL_TREE,
3899 objc_protocol_template),
3900 build1 (INDIRECT_REF, NULL_TREE,
3901 build1 (INDIRECT_REF, NULL_TREE,
3904 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3905 TREE_TYPE (refs_expr) = cast_type2;
3908 refs_expr = build_int_2 (0, 0);
3910 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3911 by generate_method_descriptors, which is called above. */
3912 initlist = build_protocol_initializer (TREE_TYPE (decl),
3913 protocol_name_expr, refs_expr,
3914 UOBJC_INSTANCE_METHODS_decl,
3915 UOBJC_CLASS_METHODS_decl);
3916 finish_decl (decl, initlist, NULL_TREE);
3918 /* Mark the decl as used to avoid "defined but not used" warning. */
3919 TREE_USED (decl) = 1;
3924 build_protocol_initializer (tree type, tree protocol_name,
3925 tree protocol_list, tree instance_methods,
3928 tree initlist = NULL_TREE, expr;
3931 cast_type = groktypename
3933 (build_tree_list (NULL_TREE,
3934 xref_tag (RECORD_TYPE,
3935 get_identifier (UTAG_CLASS))),
3936 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3938 /* Filling the "isa" in with one allows the runtime system to
3939 detect that the version change...should remove before final release. */
3941 expr = build_int_2 (PROTOCOL_VERSION, 0);
3942 TREE_TYPE (expr) = cast_type;
3943 initlist = tree_cons (NULL_TREE, expr, initlist);
3944 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3945 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3947 if (!instance_methods)
3948 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3951 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3952 initlist = tree_cons (NULL_TREE, expr, initlist);
3956 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3959 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3960 initlist = tree_cons (NULL_TREE, expr, initlist);
3963 return objc_build_constructor (type, nreverse (initlist));
3966 /* struct objc_category {
3967 char *category_name;
3969 struct objc_method_list *instance_methods;
3970 struct objc_method_list *class_methods;
3971 struct objc_protocol_list *protocols;
3975 build_category_template (void)
3977 tree decl_specs, field_decl, field_decl_chain;
3979 objc_category_template = start_struct (RECORD_TYPE,
3980 get_identifier (UTAG_CATEGORY));
3981 /* char *category_name; */
3983 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3985 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3986 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3987 field_decl_chain = field_decl;
3989 /* char *class_name; */
3991 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3992 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3993 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3994 chainon (field_decl_chain, field_decl);
3996 /* struct objc_method_list *instance_methods; */
3998 decl_specs = build_tree_list (NULL_TREE,
3999 xref_tag (RECORD_TYPE,
4000 get_identifier (UTAG_METHOD_LIST)));
4002 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
4003 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4004 chainon (field_decl_chain, field_decl);
4006 /* struct objc_method_list *class_methods; */
4008 decl_specs = build_tree_list (NULL_TREE,
4009 xref_tag (RECORD_TYPE,
4010 get_identifier (UTAG_METHOD_LIST)));
4012 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
4013 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4014 chainon (field_decl_chain, field_decl);
4016 /* struct objc_protocol **protocol_list; */
4018 decl_specs = build_tree_list (NULL_TREE,
4019 xref_tag (RECORD_TYPE,
4020 get_identifier (UTAG_PROTOCOL)));
4022 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4023 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4024 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4025 chainon (field_decl_chain, field_decl);
4027 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4030 /* struct objc_selector {
4036 build_selector_template (void)
4039 tree decl_specs, field_decl, field_decl_chain;
4041 objc_selector_template
4042 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4046 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4047 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4048 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4049 field_decl_chain = field_decl;
4051 /* char *sel_type; */
4053 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4054 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4055 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4056 chainon (field_decl_chain, field_decl);
4058 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4061 /* struct objc_class {
4062 struct objc_class *isa;
4063 struct objc_class *super_class;
4068 struct objc_ivar_list *ivars;
4069 struct objc_method_list *methods;
4070 if (flag_next_runtime)
4071 struct objc_cache *cache;
4073 struct sarray *dtable;
4074 struct objc_class *subclass_list;
4075 struct objc_class *sibling_class;
4077 struct objc_protocol_list *protocols;
4078 if (flag_next_runtime)
4080 void *gc_object_type;
4083 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4084 the NeXT/Apple runtime; still, the compiler must generate them to
4085 maintain backward binary compatibility (and to allow for future
4089 build_class_template (void)
4091 tree decl_specs, field_decl, field_decl_chain;
4094 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4096 /* struct objc_class *isa; */
4098 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4099 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4100 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4101 field_decl_chain = field_decl;
4103 /* struct objc_class *super_class; */
4105 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4107 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4108 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4109 chainon (field_decl_chain, field_decl);
4113 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4114 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4115 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4116 chainon (field_decl_chain, field_decl);
4120 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4121 field_decl = get_identifier ("version");
4122 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4123 chainon (field_decl_chain, field_decl);
4127 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4128 field_decl = get_identifier ("info");
4129 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4130 chainon (field_decl_chain, field_decl);
4132 /* long instance_size; */
4134 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4135 field_decl = get_identifier ("instance_size");
4136 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4137 chainon (field_decl_chain, field_decl);
4139 /* struct objc_ivar_list *ivars; */
4141 decl_specs = build_tree_list (NULL_TREE,
4142 xref_tag (RECORD_TYPE,
4143 get_identifier (UTAG_IVAR_LIST)));
4144 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4145 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4146 chainon (field_decl_chain, field_decl);
4148 /* struct objc_method_list *methods; */
4150 decl_specs = build_tree_list (NULL_TREE,
4151 xref_tag (RECORD_TYPE,
4152 get_identifier (UTAG_METHOD_LIST)));
4153 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4154 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4155 chainon (field_decl_chain, field_decl);
4157 if (flag_next_runtime)
4159 /* struct objc_cache *cache; */
4161 decl_specs = build_tree_list (NULL_TREE,
4162 xref_tag (RECORD_TYPE,
4163 get_identifier ("objc_cache")));
4164 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4165 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4166 chainon (field_decl_chain, field_decl);
4170 /* struct sarray *dtable; */
4172 decl_specs = build_tree_list (NULL_TREE,
4173 xref_tag (RECORD_TYPE,
4174 get_identifier ("sarray")));
4175 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4176 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4177 chainon (field_decl_chain, field_decl);
4179 /* struct objc_class *subclass_list; */
4181 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4183 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4184 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4185 chainon (field_decl_chain, field_decl);
4187 /* struct objc_class *sibling_class; */
4189 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4191 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4192 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4193 chainon (field_decl_chain, field_decl);
4196 /* struct objc_protocol **protocol_list; */
4198 decl_specs = build_tree_list (NULL_TREE,
4199 xref_tag (RECORD_TYPE,
4200 get_identifier (UTAG_PROTOCOL)));
4202 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4204 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4205 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4206 chainon (field_decl_chain, field_decl);
4208 if (flag_next_runtime)
4212 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4213 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4215 = grokfield (field_decl, decl_specs, NULL_TREE);
4216 chainon (field_decl_chain, field_decl);
4219 /* void *gc_object_type; */
4221 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4222 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4223 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4224 chainon (field_decl_chain, field_decl);
4226 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4229 /* Generate appropriate forward declarations for an implementation. */
4232 synth_forward_declarations (void)
4236 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4237 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4238 objc_class_template);
4240 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4241 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4242 objc_class_template);
4244 /* Pre-build the following entities - for speed/convenience. */
4246 an_id = get_identifier ("super_class");
4247 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4248 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4252 error_with_ivar (const char *message, tree decl, tree rawdecl)
4254 error ("%J%s `%s'", decl,
4255 message, gen_declaration (rawdecl, errbuf));
4260 check_ivars (tree inter, tree imp)
4262 tree intdecls = CLASS_IVARS (inter);
4263 tree impdecls = CLASS_IVARS (imp);
4264 tree rawintdecls = CLASS_RAW_IVARS (inter);
4265 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4272 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4273 intdecls = TREE_CHAIN (intdecls);
4275 if (intdecls == 0 && impdecls == 0)
4277 if (intdecls == 0 || impdecls == 0)
4279 error ("inconsistent instance variable specification");
4283 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4285 if (!comptypes (t1, t2, false)
4286 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4287 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4289 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4291 error_with_ivar ("conflicting instance variable type",
4292 impdecls, rawimpdecls);
4293 error_with_ivar ("previous declaration of",
4294 intdecls, rawintdecls);
4296 else /* both the type and the name don't match */
4298 error ("inconsistent instance variable specification");
4303 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4305 error_with_ivar ("conflicting instance variable name",
4306 impdecls, rawimpdecls);
4307 error_with_ivar ("previous declaration of",
4308 intdecls, rawintdecls);
4311 intdecls = TREE_CHAIN (intdecls);
4312 impdecls = TREE_CHAIN (impdecls);
4313 rawintdecls = TREE_CHAIN (rawintdecls);
4314 rawimpdecls = TREE_CHAIN (rawimpdecls);
4318 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4319 This needs to be done just once per compilation. */
4322 build_super_template (void)
4324 tree decl_specs, field_decl, field_decl_chain;
4326 /* Suppress outputting debug symbols, because
4327 dbxout_init hasn't been called yet. */
4328 enum debug_info_type save_write_symbols = write_symbols;
4329 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4331 write_symbols = NO_DEBUG;
4332 debug_hooks = &do_nothing_debug_hooks;
4334 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4336 /* struct objc_object *self; */
4338 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4339 field_decl = get_identifier ("self");
4340 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4341 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4342 field_decl_chain = field_decl;
4344 /* struct objc_class *class; */
4346 decl_specs = get_identifier (UTAG_CLASS);
4347 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4348 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4350 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4351 chainon (field_decl_chain, field_decl);
4353 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4355 write_symbols = save_write_symbols;
4356 debug_hooks = save_hooks;
4359 /* struct objc_ivar {
4366 build_ivar_template (void)
4368 tree objc_ivar_id, objc_ivar_record;
4369 tree decl_specs, field_decl, field_decl_chain;
4371 objc_ivar_id = get_identifier (UTAG_IVAR);
4372 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4374 /* char *ivar_name; */
4376 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4377 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4379 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4380 field_decl_chain = field_decl;
4382 /* char *ivar_type; */
4384 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4385 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4387 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4388 chainon (field_decl_chain, field_decl);
4390 /* int ivar_offset; */
4392 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4393 field_decl = get_identifier ("ivar_offset");
4395 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4396 chainon (field_decl_chain, field_decl);
4398 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4400 return objc_ivar_record;
4405 struct objc_ivar ivar_list[ivar_count];
4409 build_ivar_list_template (tree list_type, int size)
4411 tree objc_ivar_list_record;
4412 tree decl_specs, field_decl, field_decl_chain;
4414 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4416 /* int ivar_count; */
4418 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4419 field_decl = get_identifier ("ivar_count");
4421 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4422 field_decl_chain = field_decl;
4424 /* struct objc_ivar ivar_list[]; */
4426 decl_specs = build_tree_list (NULL_TREE, list_type);
4427 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4428 build_int_2 (size, 0));
4430 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4431 chainon (field_decl_chain, field_decl);
4433 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4435 return objc_ivar_list_record;
4441 struct objc_method method_list[method_count];
4445 build_method_list_template (tree list_type, int size)
4447 tree objc_ivar_list_record;
4448 tree decl_specs, field_decl, field_decl_chain;
4450 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4452 /* int method_next; */
4457 xref_tag (RECORD_TYPE,
4458 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4460 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4461 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4462 field_decl_chain = field_decl;
4464 /* int method_count; */
4466 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4467 field_decl = get_identifier ("method_count");
4469 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4470 chainon (field_decl_chain, field_decl);
4472 /* struct objc_method method_list[]; */
4474 decl_specs = build_tree_list (NULL_TREE, list_type);
4475 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4476 build_int_2 (size, 0));
4478 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4479 chainon (field_decl_chain, field_decl);
4481 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4483 return objc_ivar_list_record;
4487 build_ivar_list_initializer (tree type, tree field_decl)
4489 tree initlist = NULL_TREE;
4493 tree ivar = NULL_TREE;
4496 if (DECL_NAME (field_decl))
4497 ivar = tree_cons (NULL_TREE,
4498 add_objc_string (DECL_NAME (field_decl),
4502 /* Unnamed bit-field ivar (yuck). */
4503 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4506 encode_field_decl (field_decl,
4507 obstack_object_size (&util_obstack),
4508 OBJC_ENCODE_DONT_INLINE_DEFS);
4510 /* Null terminate string. */
4511 obstack_1grow (&util_obstack, 0);
4515 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4518 obstack_free (&util_obstack, util_firstobj);
4521 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4522 initlist = tree_cons (NULL_TREE,
4523 objc_build_constructor (type, nreverse (ivar)),
4526 field_decl = TREE_CHAIN (field_decl);
4527 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4531 return objc_build_constructor (build_array_type (type, 0),
4532 nreverse (initlist));
4536 generate_ivars_list (tree type, const char *name, int size, tree list)
4538 tree sc_spec, decl_specs, decl, initlist;
4540 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4541 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4543 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4544 decl_specs, 1, NULL_TREE);
4546 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4547 initlist = tree_cons (NULL_TREE, list, initlist);
4550 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4556 /* Count only the fields occurring in T. */
4558 ivar_list_length (t)
4563 for (; t; t = TREE_CHAIN (t))
4564 if (TREE_CODE (t) == FIELD_DECL)
4571 generate_ivar_lists (void)
4573 tree initlist, ivar_list_template, chain;
4574 tree cast, variable_length_type;
4577 generating_instance_variables = 1;
4579 if (!objc_ivar_template)
4580 objc_ivar_template = build_ivar_template ();
4584 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4585 get_identifier (UTAG_IVAR_LIST))),
4587 variable_length_type = groktypename (cast);
4589 /* Only generate class variables for the root of the inheritance
4590 hierarchy since these will be the same for every class. */
4592 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4593 && (chain = TYPE_FIELDS (objc_class_template)))
4595 size = ivar_list_length (chain);
4597 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4598 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4600 UOBJC_CLASS_VARIABLES_decl
4601 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4603 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4606 UOBJC_CLASS_VARIABLES_decl = 0;
4608 chain = CLASS_IVARS (implementation_template);
4611 size = ivar_list_length (chain);
4612 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4613 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4615 UOBJC_INSTANCE_VARIABLES_decl
4616 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4618 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4621 UOBJC_INSTANCE_VARIABLES_decl = 0;
4623 generating_instance_variables = 0;
4627 build_dispatch_table_initializer (tree type, tree entries)
4629 tree initlist = NULL_TREE;
4633 tree elemlist = NULL_TREE;
4635 elemlist = tree_cons (NULL_TREE,
4636 build_selector (METHOD_SEL_NAME (entries)),
4639 /* Generate the method encoding if we don't have one already. */
4640 if (! METHOD_ENCODING (entries))
4641 METHOD_ENCODING (entries) =
4642 encode_method_prototype (entries);
4644 elemlist = tree_cons (NULL_TREE,
4645 add_objc_string (METHOD_ENCODING (entries),
4649 elemlist = tree_cons (NULL_TREE,
4650 build_unary_op (ADDR_EXPR,
4651 METHOD_DEFINITION (entries), 1),
4654 initlist = tree_cons (NULL_TREE,
4655 objc_build_constructor (type, nreverse (elemlist)),
4658 entries = TREE_CHAIN (entries);
4662 return objc_build_constructor (build_array_type (type, 0),
4663 nreverse (initlist));
4666 /* To accomplish method prototyping without generating all kinds of
4667 inane warnings, the definition of the dispatch table entries were
4670 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4672 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4675 build_method_template (void)
4678 tree decl_specs, field_decl, field_decl_chain;
4680 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4682 /* struct objc_selector *_cmd; */
4683 decl_specs = tree_cons (NULL_TREE,
4684 xref_tag (RECORD_TYPE,
4685 get_identifier (TAG_SELECTOR)),
4687 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4689 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4690 field_decl_chain = field_decl;
4692 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4693 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4694 get_identifier ("method_types"));
4695 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4696 chainon (field_decl_chain, field_decl);
4700 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4701 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4702 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4703 chainon (field_decl_chain, field_decl);
4705 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4712 generate_dispatch_table (tree type, const char *name, int size, tree list)
4714 tree sc_spec, decl_specs, decl, initlist;
4716 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4717 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4719 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4720 decl_specs, 1, NULL_TREE);
4722 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4723 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4724 initlist = tree_cons (NULL_TREE, list, initlist);
4727 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4734 mark_referenced_methods (void)
4736 struct imp_entry *impent;
4739 for (impent = imp_list; impent; impent = impent->next)
4741 chain = CLASS_CLS_METHODS (impent->imp_context);
4744 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4745 chain = TREE_CHAIN (chain);
4748 chain = CLASS_NST_METHODS (impent->imp_context);
4751 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4752 chain = TREE_CHAIN (chain);
4758 generate_dispatch_tables (void)
4760 tree initlist, chain, method_list_template;
4761 tree cast, variable_length_type;
4764 if (!objc_method_template)
4765 objc_method_template = build_method_template ();
4769 (build_tree_list (NULL_TREE,
4770 xref_tag (RECORD_TYPE,
4771 get_identifier (UTAG_METHOD_LIST))),
4774 variable_length_type = groktypename (cast);
4776 chain = CLASS_CLS_METHODS (objc_implementation_context);
4779 size = list_length (chain);
4781 method_list_template
4782 = build_method_list_template (objc_method_template, size);
4784 = build_dispatch_table_initializer (objc_method_template, chain);
4786 UOBJC_CLASS_METHODS_decl
4787 = generate_dispatch_table (method_list_template,
4788 ((TREE_CODE (objc_implementation_context)
4789 == CLASS_IMPLEMENTATION_TYPE)
4790 ? "_OBJC_CLASS_METHODS"
4791 : "_OBJC_CATEGORY_CLASS_METHODS"),
4793 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4796 UOBJC_CLASS_METHODS_decl = 0;
4798 chain = CLASS_NST_METHODS (objc_implementation_context);
4801 size = list_length (chain);
4803 method_list_template
4804 = build_method_list_template (objc_method_template, size);
4806 = build_dispatch_table_initializer (objc_method_template, chain);
4808 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4809 UOBJC_INSTANCE_METHODS_decl
4810 = generate_dispatch_table (method_list_template,
4811 "_OBJC_INSTANCE_METHODS",
4814 /* We have a category. */
4815 UOBJC_INSTANCE_METHODS_decl
4816 = generate_dispatch_table (method_list_template,
4817 "_OBJC_CATEGORY_INSTANCE_METHODS",
4819 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4822 UOBJC_INSTANCE_METHODS_decl = 0;
4826 generate_protocol_list (tree i_or_p)
4828 tree initlist, decl_specs, sc_spec;
4829 tree refs_decl, expr_decl, lproto, e, plist;
4833 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4834 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4835 plist = CLASS_PROTOCOL_LIST (i_or_p);
4836 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4837 plist = PROTOCOL_LIST (i_or_p);
4841 cast_type = groktypename
4843 (build_tree_list (NULL_TREE,
4844 xref_tag (RECORD_TYPE,
4845 get_identifier (UTAG_PROTOCOL))),
4846 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4849 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4850 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4851 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4854 /* Build initializer. */
4855 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4857 e = build_int_2 (size, 0);
4858 TREE_TYPE (e) = cast_type;
4859 initlist = tree_cons (NULL_TREE, e, initlist);
4861 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4863 tree pval = TREE_VALUE (lproto);
4865 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4866 && PROTOCOL_FORWARD_DECL (pval))
4868 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4869 initlist = tree_cons (NULL_TREE, e, initlist);
4873 /* static struct objc_protocol *refs[n]; */
4875 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4876 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4877 get_identifier (UTAG_PROTOCOL)),
4880 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4881 expr_decl = build_nt (ARRAY_REF,
4882 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4884 build_int_2 (size + 2, 0));
4885 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4886 expr_decl = build_nt (ARRAY_REF,
4887 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4889 build_int_2 (size + 2, 0));
4890 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4892 = build_nt (ARRAY_REF,
4893 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4895 build_int_2 (size + 2, 0));
4899 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4901 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4902 DECL_CONTEXT (refs_decl) = NULL_TREE;
4904 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4905 nreverse (initlist)),
4912 build_category_initializer (tree type, tree cat_name, tree class_name,
4913 tree instance_methods, tree class_methods,
4916 tree initlist = NULL_TREE, expr;
4918 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4919 initlist = tree_cons (NULL_TREE, class_name, initlist);
4921 if (!instance_methods)
4922 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4925 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4926 initlist = tree_cons (NULL_TREE, expr, initlist);
4929 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4932 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4933 initlist = tree_cons (NULL_TREE, expr, initlist);
4936 /* protocol_list = */
4938 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4941 tree cast_type2 = groktypename
4943 (build_tree_list (NULL_TREE,
4944 xref_tag (RECORD_TYPE,
4945 get_identifier (UTAG_PROTOCOL))),
4946 build1 (INDIRECT_REF, NULL_TREE,
4947 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4949 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4950 TREE_TYPE (expr) = cast_type2;
4951 initlist = tree_cons (NULL_TREE, expr, initlist);
4954 return objc_build_constructor (type, nreverse (initlist));
4957 /* struct objc_class {
4958 struct objc_class *isa;
4959 struct objc_class *super_class;
4964 struct objc_ivar_list *ivars;
4965 struct objc_method_list *methods;
4966 if (flag_next_runtime)
4967 struct objc_cache *cache;
4969 struct sarray *dtable;
4970 struct objc_class *subclass_list;
4971 struct objc_class *sibling_class;
4973 struct objc_protocol_list *protocols;
4974 if (flag_next_runtime)
4976 void *gc_object_type;
4980 build_shared_structure_initializer (tree type, tree isa, tree super,
4981 tree name, tree size, int status,
4982 tree dispatch_table, tree ivar_list,
4985 tree initlist = NULL_TREE, expr;
4988 initlist = tree_cons (NULL_TREE, isa, initlist);
4991 initlist = tree_cons (NULL_TREE, super, initlist);
4994 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4997 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5000 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
5002 /* instance_size = */
5003 initlist = tree_cons (NULL_TREE, size, initlist);
5005 /* objc_ivar_list = */
5007 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5010 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
5011 initlist = tree_cons (NULL_TREE, expr, initlist);
5014 /* objc_method_list = */
5015 if (!dispatch_table)
5016 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5019 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
5020 initlist = tree_cons (NULL_TREE, expr, initlist);
5023 if (flag_next_runtime)
5024 /* method_cache = */
5025 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5029 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5031 /* subclass_list = */
5032 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5034 /* sibling_class = */
5035 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5038 /* protocol_list = */
5039 if (! protocol_list)
5040 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5046 (build_tree_list (NULL_TREE,
5047 xref_tag (RECORD_TYPE,
5048 get_identifier (UTAG_PROTOCOL))),
5049 build1 (INDIRECT_REF, NULL_TREE,
5050 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5052 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5053 TREE_TYPE (expr) = cast_type2;
5054 initlist = tree_cons (NULL_TREE, expr, initlist);
5057 if (flag_next_runtime)
5059 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5061 /* gc_object_type = NULL */
5062 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5064 return objc_build_constructor (type, nreverse (initlist));
5067 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5070 generate_category (tree cat)
5072 tree sc_spec, decl_specs, decl;
5073 tree initlist, cat_name_expr, class_name_expr;
5074 tree protocol_decl, category;
5076 add_class_reference (CLASS_NAME (cat));
5077 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5079 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5081 category = CLASS_CATEGORY_LIST (implementation_template);
5083 /* find the category interface from the class it is associated with */
5086 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
5088 category = CLASS_CATEGORY_LIST (category);
5091 if (category && CLASS_PROTOCOL_LIST (category))
5093 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5094 protocol_decl = generate_protocol_list (category);
5099 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5100 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5102 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5103 objc_implementation_context),
5104 decl_specs, 1, NULL_TREE);
5106 initlist = build_category_initializer (TREE_TYPE (decl),
5107 cat_name_expr, class_name_expr,
5108 UOBJC_INSTANCE_METHODS_decl,
5109 UOBJC_CLASS_METHODS_decl,
5112 finish_decl (decl, initlist, NULL_TREE);
5115 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5116 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5119 generate_shared_structures (void)
5121 tree sc_spec, decl_specs, decl;
5122 tree name_expr, super_expr, root_expr;
5123 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5124 tree cast_type, initlist, protocol_decl;
5126 my_super_id = CLASS_SUPER_NAME (implementation_template);
5129 add_class_reference (my_super_id);
5131 /* Compute "my_root_id" - this is required for code generation.
5132 the "isa" for all meta class structures points to the root of
5133 the inheritance hierarchy (e.g. "__Object")... */
5134 my_root_id = my_super_id;
5137 tree my_root_int = lookup_interface (my_root_id);
5139 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5140 my_root_id = CLASS_SUPER_NAME (my_root_int);
5147 /* No super class. */
5148 my_root_id = CLASS_NAME (implementation_template);
5151 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5152 objc_class_template),
5153 build1 (INDIRECT_REF,
5154 NULL_TREE, NULL_TREE)));
5156 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5159 /* Install class `isa' and `super' pointers at runtime. */
5162 super_expr = add_objc_string (my_super_id, class_names);
5163 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5166 super_expr = build_int_2 (0, 0);
5168 root_expr = add_objc_string (my_root_id, class_names);
5169 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5171 if (CLASS_PROTOCOL_LIST (implementation_template))
5173 generate_protocol_references
5174 (CLASS_PROTOCOL_LIST (implementation_template));
5175 protocol_decl = generate_protocol_list (implementation_template);
5180 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5182 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5183 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5185 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5189 = build_shared_structure_initializer
5191 root_expr, super_expr, name_expr,
5192 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5194 UOBJC_CLASS_METHODS_decl,
5195 UOBJC_CLASS_VARIABLES_decl,
5198 finish_decl (decl, initlist, NULL_TREE);
5200 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5202 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5206 = build_shared_structure_initializer
5208 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5209 super_expr, name_expr,
5210 convert (integer_type_node,
5211 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5212 (implementation_template))),
5214 UOBJC_INSTANCE_METHODS_decl,
5215 UOBJC_INSTANCE_VARIABLES_decl,
5218 finish_decl (decl, initlist, NULL_TREE);
5222 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5225 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5226 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5228 const char *const class_name
5229 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5230 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5231 sprintf (string, "%s_%s", preamble,
5232 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5234 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5235 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5237 /* We have a category. */
5238 const char *const class_name
5239 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5240 const char *const class_super_name
5241 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5242 string = (char *) alloca (strlen (preamble)
5243 + strlen (class_name)
5244 + strlen (class_super_name)
5246 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5248 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5250 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5252 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5253 sprintf (string, "%s_%s", preamble, protocol_name);
5258 return get_identifier (string);
5262 is_objc_type_qualifier (tree node)
5264 return (TREE_CODE (node) == IDENTIFIER_NODE
5265 && (node == ridpointers [(int) RID_CONST]
5266 || node == ridpointers [(int) RID_VOLATILE]
5267 || node == ridpointers [(int) RID_IN]
5268 || node == ridpointers [(int) RID_OUT]
5269 || node == ridpointers [(int) RID_INOUT]
5270 || node == ridpointers [(int) RID_BYCOPY]
5271 || node == ridpointers [(int) RID_BYREF]
5272 || node == ridpointers [(int) RID_ONEWAY]));
5275 /* If type is empty or only type qualifiers are present, add default
5276 type of id (otherwise grokdeclarator will default to int). */
5279 adjust_type_for_id_default (tree type)
5281 tree declspecs, chain;
5284 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5285 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5287 declspecs = TREE_PURPOSE (type);
5289 /* Determine if a typespec is present. */
5290 for (chain = declspecs;
5292 chain = TREE_CHAIN (chain))
5294 if (TYPED_OBJECT (TREE_VALUE (chain))
5295 && !(TREE_VALUE (type)
5296 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5297 error ("can not use an object as parameter to a method\n");
5298 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5302 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5304 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5309 selector ':' '(' typename ')' identifier
5312 Transform an Objective-C keyword argument into
5313 the C equivalent parameter declarator.
5315 In: key_name, an "identifier_node" (optional).
5316 arg_type, a "tree_list" (optional).
5317 arg_name, an "identifier_node".
5319 Note: It would be really nice to strongly type the preceding
5320 arguments in the function prototype; however, then I
5321 could not use the "accessor" macros defined in "tree.h".
5323 Out: an instance of "keyword_decl". */
5326 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5330 /* If no type is specified, default to "id". */
5331 arg_type = adjust_type_for_id_default (arg_type);
5333 keyword_decl = make_node (KEYWORD_DECL);
5335 TREE_TYPE (keyword_decl) = arg_type;
5336 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5337 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5339 return keyword_decl;
5342 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5345 build_keyword_selector (tree selector)
5348 tree key_chain, key_name;
5351 /* Scan the selector to see how much space we'll need. */
5352 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5354 if (TREE_CODE (selector) == KEYWORD_DECL)
5355 key_name = KEYWORD_KEY_NAME (key_chain);
5356 else if (TREE_CODE (selector) == TREE_LIST)
5357 key_name = TREE_PURPOSE (key_chain);
5362 len += IDENTIFIER_LENGTH (key_name) + 1;
5364 /* Just a ':' arg. */
5368 buf = (char *) alloca (len + 1);
5369 /* Start the buffer out as an empty string. */
5372 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5374 if (TREE_CODE (selector) == KEYWORD_DECL)
5375 key_name = KEYWORD_KEY_NAME (key_chain);
5376 else if (TREE_CODE (selector) == TREE_LIST)
5378 key_name = TREE_PURPOSE (key_chain);
5379 /* The keyword decl chain will later be used as a function argument
5380 chain. Unhook the selector itself so as to not confuse other
5381 parts of the compiler. */
5382 TREE_PURPOSE (key_chain) = NULL_TREE;
5388 strcat (buf, IDENTIFIER_POINTER (key_name));
5392 return get_identifier (buf);
5395 /* Used for declarations and definitions. */
5398 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5403 /* If no type is specified, default to "id". */
5404 ret_type = adjust_type_for_id_default (ret_type);
5406 method_decl = make_node (code);
5407 TREE_TYPE (method_decl) = ret_type;
5409 /* If we have a keyword selector, create an identifier_node that
5410 represents the full selector name (`:' included)... */
5411 if (TREE_CODE (selector) == KEYWORD_DECL)
5413 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5414 METHOD_SEL_ARGS (method_decl) = selector;
5415 METHOD_ADD_ARGS (method_decl) = add_args;
5419 METHOD_SEL_NAME (method_decl) = selector;
5420 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5421 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5427 #define METHOD_DEF 0
5428 #define METHOD_REF 1
5430 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5431 an argument list for method METH. CONTEXT is either METHOD_DEF or
5432 METHOD_REF, saying whether we are trying to define a method or call
5433 one. SUPERFLAG says this is for a send to super; this makes a
5434 difference for the NeXT calling sequence in which the lookup and
5435 the method call are done together. If METH is null, user-defined
5436 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5439 get_arg_type_list (tree meth, int context, int superflag)
5443 /* Receiver type. */
5444 if (flag_next_runtime && superflag)
5445 arglist = build_tree_list (NULL_TREE, super_type);
5446 else if (context == METHOD_DEF)
5447 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5449 arglist = build_tree_list (NULL_TREE, id_type);
5451 /* Selector type - will eventually change to `int'. */
5452 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
5454 /* No actual method prototype given -- assume that remaining arguments
5459 /* Build a list of argument types. */
5460 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5462 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5463 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5466 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5467 /* We have a `, ...' immediately following the selector,
5468 finalize the arglist...simulate get_parm_info (0). */
5470 else if (METHOD_ADD_ARGS (meth))
5472 /* we have a variable length selector */
5473 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5474 chainon (arglist, add_arg_list);
5477 /* finalize the arglist...simulate get_parm_info (1) */
5478 chainon (arglist, OBJC_VOID_AT_END);
5484 check_duplicates (hash hsh, int methods)
5486 tree meth = NULL_TREE;
5494 /* We have two or more methods with the same name but
5497 char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
5499 warning ("multiple %s named `%c%s' found",
5500 methods ? "methods" : "selectors", type,
5501 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5503 warn_with_method (methods ? "using" : "found", type, meth);
5504 for (loop = hsh->list; loop; loop = loop->next)
5505 warn_with_method ("also found", type, loop->value);
5511 /* If RECEIVER is a class reference, return the identifier node for
5512 the referenced class. RECEIVER is created by get_class_reference,
5513 so we check the exact form created depending on which runtimes are
5517 receiver_is_class_object (tree receiver, int self, int super)
5519 tree chain, exp, arg;
5521 /* The receiver is 'self' or 'super' in the context of a class method. */
5522 if (objc_method_context
5523 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5526 ? CLASS_SUPER_NAME (implementation_template)
5527 : CLASS_NAME (implementation_template));
5529 if (flag_next_runtime)
5531 /* The receiver is a variable created by
5532 build_class_reference_decl. */
5533 if (TREE_CODE (receiver) == VAR_DECL
5534 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5535 /* Look up the identifier. */
5536 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5537 if (TREE_PURPOSE (chain) == receiver)
5538 return TREE_VALUE (chain);
5541 /* The receiver is a function call that returns an id. Check if
5542 it is a call to objc_getClass, if so, pick up the class name. */
5543 if (TREE_CODE (receiver) == CALL_EXPR
5544 && (exp = TREE_OPERAND (receiver, 0))
5545 && TREE_CODE (exp) == ADDR_EXPR
5546 && (exp = TREE_OPERAND (exp, 0))
5547 && TREE_CODE (exp) == FUNCTION_DECL
5548 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5549 prototypes for objc_get_class(). Thankfuly, they seem to share the
5550 same function type. */
5551 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5552 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5553 /* We have a call to objc_get_class/objc_getClass! */
5554 && (arg = TREE_OPERAND (receiver, 1))
5555 && TREE_CODE (arg) == TREE_LIST
5556 && (arg = TREE_VALUE (arg)))
5559 if (TREE_CODE (arg) == ADDR_EXPR
5560 && (arg = TREE_OPERAND (arg, 0))
5561 && TREE_CODE (arg) == STRING_CST)
5562 /* Finally, we have the class name. */
5563 return get_identifier (TREE_STRING_POINTER (arg));
5568 /* If we are currently building a message expr, this holds
5569 the identifier of the selector of the message. This is
5570 used when printing warnings about argument mismatches. */
5572 static tree current_objc_message_selector = 0;
5575 objc_message_selector (void)
5577 return current_objc_message_selector;
5580 /* Construct an expression for sending a message.
5581 MESS has the object to send to in TREE_PURPOSE
5582 and the argument list (including selector) in TREE_VALUE.
5584 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5585 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5588 build_message_expr (tree mess)
5590 tree receiver = TREE_PURPOSE (mess);
5592 tree args = TREE_VALUE (mess);
5593 tree method_params = NULL_TREE;
5595 if (TREE_CODE (receiver) == ERROR_MARK)
5596 return error_mark_node;
5598 /* Obtain the full selector name. */
5599 if (TREE_CODE (args) == IDENTIFIER_NODE)
5600 /* A unary selector. */
5602 else if (TREE_CODE (args) == TREE_LIST)
5603 sel_name = build_keyword_selector (args);
5607 /* Build the parameter list to give to the method. */
5608 if (TREE_CODE (args) == TREE_LIST)
5610 tree chain = args, prev = NULL_TREE;
5612 /* We have a keyword selector--check for comma expressions. */
5615 tree element = TREE_VALUE (chain);
5617 /* We have a comma expression, must collapse... */
5618 if (TREE_CODE (element) == TREE_LIST)
5621 TREE_CHAIN (prev) = element;
5626 chain = TREE_CHAIN (chain);
5628 method_params = args;
5632 if (processing_template_decl)
5633 /* Must wait until template instantiation time. */
5634 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5638 return finish_message_expr (receiver, sel_name, method_params);
5642 lookup_method_in_hash_lists (tree sel_name)
5644 hash method_prototype = hash_lookup (nst_method_hash_list,
5647 if (!method_prototype)
5648 method_prototype = hash_lookup (cls_method_hash_list,
5651 return check_duplicates (method_prototype, 1);
5654 /* The 'finish_message_expr' routine is called from within
5655 'build_message_expr' for non-template functions. In the case of
5656 C++ template functions, it is called from 'build_expr_from_tree'
5657 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5660 finish_message_expr (tree receiver, tree sel_name, tree method_params)
5662 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5663 tree selector, retval, is_class;
5664 int self, super, have_cast;
5666 /* Extract the receiver of the message, as well as its type
5667 (where the latter may take the form of a cast or be inferred
5668 from the implementation context). */
5670 while (TREE_CODE (rtype) == COMPOUND_EXPR
5671 || TREE_CODE (rtype) == MODIFY_EXPR
5672 || TREE_CODE (rtype) == NOP_EXPR
5673 || TREE_CODE (rtype) == COMPONENT_REF)
5674 rtype = TREE_OPERAND (rtype, 0);
5675 self = (rtype == self_decl);
5676 super = (rtype == UOBJC_SUPER_decl);
5677 rtype = TREE_TYPE (receiver);
5678 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5679 || (TREE_CODE (receiver) == COMPOUND_EXPR
5680 && !IS_SUPER (rtype)));
5682 /* If the receiver is a class object, retrieve the corresponding
5683 @interface, if one exists. */
5684 is_class = receiver_is_class_object (receiver, self, super);
5686 /* Now determine the receiver type (if an explicit cast has not been
5691 rtype = lookup_interface (is_class);
5692 /* Handle `self' and `super'. */
5695 if (!CLASS_SUPER_NAME (implementation_template))
5697 error ("no super class declared in @interface for `%s'",
5698 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5699 return error_mark_node;
5701 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5704 rtype = lookup_interface (CLASS_NAME (implementation_template));
5707 /* If receiver is of type `id' or `Class' (or if the @interface for a
5708 class is not visible), we shall be satisfied with the existence of
5709 any instance or class method. */
5710 if (!rtype || IS_ID (rtype)
5711 || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
5714 rtype = xref_tag (RECORD_TYPE, is_class);
5715 else if (IS_ID (rtype))
5717 rprotos = TYPE_PROTOCOL_LIST (rtype);
5721 is_class = TYPE_NAME (rtype) = get_identifier ("Class");
5725 = lookup_method_in_protocol_list (rprotos, sel_name,
5726 is_class != NULL_TREE);
5727 if (!method_prototype && !rprotos)
5730 ? check_duplicates (hash_lookup (cls_method_hash_list, sel_name), 1)
5731 : lookup_method_in_hash_lists (sel_name));
5735 tree orig_rtype = rtype, saved_rtype;
5737 if (TREE_CODE (rtype) == POINTER_TYPE)
5738 rtype = TREE_TYPE (rtype);
5739 /* Traverse typedef aliases */
5740 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5741 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5742 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5743 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5744 saved_rtype = rtype;
5745 if (TYPED_OBJECT (rtype))
5747 rprotos = TYPE_PROTOCOL_LIST (rtype);
5748 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5750 /* If we could not find an @interface declaration, we must have
5751 only seen a @class declaration; so, we cannot say anything
5752 more intelligent about which methods the receiver will
5755 rtype = saved_rtype;
5756 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5757 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5759 /* We have a valid ObjC class name. Look up the method name
5760 in the published @interface for the class (and its
5763 = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
5765 /* If the method was not found in the @interface, it may still
5766 exist locally as part of the @implementation. */
5767 if (!method_prototype && objc_implementation_context
5768 && CLASS_NAME (objc_implementation_context)
5769 == OBJC_TYPE_NAME (rtype))
5773 ? CLASS_CLS_METHODS (objc_implementation_context)
5774 : CLASS_NST_METHODS (objc_implementation_context)),
5777 /* If we haven't found a candidate method by now, try looking for
5778 it in the protocol list. */
5779 if (!method_prototype && rprotos)
5781 = lookup_method_in_protocol_list (rprotos, sel_name,
5782 is_class != NULL_TREE);
5786 warning ("invalid receiver type `%s'",
5787 gen_declaration (orig_rtype, errbuf));
5788 rtype = rprotos = NULL_TREE;
5792 if (!method_prototype)
5794 static bool warn_missing_methods = false;
5797 warning ("`%s' may not respond to `%c%s'",
5798 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5799 (is_class ? '+' : '-'),
5800 IDENTIFIER_POINTER (sel_name));
5802 warning ("`%c%s' not implemented by protocol(s)",
5803 (is_class ? '+' : '-'),
5804 IDENTIFIER_POINTER (sel_name));
5805 if (!warn_missing_methods)
5807 warning ("(Messages without a matching method signature");
5808 warning ("will be assumed to return `id' and accept");
5809 warning ("`...' as arguments.)");
5810 warn_missing_methods = true;
5814 /* Save the selector name for printing error messages. */
5815 current_objc_message_selector = sel_name;
5817 /* Build the parameters list for looking up the method.
5818 These are the object itself and the selector. */
5820 if (flag_typed_selectors)
5821 selector = build_typed_selector_reference (sel_name, method_prototype);
5823 selector = build_selector_reference (sel_name);
5825 retval = build_objc_method_call (super, method_prototype,
5827 selector, method_params);
5829 current_objc_message_selector = 0;
5834 /* Build a tree expression to send OBJECT the operation SELECTOR,
5835 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5836 assuming the method has prototype METHOD_PROTOTYPE.
5837 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5838 Use METHOD_PARAMS as list of args to pass to the method.
5839 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5842 build_objc_method_call (int super_flag, tree method_prototype,
5843 tree lookup_object, tree selector,
5846 tree sender = (super_flag ? umsg_super_decl :
5847 (!flag_next_runtime || flag_nil_receivers
5849 : umsg_nonnil_decl));
5850 tree rcv_p = (super_flag ? super_type : id_type);
5852 /* If a prototype for the method to be called exists, then cast
5853 the sender's return type and arguments to match that of the method.
5854 Otherwise, leave sender as is. */
5857 ? groktypename (TREE_TYPE (method_prototype))
5860 = build_pointer_type
5861 (build_function_type
5864 (method_prototype, METHOD_REF, super_flag)));
5866 lookup_object = build_c_cast (rcv_p, lookup_object);
5868 if (flag_next_runtime)
5871 /* If we are returning a struct in memory, and the address
5872 of that memory location is passed as a hidden first
5873 argument, then change which messenger entry point this
5874 expr will call. NB: Note that sender_cast remains
5875 unchanged (it already has a struct return type). */
5876 if ((TREE_CODE (ret_type) == RECORD_TYPE
5877 || TREE_CODE (ret_type) == UNION_TYPE)
5878 #if defined (DEFAULT_PCC_STRUCT_RETURN) && DEFAULT_PCC_STRUCT_RETURN == 0
5879 && RETURN_IN_MEMORY (ret_type)
5881 && STRUCT_VALUE == 0)
5882 sender = (super_flag ? umsg_super_stret_decl :
5883 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5885 method_params = tree_cons (NULL_TREE, lookup_object,
5886 tree_cons (NULL_TREE, selector,
5888 TREE_USED (sender) = 1;
5889 assemble_external (sender);
5890 /* We want to cast the sender, not convert it. */
5891 return build_function_call (build_c_cast (sender_cast, sender),
5896 /* This is the portable (GNU) way. */
5897 tree method, object;
5899 /* First, call the lookup function to get a pointer to the method,
5900 then cast the pointer, then call it with the method arguments.
5901 Use SAVE_EXPR to avoid evaluating the receiver twice. */
5902 lookup_object = save_expr (lookup_object);
5903 object = (super_flag ? self_decl : lookup_object);
5904 TREE_USED (sender) = 1;
5905 assemble_external (sender);
5907 = build_function_call (sender,
5908 tree_cons (NULL_TREE, lookup_object,
5909 tree_cons (NULL_TREE, selector,
5912 /* Pass the object to the method. */
5913 TREE_USED (method) = 1;
5914 assemble_external (method);
5915 return build_function_call
5916 (build_c_cast (sender_cast, method),
5917 tree_cons (NULL_TREE, object,
5918 tree_cons (NULL_TREE, selector, method_params)));
5923 build_protocol_reference (tree p)
5925 tree decl, ident, ptype;
5927 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5929 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5931 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5932 objc_protocol_template),
5935 if (identifier_global_value (ident))
5936 decl = identifier_global_value (ident); /* Set by pushdecl. */
5939 decl = build_decl (VAR_DECL, ident, ptype);
5940 DECL_EXTERNAL (decl) = 1;
5941 TREE_PUBLIC (decl) = 0;
5942 TREE_USED (decl) = 1;
5943 DECL_ARTIFICIAL (decl) = 1;
5945 make_decl_rtl (decl, 0);
5946 pushdecl_top_level (decl);
5949 PROTOCOL_FORWARD_DECL (p) = decl;
5952 /* This function is called by the parser when (and only when) a
5953 @protocol() expression is found, in order to compile it. */
5955 build_protocol_expr (tree protoname)
5958 tree p = lookup_protocol (protoname);
5962 error ("cannot find protocol declaration for `%s'",
5963 IDENTIFIER_POINTER (protoname));
5964 return error_mark_node;
5967 if (!PROTOCOL_FORWARD_DECL (p))
5968 build_protocol_reference (p);
5970 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5972 TREE_TYPE (expr) = protocol_type;
5974 /* The @protocol() expression is being compiled into a pointer to a
5975 statically allocated instance of the Protocol class. To become
5976 usable at runtime, the 'isa' pointer of the instance need to be
5977 fixed up at runtime by the runtime library, to point to the
5978 actual 'Protocol' class. */
5980 /* For the GNU runtime, put the static Protocol instance in the list
5981 of statically allocated instances, so that we make sure that its
5982 'isa' pointer is fixed up at runtime by the GNU runtime library
5983 to point to the Protocol class (at runtime, when loading the
5984 module, the GNU runtime library loops on the statically allocated
5985 instances (as found in the defs field in objc_symtab) and fixups
5986 all the 'isa' pointers of those objects). */
5987 if (! flag_next_runtime)
5989 /* This type is a struct containing the fields of a Protocol
5990 object. (Cfr. protocol_type instead is the type of a pointer
5991 to such a struct). */
5992 tree protocol_struct_type = xref_tag
5993 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5996 /* Look for the list of Protocol statically allocated instances
5997 to fixup at runtime. Create a new list to hold Protocol
5998 statically allocated instances, if the list is not found. At
5999 present there is only another list, holding NSConstantString
6000 static instances to be fixed up at runtime. */
6001 for (chain = &objc_static_instances;
6002 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6003 chain = &TREE_CHAIN (*chain));
6006 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6007 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6011 /* Add this statically allocated instance to the Protocol list. */
6012 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6013 PROTOCOL_FORWARD_DECL (p),
6014 TREE_PURPOSE (*chain));
6021 /* This function is called by the parser when a @selector() expression
6022 is found, in order to compile it. It is only called by the parser
6023 and only to compile a @selector(). */
6025 build_selector_expr (tree selnamelist)
6029 /* Obtain the full selector name. */
6030 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6031 /* A unary selector. */
6032 selname = selnamelist;
6033 else if (TREE_CODE (selnamelist) == TREE_LIST)
6034 selname = build_keyword_selector (selnamelist);
6038 /* If we are required to check @selector() expressions as they
6039 are found, check that the selector has been declared. */
6040 if (warn_undeclared_selector)
6042 /* Look the selector up in the list of all known class and
6043 instance methods (up to this line) to check that the selector
6047 /* First try with instance methods. */
6048 hsh = hash_lookup (nst_method_hash_list, selname);
6050 /* If not found, try with class methods. */
6053 hsh = hash_lookup (cls_method_hash_list, selname);
6056 /* If still not found, print out a warning. */
6059 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6064 if (flag_typed_selectors)
6065 return build_typed_selector_reference (selname, 0);
6067 return build_selector_reference (selname);
6071 build_encode_expr (tree type)
6076 encode_type (type, obstack_object_size (&util_obstack),
6077 OBJC_ENCODE_INLINE_DEFS);
6078 obstack_1grow (&util_obstack, 0); /* null terminate string */
6079 string = obstack_finish (&util_obstack);
6081 /* Synthesize a string that represents the encoded struct/union. */
6082 result = my_build_string (strlen (string) + 1, string);
6083 obstack_free (&util_obstack, util_firstobj);
6088 build_ivar_reference (tree id)
6090 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6092 /* Historically, a class method that produced objects (factory
6093 method) would assign `self' to the instance that it
6094 allocated. This would effectively turn the class method into
6095 an instance method. Following this assignment, the instance
6096 variables could be accessed. That practice, while safe,
6097 violates the simple rule that a class method should not refer
6098 to an instance variable. It's better to catch the cases
6099 where this is done unknowingly than to support the above
6101 warning ("instance variable `%s' accessed in class method",
6102 IDENTIFIER_POINTER (id));
6103 TREE_TYPE (self_decl) = instance_type; /* cast */
6106 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6109 /* Compute a hash value for a given method SEL_NAME. */
6112 hash_func (tree sel_name)
6114 const unsigned char *s
6115 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6119 h = h * 67 + *s++ - 113;
6126 nst_method_hash_list
6127 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6128 cls_method_hash_list
6129 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6132 /* WARNING!!!! hash_enter is called with a method, and will peek
6133 inside to find its selector! But hash_lookup is given a selector
6134 directly, and looks for the selector that's inside the found
6135 entry's key (method) for comparison. */
6138 hash_enter (hash *hashlist, tree method)
6141 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6143 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6145 obj->next = hashlist[slot];
6148 hashlist[slot] = obj; /* append to front */
6152 hash_lookup (hash *hashlist, tree sel_name)
6156 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6160 if (sel_name == METHOD_SEL_NAME (target->key))
6163 target = target->next;
6169 hash_add_attr (hash entry, tree value)
6173 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6174 obj->next = entry->list;
6177 entry->list = obj; /* append to front */
6181 lookup_method (tree mchain, tree method)
6185 if (TREE_CODE (method) == IDENTIFIER_NODE)
6188 key = METHOD_SEL_NAME (method);
6192 if (METHOD_SEL_NAME (mchain) == key)
6195 mchain = TREE_CHAIN (mchain);
6201 lookup_method_static (tree interface, tree ident, int is_class)
6203 tree meth = NULL_TREE, root_inter = NULL_TREE;
6204 tree inter = interface;
6208 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6209 tree category = inter;
6211 /* First, look up the method in the class itself. */
6212 if ((meth = lookup_method (chain, ident)))
6215 /* Failing that, look for the method in each category of the class. */
6216 while ((category = CLASS_CATEGORY_LIST (category)))
6218 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6220 /* Check directly in each category. */
6221 if ((meth = lookup_method (chain, ident)))
6224 /* Failing that, check in each category's protocols. */
6225 if (CLASS_PROTOCOL_LIST (category))
6227 if ((meth = (lookup_method_in_protocol_list
6228 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6233 /* If not found in categories, check in protocols of the main class. */
6234 if (CLASS_PROTOCOL_LIST (inter))
6236 if ((meth = (lookup_method_in_protocol_list
6237 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6241 /* Failing that, climb up the inheritance hierarchy. */
6243 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6247 /* If no class (factory) method was found, check if an _instance_
6248 method of the same name exists in the root class. This is what
6249 the Objective-C runtime will do. If an instance method was not
6251 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6255 add_method (tree class, tree method, int is_class)
6260 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6262 /* put method on list in reverse order */
6265 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6266 CLASS_CLS_METHODS (class) = method;
6270 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6271 CLASS_NST_METHODS (class) = method;
6276 /* When processing an @interface for a class or category, give hard errors on methods with
6277 identical selectors but differing argument and/or return types. We do not do this for
6278 @implementations, because C/C++ will do it for us (i.e., there will be
6279 duplicate function definition errors). */
6280 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6281 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6282 && !comp_proto_with_proto (method, mth))
6283 error ("duplicate declaration of method `%c%s'",
6284 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6287 if (!(hsh = hash_lookup (is_class
6288 ? cls_method_hash_list
6289 : nst_method_hash_list, METHOD_SEL_NAME (method))))
6291 /* Install on a global chain. */
6292 hash_enter (is_class ? cls_method_hash_list : nst_method_hash_list, method);
6296 /* Check types against those; if different, add to a list. */
6298 int already_there = comp_proto_with_proto (method, hsh->key);
6299 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6300 already_there |= comp_proto_with_proto (method, loop->value);
6302 hash_add_attr (hsh, method);
6308 add_class (tree class)
6310 /* Put interfaces on list in reverse order. */
6311 TREE_CHAIN (class) = interface_chain;
6312 interface_chain = class;
6313 return interface_chain;
6317 add_category (tree class, tree category)
6319 /* Put categories on list in reverse order. */
6320 tree cat = CLASS_CATEGORY_LIST (class);
6324 if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
6326 error ("duplicate interface declaration for category `%s(%s)'",
6328 warning ("duplicate interface declaration for category `%s(%s)'",
6330 IDENTIFIER_POINTER (CLASS_NAME (class)),
6331 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6332 cat = CLASS_CATEGORY_LIST (cat);
6335 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6336 CLASS_CATEGORY_LIST (class) = category;
6339 /* Called after parsing each instance variable declaration. Necessary to
6340 preserve typedefs and implement public/private...
6342 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6345 add_instance_variable (tree class, int public, tree declarator,
6346 tree declspecs, tree width)
6348 tree field_decl = grokfield (declarator, declspecs, width);
6349 tree field_type = TREE_TYPE (field_decl);
6350 const char *ivar_name = DECL_NAME (field_decl)
6351 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6356 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6358 error ("illegal reference type specified for instance variable `%s'",
6360 /* Return class as is without adding this ivar. */
6365 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6366 || TYPE_SIZE (field_type) == error_mark_node
6367 /* 'type[0]' is allowed, but 'type[]' is not! */
6369 || (TYPE_SIZE (field_type) == bitsize_zero_node
6370 && !TREE_OPERAND (declarator, 1))
6374 error ("instance variable `%s' has unknown size", ivar_name);
6375 /* Return class as is without adding this ivar. */
6380 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6381 cannot be ivars; ditto for classes with vtables. */
6382 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6383 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6385 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6386 if(TYPE_POLYMORPHIC_P (field_type)) {
6387 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6388 error ("type `%s' has virtual member functions", type_name);
6389 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6390 type_name, ivar_name);
6391 /* Return class as is without adding this ivar. */
6394 /* user-defined constructors and destructors are not known to Obj-C and
6395 hence will not be called. This may or may not be a problem. */
6396 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6397 warning ("type `%s' has a user-defined constructor", type_name);
6398 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6399 warning ("type `%s' has a user-defined destructor", type_name);
6400 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6404 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6408 TREE_PUBLIC (field_decl) = 0;
6409 TREE_PRIVATE (field_decl) = 0;
6410 TREE_PROTECTED (field_decl) = 1;
6414 TREE_PUBLIC (field_decl) = 1;
6415 TREE_PRIVATE (field_decl) = 0;
6416 TREE_PROTECTED (field_decl) = 0;
6420 TREE_PUBLIC (field_decl) = 0;
6421 TREE_PRIVATE (field_decl) = 1;
6422 TREE_PROTECTED (field_decl) = 0;
6427 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6428 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6429 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6434 is_ivar (tree decl_chain, tree ident)
6436 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6437 if (DECL_NAME (decl_chain) == ident)
6442 /* True if the ivar is private and we are not in its implementation. */
6445 is_private (tree decl)
6447 if (TREE_PRIVATE (decl)
6448 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
6450 error ("instance variable `%s' is declared private",
6451 IDENTIFIER_POINTER (DECL_NAME (decl)));
6458 /* We have an instance variable reference;, check to see if it is public. */
6461 is_public (tree expr, tree identifier)
6463 tree basetype = TREE_TYPE (expr);
6464 enum tree_code code = TREE_CODE (basetype);
6467 if (code == RECORD_TYPE)
6469 if (TREE_STATIC_TEMPLATE (basetype))
6471 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6473 error ("cannot find interface declaration for `%s'",
6474 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6478 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6480 if (TREE_PUBLIC (decl))
6483 /* Important difference between the Stepstone translator:
6484 all instance variables should be public within the context
6485 of the implementation. */
6486 if (objc_implementation_context
6487 && (((TREE_CODE (objc_implementation_context)
6488 == CLASS_IMPLEMENTATION_TYPE)
6489 || (TREE_CODE (objc_implementation_context)
6490 == CATEGORY_IMPLEMENTATION_TYPE))
6491 && (CLASS_NAME (objc_implementation_context)
6492 == OBJC_TYPE_NAME (basetype))))
6493 return ! is_private (decl);
6495 /* The 2.95.2 compiler sometimes allowed C functions to access
6496 non-@public ivars. We will let this slide for now... */
6497 if (!objc_method_context)
6499 warning ("instance variable `%s' is %s; "
6500 "this will be a hard error in the future",
6501 IDENTIFIER_POINTER (identifier),
6502 TREE_PRIVATE (decl) ? "@private" : "@protected");
6506 error ("instance variable `%s' is declared %s",
6507 IDENTIFIER_POINTER (identifier),
6508 TREE_PRIVATE (decl) ? "private" : "protected");
6513 else if (objc_implementation_context && (basetype == objc_object_reference))
6515 TREE_TYPE (expr) = uprivate_record;
6516 warning ("static access to object of type `id'");
6523 /* Make sure all entries in CHAIN are also in LIST. */
6526 check_methods (tree chain, tree list, int mtype)
6532 if (!lookup_method (list, chain))
6536 if (TREE_CODE (objc_implementation_context)
6537 == CLASS_IMPLEMENTATION_TYPE)
6538 warning ("incomplete implementation of class `%s'",
6539 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6540 else if (TREE_CODE (objc_implementation_context)
6541 == CATEGORY_IMPLEMENTATION_TYPE)
6542 warning ("incomplete implementation of category `%s'",
6543 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6547 warning ("method definition for `%c%s' not found",
6548 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6551 chain = TREE_CHAIN (chain);
6557 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6560 conforms_to_protocol (tree class, tree protocol)
6562 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6564 tree p = CLASS_PROTOCOL_LIST (class);
6565 while (p && TREE_VALUE (p) != protocol)
6570 tree super = (CLASS_SUPER_NAME (class)
6571 ? lookup_interface (CLASS_SUPER_NAME (class))
6573 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6582 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6583 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6586 check_methods_accessible (tree chain, tree context, int mtype)
6590 tree base_context = context;
6594 context = base_context;
6598 list = CLASS_CLS_METHODS (context);
6600 list = CLASS_NST_METHODS (context);
6602 if (lookup_method (list, chain))
6605 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6606 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6607 context = (CLASS_SUPER_NAME (context)
6608 ? lookup_interface (CLASS_SUPER_NAME (context))
6611 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6612 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6613 context = (CLASS_NAME (context)
6614 ? lookup_interface (CLASS_NAME (context))
6620 if (context == NULL_TREE)
6624 if (TREE_CODE (objc_implementation_context)
6625 == CLASS_IMPLEMENTATION_TYPE)
6626 warning ("incomplete implementation of class `%s'",
6628 (CLASS_NAME (objc_implementation_context)));
6629 else if (TREE_CODE (objc_implementation_context)
6630 == CATEGORY_IMPLEMENTATION_TYPE)
6631 warning ("incomplete implementation of category `%s'",
6633 (CLASS_SUPER_NAME (objc_implementation_context)));
6636 warning ("method definition for `%c%s' not found",
6637 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6640 chain = TREE_CHAIN (chain); /* next method... */
6645 /* Check whether the current interface (accessible via
6646 'objc_implementation_context') actually implements protocol P, along
6647 with any protocols that P inherits. */
6650 check_protocol (tree p, const char *type, const char *name)
6652 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6656 /* Ensure that all protocols have bodies! */
6659 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6660 CLASS_CLS_METHODS (objc_implementation_context),
6662 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6663 CLASS_NST_METHODS (objc_implementation_context),
6668 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6669 objc_implementation_context,
6671 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6672 objc_implementation_context,
6677 warning ("%s `%s' does not fully implement the `%s' protocol",
6678 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6681 /* Check protocols recursively. */
6682 if (PROTOCOL_LIST (p))
6684 tree subs = PROTOCOL_LIST (p);
6686 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6690 tree sub = TREE_VALUE (subs);
6692 /* If the superclass does not conform to the protocols
6693 inherited by P, then we must! */
6694 if (!super_class || !conforms_to_protocol (super_class, sub))
6695 check_protocol (sub, type, name);
6696 subs = TREE_CHAIN (subs);
6701 /* Check whether the current interface (accessible via
6702 'objc_implementation_context') actually implements the protocols listed
6706 check_protocols (tree proto_list, const char *type, const char *name)
6708 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6710 tree p = TREE_VALUE (proto_list);
6712 check_protocol (p, type, name);
6716 /* Make sure that the class CLASS_NAME is defined
6717 CODE says which kind of thing CLASS_NAME ought to be.
6718 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6719 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6722 start_class (enum tree_code code, tree class_name, tree super_name,
6728 if (current_namespace != global_namespace) {
6729 error ("Objective-C declarations may only appear in global scope");
6731 #endif /* OBJCPLUS */
6733 if (objc_implementation_context)
6735 warning ("`@end' missing in implementation context");
6736 finish_class (objc_implementation_context);
6737 objc_ivar_chain = NULL_TREE;
6738 objc_implementation_context = NULL_TREE;
6741 class = make_node (code);
6742 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6744 CLASS_NAME (class) = class_name;
6745 CLASS_SUPER_NAME (class) = super_name;
6746 CLASS_CLS_METHODS (class) = NULL_TREE;
6748 if (! is_class_name (class_name)
6749 && (decl = lookup_name (class_name)))
6751 error ("`%s' redeclared as different kind of symbol",
6752 IDENTIFIER_POINTER (class_name));
6753 error ("%Jprevious declaration of '%D'",
6757 if (code == CLASS_IMPLEMENTATION_TYPE)
6762 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6763 if (TREE_VALUE (chain) == class_name)
6765 error ("reimplementation of class `%s'",
6766 IDENTIFIER_POINTER (class_name));
6767 return error_mark_node;
6769 implemented_classes = tree_cons (NULL_TREE, class_name,
6770 implemented_classes);
6773 /* Reset for multiple classes per file. */
6776 objc_implementation_context = class;
6778 /* Lookup the interface for this implementation. */
6780 if (!(implementation_template = lookup_interface (class_name)))
6782 warning ("cannot find interface declaration for `%s'",
6783 IDENTIFIER_POINTER (class_name));
6784 add_class (implementation_template = objc_implementation_context);
6787 /* If a super class has been specified in the implementation,
6788 insure it conforms to the one specified in the interface. */
6791 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6793 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6794 const char *const name =
6795 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6796 error ("conflicting super class name `%s'",
6797 IDENTIFIER_POINTER (super_name));
6798 error ("previous declaration of `%s'", name);
6801 else if (! super_name)
6803 CLASS_SUPER_NAME (objc_implementation_context)
6804 = CLASS_SUPER_NAME (implementation_template);
6808 else if (code == CLASS_INTERFACE_TYPE)
6810 if (lookup_interface (class_name))
6812 error ("duplicate interface declaration for class `%s'",
6814 warning ("duplicate interface declaration for class `%s'",
6816 IDENTIFIER_POINTER (class_name));
6821 CLASS_PROTOCOL_LIST (class)
6822 = lookup_and_install_protocols (protocol_list);
6825 else if (code == CATEGORY_INTERFACE_TYPE)
6827 tree class_category_is_assoc_with;
6829 /* For a category, class_name is really the name of the class that
6830 the following set of methods will be associated with. We must
6831 find the interface so that can derive the objects template. */
6833 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6835 error ("cannot find interface declaration for `%s'",
6836 IDENTIFIER_POINTER (class_name));
6837 exit (FATAL_EXIT_CODE);
6840 add_category (class_category_is_assoc_with, class);
6843 CLASS_PROTOCOL_LIST (class)
6844 = lookup_and_install_protocols (protocol_list);
6847 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6849 /* Reset for multiple classes per file. */
6852 objc_implementation_context = class;
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 (!(implementation_template = lookup_interface (class_name)))
6860 error ("cannot find interface declaration for `%s'",
6861 IDENTIFIER_POINTER (class_name));
6862 exit (FATAL_EXIT_CODE);
6869 continue_class (tree class)
6871 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6872 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6874 struct imp_entry *imp_entry;
6877 /* Check consistency of the instance variables. */
6879 if (CLASS_IVARS (class))
6880 check_ivars (implementation_template, class);
6882 /* code generation */
6884 ivar_context = build_private_template (implementation_template);
6886 if (!objc_class_template)
6887 build_class_template ();
6889 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6891 imp_entry->next = imp_list;
6892 imp_entry->imp_context = class;
6893 imp_entry->imp_template = implementation_template;
6895 synth_forward_declarations ();
6896 imp_entry->class_decl = UOBJC_CLASS_decl;
6897 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6899 /* Append to front and increment count. */
6900 imp_list = imp_entry;
6901 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6906 return ivar_context;
6909 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6911 if (!CLASS_STATIC_TEMPLATE (class))
6913 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6914 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6915 CLASS_STATIC_TEMPLATE (class) = record;
6917 /* Mark this record as a class template for static typing. */
6918 TREE_STATIC_TEMPLATE (record) = 1;
6925 return error_mark_node;
6928 /* This is called once we see the "@end" in an interface/implementation. */
6931 finish_class (tree class)
6933 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6935 /* All code generation is done in finish_objc. */
6937 if (implementation_template != objc_implementation_context)
6939 /* Ensure that all method listed in the interface contain bodies. */
6940 check_methods (CLASS_CLS_METHODS (implementation_template),
6941 CLASS_CLS_METHODS (objc_implementation_context), '+');
6942 check_methods (CLASS_NST_METHODS (implementation_template),
6943 CLASS_NST_METHODS (objc_implementation_context), '-');
6945 if (CLASS_PROTOCOL_LIST (implementation_template))
6946 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6948 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6952 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6954 tree category = CLASS_CATEGORY_LIST (implementation_template);
6956 /* Find the category interface from the class it is associated with. */
6959 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
6961 category = CLASS_CATEGORY_LIST (category);
6966 /* Ensure all method listed in the interface contain bodies. */
6967 check_methods (CLASS_CLS_METHODS (category),
6968 CLASS_CLS_METHODS (objc_implementation_context), '+');
6969 check_methods (CLASS_NST_METHODS (category),
6970 CLASS_NST_METHODS (objc_implementation_context), '-');
6972 if (CLASS_PROTOCOL_LIST (category))
6973 check_protocols (CLASS_PROTOCOL_LIST (category),
6975 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6979 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6982 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6983 char *string = (char *) alloca (strlen (class_name) + 3);
6985 /* extern struct objc_object *_<my_name>; */
6987 sprintf (string, "_%s", class_name);
6989 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6990 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6991 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
6997 add_protocol (tree protocol)
6999 /* Put protocol on list in reverse order. */
7000 TREE_CHAIN (protocol) = protocol_chain;
7001 protocol_chain = protocol;
7002 return protocol_chain;
7006 lookup_protocol (tree ident)
7010 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7011 if (ident == PROTOCOL_NAME (chain))
7017 /* This function forward declares the protocols named by NAMES. If
7018 they are already declared or defined, the function has no effect. */
7021 objc_declare_protocols (tree names)
7026 if (current_namespace != global_namespace) {
7027 error ("Objective-C declarations may only appear in global scope");
7029 #endif /* OBJCPLUS */
7031 for (list = names; list; list = TREE_CHAIN (list))
7033 tree name = TREE_VALUE (list);
7035 if (lookup_protocol (name) == NULL_TREE)
7037 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7039 TYPE_BINFO (protocol) = make_tree_vec (2);
7040 PROTOCOL_NAME (protocol) = name;
7041 PROTOCOL_LIST (protocol) = NULL_TREE;
7042 add_protocol (protocol);
7043 PROTOCOL_DEFINED (protocol) = 0;
7044 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7050 start_protocol (enum tree_code code, tree name, tree list)
7055 if (current_namespace != global_namespace) {
7056 error ("Objective-C declarations may only appear in global scope");
7058 #endif /* OBJCPLUS */
7060 /* This is as good a place as any. Need to invoke
7061 push_tag_toplevel. */
7062 if (!objc_protocol_template)
7063 objc_protocol_template = build_protocol_template ();
7065 protocol = lookup_protocol (name);
7069 protocol = make_node (code);
7070 TYPE_BINFO (protocol) = make_tree_vec (2);
7072 PROTOCOL_NAME (protocol) = name;
7073 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7074 add_protocol (protocol);
7075 PROTOCOL_DEFINED (protocol) = 1;
7076 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7078 check_protocol_recursively (protocol, list);
7080 else if (! PROTOCOL_DEFINED (protocol))
7082 PROTOCOL_DEFINED (protocol) = 1;
7083 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7085 check_protocol_recursively (protocol, list);
7089 warning ("duplicate declaration for protocol `%s'",
7090 IDENTIFIER_POINTER (name));
7096 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7101 /* "Encode" a data type into a string, which grows in util_obstack.
7102 ??? What is the FORMAT? Someone please document this! */
7105 encode_type_qualifiers (tree declspecs)
7109 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7111 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7112 obstack_1grow (&util_obstack, 'r');
7113 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7114 obstack_1grow (&util_obstack, 'n');
7115 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7116 obstack_1grow (&util_obstack, 'N');
7117 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7118 obstack_1grow (&util_obstack, 'o');
7119 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7120 obstack_1grow (&util_obstack, 'O');
7121 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7122 obstack_1grow (&util_obstack, 'R');
7123 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7124 obstack_1grow (&util_obstack, 'V');
7128 /* Encode a pointer type. */
7131 encode_pointer (tree type, int curtype, int format)
7133 tree pointer_to = TREE_TYPE (type);
7135 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7137 if (OBJC_TYPE_NAME (pointer_to)
7138 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7140 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7142 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7144 obstack_1grow (&util_obstack, '@');
7147 else if (TREE_STATIC_TEMPLATE (pointer_to))
7149 if (generating_instance_variables)
7151 obstack_1grow (&util_obstack, '@');
7152 obstack_1grow (&util_obstack, '"');
7153 obstack_grow (&util_obstack, name, strlen (name));
7154 obstack_1grow (&util_obstack, '"');
7159 obstack_1grow (&util_obstack, '@');
7163 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7165 obstack_1grow (&util_obstack, '#');
7168 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7170 obstack_1grow (&util_obstack, ':');
7175 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7176 && TYPE_MODE (pointer_to) == QImode)
7178 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7179 ? OBJC_TYPE_NAME (pointer_to)
7180 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7182 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7184 obstack_1grow (&util_obstack, '*');
7189 /* We have a type that does not get special treatment. */
7191 /* NeXT extension */
7192 obstack_1grow (&util_obstack, '^');
7193 encode_type (pointer_to, curtype, format);
7197 encode_array (tree type, int curtype, int format)
7199 tree an_int_cst = TYPE_SIZE (type);
7200 tree array_of = TREE_TYPE (type);
7203 /* An incomplete array is treated like a pointer. */
7204 if (an_int_cst == NULL)
7206 encode_pointer (type, curtype, format);
7210 sprintf (buffer, "[%ld",
7211 (long) (TREE_INT_CST_LOW (an_int_cst)
7212 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7214 obstack_grow (&util_obstack, buffer, strlen (buffer));
7215 encode_type (array_of, curtype, format);
7216 obstack_1grow (&util_obstack, ']');
7221 encode_aggregate_within (tree type, int curtype, int format, int left,
7225 /* NB: aggregates that are pointed to have slightly different encoding
7226 rules in that you never encode the names of instance variables. */
7228 = (obstack_object_size (&util_obstack) > 0
7229 && *(obstack_next_free (&util_obstack) - 1) == '^');
7231 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7232 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7234 /* Traverse struct aliases; it is important to get the
7235 original struct and its tag name (if any). */
7236 type = TYPE_MAIN_VARIANT (type);
7237 name = OBJC_TYPE_NAME (type);
7238 /* Open parenth/bracket. */
7239 obstack_1grow (&util_obstack, left);
7241 /* Encode the struct/union tag name, or '?' if a tag was
7242 not provided. Typedef aliases do not qualify. */
7243 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7245 /* Did this struct have a tag? */
7246 && !TYPE_WAS_ANONYMOUS (type)
7249 obstack_grow (&util_obstack,
7250 IDENTIFIER_POINTER (name),
7251 strlen (IDENTIFIER_POINTER (name)));
7253 obstack_1grow (&util_obstack, '?');
7255 /* Encode the types (and possibly names) of the inner fields,
7257 if (inline_contents)
7259 tree fields = TYPE_FIELDS (type);
7261 obstack_1grow (&util_obstack, '=');
7262 for (; fields; fields = TREE_CHAIN (fields))
7265 /* C++ static members, and things that are not fields at all,
7266 should not appear in the encoding. */
7267 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7270 if (generating_instance_variables && !pointed_to)
7272 tree fname = DECL_NAME (fields);
7274 obstack_1grow (&util_obstack, '"');
7275 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7276 obstack_grow (&util_obstack,
7277 IDENTIFIER_POINTER (fname),
7278 strlen (IDENTIFIER_POINTER (fname)));
7279 obstack_1grow (&util_obstack, '"');
7281 encode_field_decl (fields, curtype, format);
7284 /* Close parenth/bracket. */
7285 obstack_1grow (&util_obstack, right);
7289 encode_aggregate (tree type, int curtype, int format)
7291 enum tree_code code = TREE_CODE (type);
7297 encode_aggregate_within (type, curtype, format, '{', '}');
7302 encode_aggregate_within (type, curtype, format, '(', ')');
7307 obstack_1grow (&util_obstack, 'i');
7315 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7319 encode_next_bitfield (int width)
7322 sprintf (buffer, "b%d", width);
7323 obstack_grow (&util_obstack, buffer, strlen (buffer));
7326 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7329 encode_type (tree type, int curtype, int format)
7331 enum tree_code code = TREE_CODE (type);
7333 if (code == INTEGER_TYPE)
7335 if (integer_zerop (TYPE_MIN_VALUE (type)))
7337 /* Unsigned integer types. */
7339 if (TYPE_MODE (type) == QImode)
7340 obstack_1grow (&util_obstack, 'C');
7341 else if (TYPE_MODE (type) == HImode)
7342 obstack_1grow (&util_obstack, 'S');
7343 else if (TYPE_MODE (type) == SImode)
7345 if (type == long_unsigned_type_node)
7346 obstack_1grow (&util_obstack, 'L');
7348 obstack_1grow (&util_obstack, 'I');
7350 else if (TYPE_MODE (type) == DImode)
7351 obstack_1grow (&util_obstack, 'Q');
7355 /* Signed integer types. */
7357 if (TYPE_MODE (type) == QImode)
7358 obstack_1grow (&util_obstack, 'c');
7359 else if (TYPE_MODE (type) == HImode)
7360 obstack_1grow (&util_obstack, 's');
7361 else if (TYPE_MODE (type) == SImode)
7363 if (type == long_integer_type_node)
7364 obstack_1grow (&util_obstack, 'l');
7366 obstack_1grow (&util_obstack, 'i');
7369 else if (TYPE_MODE (type) == DImode)
7370 obstack_1grow (&util_obstack, 'q');
7374 else if (code == REAL_TYPE)
7376 /* Floating point types. */
7378 if (TYPE_MODE (type) == SFmode)
7379 obstack_1grow (&util_obstack, 'f');
7380 else if (TYPE_MODE (type) == DFmode
7381 || TYPE_MODE (type) == TFmode)
7382 obstack_1grow (&util_obstack, 'd');
7385 else if (code == VOID_TYPE)
7386 obstack_1grow (&util_obstack, 'v');
7388 else if (code == BOOLEAN_TYPE)
7389 obstack_1grow (&util_obstack, 'B');
7391 else if (code == ARRAY_TYPE)
7392 encode_array (type, curtype, format);
7394 else if (code == POINTER_TYPE)
7395 encode_pointer (type, curtype, format);
7397 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7398 encode_aggregate (type, curtype, format);
7400 else if (code == FUNCTION_TYPE) /* '?' */
7401 obstack_1grow (&util_obstack, '?');
7405 encode_gnu_bitfield (int position, tree type, int size)
7407 enum tree_code code = TREE_CODE (type);
7409 char charType = '?';
7411 if (code == INTEGER_TYPE)
7413 if (integer_zerop (TYPE_MIN_VALUE (type)))
7415 /* Unsigned integer types. */
7417 if (TYPE_MODE (type) == QImode)
7419 else if (TYPE_MODE (type) == HImode)
7421 else if (TYPE_MODE (type) == SImode)
7423 if (type == long_unsigned_type_node)
7428 else if (TYPE_MODE (type) == DImode)
7433 /* Signed integer types. */
7435 if (TYPE_MODE (type) == QImode)
7437 else if (TYPE_MODE (type) == HImode)
7439 else if (TYPE_MODE (type) == SImode)
7441 if (type == long_integer_type_node)
7447 else if (TYPE_MODE (type) == DImode)
7451 else if (code == ENUMERAL_TYPE)
7456 sprintf (buffer, "b%d%c%d", position, charType, size);
7457 obstack_grow (&util_obstack, buffer, strlen (buffer));
7461 encode_field_decl (tree field_decl, int curtype, int format)
7466 /* C++ static members, and things that are not fields at all,
7467 should not appear in the encoding. */
7468 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7472 type = TREE_TYPE (field_decl);
7474 /* Generate the bitfield typing information, if needed. Note the difference
7475 between GNU and NeXT runtimes. */
7476 if (DECL_BIT_FIELD_TYPE (field_decl))
7478 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7480 if (flag_next_runtime)
7481 encode_next_bitfield (size);
7483 encode_gnu_bitfield (int_bit_position (field_decl),
7484 DECL_BIT_FIELD_TYPE (field_decl), size);
7487 encode_type (TREE_TYPE (field_decl), curtype, format);
7491 objc_expr_last (tree complex_expr)
7496 while ((next = TREE_OPERAND (complex_expr, 0)))
7497 complex_expr = next;
7499 return complex_expr;
7503 synth_self_and_ucmd_args (void)
7507 if (objc_method_context
7508 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7509 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7511 /* Really a `struct objc_class *'. However, we allow people to
7512 assign to self, which changes its type midstream. */
7513 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7515 push_parm_decl (build_tree_list
7516 (build_tree_list (decl_specs,
7517 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7520 decl_specs = build_tree_list (NULL_TREE,
7521 xref_tag (RECORD_TYPE,
7522 get_identifier (TAG_SELECTOR)));
7523 push_parm_decl (build_tree_list
7524 (build_tree_list (decl_specs,
7525 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7529 /* Transform a method definition into a function definition as follows:
7530 - synthesize the first two arguments, "self" and "_cmd". */
7533 start_method_def (tree method)
7535 /* Required to implement _msgSuper. */
7536 objc_method_context = method;
7537 UOBJC_SUPER_decl = NULL_TREE;
7539 /* Must be called BEFORE start_function. */
7542 /* Generate prototype declarations for arguments..."new-style". */
7543 synth_self_and_ucmd_args ();
7545 /* Generate argument declarations if a keyword_decl. */
7546 if (METHOD_SEL_ARGS (method))
7548 tree arglist = METHOD_SEL_ARGS (method);
7551 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7552 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7556 tree last_expr = objc_expr_last (arg_decl);
7558 /* Unite the abstract decl with its name. */
7559 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7560 push_parm_decl (build_tree_list
7561 (build_tree_list (arg_spec, arg_decl),
7565 /* Unhook: restore the abstract declarator. */
7566 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7571 push_parm_decl (build_tree_list
7572 (build_tree_list (arg_spec,
7573 KEYWORD_ARG_NAME (arglist)),
7576 arglist = TREE_CHAIN (arglist);
7581 if (METHOD_ADD_ARGS (method) != NULL_TREE
7582 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7584 /* We have a variable length selector - in "prototype" format. */
7585 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7588 /* This must be done prior to calling pushdecl. pushdecl is
7589 going to change our chain on us. */
7590 tree nextkey = TREE_CHAIN (akey);
7598 warn_with_method (const char *message, int mtype, tree method)
7600 /* Add a readable method name to the warning. */
7601 warning ("%J%s `%c%s'", method,
7602 message, mtype, gen_method_decl (method, errbuf));
7605 /* Return 1 if METHOD is consistent with PROTO. */
7608 comp_method_with_proto (tree method, tree proto)
7610 /* Create a function template node at most once. */
7611 if (!function1_template)
7612 function1_template = make_node (FUNCTION_TYPE);
7614 /* Install argument types - normally set by build_function_type. */
7615 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7617 /* install return type */
7618 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7620 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
7624 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7627 objc_types_are_equivalent (tree type1, tree type2)
7631 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7633 type1 = TYPE_PROTOCOL_LIST (type1);
7634 type2 = TYPE_PROTOCOL_LIST (type2);
7635 if (list_length (type1) == list_length (type2))
7637 for (; type2; type2 = TREE_CHAIN (type2))
7638 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7645 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7648 comp_proto_with_proto (tree proto1, tree proto2)
7652 /* The following test is needed in case there are hashing
7654 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7657 /* Compare return types. */
7658 type1 = groktypename (TREE_TYPE (proto1));
7659 type2 = groktypename (TREE_TYPE (proto2));
7661 if (!objc_types_are_equivalent (type1, type2))
7664 /* Compare argument types. */
7665 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7666 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7668 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7670 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7674 return (!type1 && !type2);
7677 /* - Generate an identifier for the function. the format is "_n_cls",
7678 where 1 <= n <= nMethods, and cls is the name the implementation we
7680 - Install the return type from the method declaration.
7681 - If we have a prototype, check for type consistency. */
7684 really_start_method (tree method, tree parmlist)
7686 tree sc_spec, ret_spec, ret_decl, decl_specs;
7687 tree method_decl, method_id;
7688 const char *sel_name, *class_name, *cat_name;
7691 /* Synth the storage class & assemble the return type. */
7692 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7693 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7694 decl_specs = chainon (sc_spec, ret_spec);
7696 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7697 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7698 cat_name = ((TREE_CODE (objc_implementation_context)
7699 == CLASS_IMPLEMENTATION_TYPE)
7701 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7704 /* Make sure this is big enough for any plausible method label. */
7705 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7706 + (cat_name ? strlen (cat_name) : 0));
7708 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7709 class_name, cat_name, sel_name, method_slot);
7711 method_id = get_identifier (buf);
7714 /* Objective-C methods cannot be overloaded, so we don't need
7715 the type encoding appended. It looks bad anyway... */
7716 push_lang_context (lang_name_c);
7719 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7721 /* Check the declarator portion of the return type for the method. */
7722 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7724 /* Unite the complex decl (specified in the abstract decl) with the
7725 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7726 tree save_expr = objc_expr_last (ret_decl);
7728 TREE_OPERAND (save_expr, 0) = method_decl;
7729 method_decl = ret_decl;
7731 /* Fool the parser into thinking it is starting a function. */
7732 start_function (decl_specs, method_decl, NULL_TREE);
7734 /* Unhook: this has the effect of restoring the abstract declarator. */
7735 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7740 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7742 /* Fool the parser into thinking it is starting a function. */
7743 start_function (decl_specs, method_decl, NULL_TREE);
7745 /* Unhook: this has the effect of restoring the abstract declarator. */
7746 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7750 /* set self_decl from the first argument...this global is used by
7751 * build_ivar_reference().build_indirect_ref().
7753 self_decl = DECL_ARGUMENTS (current_function_decl);
7755 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7756 * the following: warning:unused parameter `struct objc_selector * _cmd'
7758 TREE_USED (self_decl) = 1;
7759 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7760 /* Ditto for the underlying (static) C function. */
7761 TREE_USED (current_function_decl) = 1;
7762 pop_lang_context ();
7765 METHOD_DEFINITION (method) = current_function_decl;
7767 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7769 if (implementation_template != objc_implementation_context)
7772 = lookup_method_static (implementation_template,
7773 METHOD_SEL_NAME (method),
7774 TREE_CODE (method) == CLASS_METHOD_DECL);
7776 if (proto && ! comp_method_with_proto (method, proto))
7778 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7780 warn_with_method ("conflicting types for", type, method);
7781 warn_with_method ("previous declaration of", type, proto);
7786 /* The following routine is always called...this "architecture" is to
7787 accommodate "old-style" variable length selectors.
7789 - a:a b:b // prototype ; id c; id d; // old-style. */
7792 continue_method_def (void)
7796 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7797 /* We have a `, ...' immediately following the selector. */
7798 parmlist = get_parm_info (0);
7800 parmlist = get_parm_info (1); /* place a `void_at_end' */
7803 /* Set self_decl from the first argument...this global is used by
7804 build_ivar_reference calling build_indirect_ref. */
7805 self_decl = TREE_PURPOSE (parmlist);
7806 #endif /* !OBJCPLUS */
7809 really_start_method (objc_method_context, parmlist);
7810 store_parm_decls ();
7813 static void *UOBJC_SUPER_scope = 0;
7815 /* _n_Method (id self, SEL sel, ...)
7817 struct objc_super _S;
7818 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7822 get_super_receiver (void)
7824 if (objc_method_context)
7826 tree super_expr, super_expr_list;
7828 if (!UOBJC_SUPER_decl)
7830 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7831 build_tree_list (NULL_TREE,
7832 objc_super_template),
7835 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7837 /* This prevents `unused variable' warnings when compiling with -Wall. */
7838 TREE_USED (UOBJC_SUPER_decl) = 1;
7839 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7841 UOBJC_SUPER_scope = get_current_scope ();
7844 /* Set receiver to self. */
7845 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7846 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7847 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7849 /* Set class to begin searching. */
7850 super_expr = build_component_ref (UOBJC_SUPER_decl,
7851 get_identifier ("class"));
7853 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7855 /* [_cls, __cls]Super are "pre-built" in
7856 synth_forward_declarations. */
7858 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7859 ((TREE_CODE (objc_method_context)
7860 == INSTANCE_METHOD_DECL)
7862 : uucls_super_ref));
7866 /* We have a category. */
7868 tree super_name = CLASS_SUPER_NAME (implementation_template);
7871 /* Barf if super used in a category of Object. */
7874 error ("no super class declared in interface for `%s'",
7875 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7876 return error_mark_node;
7879 if (flag_next_runtime && !flag_zero_link)
7881 super_class = get_class_reference (super_name);
7882 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7883 /* If we are in a class method, we must retrieve the
7884 _metaclass_ for the current class, pointed at by
7885 the class's "isa" pointer. The following assumes that
7886 "isa" is the first ivar in a class (which it must be). */
7888 = build_indirect_ref
7889 (build_c_cast (build_pointer_type (objc_class_type),
7890 super_class), "unary *");
7894 add_class_reference (super_name);
7895 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7896 ? objc_get_class_decl : objc_get_meta_class_decl);
7897 assemble_external (super_class);
7899 = build_function_call
7903 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7904 IDENTIFIER_POINTER (super_name))));
7908 = build_modify_expr (super_expr, NOP_EXPR,
7909 build_c_cast (TREE_TYPE (super_expr),
7913 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7915 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7916 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7918 return build_compound_expr (super_expr_list);
7922 error ("[super ...] must appear in a method context");
7923 return error_mark_node;
7927 /* When exiting a scope, sever links to a 'super' declaration (if any)
7928 therein contained. */
7931 objc_clear_super_receiver (void)
7933 if (objc_method_context
7934 && UOBJC_SUPER_scope == get_current_scope ()) {
7935 UOBJC_SUPER_decl = 0;
7936 UOBJC_SUPER_scope = 0;
7941 objc_expand_function_end (void)
7943 /* This routine may also get called for C functions, including those
7944 nested within ObjC methods. In such cases, method encoding is
7946 if (objc_method_context == NULL_TREE
7947 || DECL_INITIAL (objc_method_context) != current_function_decl)
7950 METHOD_ENCODING (objc_method_context)
7951 = encode_method_prototype (objc_method_context);
7955 finish_method_def (void)
7957 lang_expand_function_end = objc_expand_function_end;
7958 /* We cannot validly inline ObjC methods, at least not without a language
7959 extension to declare that a method need not be dynamically
7960 dispatched, so suppress all thoughts of doing so. */
7961 DECL_INLINE (current_function_decl) = 0;
7962 DECL_UNINLINABLE (current_function_decl) = 1;
7963 current_function_cannot_inline = "methods cannot be inlined";
7966 lang_expand_function_end = NULL;
7968 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7969 since the optimizer may find "may be used before set" errors. */
7970 objc_method_context = NULL_TREE;
7975 lang_report_error_function (tree decl)
7977 if (objc_method_context)
7979 fprintf (stderr, "In method `%s'\n",
7980 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7990 is_complex_decl (tree type)
7992 return (TREE_CODE (type) == ARRAY_TYPE
7993 || TREE_CODE (type) == FUNCTION_TYPE
7994 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
7998 /* Code to convert a decl node into text for a declaration in C. */
8000 static char tmpbuf[256];
8003 adorn_decl (tree decl, char *str)
8005 enum tree_code code = TREE_CODE (decl);
8007 if (code == ARRAY_REF)
8009 tree an_int_cst = TREE_OPERAND (decl, 1);
8011 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8012 sprintf (str + strlen (str), "[%ld]",
8013 (long) TREE_INT_CST_LOW (an_int_cst));
8018 else if (code == ARRAY_TYPE)
8020 tree an_int_cst = TYPE_SIZE (decl);
8021 tree array_of = TREE_TYPE (decl);
8023 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8024 sprintf (str + strlen (str), "[%ld]",
8025 (long) (TREE_INT_CST_LOW (an_int_cst)
8026 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8031 else if (code == CALL_EXPR)
8033 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8038 gen_declaration_1 (chain, str);
8039 chain = TREE_CHAIN (chain);
8046 else if (code == FUNCTION_TYPE)
8048 tree chain = TYPE_ARG_TYPES (decl);
8051 while (chain && TREE_VALUE (chain) != void_type_node)
8053 gen_declaration_1 (TREE_VALUE (chain), str);
8054 chain = TREE_CHAIN (chain);
8055 if (chain && TREE_VALUE (chain) != void_type_node)
8061 else if (code == INDIRECT_REF)
8063 strcpy (tmpbuf, "*");
8064 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8068 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8070 chain = TREE_CHAIN (chain))
8072 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8074 strcat (tmpbuf, " ");
8075 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8079 strcat (tmpbuf, " ");
8081 strcat (tmpbuf, str);
8082 strcpy (str, tmpbuf);
8085 else if (code == POINTER_TYPE)
8087 strcpy (tmpbuf, "*");
8088 if (TREE_READONLY (decl) || TYPE_VOLATILE (decl))
8090 if (TREE_READONLY (decl))
8091 strcat (tmpbuf, " const");
8092 if (TYPE_VOLATILE (decl))
8093 strcat (tmpbuf, " volatile");
8095 strcat (tmpbuf, " ");
8097 strcat (tmpbuf, str);
8098 strcpy (str, tmpbuf);
8103 gen_declarator (tree decl, char *buf, const char *name)
8107 enum tree_code code = TREE_CODE (decl);
8117 op = TREE_OPERAND (decl, 0);
8119 /* We have a pointer to a function or array...(*)(), (*)[] */
8120 if ((code == ARRAY_REF || code == CALL_EXPR)
8121 && op && TREE_CODE (op) == INDIRECT_REF)
8124 str = gen_declarator (op, buf, name);
8128 strcpy (tmpbuf, "(");
8129 strcat (tmpbuf, str);
8130 strcat (tmpbuf, ")");
8131 strcpy (str, tmpbuf);
8134 adorn_decl (decl, str);
8143 /* This clause is done iteratively rather than recursively. */
8146 op = (is_complex_decl (TREE_TYPE (decl))
8147 ? TREE_TYPE (decl) : NULL_TREE);
8149 adorn_decl (decl, str);
8151 /* We have a pointer to a function or array...(*)(), (*)[] */
8152 if (code == POINTER_TYPE
8153 && op && (TREE_CODE (op) == FUNCTION_TYPE
8154 || TREE_CODE (op) == ARRAY_TYPE))
8156 strcpy (tmpbuf, "(");
8157 strcat (tmpbuf, str);
8158 strcat (tmpbuf, ")");
8159 strcpy (str, tmpbuf);
8162 decl = (is_complex_decl (TREE_TYPE (decl))
8163 ? TREE_TYPE (decl) : NULL_TREE);
8166 while (decl && (code = TREE_CODE (decl)))
8171 case IDENTIFIER_NODE:
8172 /* Will only happen if we are processing a "raw" expr-decl. */
8173 strcpy (buf, IDENTIFIER_POINTER (decl));
8184 /* We have an abstract declarator or a _DECL node. */
8192 gen_declspecs (tree declspecs, char *buf, int raw)
8198 for (chain = nreverse (copy_list (declspecs));
8199 chain; chain = TREE_CHAIN (chain))
8201 tree aspec = TREE_VALUE (chain);
8203 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8204 strcat (buf, IDENTIFIER_POINTER (aspec));
8205 else if (TREE_CODE (aspec) == RECORD_TYPE)
8207 if (OBJC_TYPE_NAME (aspec))
8209 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8211 if (! TREE_STATIC_TEMPLATE (aspec))
8212 strcat (buf, "struct ");
8213 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8218 tree chain = protocol_list;
8225 (PROTOCOL_NAME (TREE_VALUE (chain))));
8226 chain = TREE_CHAIN (chain);
8235 strcat (buf, "untagged struct");
8238 else if (TREE_CODE (aspec) == UNION_TYPE)
8240 if (OBJC_TYPE_NAME (aspec))
8242 if (! TREE_STATIC_TEMPLATE (aspec))
8243 strcat (buf, "union ");
8244 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8247 strcat (buf, "untagged union");
8250 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8252 if (OBJC_TYPE_NAME (aspec))
8254 if (! TREE_STATIC_TEMPLATE (aspec))
8255 strcat (buf, "enum ");
8256 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8259 strcat (buf, "untagged enum");
8262 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8263 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8265 else if (IS_ID (aspec))
8267 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8272 tree chain = protocol_list;
8279 (PROTOCOL_NAME (TREE_VALUE (chain))));
8280 chain = TREE_CHAIN (chain);
8287 if (TREE_CHAIN (chain))
8293 /* Type qualifiers. */
8294 if (TREE_READONLY (declspecs))
8295 strcat (buf, "const ");
8296 if (TYPE_VOLATILE (declspecs))
8297 strcat (buf, "volatile ");
8299 switch (TREE_CODE (declspecs))
8301 /* Type specifiers. */
8304 declspecs = TYPE_MAIN_VARIANT (declspecs);
8306 /* Signed integer types. */
8308 if (declspecs == short_integer_type_node)
8309 strcat (buf, "short int ");
8310 else if (declspecs == integer_type_node)
8311 strcat (buf, "int ");
8312 else if (declspecs == long_integer_type_node)
8313 strcat (buf, "long int ");
8314 else if (declspecs == long_long_integer_type_node)
8315 strcat (buf, "long long int ");
8316 else if (declspecs == signed_char_type_node
8317 || declspecs == char_type_node)
8318 strcat (buf, "char ");
8320 /* Unsigned integer types. */
8322 else if (declspecs == short_unsigned_type_node)
8323 strcat (buf, "unsigned short ");
8324 else if (declspecs == unsigned_type_node)
8325 strcat (buf, "unsigned int ");
8326 else if (declspecs == long_unsigned_type_node)
8327 strcat (buf, "unsigned long ");
8328 else if (declspecs == long_long_unsigned_type_node)
8329 strcat (buf, "unsigned long long ");
8330 else if (declspecs == unsigned_char_type_node)
8331 strcat (buf, "unsigned char ");
8335 declspecs = TYPE_MAIN_VARIANT (declspecs);
8337 if (declspecs == float_type_node)
8338 strcat (buf, "float ");
8339 else if (declspecs == double_type_node)
8340 strcat (buf, "double ");
8341 else if (declspecs == long_double_type_node)
8342 strcat (buf, "long double ");
8346 if (OBJC_TYPE_NAME (declspecs)
8347 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8349 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8351 if (! TREE_STATIC_TEMPLATE (declspecs))
8352 strcat (buf, "struct ");
8353 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8357 tree chain = protocol_list;
8364 (PROTOCOL_NAME (TREE_VALUE (chain))));
8365 chain = TREE_CHAIN (chain);
8374 strcat (buf, "untagged struct");
8380 if (OBJC_TYPE_NAME (declspecs)
8381 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8383 strcat (buf, "union ");
8384 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8389 strcat (buf, "untagged union ");
8393 if (OBJC_TYPE_NAME (declspecs)
8394 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8396 strcat (buf, "enum ");
8397 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8402 strcat (buf, "untagged enum ");
8406 strcat (buf, "void ");
8411 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8416 tree chain = protocol_list;
8423 (PROTOCOL_NAME (TREE_VALUE (chain))));
8424 chain = TREE_CHAIN (chain);
8440 /* Given a tree node, produce a printable description of it in the given
8441 buffer, overwriting the buffer. */
8444 gen_declaration (tree atype_or_adecl, char *buf)
8447 gen_declaration_1 (atype_or_adecl, buf);
8451 /* Given a tree node, append a printable description to the end of the
8455 gen_declaration_1 (tree atype_or_adecl, char *buf)
8459 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8461 tree declspecs; /* "identifier_node", "record_type" */
8462 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8463 tree width = NULL_TREE; /* for bitfields */
8465 /* We have a "raw", abstract declarator (typename). */
8466 declarator = TREE_VALUE (atype_or_adecl);
8467 /* In the case of raw ivars, the declarator itself is a list,
8468 and contains bitfield widths. */
8469 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8471 width = TREE_VALUE (declarator);
8472 declarator = TREE_PURPOSE (declarator);
8474 declspecs = TREE_PURPOSE (atype_or_adecl);
8476 gen_declspecs (declspecs, buf, 1);
8480 strcat (buf, gen_declarator (declarator, declbuf, ""));
8483 sprintf (buf + strlen (buf), ": %lu", TREE_INT_CST_LOW (width));
8489 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8490 tree declarator; /* "array_type", "function_type", "pointer_type". */
8492 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8493 || TREE_CODE (atype_or_adecl) == PARM_DECL
8494 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8495 atype = TREE_TYPE (atype_or_adecl);
8497 /* Assume we have a *_type node. */
8498 atype = atype_or_adecl;
8500 if (is_complex_decl (atype))
8504 /* Get the declaration specifier; it is at the end of the list. */
8505 declarator = chain = atype;
8507 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8508 while (is_complex_decl (chain));
8515 declarator = NULL_TREE;
8518 gen_declspecs (declspecs, buf, 0);
8520 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8521 || TREE_CODE (atype_or_adecl) == PARM_DECL
8522 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8524 const char *const decl_name =
8525 (DECL_NAME (atype_or_adecl)
8526 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8531 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8534 else if (decl_name[0])
8537 strcat (buf, decl_name);
8540 else if (declarator)
8543 strcat (buf, gen_declarator (declarator, declbuf, ""));
8548 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8550 /* Given a method tree, put a printable description into the given
8551 buffer (overwriting) and return a pointer to the buffer. */
8554 gen_method_decl (tree method, char *buf)
8559 if (RAW_TYPESPEC (method) != objc_object_reference)
8562 gen_declaration_1 (TREE_TYPE (method), buf);
8566 chain = METHOD_SEL_ARGS (method);
8569 /* We have a chain of keyword_decls. */
8572 if (KEYWORD_KEY_NAME (chain))
8573 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8576 if (RAW_TYPESPEC (chain) != objc_object_reference)
8579 gen_declaration_1 (TREE_TYPE (chain), buf);
8583 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8584 if ((chain = TREE_CHAIN (chain)))
8589 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8590 strcat (buf, ", ...");
8591 else if (METHOD_ADD_ARGS (method))
8593 /* We have a tree list node as generate by get_parm_info. */
8594 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8596 /* Know we have a chain of parm_decls. */
8600 gen_declaration_1 (chain, buf);
8601 chain = TREE_CHAIN (chain);
8607 /* We have a unary selector. */
8608 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8616 /* Dump an @interface declaration of the supplied class CHAIN to the
8617 supplied file FP. Used to implement the -gen-decls option (which
8618 prints out an @interface declaration of all classes compiled in
8619 this run); potentially useful for debugging the compiler too. */
8621 dump_interface (FILE *fp, tree chain)
8623 /* FIXME: A heap overflow here whenever a method (or ivar)
8624 declaration is so long that it doesn't fit in the buffer. The
8625 code and all the related functions should be rewritten to avoid
8626 using fixed size buffers. */
8627 char *buf = (char *) xmalloc (1024 * 10);
8628 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8629 tree ivar_decls = CLASS_RAW_IVARS (chain);
8630 tree nst_methods = CLASS_NST_METHODS (chain);
8631 tree cls_methods = CLASS_CLS_METHODS (chain);
8633 fprintf (fp, "\n@interface %s", my_name);
8635 /* CLASS_SUPER_NAME is used to store the superclass name for
8636 classes, and the category name for categories. */
8637 if (CLASS_SUPER_NAME (chain))
8639 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8641 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8642 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8644 fprintf (fp, " (%s)\n", name);
8648 fprintf (fp, " : %s\n", name);
8654 /* FIXME - the following doesn't seem to work at the moment. */
8657 fprintf (fp, "{\n");
8660 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8661 ivar_decls = TREE_CHAIN (ivar_decls);
8664 fprintf (fp, "}\n");
8669 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8670 nst_methods = TREE_CHAIN (nst_methods);
8675 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8676 cls_methods = TREE_CHAIN (cls_methods);
8679 fprintf (fp, "@end\n");
8682 /* Demangle function for Objective-C */
8684 objc_demangle (const char *mangled)
8686 char *demangled, *cp;
8688 if (mangled[0] == '_' &&
8689 (mangled[1] == 'i' || mangled[1] == 'c') &&
8692 cp = demangled = xmalloc(strlen(mangled) + 2);
8693 if (mangled[1] == 'i')
8694 *cp++ = '-'; /* for instance method */
8696 *cp++ = '+'; /* for class method */
8697 *cp++ = '['; /* opening left brace */
8698 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8699 while (*cp && *cp == '_')
8700 cp++; /* skip any initial underbars in class name */
8701 cp = strchr(cp, '_'); /* find first non-initial underbar */
8704 free(demangled); /* not mangled name */
8707 if (cp[1] == '_') /* easy case: no category name */
8709 *cp++ = ' '; /* replace two '_' with one ' ' */
8710 strcpy(cp, mangled + (cp - demangled) + 2);
8714 *cp++ = '('; /* less easy case: category name */
8715 cp = strchr(cp, '_');
8718 free(demangled); /* not mangled name */
8722 *cp++ = ' '; /* overwriting 1st char of method name... */
8723 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8725 while (*cp && *cp == '_')
8726 cp++; /* skip any initial underbars in method name */
8729 *cp = ':'; /* replace remaining '_' with ':' */
8730 *cp++ = ']'; /* closing right brace */
8731 *cp++ = 0; /* string terminator */
8735 return mangled; /* not an objc mangled name */
8739 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8741 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8747 gcc_obstack_init (&util_obstack);
8748 util_firstobj = (char *) obstack_finish (&util_obstack);
8750 errbuf = (char *) xmalloc (BUFSIZE);
8752 synth_module_prologue ();
8758 struct imp_entry *impent;
8760 /* The internally generated initializers appear to have missing braces.
8761 Don't warn about this. */
8762 int save_warn_missing_braces = warn_missing_braces;
8763 warn_missing_braces = 0;
8765 /* A missing @end may not be detected by the parser. */
8766 if (objc_implementation_context)
8768 warning ("`@end' missing in implementation context");
8769 finish_class (objc_implementation_context);
8770 objc_ivar_chain = NULL_TREE;
8771 objc_implementation_context = NULL_TREE;
8774 generate_forward_declaration_to_string_table ();
8776 /* Process the static instances here because initialization of objc_symtab
8778 if (objc_static_instances)
8779 generate_static_references ();
8781 if (imp_list || class_names_chain
8782 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8783 generate_objc_symtab_decl ();
8785 for (impent = imp_list; impent; impent = impent->next)
8787 objc_implementation_context = impent->imp_context;
8788 implementation_template = impent->imp_template;
8790 UOBJC_CLASS_decl = impent->class_decl;
8791 UOBJC_METACLASS_decl = impent->meta_decl;
8793 /* Dump the @interface of each class as we compile it, if the
8794 -gen-decls option is in use. TODO: Dump the classes in the
8795 order they were found, rather than in reverse order as we
8797 if (flag_gen_declaration)
8799 dump_interface (gen_declaration_file, objc_implementation_context);
8802 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8804 /* all of the following reference the string pool... */
8805 generate_ivar_lists ();
8806 generate_dispatch_tables ();
8807 generate_shared_structures ();
8811 generate_dispatch_tables ();
8812 generate_category (objc_implementation_context);
8816 /* If we are using an array of selectors, we must always
8817 finish up the array decl even if no selectors were used. */
8818 if (! flag_next_runtime || sel_ref_chain)
8819 build_selector_translation_table ();
8822 generate_protocols ();
8824 if (flag_replace_objc_classes && imp_list)
8825 generate_objc_image_info ();
8827 if (objc_implementation_context || class_names_chain || objc_static_instances
8828 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8830 /* Arrange for ObjC data structures to be initialized at run time. */
8831 rtx init_sym = build_module_descriptor ();
8832 if (init_sym && targetm.have_ctors_dtors)
8833 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8836 /* Dump the class references. This forces the appropriate classes
8837 to be linked into the executable image, preserving unix archive
8838 semantics. This can be removed when we move to a more dynamically
8839 linked environment. */
8841 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8843 handle_class_ref (chain);
8844 if (TREE_PURPOSE (chain))
8845 generate_classref_translation_entry (chain);
8848 for (impent = imp_list; impent; impent = impent->next)
8849 handle_impent (impent);
8851 /* Dump the string table last. */
8853 generate_strings ();
8860 /* Run through the selector hash tables and print a warning for any
8861 selector which has multiple methods. */
8863 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8865 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8866 check_duplicates (hsh, 0);
8867 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8868 check_duplicates (hsh, 0);
8872 warn_missing_braces = save_warn_missing_braces;
8875 /* Subroutines of finish_objc. */
8878 generate_classref_translation_entry (tree chain)
8880 tree expr, name, decl_specs, decl, sc_spec;
8883 type = TREE_TYPE (TREE_PURPOSE (chain));
8885 expr = add_objc_string (TREE_VALUE (chain), class_names);
8886 expr = build_c_cast (type, expr); /* cast! */
8888 name = DECL_NAME (TREE_PURPOSE (chain));
8890 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8892 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8893 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8895 /* The decl that is returned from start_decl is the one that we
8896 forward declared in build_class_reference. */
8897 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8898 DECL_CONTEXT (decl) = NULL_TREE;
8899 finish_decl (decl, expr, NULL_TREE);
8904 handle_class_ref (tree chain)
8906 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8907 char *string = (char *) alloca (strlen (name) + 30);
8911 sprintf (string, "%sobjc_class_name_%s",
8912 (flag_next_runtime ? "." : "__"), name);
8914 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8915 if (flag_next_runtime)
8917 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8922 /* Make a decl for this name, so we can use its address in a tree. */
8923 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8924 DECL_EXTERNAL (decl) = 1;
8925 TREE_PUBLIC (decl) = 1;
8928 rest_of_decl_compilation (decl, 0, 0, 0);
8930 /* Make a decl for the address. */
8931 sprintf (string, "%sobjc_class_ref_%s",
8932 (flag_next_runtime ? "." : "__"), name);
8933 exp = build1 (ADDR_EXPR, string_type_node, decl);
8934 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8935 DECL_INITIAL (decl) = exp;
8936 TREE_STATIC (decl) = 1;
8937 TREE_USED (decl) = 1;
8940 rest_of_decl_compilation (decl, 0, 0, 0);
8944 handle_impent (struct imp_entry *impent)
8948 objc_implementation_context = impent->imp_context;
8949 implementation_template = impent->imp_template;
8951 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8953 const char *const class_name =
8954 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8956 string = (char *) alloca (strlen (class_name) + 30);
8958 sprintf (string, "%sobjc_class_name_%s",
8959 (flag_next_runtime ? "." : "__"), class_name);
8961 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8963 const char *const class_name =
8964 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8965 const char *const class_super_name =
8966 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8968 string = (char *) alloca (strlen (class_name)
8969 + strlen (class_super_name) + 30);
8971 /* Do the same for categories. Even though no references to
8972 these symbols are generated automatically by the compiler, it
8973 gives you a handle to pull them into an archive by hand. */
8974 sprintf (string, "*%sobjc_category_name_%s_%s",
8975 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8980 #ifdef ASM_DECLARE_CLASS_REFERENCE
8981 if (flag_next_runtime)
8983 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8991 init = build_int_2 (0, 0);
8992 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
8993 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8994 TREE_PUBLIC (decl) = 1;
8995 TREE_READONLY (decl) = 1;
8996 TREE_USED (decl) = 1;
8997 TREE_CONSTANT (decl) = 1;
8998 DECL_CONTEXT (decl) = 0;
8999 DECL_ARTIFICIAL (decl) = 1;
9000 DECL_INITIAL (decl) = init;
9001 assemble_variable (decl, 1, 0, 0);
9005 /* The Fix-and-Countinue functionality available in Mac OS X 10.3 and
9006 later requires that ObjC translation units participating in F&C be
9007 specially marked. The following routine accomplishes this. */
9009 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9012 generate_objc_image_info (void)
9014 tree sc_spec, decl, initlist;
9016 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9018 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9019 tree_cons (NULL_TREE,
9022 build_index_type (build_int_2 (1, 0))),
9027 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9028 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9029 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9031 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9032 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9033 finish_decl (decl, initlist, NULL_TREE);
9036 /* Look up ID as an instance variable. */
9039 lookup_objc_ivar (tree id)
9043 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9044 /* We have a message to super. */
9045 return get_super_receiver ();
9046 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9048 if (is_private (decl))
9049 return error_mark_node;
9051 return build_ivar_reference (id);
9057 #include "gt-objc-objc-act.h"
9058 #include "gtype-objc.h"