1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
53 #include "langhooks.h"
64 #include "diagnostic.h"
67 /* This is the default way of generating a method name. */
68 /* I am not sure it is really correct.
69 Perhaps there's a danger that it will make name conflicts
70 if method names contain underscores. -- rms. */
71 #ifndef OBJC_GEN_METHOD_LABEL
72 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
75 sprintf ((BUF), "_%s_%s_%s_%s", \
76 ((IS_INST) ? "i" : "c"), \
78 ((CAT_NAME)? (CAT_NAME) : ""), \
80 for (temp = (BUF); *temp; temp++) \
81 if (*temp == ':') *temp = '_'; \
85 /* These need specifying. */
86 #ifndef OBJC_FORWARDING_STACK_OFFSET
87 #define OBJC_FORWARDING_STACK_OFFSET 0
90 #ifndef OBJC_FORWARDING_MIN_OFFSET
91 #define OBJC_FORWARDING_MIN_OFFSET 0
94 /* Set up for use of obstacks. */
98 /* This obstack is used to accumulate the encoding of a data type. */
99 static struct obstack util_obstack;
101 /* This points to the beginning of obstack contents, so we can free
102 the whole contents. */
105 /* The version identifies which language generation and runtime
106 the module (file) was compiled for, and is recorded in the
107 module descriptor. */
109 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
110 #define PROTOCOL_VERSION 2
112 /* (Decide if these can ever be validly changed.) */
113 #define OBJC_ENCODE_INLINE_DEFS 0
114 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
116 /*** Private Interface (procedures) ***/
118 /* Used by compile_file. */
120 static void init_objc (void);
121 static void finish_objc (void);
123 /* Code generation. */
125 static void synth_module_prologue (void);
126 static tree objc_build_constructor (tree, tree);
127 static rtx build_module_descriptor (void);
128 static tree init_module_descriptor (tree);
129 static tree build_objc_method_call (int, tree, tree, tree, tree);
130 static void generate_strings (void);
131 static tree get_proto_encoding (tree);
132 static void build_selector_translation_table (void);
134 static tree objc_add_static_instance (tree, tree);
136 static void build_objc_exception_stuff (void);
137 static tree objc_declare_variable (enum rid, tree, tree, tree);
138 static tree objc_enter_block (void);
139 static tree objc_exit_block (void);
140 static void objc_build_try_enter_fragment (void);
141 static void objc_build_try_exit_fragment (void);
142 static void objc_build_extract_fragment (void);
143 static tree objc_build_extract_expr (void);
145 static tree build_ivar_template (void);
146 static tree build_method_template (void);
147 static tree build_private_template (tree);
148 static void build_class_template (void);
149 static void build_selector_template (void);
150 static void build_category_template (void);
151 static tree lookup_method_in_hash_lists (tree, int);
152 static void build_super_template (void);
153 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
154 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
155 static void synth_forward_declarations (void);
156 static int ivar_list_length (tree);
157 static tree get_class_ivars (tree, int);
158 static void generate_ivar_lists (void);
159 static void generate_dispatch_tables (void);
160 static void generate_shared_structures (void);
161 static tree generate_protocol_list (tree);
162 static void build_protocol_reference (tree);
164 static tree build_keyword_selector (tree);
165 static tree synth_id_with_class_suffix (const char *, tree);
167 static void generate_static_references (void);
168 static int check_methods_accessible (tree, tree, int);
169 static void encode_aggregate_within (tree, int, int, int, int);
170 static const char *objc_demangle (const char *);
171 static void objc_expand_function_end (void);
173 /* Hash tables to manage the global pool of method prototypes. */
175 hash *nst_method_hash_list = 0;
176 hash *cls_method_hash_list = 0;
178 static size_t hash_func (tree);
179 static void hash_init (void);
180 static void hash_enter (hash *, tree);
181 static hash hash_lookup (hash *, tree);
182 static void hash_add_attr (hash, tree);
183 static tree lookup_method (tree, tree);
184 static tree lookup_method_static (tree, tree, int);
185 static void add_method_to_hash_list (hash *, tree);
186 static tree add_class (tree);
187 static void add_category (tree, tree);
188 static inline tree lookup_category (tree, tree);
192 class_names, /* class, category, protocol, module names */
193 meth_var_names, /* method and variable names */
194 meth_var_types /* method and variable type descriptors */
197 static tree add_objc_string (tree, enum string_section);
198 static tree get_objc_string_decl (tree, enum string_section);
199 static tree build_objc_string_decl (enum string_section);
200 static tree build_selector_reference_decl (void);
202 /* Protocol additions. */
204 static tree add_protocol (tree);
205 static tree lookup_protocol (tree);
206 static void check_protocol_recursively (tree, tree);
207 static tree lookup_and_install_protocols (tree);
211 static void encode_type_qualifiers (tree);
212 static void encode_pointer (tree, int, int);
213 static void encode_array (tree, int, int);
214 static void encode_aggregate (tree, int, int);
215 static void encode_next_bitfield (int);
216 static void encode_gnu_bitfield (int, tree, int);
217 static void encode_type (tree, int, int);
218 static void encode_field_decl (tree, int, int);
220 static void really_start_method (tree, tree);
221 static int comp_method_with_proto (tree, tree);
222 static int objc_types_are_equivalent (tree, tree);
223 static int comp_proto_with_proto (tree, tree);
224 static tree get_arg_type_list (tree, int, int);
225 static tree objc_expr_last (tree);
226 static void synth_self_and_ucmd_args (void);
228 /* Utilities for debugging and error diagnostics. */
230 static void warn_with_method (const char *, int, tree);
231 static void error_with_ivar (const char *, tree, tree);
232 static char *gen_method_decl (tree, char *);
233 static char *gen_declaration (tree, char *);
234 static void gen_declaration_1 (tree, char *);
235 static char *gen_declarator (tree, char *, const char *);
236 static int is_complex_decl (tree);
237 static void adorn_decl (tree, char *);
238 static void dump_interface (FILE *, tree);
240 /* Everything else. */
242 static tree define_decl (tree, tree);
243 static tree lookup_method_in_protocol_list (tree, tree, int);
244 static tree lookup_protocol_in_reflist (tree, tree);
245 static tree create_builtin_decl (enum tree_code, tree, const char *);
246 static void setup_string_decl (void);
247 static int check_string_class_template (void);
248 static tree my_build_string (int, const char *);
249 static void build_objc_symtab_template (void);
250 static tree init_def_list (tree);
251 static tree init_objc_symtab (tree);
252 static tree build_metadata_decl (const char *, tree);
253 static void forward_declare_categories (void);
254 static void generate_objc_symtab_decl (void);
255 static tree build_selector (tree);
256 static tree build_typed_selector_reference (tree, tree);
257 static tree build_selector_reference (tree);
258 static tree build_class_reference_decl (void);
259 static void add_class_reference (tree);
260 static tree build_protocol_template (void);
261 static tree build_descriptor_table_initializer (tree, tree);
262 static tree build_method_prototype_list_template (tree, int);
263 static tree build_method_prototype_template (void);
264 static tree objc_method_parm_type (tree);
265 static int objc_encoded_type_size (tree);
266 static tree encode_method_prototype (tree);
267 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
268 static void generate_method_descriptors (tree);
269 static void generate_protocol_references (tree);
270 static void generate_protocols (void);
271 static void check_ivars (tree, tree);
272 static tree build_ivar_list_template (tree, int);
273 static tree build_method_list_template (tree, int);
274 static tree build_ivar_list_initializer (tree, tree);
275 static tree generate_ivars_list (tree, const char *, int, tree);
276 static tree build_dispatch_table_initializer (tree, tree);
277 static tree generate_dispatch_table (tree, const char *, int, tree);
278 static tree build_shared_structure_initializer (tree, tree, tree, tree,
279 tree, int, tree, tree, tree);
280 static void generate_category (tree);
281 static int is_objc_type_qualifier (tree);
282 static tree adjust_type_for_id_default (tree);
283 static tree check_duplicates (hash, int, int);
284 static tree receiver_is_class_object (tree, int, int);
285 static int check_methods (tree, tree, int);
286 static int conforms_to_protocol (tree, tree);
287 static void check_protocol (tree, const char *, const char *);
288 static void check_protocols (tree, const char *, const char *);
289 static void gen_declspecs (tree, char *, int);
290 static void generate_classref_translation_entry (tree);
291 static void handle_class_ref (tree);
292 static void generate_struct_by_value_array (void)
294 static void mark_referenced_methods (void);
295 static void generate_objc_image_info (void);
297 /*** Private Interface (data) ***/
299 /* Reserved tag definitions. */
302 #define TAG_OBJECT "objc_object"
303 #define TAG_CLASS "objc_class"
304 #define TAG_SUPER "objc_super"
305 #define TAG_SELECTOR "objc_selector"
307 #define UTAG_CLASS "_objc_class"
308 #define UTAG_IVAR "_objc_ivar"
309 #define UTAG_IVAR_LIST "_objc_ivar_list"
310 #define UTAG_METHOD "_objc_method"
311 #define UTAG_METHOD_LIST "_objc_method_list"
312 #define UTAG_CATEGORY "_objc_category"
313 #define UTAG_MODULE "_objc_module"
314 #define UTAG_SYMTAB "_objc_symtab"
315 #define UTAG_SUPER "_objc_super"
316 #define UTAG_SELECTOR "_objc_selector"
318 #define UTAG_PROTOCOL "_objc_protocol"
319 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
320 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
322 /* Note that the string object global name is only needed for the
324 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
326 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
328 static const char *TAG_GETCLASS;
329 static const char *TAG_GETMETACLASS;
330 static const char *TAG_MSGSEND;
331 static const char *TAG_MSGSENDSUPER;
332 /* The NeXT Objective-C messenger may have two extra entry points, for use
333 when returning a structure. */
334 static const char *TAG_MSGSEND_STRET;
335 static const char *TAG_MSGSENDSUPER_STRET;
336 static const char *TAG_EXECCLASS;
337 static const char *default_constant_string_class_name;
339 /* Runtime metadata flags. */
340 #define CLS_FACTORY 0x0001L
341 #define CLS_META 0x0002L
343 #define OBJC_MODIFIER_STATIC 0x00000001
344 #define OBJC_MODIFIER_FINAL 0x00000002
345 #define OBJC_MODIFIER_PUBLIC 0x00000004
346 #define OBJC_MODIFIER_PRIVATE 0x00000008
347 #define OBJC_MODIFIER_PROTECTED 0x00000010
348 #define OBJC_MODIFIER_NATIVE 0x00000020
349 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
350 #define OBJC_MODIFIER_ABSTRACT 0x00000080
351 #define OBJC_MODIFIER_VOLATILE 0x00000100
352 #define OBJC_MODIFIER_TRANSIENT 0x00000200
353 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
355 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
356 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
357 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
358 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
359 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
360 #define TAG_EXCEPTIONMATCH "objc_exception_match"
361 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
362 #define TAG_SYNCENTER "objc_sync_enter"
363 #define TAG_SYNCEXIT "objc_sync_exit"
364 #define TAG_SETJMP "_setjmp"
365 #define TAG_RETURN_STRUCT "objc_return_struct"
367 #define UTAG_EXCDATA "_objc_exception_data"
368 #define UTAG_EXCDATA_VAR "_stackExceptionData"
369 #define UTAG_CAUGHTEXC_VAR "_caughtException"
370 #define UTAG_RETHROWEXC_VAR "_rethrowException"
371 #define UTAG_EVALONCE_VAR "_eval_once"
375 struct val_stack *next;
377 static struct val_stack *catch_count_stack, *exc_binding_stack;
379 /* useful for debugging */
380 static int if_nesting_count;
381 static int blk_nesting_count;
383 static void val_stack_push (struct val_stack **, long);
384 static void val_stack_pop (struct val_stack **);
386 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
387 tree objc_global_trees[OCTI_MAX];
389 static void handle_impent (struct imp_entry *);
391 struct imp_entry *imp_list = 0;
392 int imp_count = 0; /* `@implementation' */
393 int cat_count = 0; /* `@category' */
395 /* Use to generate method labels. */
396 static int method_slot = 0;
400 static char *errbuf; /* Buffer for error diagnostics */
402 /* Data imported from tree.c. */
404 extern enum debug_info_type write_symbols;
406 /* Data imported from toplev.c. */
408 extern const char *dump_base_name;
410 static int flag_typed_selectors;
412 FILE *gen_declaration_file;
414 /* Tells "encode_pointer/encode_aggregate" whether we are generating
415 type descriptors for instance variables (as opposed to methods).
416 Type descriptors for instance variables contain more information
417 than methods (for static typing and embedded structures). */
419 static int generating_instance_variables = 0;
421 /* Some platforms pass small structures through registers versus
422 through an invisible pointer. Determine at what size structure is
423 the transition point between the two possibilities. */
426 generate_struct_by_value_array (void)
429 tree field_decl, field_decl_chain;
431 int aggregate_in_mem[32];
434 /* Presumably no platform passes 32 byte structures in a register. */
435 for (i = 1; i < 32; i++)
439 /* Create an unnamed struct that has `i' character components */
440 type = start_struct (RECORD_TYPE, NULL_TREE);
442 strcpy (buffer, "c1");
443 field_decl = create_builtin_decl (FIELD_DECL,
446 field_decl_chain = field_decl;
448 for (j = 1; j < i; j++)
450 sprintf (buffer, "c%d", j + 1);
451 field_decl = create_builtin_decl (FIELD_DECL,
454 chainon (field_decl_chain, field_decl);
456 finish_struct (type, field_decl_chain, NULL_TREE);
458 aggregate_in_mem[i] = aggregate_value_p (type, 0);
459 if (!aggregate_in_mem[i])
463 /* We found some structures that are returned in registers instead of memory
464 so output the necessary data. */
467 for (i = 31; i >= 0; i--)
468 if (!aggregate_in_mem[i])
470 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
472 /* The first member of the structure is always 0 because we don't handle
473 structures with 0 members */
474 printf ("static int struct_forward_array[] = {\n 0");
476 for (j = 1; j <= i; j++)
477 printf (", %d", aggregate_in_mem[j]);
487 if (c_objc_common_init () == false)
490 /* Force the line number back to 0; check_newline will have
491 raised it to 1, which will make the builtin functions appear
492 not to be built in. */
495 /* If gen_declaration desired, open the output file. */
496 if (flag_gen_declaration)
498 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
499 gen_declaration_file = fopen (dumpname, "w");
500 if (gen_declaration_file == 0)
501 fatal_error ("can't open %s: %m", dumpname);
505 if (flag_next_runtime)
507 TAG_GETCLASS = "objc_getClass";
508 TAG_GETMETACLASS = "objc_getMetaClass";
509 TAG_MSGSEND = "objc_msgSend";
510 TAG_MSGSENDSUPER = "objc_msgSendSuper";
511 TAG_MSGSEND_STRET = "objc_msgSend_stret";
512 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
513 TAG_EXECCLASS = "__objc_execClass";
514 default_constant_string_class_name = "NSConstantString";
518 TAG_GETCLASS = "objc_get_class";
519 TAG_GETMETACLASS = "objc_get_meta_class";
520 TAG_MSGSEND = "objc_msg_lookup";
521 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
522 /* GNU runtime does not provide special functions to support
523 structure-returning methods. */
524 TAG_EXECCLASS = "__objc_exec_class";
525 default_constant_string_class_name = "NXConstantString";
526 flag_typed_selectors = 1;
529 objc_ellipsis_node = make_node (ERROR_MARK);
533 if (print_struct_values)
534 generate_struct_by_value_array ();
542 mark_referenced_methods ();
543 c_objc_common_finish_file ();
545 /* Finalize Objective-C runtime data. No need to generate tables
546 and code if only checking syntax. */
547 if (!flag_syntax_only)
550 if (gen_declaration_file)
551 fclose (gen_declaration_file);
555 define_decl (tree declarator, tree declspecs)
557 tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
558 finish_decl (decl, NULL_TREE, NULL_TREE);
563 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
569 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
571 p = TREE_VALUE (rproto);
573 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
575 if ((fnd = lookup_method (class_meth
576 ? PROTOCOL_CLS_METHODS (p)
577 : PROTOCOL_NST_METHODS (p), sel_name)))
579 else if (PROTOCOL_LIST (p))
580 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
581 sel_name, class_meth);
585 ; /* An identifier...if we could not find a protocol. */
596 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
600 /* Make sure the protocol is supported by the object on the rhs. */
601 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
604 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
606 p = TREE_VALUE (rproto);
608 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
613 else if (PROTOCOL_LIST (p))
614 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
623 ; /* An identifier...if we could not find a protocol. */
629 /* Return 1 if LHS and RHS are compatible types for assignment or
630 various other operations. Return 0 if they are incompatible, and
631 return -1 if we choose to not decide (because the types are really
632 just C types, not ObjC specific ones). When the operation is
633 REFLEXIVE (typically comparisons), check for compatibility in
634 either direction; when it's not (typically assignments), don't.
636 This function is called in two cases: when both lhs and rhs are
637 pointers to records (in which case we check protocols too), and
638 when both lhs and rhs are records (in which case we check class
641 Warnings about classes/protocols not implementing a protocol are
642 emitted here (multiple of those warnings might be emitted for a
643 single line!); generic warnings about incompatible assignments and
644 lacks of casts in comparisons are/must be emitted by the caller if
649 objc_comptypes (tree lhs, tree rhs, int reflexive)
651 /* New clause for protocols. */
653 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
654 manage the ObjC ones, and leave the rest to the C code. */
655 if (TREE_CODE (lhs) == POINTER_TYPE
656 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
657 && TREE_CODE (rhs) == POINTER_TYPE
658 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
660 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
661 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
665 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
666 tree rproto, rproto_list;
669 /* <Protocol> = <Protocol> */
672 rproto_list = TYPE_PROTOCOL_LIST (rhs);
676 /* An assignment between objects of type 'id
677 <Protocol>'; make sure the protocol on the lhs is
678 supported by the object on the rhs. */
679 for (lproto = lproto_list; lproto;
680 lproto = TREE_CHAIN (lproto))
682 p = TREE_VALUE (lproto);
683 rproto = lookup_protocol_in_reflist (rproto_list, p);
687 ("object does not conform to the `%s' protocol",
688 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
694 /* Obscure case - a comparison between two objects
695 of type 'id <Protocol>'. Check that either the
696 protocol on the lhs is supported by the object on
697 the rhs, or viceversa. */
699 /* Check if the protocol on the lhs is supported by the
700 object on the rhs. */
701 for (lproto = lproto_list; lproto;
702 lproto = TREE_CHAIN (lproto))
704 p = TREE_VALUE (lproto);
705 rproto = lookup_protocol_in_reflist (rproto_list, p);
709 /* Check failed - check if the protocol on the rhs
710 is supported by the object on the lhs. */
711 for (rproto = rproto_list; rproto;
712 rproto = TREE_CHAIN (rproto))
714 p = TREE_VALUE (rproto);
715 lproto = lookup_protocol_in_reflist (lproto_list,
720 /* This check failed too: incompatible */
730 /* <Protocol> = <class> * */
731 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
733 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
736 /* Make sure the protocol is supported by the object on
738 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
740 p = TREE_VALUE (lproto);
742 rinter = lookup_interface (rname);
744 while (rinter && !rproto)
748 rproto_list = CLASS_PROTOCOL_LIST (rinter);
749 rproto = lookup_protocol_in_reflist (rproto_list, p);
750 /* If the underlying ObjC class does not have
751 the protocol we're looking for, check for "one-off"
752 protocols (e.g., `NSObject<MyProt> *foo;') attached
756 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
757 rproto = lookup_protocol_in_reflist (rproto_list, p);
760 /* Check for protocols adopted by categories. */
761 cat = CLASS_CATEGORY_LIST (rinter);
762 while (cat && !rproto)
764 rproto_list = CLASS_PROTOCOL_LIST (cat);
765 rproto = lookup_protocol_in_reflist (rproto_list, p);
766 cat = CLASS_CATEGORY_LIST (cat);
769 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
773 warning ("class `%s' does not implement the `%s' protocol",
774 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
775 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
779 /* <Protocol> = id */
780 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
784 /* <Protocol> = Class */
785 else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
789 /* <Protocol> = ?? : let comptypes decide. */
792 else if (rhs_is_proto)
794 /* <class> * = <Protocol> */
795 if (TYPED_OBJECT (TREE_TYPE (lhs)))
799 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
801 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
803 /* Make sure the protocol is supported by the object on
805 for (rproto = rproto_list; rproto;
806 rproto = TREE_CHAIN (rproto))
808 tree p = TREE_VALUE (rproto);
810 rinter = lookup_interface (rname);
812 while (rinter && !lproto)
816 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
817 lproto = lookup_protocol_in_reflist (lproto_list, p);
818 /* If the underlying ObjC class does not
819 have the protocol we're looking for,
820 check for "one-off" protocols (e.g.,
821 `NSObject<MyProt> *foo;') attached to the
825 lproto_list = TYPE_PROTOCOL_LIST
827 lproto = lookup_protocol_in_reflist
831 /* Check for protocols adopted by categories. */
832 cat = CLASS_CATEGORY_LIST (rinter);
833 while (cat && !lproto)
835 lproto_list = CLASS_PROTOCOL_LIST (cat);
836 lproto = lookup_protocol_in_reflist (lproto_list,
838 cat = CLASS_CATEGORY_LIST (cat);
841 rinter = lookup_interface (CLASS_SUPER_NAME
846 warning ("class `%s' does not implement the `%s' protocol",
847 IDENTIFIER_POINTER (OBJC_TYPE_NAME
849 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
856 /* id = <Protocol> */
857 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
861 /* Class = <Protocol> */
862 else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
866 /* ??? = <Protocol> : let comptypes decide */
874 /* Attention: we shouldn't defer to comptypes here. One bad
875 side effect would be that we might loose the REFLEXIVE
878 lhs = TREE_TYPE (lhs);
879 rhs = TREE_TYPE (rhs);
883 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
885 /* Nothing to do with ObjC - let immediately comptypes take
886 responsibility for checking. */
890 /* `id' = `<class> *' `<class> *' = `id': always allow it.
892 'Object *o = [[Object alloc] init]; falls
893 in the case <class> * = `id'.
895 if ((OBJC_TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
896 || (OBJC_TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
899 /* `id' = `Class', `Class' = `id' */
901 else if ((OBJC_TYPE_NAME (lhs) == objc_object_id
902 && OBJC_TYPE_NAME (rhs) == objc_class_id)
903 || (OBJC_TYPE_NAME (lhs) == objc_class_id
904 && OBJC_TYPE_NAME (rhs) == objc_object_id))
907 /* `Class' != `<class> *' && `<class> *' != `Class'! */
908 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
909 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
912 /* `<class> *' = `<class> *' */
914 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
916 tree lname = OBJC_TYPE_NAME (lhs);
917 tree rname = OBJC_TYPE_NAME (rhs);
923 /* If the left hand side is a super class of the right hand side,
925 for (inter = lookup_interface (rname); inter;
926 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
927 if (lname == CLASS_SUPER_NAME (inter))
930 /* Allow the reverse when reflexive. */
932 for (inter = lookup_interface (lname); inter;
933 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
934 if (rname == CLASS_SUPER_NAME (inter))
940 /* Not an ObjC type - let comptypes do the check. */
944 /* Called from finish_decl. */
947 objc_check_decl (tree decl)
949 tree type = TREE_TYPE (decl);
951 if (TREE_CODE (type) != RECORD_TYPE)
953 if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
954 error ("statically allocated instance of Objective-C class `%s'",
955 IDENTIFIER_POINTER (type));
958 /* Implement static typing. At this point, we know we have an interface. */
961 get_static_reference (tree interface, tree protocols)
963 tree type = xref_tag (RECORD_TYPE, interface);
967 tree t, m = TYPE_MAIN_VARIANT (type);
969 t = copy_node (type);
971 /* Add this type to the chain of variants of TYPE. */
972 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
973 TYPE_NEXT_VARIANT (m) = t;
975 /* Look up protocols and install in lang specific list. Note
976 that the protocol list can have a different lifetime than T! */
977 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
979 /* This forces a new pointer type to be created later
980 (in build_pointer_type)...so that the new template
981 we just created will actually be used...what a hack! */
982 if (TYPE_POINTER_TO (t))
983 TYPE_POINTER_TO (t) = NULL_TREE;
992 get_object_reference (tree protocols)
994 tree type_decl = lookup_name (objc_id_id);
997 if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
999 type = TREE_TYPE (type_decl);
1000 if (TYPE_MAIN_VARIANT (type) != id_type)
1001 warning ("unexpected type for `id' (%s)",
1002 gen_declaration (type, errbuf));
1006 error ("undefined type `id', please import <objc/objc.h>");
1007 return error_mark_node;
1010 /* This clause creates a new pointer type that is qualified with
1011 the protocol specification...this info is used later to do more
1012 elaborate type checking. */
1016 tree t, m = TYPE_MAIN_VARIANT (type);
1018 t = copy_node (type);
1020 /* Add this type to the chain of variants of TYPE. */
1021 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
1022 TYPE_NEXT_VARIANT (m) = t;
1024 /* Look up protocols...and install in lang specific list */
1025 SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
1027 /* This forces a new pointer type to be created later
1028 (in build_pointer_type)...so that the new template
1029 we just created will actually be used...what a hack! */
1030 if (TYPE_POINTER_TO (t))
1031 TYPE_POINTER_TO (t) = NULL_TREE;
1038 /* Check for circular dependencies in protocols. The arguments are
1039 PROTO, the protocol to check, and LIST, a list of protocol it
1043 check_protocol_recursively (tree proto, tree list)
1047 for (p = list; p; p = TREE_CHAIN (p))
1049 tree pp = TREE_VALUE (p);
1051 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1052 pp = lookup_protocol (pp);
1055 fatal_error ("protocol `%s' has circular dependency",
1056 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1058 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1062 /* Look up PROTOCOLS, and return a list of those that are found.
1063 If none are found, return NULL. */
1066 lookup_and_install_protocols (tree protocols)
1069 tree return_value = NULL_TREE;
1071 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1073 tree ident = TREE_VALUE (proto);
1074 tree p = lookup_protocol (ident);
1077 error ("cannot find protocol declaration for `%s'",
1078 IDENTIFIER_POINTER (ident));
1080 return_value = chainon (return_value,
1081 build_tree_list (NULL_TREE, p));
1084 return return_value;
1087 /* Create and push a decl for a built-in external variable or field NAME.
1089 TYPE is its data type. */
1092 create_builtin_decl (enum tree_code code, tree type, const char *name)
1094 tree decl = build_decl (code, get_identifier (name), type);
1096 if (code == VAR_DECL)
1098 TREE_STATIC (decl) = 1;
1099 make_decl_rtl (decl, 0);
1101 DECL_ARTIFICIAL (decl) = 1;
1107 /* Find the decl for the constant string class. */
1110 setup_string_decl (void)
1112 if (!string_class_decl)
1114 if (!constant_string_global_id)
1118 /* %s in format will provide room for terminating null */
1119 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1120 + strlen (constant_string_class_name);
1121 name = xmalloc (length);
1122 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1123 constant_string_class_name);
1124 constant_string_global_id = get_identifier (name);
1126 string_class_decl = lookup_name (constant_string_global_id);
1130 /* Purpose: "play" parser, creating/installing representations
1131 of the declarations that are required by Objective-C.
1135 type_spec--------->sc_spec
1136 (tree_list) (tree_list)
1139 identifier_node identifier_node */
1142 synth_module_prologue (void)
1146 /* Defined in `objc.h' */
1147 objc_object_id = get_identifier (TAG_OBJECT);
1149 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1151 id_type = build_pointer_type (objc_object_reference);
1153 objc_id_id = get_identifier (TYPE_ID);
1154 objc_class_id = get_identifier (TAG_CLASS);
1156 objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
1157 temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1158 objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
1159 protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1162 /* Declare type of selector-objects that represent an operation name. */
1164 if (flag_next_runtime)
1165 /* `struct objc_selector *' */
1167 = build_pointer_type (xref_tag (RECORD_TYPE,
1168 get_identifier (TAG_SELECTOR)));
1170 /* `const struct objc_selector *' */
1172 = build_pointer_type
1173 (build_qualified_type (xref_tag (RECORD_TYPE,
1174 get_identifier (TAG_SELECTOR)),
1177 /* Declare receiver type used for dispatching messages to 'super'. */
1179 /* `struct objc_super *' */
1180 super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1181 get_identifier (TAG_SUPER)));
1183 if (flag_next_runtime)
1185 /* NB: In order to call one of the ..._stret (struct-returning)
1186 functions, the function *MUST* first be cast to a signature that
1187 corresponds to the actual ObjC method being invoked. This is
1188 what is done by the build_objc_method_call() routine below. */
1190 /* id objc_msgSend (id, SEL, ...); */
1191 /* id objc_msgSendNonNil (id, SEL, ...); */
1192 /* id objc_msgSend_stret (id, SEL, ...); */
1193 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1195 = build_function_type (id_type,
1196 tree_cons (NULL_TREE, id_type,
1197 tree_cons (NULL_TREE, selector_type,
1199 umsg_decl = builtin_function (TAG_MSGSEND,
1200 temp_type, 0, NOT_BUILT_IN,
1202 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1203 temp_type, 0, NOT_BUILT_IN,
1205 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1206 temp_type, 0, NOT_BUILT_IN,
1208 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1209 temp_type, 0, NOT_BUILT_IN,
1212 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1213 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1215 = build_function_type (id_type,
1216 tree_cons (NULL_TREE, super_type,
1217 tree_cons (NULL_TREE, selector_type,
1219 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1220 temp_type, 0, NOT_BUILT_IN,
1222 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1223 temp_type, 0, NOT_BUILT_IN, 0,
1228 /* GNU runtime messenger entry points. */
1230 /* typedef id (*IMP)(id, SEL, ...); */
1232 = build_pointer_type
1233 (build_function_type (id_type,
1234 tree_cons (NULL_TREE, id_type,
1235 tree_cons (NULL_TREE, selector_type,
1238 /* IMP objc_msg_lookup (id, SEL); */
1240 = build_function_type (IMP_type,
1241 tree_cons (NULL_TREE, id_type,
1242 tree_cons (NULL_TREE, selector_type,
1244 umsg_decl = builtin_function (TAG_MSGSEND,
1245 temp_type, 0, NOT_BUILT_IN,
1248 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1250 = build_function_type (IMP_type,
1251 tree_cons (NULL_TREE, super_type,
1252 tree_cons (NULL_TREE, selector_type,
1254 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1255 temp_type, 0, NOT_BUILT_IN,
1259 /* id objc_getClass (const char *); */
1261 temp_type = build_function_type (id_type,
1262 tree_cons (NULL_TREE,
1263 const_string_type_node,
1267 = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
1270 /* id objc_getMetaClass (const char *); */
1272 objc_get_meta_class_decl
1273 = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1275 build_super_template ();
1276 if (flag_next_runtime)
1277 build_objc_exception_stuff ();
1279 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1281 if (! flag_next_runtime)
1283 if (flag_typed_selectors)
1285 /* Suppress outputting debug symbols, because
1286 dbxout_init hasn'r been called yet. */
1287 enum debug_info_type save_write_symbols = write_symbols;
1288 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1289 write_symbols = NO_DEBUG;
1290 debug_hooks = &do_nothing_debug_hooks;
1292 build_selector_template ();
1293 temp_type = build_array_type (objc_selector_template, NULL_TREE);
1295 write_symbols = save_write_symbols;
1296 debug_hooks = save_hooks;
1299 temp_type = build_array_type (selector_type, NULL_TREE);
1301 layout_type (temp_type);
1302 UOBJC_SELECTOR_TABLE_decl
1303 = create_builtin_decl (VAR_DECL, temp_type,
1304 "_OBJC_SELECTOR_TABLE");
1306 /* Avoid warning when not sending messages. */
1307 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
1310 /* Forward declare constant_string_id and constant_string_type. */
1311 if (!constant_string_class_name)
1312 constant_string_class_name = default_constant_string_class_name;
1314 constant_string_id = get_identifier (constant_string_class_name);
1315 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1317 /* Pre-build the following entities - for speed/convenience. */
1318 self_id = get_identifier ("self");
1319 ucmd_id = get_identifier ("_cmd");
1321 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1322 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1326 /* Ensure that the ivar list for NSConstantString/NXConstantString
1327 (or whatever was specified via `-fconstant-string-class')
1328 contains fields at least as large as the following three, so that
1329 the runtime can stomp on them with confidence:
1331 struct STRING_OBJECT_CLASS_NAME
1335 unsigned int length;
1339 check_string_class_template (void)
1341 tree field_decl = TYPE_FIELDS (constant_string_type);
1343 #define AT_LEAST_AS_LARGE_AS(F, T) \
1344 (F && TREE_CODE (F) == FIELD_DECL \
1345 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1346 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1348 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1351 field_decl = TREE_CHAIN (field_decl);
1352 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1355 field_decl = TREE_CHAIN (field_decl);
1356 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1358 #undef AT_LEAST_AS_LARGE_AS
1361 /* Avoid calling `check_string_class_template ()' more than once. */
1362 static GTY(()) int string_layout_checked;
1364 /* Custom build_string which sets TREE_TYPE! */
1367 my_build_string (int len, const char *str)
1369 return fix_string_type (build_string (len, str));
1372 /* Given a chain of STRING_CST's, build a static instance of
1373 NXConstantString which points at the concatenation of those
1374 strings. We place the string object in the __string_objects
1375 section of the __OBJC segment. The Objective-C runtime will
1376 initialize the isa pointers of the string objects to point at the
1377 NXConstantString class object. */
1380 build_objc_string_object (tree string)
1382 tree initlist, constructor, constant_string_class;
1385 string = fix_string_type (string);
1387 constant_string_class = lookup_interface (constant_string_id);
1388 if (!constant_string_class
1389 || !(constant_string_type
1390 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1392 error ("cannot find interface declaration for `%s'",
1393 IDENTIFIER_POINTER (constant_string_id));
1394 return error_mark_node;
1397 /* Call to 'combine_strings' has been moved above. */
1398 TREE_SET_CODE (string, STRING_CST);
1399 length = TREE_STRING_LENGTH (string) - 1;
1401 if (!string_layout_checked)
1403 /* The NSConstantString/NXConstantString ivar layout is now
1405 if (!check_string_class_template ())
1407 error ("interface `%s' does not have valid constant string layout",
1408 IDENTIFIER_POINTER (constant_string_id));
1409 return error_mark_node;
1411 add_class_reference (constant_string_id);
1414 /* & ((NXConstantString) { NULL, string, length }) */
1416 if (flag_next_runtime)
1418 /* For the NeXT runtime, we can generate a literal reference
1419 to the string class, don't need to run a constructor. */
1420 setup_string_decl ();
1421 if (string_class_decl == NULL_TREE)
1423 error ("cannot find reference tag for class `%s'",
1424 IDENTIFIER_POINTER (constant_string_id));
1425 return error_mark_node;
1427 initlist = build_tree_list
1429 copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
1433 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1437 = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
1439 initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
1440 constructor = objc_build_constructor (constant_string_type,
1441 nreverse (initlist));
1443 if (!flag_next_runtime)
1446 = objc_add_static_instance (constructor, constant_string_type);
1449 return (build_unary_op (ADDR_EXPR, constructor, 1));
1452 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1454 static GTY(()) int num_static_inst;
1457 objc_add_static_instance (tree constructor, tree class_decl)
1462 /* Find the list of static instances for the CLASS_DECL. Create one if
1464 for (chain = &objc_static_instances;
1465 *chain && TREE_VALUE (*chain) != class_decl;
1466 chain = &TREE_CHAIN (*chain));
1469 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1470 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1473 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1474 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1475 DECL_COMMON (decl) = 1;
1476 TREE_STATIC (decl) = 1;
1477 DECL_ARTIFICIAL (decl) = 1;
1478 DECL_INITIAL (decl) = constructor;
1480 /* We may be writing something else just now.
1481 Postpone till end of input. */
1482 DECL_DEFER_OUTPUT (decl) = 1;
1483 pushdecl_top_level (decl);
1484 rest_of_decl_compilation (decl, 0, 1, 0);
1486 /* Add the DECL to the head of this CLASS' list. */
1487 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1492 /* Build a static constant CONSTRUCTOR
1493 with type TYPE and elements ELTS. */
1496 objc_build_constructor (tree type, tree elts)
1498 tree constructor, f, e;
1500 /* ??? Most of the places that we build constructors, we don't fill in
1501 the type of integers properly. Convert them all en masse. */
1502 if (TREE_CODE (type) == ARRAY_TYPE)
1504 f = TREE_TYPE (type);
1505 if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) == INTEGER_TYPE)
1506 for (e = elts; e ; e = TREE_CHAIN (e))
1507 TREE_VALUE (e) = convert (f, TREE_VALUE (e));
1511 f = TYPE_FIELDS (type);
1512 for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f))
1513 if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE
1514 || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
1515 TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
1518 constructor = build_constructor (type, elts);
1519 TREE_CONSTANT (constructor) = 1;
1520 TREE_STATIC (constructor) = 1;
1521 TREE_READONLY (constructor) = 1;
1524 /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
1525 build_unary_op (wasn't true in 2.7.2.1 days) */
1526 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1531 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1533 /* Predefine the following data type:
1541 void *defs[cls_def_cnt + cat_def_cnt];
1545 build_objc_symtab_template (void)
1547 tree field_decl, field_decl_chain;
1549 objc_symtab_template
1550 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1552 /* long sel_ref_cnt; */
1554 field_decl = create_builtin_decl (FIELD_DECL,
1555 long_integer_type_node,
1557 field_decl_chain = field_decl;
1561 field_decl = create_builtin_decl (FIELD_DECL,
1562 build_pointer_type (selector_type),
1564 chainon (field_decl_chain, field_decl);
1566 /* short cls_def_cnt; */
1568 field_decl = create_builtin_decl (FIELD_DECL,
1569 short_integer_type_node,
1571 chainon (field_decl_chain, field_decl);
1573 /* short cat_def_cnt; */
1575 field_decl = create_builtin_decl (FIELD_DECL,
1576 short_integer_type_node,
1578 chainon (field_decl_chain, field_decl);
1580 if (imp_count || cat_count || !flag_next_runtime)
1582 /* void *defs[imp_count + cat_count (+ 1)]; */
1583 /* NB: The index is one less than the size of the array. */
1584 int index = imp_count + cat_count
1585 + (flag_next_runtime? -1: 0);
1586 field_decl = create_builtin_decl
1590 build_index_type (build_int_2 (index, 0))),
1592 chainon (field_decl_chain, field_decl);
1595 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1598 /* Create the initial value for the `defs' field of _objc_symtab.
1599 This is a CONSTRUCTOR. */
1602 init_def_list (tree type)
1604 tree expr, initlist = NULL_TREE;
1605 struct imp_entry *impent;
1608 for (impent = imp_list; impent; impent = impent->next)
1610 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1612 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1613 initlist = tree_cons (NULL_TREE, expr, initlist);
1618 for (impent = imp_list; impent; impent = impent->next)
1620 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1622 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1623 initlist = tree_cons (NULL_TREE, expr, initlist);
1627 if (!flag_next_runtime)
1629 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1632 if (static_instances_decl)
1633 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1635 expr = build_int_2 (0, 0);
1637 initlist = tree_cons (NULL_TREE, expr, initlist);
1640 return objc_build_constructor (type, nreverse (initlist));
1643 /* Construct the initial value for all of _objc_symtab. */
1646 init_objc_symtab (tree type)
1650 /* sel_ref_cnt = { ..., 5, ... } */
1652 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
1654 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1656 if (flag_next_runtime || ! sel_ref_chain)
1657 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1659 initlist = tree_cons (NULL_TREE,
1660 build_unary_op (ADDR_EXPR,
1661 UOBJC_SELECTOR_TABLE_decl, 1),
1664 /* cls_def_cnt = { ..., 5, ... } */
1666 initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist);
1668 /* cat_def_cnt = { ..., 5, ... } */
1670 initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist);
1672 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1674 if (imp_count || cat_count || !flag_next_runtime)
1677 tree field = TYPE_FIELDS (type);
1678 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1680 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1684 return objc_build_constructor (type, nreverse (initlist));
1687 /* Generate forward declarations for metadata such as
1688 'OBJC_CLASS_...'. */
1691 build_metadata_decl (const char *name, tree type)
1693 tree decl, decl_specs;
1694 /* extern struct TYPE NAME_<name>; */
1695 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
1696 decl_specs = tree_cons (NULL_TREE, type, decl_specs);
1697 decl = define_decl (synth_id_with_class_suffix
1699 objc_implementation_context),
1701 TREE_USED (decl) = 1;
1702 DECL_ARTIFICIAL (decl) = 1;
1703 TREE_PUBLIC (decl) = 0;
1707 /* Push forward-declarations of all the categories so that
1708 init_def_list can use them in a CONSTRUCTOR. */
1711 forward_declare_categories (void)
1713 struct imp_entry *impent;
1714 tree sav = objc_implementation_context;
1716 for (impent = imp_list; impent; impent = impent->next)
1718 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1720 /* Set an invisible arg to synth_id_with_class_suffix. */
1721 objc_implementation_context = impent->imp_context;
1722 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1723 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1724 objc_category_template);
1727 objc_implementation_context = sav;
1730 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1731 and initialized appropriately. */
1734 generate_objc_symtab_decl (void)
1738 if (!objc_category_template)
1739 build_category_template ();
1741 /* forward declare categories */
1743 forward_declare_categories ();
1745 if (!objc_symtab_template)
1746 build_objc_symtab_template ();
1748 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
1750 UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
1751 tree_cons (NULL_TREE,
1752 objc_symtab_template, sc_spec),
1756 TREE_USED (UOBJC_SYMBOLS_decl) = 1;
1757 DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
1758 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
1759 finish_decl (UOBJC_SYMBOLS_decl,
1760 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
1765 init_module_descriptor (tree type)
1767 tree initlist, expr;
1769 /* version = { 1, ... } */
1771 expr = build_int_2 (OBJC_VERSION, 0);
1772 initlist = build_tree_list (NULL_TREE, expr);
1774 /* size = { ..., sizeof (struct objc_module), ... } */
1776 expr = size_in_bytes (objc_module_template);
1777 initlist = tree_cons (NULL_TREE, expr, initlist);
1779 /* name = { ..., "foo.m", ... } */
1781 expr = add_objc_string (get_identifier (input_filename), class_names);
1782 initlist = tree_cons (NULL_TREE, expr, initlist);
1784 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1786 if (UOBJC_SYMBOLS_decl)
1787 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1789 expr = build_int_2 (0, 0);
1790 initlist = tree_cons (NULL_TREE, expr, initlist);
1792 return objc_build_constructor (type, nreverse (initlist));
1795 /* Write out the data structures to describe Objective C classes defined.
1796 If appropriate, compile and output a setup function to initialize them.
1797 Return a symbol_ref to the function to call to initialize the Objective C
1798 data structures for this file (and perhaps for other files also).
1800 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1803 build_module_descriptor (void)
1805 tree decl_specs, field_decl, field_decl_chain;
1807 objc_module_template
1808 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1812 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1813 field_decl = get_identifier ("version");
1814 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1815 field_decl_chain = field_decl;
1819 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
1820 field_decl = get_identifier ("size");
1821 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1822 chainon (field_decl_chain, field_decl);
1826 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
1827 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
1828 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1829 chainon (field_decl_chain, field_decl);
1831 /* struct objc_symtab *symtab; */
1833 decl_specs = get_identifier (UTAG_SYMTAB);
1834 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
1835 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
1836 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
1837 chainon (field_decl_chain, field_decl);
1839 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
1841 /* Create an instance of "objc_module". */
1843 decl_specs = tree_cons (NULL_TREE, objc_module_template,
1844 build_tree_list (NULL_TREE,
1845 ridpointers[(int) RID_STATIC]));
1847 UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
1848 decl_specs, 1, NULL_TREE);
1850 DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
1851 DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
1852 DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
1854 finish_decl (UOBJC_MODULES_decl,
1855 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
1858 /* Mark the decl to avoid "defined but not used" warning. */
1859 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
1861 /* Generate a constructor call for the module descriptor.
1862 This code was generated by reading the grammar rules
1863 of c-parse.in; Therefore, it may not be the most efficient
1864 way of generating the requisite code. */
1866 if (flag_next_runtime)
1870 tree parms, execclass_decl, decelerator, void_list_node_1;
1871 tree init_function_name, init_function_decl;
1873 /* Declare void __objc_execClass (void *); */
1875 void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
1876 execclass_decl = build_decl (FUNCTION_DECL,
1877 get_identifier (TAG_EXECCLASS),
1878 build_function_type (void_type_node,
1879 tree_cons (NULL_TREE, ptr_type_node,
1882 DECL_EXTERNAL (execclass_decl) = 1;
1883 DECL_ARTIFICIAL (execclass_decl) = 1;
1884 TREE_PUBLIC (execclass_decl) = 1;
1885 pushdecl (execclass_decl);
1886 rest_of_decl_compilation (execclass_decl, 0, 0, 0);
1887 assemble_external (execclass_decl);
1889 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1891 init_function_name = get_file_function_name ('I');
1892 start_function (void_list_node_1,
1893 build_nt (CALL_EXPR, init_function_name,
1894 tree_cons (NULL_TREE, NULL_TREE,
1898 store_parm_decls ();
1900 init_function_decl = current_function_decl;
1901 TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
1902 TREE_USED (init_function_decl) = 1;
1903 /* Don't let this one be deferred. */
1904 DECL_INLINE (init_function_decl) = 0;
1905 DECL_UNINLINABLE (init_function_decl) = 1;
1906 current_function_cannot_inline
1907 = "static constructors and destructors cannot be inlined";
1910 = build_tree_list (NULL_TREE,
1911 build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0));
1912 decelerator = build_function_call (execclass_decl, parms);
1914 c_expand_expr_stmt (decelerator);
1918 return XEXP (DECL_RTL (init_function_decl), 0);
1922 /* Return the DECL of the string IDENT in the SECTION. */
1925 get_objc_string_decl (tree ident, enum string_section section)
1929 if (section == class_names)
1930 chain = class_names_chain;
1931 else if (section == meth_var_names)
1932 chain = meth_var_names_chain;
1933 else if (section == meth_var_types)
1934 chain = meth_var_types_chain;
1938 for (; chain != 0; chain = TREE_CHAIN (chain))
1939 if (TREE_VALUE (chain) == ident)
1940 return (TREE_PURPOSE (chain));
1946 /* Output references to all statically allocated objects. Return the DECL
1947 for the array built. */
1950 generate_static_references (void)
1952 tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
1953 tree class_name, class, decl, initlist;
1954 tree cl_chain, in_chain, type;
1955 int num_inst, num_class;
1958 if (flag_next_runtime)
1961 for (cl_chain = objc_static_instances, num_class = 0;
1962 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1964 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1965 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1967 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
1968 ident = get_identifier (buf);
1970 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
1971 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
1972 build_tree_list (NULL_TREE,
1973 ridpointers[(int) RID_STATIC]));
1974 decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
1975 DECL_CONTEXT (decl) = 0;
1976 DECL_ARTIFICIAL (decl) = 1;
1978 /* Output {class_name, ...}. */
1979 class = TREE_VALUE (cl_chain);
1980 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
1981 initlist = build_tree_list (NULL_TREE,
1982 build_unary_op (ADDR_EXPR, class_name, 1));
1984 /* Output {..., instance, ...}. */
1985 for (in_chain = TREE_PURPOSE (cl_chain);
1986 in_chain; in_chain = TREE_CHAIN (in_chain))
1988 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
1989 initlist = tree_cons (NULL_TREE, expr, initlist);
1992 /* Output {..., NULL}. */
1993 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
1995 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
1996 finish_decl (decl, expr, NULL_TREE);
1997 TREE_USED (decl) = 1;
1999 type = build_array_type (build_pointer_type (void_type_node), 0);
2000 decl = build_decl (VAR_DECL, ident, type);
2001 TREE_USED (decl) = 1;
2002 TREE_STATIC (decl) = 1;
2004 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2007 decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
2008 ident = get_identifier ("_OBJC_STATIC_INSTANCES");
2009 expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
2010 decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
2011 build_tree_list (NULL_TREE,
2012 ridpointers[(int) RID_STATIC]));
2013 static_instances_decl
2014 = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
2015 TREE_USED (static_instances_decl) = 1;
2016 DECL_CONTEXT (static_instances_decl) = 0;
2017 DECL_ARTIFICIAL (static_instances_decl) = 1;
2018 expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
2020 finish_decl (static_instances_decl, expr, NULL_TREE);
2023 /* Output all strings. */
2026 generate_strings (void)
2028 tree sc_spec, decl_specs, expr_decl;
2029 tree chain, string_expr;
2032 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2034 string = TREE_VALUE (chain);
2035 decl = TREE_PURPOSE (chain);
2037 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2038 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2039 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2040 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2041 DECL_CONTEXT (decl) = NULL_TREE;
2042 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2043 IDENTIFIER_POINTER (string));
2044 finish_decl (decl, string_expr, NULL_TREE);
2047 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2049 string = TREE_VALUE (chain);
2050 decl = TREE_PURPOSE (chain);
2052 = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
2053 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
2054 expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
2055 decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
2056 DECL_CONTEXT (decl) = NULL_TREE;
2057 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2058 IDENTIFIER_POINTER (string));
2059 finish_decl (decl, string_expr, NULL_TREE);
2062 for (chain = meth_var_types_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);
2078 static GTY(()) int selector_reference_idx;
2081 build_selector_reference_decl (void)
2086 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2088 ident = get_identifier (buf);
2090 decl = build_decl (VAR_DECL, ident, selector_type);
2091 DECL_EXTERNAL (decl) = 1;
2092 TREE_PUBLIC (decl) = 0;
2093 TREE_USED (decl) = 1;
2094 DECL_ARTIFICIAL (decl) = 1;
2095 DECL_CONTEXT (decl) = 0;
2097 make_decl_rtl (decl, 0);
2098 pushdecl_top_level (decl);
2103 /* Just a handy wrapper for add_objc_string. */
2106 build_selector (tree ident)
2108 tree expr = add_objc_string (ident, meth_var_names);
2109 if (flag_typed_selectors)
2112 return build_c_cast (selector_type, expr); /* cast! */
2116 build_selector_translation_table (void)
2118 tree sc_spec, decl_specs;
2119 tree chain, initlist = NULL_TREE;
2121 tree decl = NULL_TREE, var_decl, name;
2123 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2127 if (warn_selector && objc_implementation_context)
2131 for (method_chain = meth_var_names_chain;
2133 method_chain = TREE_CHAIN (method_chain))
2135 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2143 /* Adjust line number for warning message. */
2144 int save_lineno = input_line;
2145 if (flag_next_runtime && TREE_PURPOSE (chain))
2146 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2147 warning ("creating selector for non existant method %s",
2148 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2149 input_line = save_lineno;
2153 expr = build_selector (TREE_VALUE (chain));
2155 if (flag_next_runtime)
2157 name = DECL_NAME (TREE_PURPOSE (chain));
2159 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
2161 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2162 decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec);
2166 /* The `decl' that is returned from start_decl is the one that we
2167 forward declared in `build_selector_reference' */
2168 decl = start_decl (var_decl, decl_specs, 1, NULL_TREE );
2171 /* add one for the '\0' character */
2172 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2174 if (flag_next_runtime)
2175 finish_decl (decl, expr, NULL_TREE);
2178 if (flag_typed_selectors)
2180 tree eltlist = NULL_TREE;
2181 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2182 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2183 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2184 expr = objc_build_constructor (objc_selector_template,
2185 nreverse (eltlist));
2187 initlist = tree_cons (NULL_TREE, expr, initlist);
2192 if (! flag_next_runtime)
2194 /* Cause the variable and its initial value to be actually output. */
2195 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
2196 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
2197 /* NULL terminate the list and fix the decl for output. */
2198 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
2199 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
2200 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2201 nreverse (initlist));
2202 finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
2203 current_function_decl = NULL_TREE;
2208 get_proto_encoding (tree proto)
2213 if (! METHOD_ENCODING (proto))
2215 encoding = encode_method_prototype (proto);
2216 METHOD_ENCODING (proto) = encoding;
2219 encoding = METHOD_ENCODING (proto);
2221 return add_objc_string (encoding, meth_var_types);
2224 return build_int_2 (0, 0);
2227 /* sel_ref_chain is a list whose "value" fields will be instances of
2228 identifier_node that represent the selector. */
2231 build_typed_selector_reference (tree ident, tree prototype)
2233 tree *chain = &sel_ref_chain;
2239 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2240 goto return_at_index;
2243 chain = &TREE_CHAIN (*chain);
2246 *chain = tree_cons (prototype, ident, NULL_TREE);
2249 expr = build_unary_op (ADDR_EXPR,
2250 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2251 build_int_2 (index, 0)),
2253 return build_c_cast (selector_type, expr);
2257 build_selector_reference (tree ident)
2259 tree *chain = &sel_ref_chain;
2265 if (TREE_VALUE (*chain) == ident)
2266 return (flag_next_runtime
2267 ? TREE_PURPOSE (*chain)
2268 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2269 build_int_2 (index, 0)));
2272 chain = &TREE_CHAIN (*chain);
2275 expr = build_selector_reference_decl ();
2277 *chain = tree_cons (expr, ident, NULL_TREE);
2279 return (flag_next_runtime
2281 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2282 build_int_2 (index, 0)));
2285 static GTY(()) int class_reference_idx;
2288 build_class_reference_decl (void)
2293 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2295 ident = get_identifier (buf);
2297 decl = build_decl (VAR_DECL, ident, objc_class_type);
2298 DECL_EXTERNAL (decl) = 1;
2299 TREE_PUBLIC (decl) = 0;
2300 TREE_USED (decl) = 1;
2301 DECL_CONTEXT (decl) = 0;
2302 DECL_ARTIFICIAL (decl) = 1;
2304 make_decl_rtl (decl, 0);
2305 pushdecl_top_level (decl);
2310 /* Create a class reference, but don't create a variable to reference
2314 add_class_reference (tree ident)
2318 if ((chain = cls_ref_chain))
2323 if (ident == TREE_VALUE (chain))
2327 chain = TREE_CHAIN (chain);
2331 /* Append to the end of the list */
2332 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2335 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2338 /* Get a class reference, creating it if necessary. Also create the
2339 reference variable. */
2342 get_class_reference (tree ident)
2347 if (processing_template_decl)
2348 /* Must wait until template instantiation time. */
2349 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2350 if (TREE_CODE (ident) == TYPE_DECL)
2351 ident = DECL_NAME (ident);
2355 if (!(ident = is_class_name (ident)))
2357 error ("`%s' is not an Objective-C class name or alias",
2358 IDENTIFIER_POINTER (orig_ident));
2359 return error_mark_node;
2362 if (flag_next_runtime && !flag_zero_link)
2367 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2368 if (TREE_VALUE (*chain) == ident)
2370 if (! TREE_PURPOSE (*chain))
2371 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2373 return TREE_PURPOSE (*chain);
2376 decl = build_class_reference_decl ();
2377 *chain = tree_cons (decl, ident, NULL_TREE);
2384 add_class_reference (ident);
2386 params = build_tree_list (NULL_TREE,
2387 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2388 IDENTIFIER_POINTER (ident)));
2390 assemble_external (objc_get_class_decl);
2391 return build_function_call (objc_get_class_decl, params);
2395 /* For each string section we have a chain which maps identifier nodes
2396 to decls for the strings. */
2399 add_objc_string (tree ident, enum string_section section)
2403 if (section == class_names)
2404 chain = &class_names_chain;
2405 else if (section == meth_var_names)
2406 chain = &meth_var_names_chain;
2407 else if (section == meth_var_types)
2408 chain = &meth_var_types_chain;
2414 if (TREE_VALUE (*chain) == ident)
2415 return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
2417 chain = &TREE_CHAIN (*chain);
2420 decl = build_objc_string_decl (section);
2422 *chain = tree_cons (decl, ident, NULL_TREE);
2424 return build_unary_op (ADDR_EXPR, decl, 1);
2427 static GTY(()) int class_names_idx;
2428 static GTY(()) int meth_var_names_idx;
2429 static GTY(()) int meth_var_types_idx;
2432 build_objc_string_decl (enum string_section section)
2437 if (section == class_names)
2438 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2439 else if (section == meth_var_names)
2440 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2441 else if (section == meth_var_types)
2442 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2444 ident = get_identifier (buf);
2446 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2447 DECL_EXTERNAL (decl) = 1;
2448 TREE_PUBLIC (decl) = 0;
2449 TREE_USED (decl) = 1;
2450 TREE_CONSTANT (decl) = 1;
2451 DECL_CONTEXT (decl) = 0;
2452 DECL_ARTIFICIAL (decl) = 1;
2454 make_decl_rtl (decl, 0);
2455 pushdecl_top_level (decl);
2462 objc_declare_alias (tree alias_ident, tree class_ident)
2464 tree underlying_class;
2467 if (current_namespace != global_namespace) {
2468 error ("Objective-C declarations may only appear in global scope");
2470 #endif /* OBJCPLUS */
2472 if (!(underlying_class = is_class_name (class_ident)))
2473 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2474 else if (is_class_name (alias_ident))
2475 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2477 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2481 objc_declare_class (tree ident_list)
2485 if (current_namespace != global_namespace) {
2486 error ("Objective-C declarations may only appear in global scope");
2488 #endif /* OBJCPLUS */
2490 for (list = ident_list; list; list = TREE_CHAIN (list))
2492 tree ident = TREE_VALUE (list);
2494 if (! is_class_name (ident))
2496 tree record = lookup_name (ident);
2498 if (record && ! TREE_STATIC_TEMPLATE (record))
2500 error ("`%s' redeclared as different kind of symbol",
2501 IDENTIFIER_POINTER (ident));
2502 error ("%Jprevious declaration of '%D'",
2506 record = xref_tag (RECORD_TYPE, ident);
2507 TREE_STATIC_TEMPLATE (record) = 1;
2508 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2514 is_class_name (tree ident)
2518 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2519 && identifier_global_value (ident))
2520 ident = identifier_global_value (ident);
2521 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2522 ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2525 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2526 ident = TYPE_NAME (ident);
2527 if (ident && TREE_CODE (ident) == TYPE_DECL)
2528 ident = DECL_NAME (ident);
2530 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2533 if (lookup_interface (ident))
2536 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2538 if (ident == TREE_VALUE (chain))
2542 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2544 if (ident == TREE_VALUE (chain))
2545 return TREE_PURPOSE (chain);
2551 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2552 class instance. This is needed by other parts of the compiler to
2553 handle ObjC types gracefully. */
2556 objc_is_object_ptr (tree type)
2558 type = TYPE_MAIN_VARIANT (type);
2559 if (!type || TREE_CODE (type) != POINTER_TYPE)
2561 /* NB: This function may be called before the ObjC front-end has
2562 been initialized, in which case ID_TYPE will be NULL. */
2563 if (id_type && type && TYPE_P (type)
2565 || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
2567 return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
2571 lookup_interface (tree ident)
2576 if (ident && TREE_CODE (ident) == TYPE_DECL)
2577 ident = DECL_NAME (ident);
2579 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2581 if (ident == CLASS_NAME (chain))
2587 /* Implement @defs (<classname>) within struct bodies. */
2590 get_class_ivars_from_name (tree class_name)
2592 tree interface = lookup_interface (class_name);
2593 tree field, fields = NULL_TREE;
2597 tree raw_ivar = get_class_ivars (interface, 1);
2599 /* Regenerate the FIELD_DECLs for the enclosing struct. */
2600 for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
2602 field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
2603 TREE_PURPOSE (raw_ivar),
2604 TREE_VALUE (TREE_VALUE (raw_ivar)));
2606 finish_member_declaration (field);
2608 fields = chainon (fields, field);
2613 error ("cannot find interface declaration for `%s'",
2614 IDENTIFIER_POINTER (class_name));
2619 /* Used by: build_private_template, continue_class,
2620 and for @defs constructs. */
2623 get_class_ivars (tree interface, int raw)
2625 tree my_name, super_name, ivar_chain;
2627 my_name = CLASS_NAME (interface);
2628 super_name = CLASS_SUPER_NAME (interface);
2630 ivar_chain = CLASS_RAW_IVARS (interface);
2633 ivar_chain = CLASS_IVARS (interface);
2634 /* Save off a pristine copy of the leaf ivars (i.e, those not
2635 inherited from a super class). */
2636 if (!CLASS_OWN_IVARS (interface))
2637 CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
2643 tree super_interface = lookup_interface (super_name);
2645 if (!super_interface)
2647 /* fatal did not work with 2 args...should fix */
2648 error ("cannot find interface declaration for `%s', superclass of `%s'",
2649 IDENTIFIER_POINTER (super_name),
2650 IDENTIFIER_POINTER (my_name));
2651 exit (FATAL_EXIT_CODE);
2654 if (super_interface == interface)
2655 fatal_error ("circular inheritance in interface declaration for `%s'",
2656 IDENTIFIER_POINTER (super_name));
2658 interface = super_interface;
2659 my_name = CLASS_NAME (interface);
2660 super_name = CLASS_SUPER_NAME (interface);
2662 op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
2665 tree head = copy_list (op1);
2667 /* Prepend super class ivars...make a copy of the list, we
2668 do not want to alter the original. */
2669 chainon (head, ivar_chain);
2678 objc_enter_block (void)
2683 block = begin_compound_stmt (0);
2685 block = c_begin_compound_stmt ();
2688 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
2691 objc_exception_block_stack = tree_cons (NULL_TREE, block,
2692 objc_exception_block_stack);
2694 blk_nesting_count++;
2699 objc_exit_block (void)
2701 tree block = TREE_VALUE (objc_exception_block_stack);
2703 tree scope_stmt, inner;
2706 objc_clear_super_receiver ();
2708 finish_compound_stmt (0, block);
2710 scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
2711 inner = pop_scope ();
2713 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
2714 = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
2716 RECHAIN_STMTS (block, COMPOUND_BODY (block));
2718 last_expr_type = NULL_TREE;
2719 objc_exception_block_stack = TREE_CHAIN (objc_exception_block_stack);
2721 blk_nesting_count--;
2726 objc_declare_variable (enum rid scspec, tree name, tree type, tree init)
2730 type = tree_cons (NULL_TREE, type,
2731 tree_cons (NULL_TREE, ridpointers[(int) scspec],
2733 TREE_STATIC (type) = 1;
2734 decl = start_decl (name, type, (init != NULL_TREE), NULL_TREE);
2735 finish_decl (decl, init, NULL_TREE);
2736 /* This prevents `unused variable' warnings when compiling with -Wall. */
2737 TREE_USED (decl) = 1;
2738 DECL_ARTIFICIAL (decl) = 1;
2743 objc_build_throw_stmt (tree throw_expr)
2747 if (!flag_objc_exceptions)
2748 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2750 if (!throw_expr && objc_caught_exception)
2751 throw_expr = TREE_VALUE (objc_caught_exception);
2755 error ("`@throw;' (rethrow) used outside of a `@catch' block");
2756 return error_mark_node;
2759 func_params = tree_cons (NULL_TREE, throw_expr, NULL_TREE);
2761 assemble_external (objc_exception_throw_decl);
2762 return c_expand_expr_stmt (build_function_call (objc_exception_throw_decl,
2767 val_stack_push (struct val_stack **nc, long val)
2769 struct val_stack *new_elem = xmalloc (sizeof (struct val_stack));
2770 new_elem->val = val;
2771 new_elem->next = *nc;
2776 val_stack_pop (struct val_stack **nc)
2778 struct val_stack *old_elem = *nc;
2779 *nc = old_elem->next;
2784 objc_build_try_enter_fragment (void)
2786 /* objc_exception_try_enter(&_stackExceptionData);
2787 if (!_setjmp(&_stackExceptionData.buf)) { */
2789 tree func_params, if_stmt, cond;
2792 = tree_cons (NULL_TREE,
2793 build_unary_op (ADDR_EXPR,
2794 TREE_VALUE (objc_stack_exception_data),
2798 assemble_external (objc_exception_try_enter_decl);
2799 c_expand_expr_stmt (build_function_call
2800 (objc_exception_try_enter_decl, func_params));
2802 if_stmt = c_begin_if_stmt ();
2804 /* If <setjmp.h> has been included, the _setjmp prototype has
2805 acquired a real, breathing type for its parameter. Cast our
2806 argument to that type. */
2808 = tree_cons (NULL_TREE,
2809 build_c_cast (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))
2810 ? TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
2814 build_component_ref (TREE_VALUE (objc_stack_exception_data),
2815 get_identifier ("buf")), 0)),
2817 assemble_external (objc_setjmp_decl);
2818 cond = build_unary_op (TRUTH_NOT_EXPR,
2819 build_function_call (objc_setjmp_decl, func_params),
2821 c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (cond),
2823 objc_enter_block ();
2827 objc_build_extract_expr (void)
2829 /* ... = objc_exception_extract(&_stackExceptionData); */
2832 = tree_cons (NULL_TREE,
2833 build_unary_op (ADDR_EXPR,
2834 TREE_VALUE (objc_stack_exception_data), 0),
2837 assemble_external (objc_exception_extract_decl);
2838 return build_function_call (objc_exception_extract_decl, func_params);
2842 objc_build_try_exit_fragment (void)
2844 /* objc_exception_try_exit(&_stackExceptionData); */
2847 = tree_cons (NULL_TREE,
2848 build_unary_op (ADDR_EXPR,
2849 TREE_VALUE (objc_stack_exception_data), 0),
2852 assemble_external (objc_exception_try_exit_decl);
2853 c_expand_expr_stmt (build_function_call (objc_exception_try_exit_decl,
2858 objc_build_extract_fragment (void)
2861 _rethrowException = objc_exception_extract(&_stackExceptionData);
2867 c_expand_start_else ();
2868 objc_enter_block ();
2869 c_expand_expr_stmt (build_modify_expr
2870 (TREE_VALUE (objc_rethrow_exception),
2872 objc_build_extract_expr ()));
2875 c_expand_end_cond ();
2880 objc_build_try_prologue (void)
2883 struct _objc_exception_data _stackExceptionData;
2884 volatile id _rethrowException = nil;
2885 { // begin TRY-CATCH scope
2886 objc_exception_try_enter(&_stackExceptionData);
2887 if (!_setjmp(&_stackExceptionData.buf)) { */
2889 tree try_catch_block;
2891 if (!flag_objc_exceptions)
2892 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2894 objc_mark_locals_volatile ((void *)(exc_binding_stack
2895 ? exc_binding_stack->val
2897 objc_enter_block ();
2898 objc_stack_exception_data
2899 = tree_cons (NULL_TREE,
2900 objc_declare_variable (RID_AUTO,
2901 get_identifier (UTAG_EXCDATA_VAR),
2902 xref_tag (RECORD_TYPE,
2903 get_identifier (UTAG_EXCDATA)),
2905 objc_stack_exception_data);
2906 objc_rethrow_exception = tree_cons (NULL_TREE,
2907 objc_declare_variable (RID_VOLATILE,
2908 get_identifier (UTAG_RETHROWEXC_VAR),
2910 build_int_2 (0, 0)),
2911 objc_rethrow_exception);
2913 try_catch_block = objc_enter_block ();
2914 val_stack_push (&exc_binding_stack, (long) get_current_scope ());
2915 objc_build_try_enter_fragment ();
2917 return try_catch_block;
2921 objc_build_try_epilogue (int also_catch_prologue)
2923 if (also_catch_prologue)
2926 register id _caughtException = objc_exception_extract( &_stackExceptionData);
2927 objc_exception_try_enter(&_stackExceptionData);
2928 if(!_setjmp(&_stackExceptionData.buf)) {
2936 c_expand_start_else ();
2937 objc_enter_block ();
2938 objc_caught_exception
2939 = tree_cons (NULL_TREE,
2940 objc_declare_variable (RID_REGISTER,
2941 get_identifier (UTAG_CAUGHTEXC_VAR),
2943 objc_build_extract_expr ()),
2944 objc_caught_exception);
2945 objc_build_try_enter_fragment ();
2946 val_stack_push (&catch_count_stack, 1);
2947 if_stmt = c_begin_if_stmt ();
2949 c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (boolean_false_node),
2951 objc_enter_block ();
2953 /* Start a new chain of @catch statements for this @try. */
2954 objc_catch_type = tree_cons (objc_catch_type, NULL_TREE, NULL_TREE);
2957 { /* !also_catch_prologue */
2960 _rethrowException = objc_exception_extract( &_stackExceptionData);
2963 objc_build_extract_fragment ();
2969 objc_build_catch_stmt (tree catch_expr)
2971 /* } else if (objc_exception_match(objc_get_class("SomeClass"), _caughtException)) {
2972 register SomeClass *e = _caughtException; */
2974 tree if_stmt, cond, func_params, prev_catch, var_name, var_type;
2978 /* Yet another C/C++ impedance mismatch. */
2979 catch_expr = TREE_PURPOSE (catch_expr);
2982 var_name = TREE_VALUE (catch_expr);
2983 var_type = TREE_VALUE (TREE_PURPOSE (catch_expr));
2984 if (TREE_CODE (var_name) == INDIRECT_REF)
2985 var_name = TREE_OPERAND (var_name, 0);
2986 if (TREE_CODE (var_type) == TYPE_DECL
2987 || TREE_CODE (var_type) == POINTER_TYPE)
2988 var_type = TREE_TYPE (var_type);
2989 catch_id = (var_type == TREE_TYPE (id_type));
2991 if (!flag_objc_exceptions)
2992 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
2994 if (!(catch_id || TYPED_OBJECT (var_type)))
2995 fatal_error ("`@catch' parameter is not a known Objective-C class type");
2997 /* Examine previous @catch clauses for the current @try block for
2998 superclasses of the 'var_type' class. */
2999 for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch);
3000 prev_catch = TREE_CHAIN (prev_catch))
3002 if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
3004 warning ("Exception already handled by preceding `@catch(id)'");
3008 && objc_comptypes (TREE_VALUE (prev_catch), var_type, 0) == 1)
3009 warning ("Exception of type `%s *' already handled by `@catch (%s *)'",
3010 IDENTIFIER_POINTER (OBJC_TYPE_NAME (var_type)),
3011 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_VALUE (prev_catch))));
3014 objc_catch_type = tree_cons (NULL_TREE, var_type, objc_catch_type);
3019 c_expand_start_else ();
3020 catch_count_stack->val++;
3021 if_stmt = c_begin_if_stmt ();
3025 cond = integer_one_node;
3028 cond = get_class_reference (OBJC_TYPE_NAME (var_type));
3031 = tree_cons (NULL_TREE, cond,
3032 tree_cons (NULL_TREE,
3033 TREE_VALUE (objc_caught_exception),
3035 assemble_external (objc_exception_match_decl);
3036 cond = build_function_call (objc_exception_match_decl, func_params);
3039 c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (cond),
3041 objc_enter_block ();
3042 objc_declare_variable (RID_REGISTER, var_name,
3043 build_pointer_type (var_type),
3044 TREE_VALUE (objc_caught_exception));
3048 objc_build_catch_epilogue (void)
3051 _rethrowException = _caughtException;
3052 objc_exception_try_exit(&_stackExceptionData);
3055 _rethrowException = objc_exception_extract(&_stackExceptionData);
3058 } // end TRY-CATCH scope
3064 c_expand_start_else ();
3065 objc_enter_block ();
3068 (TREE_VALUE (objc_rethrow_exception),
3070 TREE_VALUE (objc_caught_exception)));
3071 objc_build_try_exit_fragment ();
3073 while (catch_count_stack->val--)
3075 c_finish_else (); /* close off all the nested ifs ! */
3076 c_expand_end_cond ();
3079 val_stack_pop (&catch_count_stack);
3080 objc_caught_exception = TREE_CHAIN (objc_caught_exception);
3082 objc_build_extract_fragment ();
3086 c_expand_end_cond ();
3090 /* Return to enclosing chain of @catch statements (if any). */
3091 while (TREE_VALUE (objc_catch_type))
3092 objc_catch_type = TREE_CHAIN (objc_catch_type);
3093 objc_catch_type = TREE_PURPOSE (objc_catch_type);
3097 objc_build_finally_prologue (void)
3099 /* { // begin FINALLY scope
3100 if (!_rethrowException) {
3101 objc_exception_try_exit(&_stackExceptionData);
3104 tree blk = objc_enter_block ();
3106 tree if_stmt = c_begin_if_stmt ();
3109 c_expand_start_cond ((*lang_hooks.truthvalue_conversion)
3112 TREE_VALUE (objc_rethrow_exception), 0)),
3114 objc_enter_block ();
3115 objc_build_try_exit_fragment ();
3118 c_expand_end_cond ();
3125 objc_build_finally_epilogue (void)
3127 /* if (_rethrowException) {
3128 objc_exception_throw(_rethrowException);
3130 } // end FINALLY scope
3133 tree if_stmt = c_begin_if_stmt ();
3137 ((*lang_hooks.truthvalue_conversion) (TREE_VALUE (objc_rethrow_exception)),
3139 objc_enter_block ();
3140 objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception));
3143 c_expand_end_cond ();
3147 objc_rethrow_exception = TREE_CHAIN (objc_rethrow_exception);
3148 objc_stack_exception_data = TREE_CHAIN (objc_stack_exception_data);
3150 val_stack_pop (&exc_binding_stack);
3151 return objc_exit_block ();
3155 objc_build_try_catch_finally_stmt (int has_catch, int has_finally)
3157 /* NB: The operative assumption here is that TRY_FINALLY_EXPR will
3158 deal with all exits from 'try_catch_blk' and route them through
3160 tree outer_blk = objc_build_finally_epilogue ();
3161 tree prec_stmt = TREE_CHAIN (TREE_CHAIN (COMPOUND_BODY (outer_blk)));
3162 tree try_catch_blk = TREE_CHAIN (prec_stmt), try_catch_expr;
3163 tree finally_blk = TREE_CHAIN (try_catch_blk), finally_expr;
3164 tree succ_stmt = TREE_CHAIN (finally_blk);
3165 tree try_finally_stmt, try_finally_expr;
3167 if (!flag_objc_exceptions)
3168 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3170 /* It is an error to have a @try block without a @catch and/or @finally
3171 (even though sensible code can be generated nonetheless). */
3173 if (!has_catch && !has_finally)
3174 error ("`@try' without `@catch' or `@finally'");
3176 /* We shall now do something truly disgusting. We shall remove the
3177 'try_catch_blk' and 'finally_blk' from the 'outer_blk' statement
3178 chain, and replace them with a TRY_FINALLY_EXPR statement! If
3179 this doesn't work, we will have to learn (from Per/gcj) how to
3180 construct the 'outer_blk' lazily. */
3182 TREE_CHAIN (try_catch_blk) = TREE_CHAIN (finally_blk) = NULL_TREE;
3183 try_catch_expr = build1 (STMT_EXPR, void_type_node, try_catch_blk);
3184 TREE_SIDE_EFFECTS (try_catch_expr) = 1;
3185 finally_expr = build1 (STMT_EXPR, void_type_node, finally_blk);
3186 TREE_SIDE_EFFECTS (finally_expr) = 1;
3187 try_finally_expr = build (TRY_FINALLY_EXPR, void_type_node, try_catch_expr,
3189 TREE_SIDE_EFFECTS (try_finally_expr) = 1;
3190 try_finally_stmt = build_stmt (EXPR_STMT, try_finally_expr);
3191 TREE_CHAIN (prec_stmt) = try_finally_stmt;
3192 TREE_CHAIN (try_finally_stmt) = succ_stmt;
3194 return outer_blk; /* the whole enchilada */
3198 objc_build_synchronized_prologue (tree sync_expr)
3201 id _eval_once = <sync_expr>;
3203 objc_sync_enter( _eval_once ); */
3207 if (!flag_objc_exceptions)
3208 fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
3210 objc_enter_block ();
3212 = tree_cons (NULL_TREE,
3213 objc_declare_variable (RID_AUTO,
3214 get_identifier (UTAG_EVALONCE_VAR),
3218 objc_build_try_prologue ();
3219 objc_enter_block ();
3220 func_params = tree_cons (NULL_TREE,
3221 TREE_VALUE (objc_eval_once),
3224 assemble_external (objc_sync_enter_decl);
3225 c_expand_expr_stmt (build_function_call
3226 (objc_sync_enter_decl, func_params));
3230 objc_build_synchronized_epilogue (void)
3234 objc_sync_exit( _eval_once );
3241 objc_build_try_epilogue (0);
3242 objc_build_finally_prologue ();
3243 func_params = tree_cons (NULL_TREE, TREE_VALUE (objc_eval_once),
3246 assemble_external (objc_sync_exit_decl);
3247 c_expand_expr_stmt (build_function_call (objc_sync_exit_decl,
3249 objc_build_try_catch_finally_stmt (0, 1);
3251 return objc_exit_block ();
3254 /* Predefine the following data type:
3256 struct _objc_exception_data
3262 /* The following yuckiness should prevent users from having to #include
3263 <setjmp.h> in their code... */
3265 #ifdef TARGET_POWERPC
3266 /* snarfed from /usr/include/ppc/setjmp.h */
3267 #define _JBLEN (26 + 36 + 129 + 1)
3269 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3274 build_objc_exception_stuff (void)
3276 tree field_decl, field_decl_chain, index, temp_type;
3278 /* Suppress outputting debug symbols, because
3279 dbxout_init hasn't been called yet. */
3280 enum debug_info_type save_write_symbols = write_symbols;
3281 const struct gcc_debug_hooks *save_hooks = debug_hooks;
3283 write_symbols = NO_DEBUG;
3284 debug_hooks = &do_nothing_debug_hooks;
3285 objc_exception_data_template
3286 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3288 /* int buf[_JBLEN]; */
3290 index = build_index_type (build_int_2 (_JBLEN - 1, 0));
3291 field_decl = create_builtin_decl (FIELD_DECL,
3292 build_array_type (integer_type_node, index),
3294 field_decl_chain = field_decl;
3296 /* void *pointers[4]; */
3298 index = build_index_type (build_int_2 (4 - 1, 0));
3299 field_decl = create_builtin_decl (FIELD_DECL,
3300 build_array_type (ptr_type_node, index),
3302 chainon (field_decl_chain, field_decl);
3304 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3306 /* int _setjmp(...); */
3307 /* If the user includes <setjmp.h>, this shall be superseded by
3308 'int _setjmp(jmp_buf);' */
3309 temp_type = build_function_type (integer_type_node, NULL_TREE);
3311 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3313 /* id objc_exception_extract(struct _objc_exception_data *); */
3315 = build_function_type (id_type,
3316 tree_cons (NULL_TREE,
3317 build_pointer_type (objc_exception_data_template),
3319 objc_exception_extract_decl
3320 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3321 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3322 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3324 = build_function_type (void_type_node,
3325 tree_cons (NULL_TREE,
3326 build_pointer_type (objc_exception_data_template),
3328 objc_exception_try_enter_decl
3329 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3330 objc_exception_try_exit_decl
3331 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3332 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3333 /* void objc_sync_enter(id); */
3334 /* void objc_sync_exit(id); */
3335 temp_type = build_function_type (void_type_node,
3336 tree_cons (NULL_TREE, id_type,
3338 objc_exception_throw_decl
3339 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3340 DECL_ATTRIBUTES (objc_exception_throw_decl)
3341 = tree_cons (get_identifier ("noreturn"), NULL_TREE, NULL_TREE);
3342 objc_sync_enter_decl
3343 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3345 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3346 /* int objc_exception_match(id, id); */
3347 temp_type = build_function_type (integer_type_node,
3348 tree_cons (NULL_TREE, id_type,
3349 tree_cons (NULL_TREE, id_type,
3351 objc_exception_match_decl
3352 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3354 write_symbols = save_write_symbols;
3355 debug_hooks = save_hooks;
3358 /* struct <classname> {
3359 struct objc_class *isa;
3364 build_private_template (tree class)
3368 if (CLASS_STATIC_TEMPLATE (class))
3370 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3371 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3375 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3376 ivar_context = get_class_ivars (class, 0);
3378 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3380 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3382 /* mark this record as class template - for class type checking */
3383 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3387 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
3389 build1 (INDIRECT_REF, NULL_TREE,
3392 return ivar_context;
3395 /* Begin code generation for protocols... */
3397 /* struct objc_protocol {
3398 char *protocol_name;
3399 struct objc_protocol **protocol_list;
3400 struct objc_method_desc *instance_methods;
3401 struct objc_method_desc *class_methods;
3405 build_protocol_template (void)
3407 tree decl_specs, field_decl, field_decl_chain;
3410 template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL));
3412 /* struct objc_class *isa; */
3414 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3415 get_identifier (UTAG_CLASS)));
3416 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
3417 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3418 field_decl_chain = field_decl;
3420 /* char *protocol_name; */
3422 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3424 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
3425 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3426 chainon (field_decl_chain, field_decl);
3428 /* struct objc_protocol **protocol_list; */
3430 decl_specs = build_tree_list (NULL_TREE, template);
3432 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3433 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3434 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3435 chainon (field_decl_chain, field_decl);
3437 /* struct objc_method_list *instance_methods; */
3440 = build_tree_list (NULL_TREE,
3441 xref_tag (RECORD_TYPE,
3442 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3444 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3445 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3446 chainon (field_decl_chain, field_decl);
3448 /* struct objc_method_list *class_methods; */
3451 = build_tree_list (NULL_TREE,
3452 xref_tag (RECORD_TYPE,
3453 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3455 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3456 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3457 chainon (field_decl_chain, field_decl);
3459 return finish_struct (template, field_decl_chain, NULL_TREE);
3463 build_descriptor_table_initializer (tree type, tree entries)
3465 tree initlist = NULL_TREE;
3469 tree eltlist = NULL_TREE;
3472 = tree_cons (NULL_TREE,
3473 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3475 = tree_cons (NULL_TREE,
3476 add_objc_string (METHOD_ENCODING (entries),
3481 = tree_cons (NULL_TREE,
3482 objc_build_constructor (type, nreverse (eltlist)),
3485 entries = TREE_CHAIN (entries);
3489 return objc_build_constructor (build_array_type (type, 0),
3490 nreverse (initlist));
3493 /* struct objc_method_prototype_list {
3495 struct objc_method_prototype {
3502 build_method_prototype_list_template (tree list_type, int size)
3504 tree objc_ivar_list_record;
3505 tree decl_specs, field_decl, field_decl_chain;
3507 /* Generate an unnamed struct definition. */
3509 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3511 /* int method_count; */
3513 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
3514 field_decl = get_identifier ("method_count");
3515 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3516 field_decl_chain = field_decl;
3518 /* struct objc_method method_list[]; */
3520 decl_specs = build_tree_list (NULL_TREE, list_type);
3521 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
3522 build_int_2 (size, 0));
3523 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3524 chainon (field_decl_chain, field_decl);
3526 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3528 return objc_ivar_list_record;
3532 build_method_prototype_template (void)
3535 tree decl_specs, field_decl, field_decl_chain;
3538 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3540 /* struct objc_selector *_cmd; */
3541 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
3542 get_identifier (TAG_SELECTOR)), NULL_TREE);
3543 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
3544 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3545 field_decl_chain = field_decl;
3547 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
3549 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
3550 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3551 chainon (field_decl_chain, field_decl);
3553 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3555 return proto_record;
3559 objc_method_parm_type (tree type)
3561 type = groktypename (TREE_TYPE (type));
3562 if (TREE_CODE (type) == TYPE_DECL)
3563 type = TREE_TYPE (type);
3564 return TYPE_MAIN_VARIANT (type);
3568 objc_encoded_type_size (tree type)
3570 int sz = int_size_in_bytes (type);
3572 /* Make all integer and enum types at least as large
3574 if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
3575 || TREE_CODE (type) == BOOLEAN_TYPE
3576 || TREE_CODE (type) == ENUMERAL_TYPE))
3577 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3578 /* Treat arrays as pointers, since that's how they're
3580 else if (TREE_CODE (type) == ARRAY_TYPE)
3581 sz = int_size_in_bytes (ptr_type_node);
3586 encode_method_prototype (tree method_decl)
3593 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3594 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3596 /* Encode return type. */
3597 encode_type (objc_method_parm_type (method_decl),
3598 obstack_object_size (&util_obstack),
3599 OBJC_ENCODE_INLINE_DEFS);
3602 /* The first two arguments (self and _cmd) are pointers; account for
3604 i = int_size_in_bytes (ptr_type_node);
3605 parm_offset = 2 * i;
3606 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3607 parms = TREE_CHAIN (parms))
3609 tree type = objc_method_parm_type (parms);
3610 int sz = objc_encoded_type_size (type);
3612 /* If a type size is not known, bail out. */
3615 error ("%Jtype '%D' does not have a known size",
3617 /* Pretend that the encoding succeeded; the compilation will
3618 fail nevertheless. */
3619 goto finish_encoding;
3624 sprintf (buf, "%d@0:%d", parm_offset, i);
3625 obstack_grow (&util_obstack, buf, strlen (buf));
3627 /* Argument types. */
3628 parm_offset = 2 * i;
3629 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3630 parms = TREE_CHAIN (parms))
3632 tree type = objc_method_parm_type (parms);
3634 /* Process argument qualifiers for user supplied arguments. */
3635 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3638 encode_type (type, obstack_object_size (&util_obstack),
3639 OBJC_ENCODE_INLINE_DEFS);
3641 /* Compute offset. */
3642 sprintf (buf, "%d", parm_offset);
3643 parm_offset += objc_encoded_type_size (type);
3645 obstack_grow (&util_obstack, buf, strlen (buf));
3649 obstack_1grow (&util_obstack, '\0');
3650 result = get_identifier (obstack_finish (&util_obstack));
3651 obstack_free (&util_obstack, util_firstobj);
3656 generate_descriptor_table (tree type, const char *name, int size, tree list,
3659 tree sc_spec, decl_specs, decl, initlist;
3661 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
3662 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
3664 decl = start_decl (synth_id_with_class_suffix (name, proto),
3665 decl_specs, 1, NULL_TREE);
3666 DECL_CONTEXT (decl) = NULL_TREE;
3668 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
3669 initlist = tree_cons (NULL_TREE, list, initlist);
3671 finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
3678 generate_method_descriptors (tree protocol)
3680 tree initlist, chain, method_list_template;
3681 tree cast, variable_length_type;
3684 if (!objc_method_prototype_template)
3685 objc_method_prototype_template = build_method_prototype_template ();
3687 cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
3688 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))),
3690 variable_length_type = groktypename (cast);
3692 chain = PROTOCOL_CLS_METHODS (protocol);
3695 size = list_length (chain);
3697 method_list_template
3698 = build_method_prototype_list_template (objc_method_prototype_template,
3702 = build_descriptor_table_initializer (objc_method_prototype_template,
3705 UOBJC_CLASS_METHODS_decl
3706 = generate_descriptor_table (method_list_template,
3707 "_OBJC_PROTOCOL_CLASS_METHODS",
3708 size, initlist, protocol);
3709 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3712 UOBJC_CLASS_METHODS_decl = 0;
3714 chain = PROTOCOL_NST_METHODS (protocol);
3717 size = list_length (chain);
3719 method_list_template
3720 = build_method_prototype_list_template (objc_method_prototype_template,
3723 = build_descriptor_table_initializer (objc_method_prototype_template,
3726 UOBJC_INSTANCE_METHODS_decl
3727 = generate_descriptor_table (method_list_template,
3728 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3729 size, initlist, protocol);
3730 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3733 UOBJC_INSTANCE_METHODS_decl = 0;
3737 generate_protocol_references (tree plist)
3741 /* Forward declare protocols referenced. */
3742 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3744 tree proto = TREE_VALUE (lproto);
3746 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3747 && PROTOCOL_NAME (proto))
3749 if (! PROTOCOL_FORWARD_DECL (proto))
3750 build_protocol_reference (proto);
3752 if (PROTOCOL_LIST (proto))
3753 generate_protocol_references (PROTOCOL_LIST (proto));
3758 /* For each protocol which was referenced either from a @protocol()
3759 expression, or because a class/category implements it (then a
3760 pointer to the protocol is stored in the struct describing the
3761 class/category), we create a statically allocated instance of the
3762 Protocol class. The code is written in such a way as to generate
3763 as few Protocol objects as possible; we generate a unique Protocol
3764 instance for each protocol, and we don't generate a Protocol
3765 instance if the protocol is never referenced (either from a
3766 @protocol() or from a class/category implementation). These
3767 statically allocated objects can be referred to via the static
3768 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3770 The statically allocated Protocol objects that we generate here
3771 need to be fixed up at runtime in order to be used: the 'isa'
3772 pointer of the objects need to be set up to point to the 'Protocol'
3773 class, as known at runtime.
3775 The NeXT runtime fixes up all protocols at program startup time,
3776 before main() is entered. It uses a low-level trick to look up all
3777 those symbols, then loops on them and fixes them up.
3779 The GNU runtime as well fixes up all protocols before user code
3780 from the module is executed; it requires pointers to those symbols
3781 to be put in the objc_symtab (which is then passed as argument to
3782 the function __objc_exec_class() which the compiler sets up to be
3783 executed automatically when the module is loaded); setup of those
3784 Protocol objects happen in two ways in the GNU runtime: all
3785 Protocol objects referred to by a class or category implementation
3786 are fixed up when the class/category is loaded; all Protocol
3787 objects referred to by a @protocol() expression are added by the
3788 compiler to the list of statically allocated instances to fixup
3789 (the same list holding the statically allocated constant string
3790 objects). Because, as explained above, the compiler generates as
3791 few Protocol objects as possible, some Protocol object might end up
3792 being referenced multiple times when compiled with the GNU runtime,
3793 and end up being fixed up multiple times at runtime inizialization.
3794 But that doesn't hurt, it's just a little inefficient. */
3797 generate_protocols (void)
3800 tree sc_spec, decl_specs, decl;
3801 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3804 if (! objc_protocol_template)
3805 objc_protocol_template = build_protocol_template ();
3807 /* If a protocol was directly referenced, pull in indirect references. */
3808 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3809 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3810 generate_protocol_references (PROTOCOL_LIST (p));
3812 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3814 tree nst_methods = PROTOCOL_NST_METHODS (p);
3815 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3817 /* If protocol wasn't referenced, don't generate any code. */
3818 if (! PROTOCOL_FORWARD_DECL (p))
3821 /* Make sure we link in the Protocol class. */
3822 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3826 if (! METHOD_ENCODING (nst_methods))
3828 encoding = encode_method_prototype (nst_methods);
3829 METHOD_ENCODING (nst_methods) = encoding;
3831 nst_methods = TREE_CHAIN (nst_methods);
3836 if (! METHOD_ENCODING (cls_methods))
3838 encoding = encode_method_prototype (cls_methods);
3839 METHOD_ENCODING (cls_methods) = encoding;
3842 cls_methods = TREE_CHAIN (cls_methods);
3844 generate_method_descriptors (p);
3846 if (PROTOCOL_LIST (p))
3847 refs_decl = generate_protocol_list (p);
3851 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3853 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
3855 decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec);
3857 decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p),
3858 decl_specs, 1, NULL_TREE);
3860 DECL_CONTEXT (decl) = NULL_TREE;
3862 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3868 (build_tree_list (build_tree_list (NULL_TREE,
3869 objc_protocol_template),
3870 build1 (INDIRECT_REF, NULL_TREE,
3871 build1 (INDIRECT_REF, NULL_TREE,
3874 refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
3875 TREE_TYPE (refs_expr) = cast_type2;
3878 refs_expr = build_int_2 (0, 0);
3880 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3881 by generate_method_descriptors, which is called above. */
3882 initlist = build_protocol_initializer (TREE_TYPE (decl),
3883 protocol_name_expr, refs_expr,
3884 UOBJC_INSTANCE_METHODS_decl,
3885 UOBJC_CLASS_METHODS_decl);
3886 finish_decl (decl, initlist, NULL_TREE);
3888 /* Mark the decl as used to avoid "defined but not used" warning. */
3889 TREE_USED (decl) = 1;
3894 build_protocol_initializer (tree type, tree protocol_name,
3895 tree protocol_list, tree instance_methods,
3898 tree initlist = NULL_TREE, expr;
3901 cast_type = groktypename
3903 (build_tree_list (NULL_TREE,
3904 xref_tag (RECORD_TYPE,
3905 get_identifier (UTAG_CLASS))),
3906 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
3908 /* Filling the "isa" in with one allows the runtime system to
3909 detect that the version change...should remove before final release. */
3911 expr = build_int_2 (PROTOCOL_VERSION, 0);
3912 TREE_TYPE (expr) = cast_type;
3913 initlist = tree_cons (NULL_TREE, expr, initlist);
3914 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3915 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3917 if (!instance_methods)
3918 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3921 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3922 initlist = tree_cons (NULL_TREE, expr, initlist);
3926 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
3929 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3930 initlist = tree_cons (NULL_TREE, expr, initlist);
3933 return objc_build_constructor (type, nreverse (initlist));
3936 /* struct objc_category {
3937 char *category_name;
3939 struct objc_method_list *instance_methods;
3940 struct objc_method_list *class_methods;
3941 struct objc_protocol_list *protocols;
3945 build_category_template (void)
3947 tree decl_specs, field_decl, field_decl_chain;
3949 objc_category_template = start_struct (RECORD_TYPE,
3950 get_identifier (UTAG_CATEGORY));
3951 /* char *category_name; */
3953 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3955 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
3956 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3957 field_decl_chain = field_decl;
3959 /* char *class_name; */
3961 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
3962 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
3963 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3964 chainon (field_decl_chain, field_decl);
3966 /* struct objc_method_list *instance_methods; */
3968 decl_specs = build_tree_list (NULL_TREE,
3969 xref_tag (RECORD_TYPE,
3970 get_identifier (UTAG_METHOD_LIST)));
3972 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
3973 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3974 chainon (field_decl_chain, field_decl);
3976 /* struct objc_method_list *class_methods; */
3978 decl_specs = build_tree_list (NULL_TREE,
3979 xref_tag (RECORD_TYPE,
3980 get_identifier (UTAG_METHOD_LIST)));
3982 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
3983 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3984 chainon (field_decl_chain, field_decl);
3986 /* struct objc_protocol **protocol_list; */
3988 decl_specs = build_tree_list (NULL_TREE,
3989 xref_tag (RECORD_TYPE,
3990 get_identifier (UTAG_PROTOCOL)));
3992 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
3993 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
3994 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
3995 chainon (field_decl_chain, field_decl);
3997 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4000 /* struct objc_selector {
4006 build_selector_template (void)
4009 tree decl_specs, field_decl, field_decl_chain;
4011 objc_selector_template
4012 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4016 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4017 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4018 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4019 field_decl_chain = field_decl;
4021 /* char *sel_type; */
4023 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4024 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
4025 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4026 chainon (field_decl_chain, field_decl);
4028 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4031 /* struct objc_class {
4032 struct objc_class *isa;
4033 struct objc_class *super_class;
4038 struct objc_ivar_list *ivars;
4039 struct objc_method_list *methods;
4040 if (flag_next_runtime)
4041 struct objc_cache *cache;
4043 struct sarray *dtable;
4044 struct objc_class *subclass_list;
4045 struct objc_class *sibling_class;
4047 struct objc_protocol_list *protocols;
4048 if (flag_next_runtime)
4050 void *gc_object_type;
4053 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4054 the NeXT/Apple runtime; still, the compiler must generate them to
4055 maintain backward binary compatibility (and to allow for future
4059 build_class_template (void)
4061 tree decl_specs, field_decl, field_decl_chain;
4064 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4066 /* struct objc_class *isa; */
4068 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4069 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
4070 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4071 field_decl_chain = field_decl;
4073 /* struct objc_class *super_class; */
4075 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4077 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4078 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4079 chainon (field_decl_chain, field_decl);
4083 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4084 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
4085 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4086 chainon (field_decl_chain, field_decl);
4090 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4091 field_decl = get_identifier ("version");
4092 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4093 chainon (field_decl_chain, field_decl);
4097 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4098 field_decl = get_identifier ("info");
4099 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4100 chainon (field_decl_chain, field_decl);
4102 /* long instance_size; */
4104 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
4105 field_decl = get_identifier ("instance_size");
4106 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4107 chainon (field_decl_chain, field_decl);
4109 /* struct objc_ivar_list *ivars; */
4111 decl_specs = build_tree_list (NULL_TREE,
4112 xref_tag (RECORD_TYPE,
4113 get_identifier (UTAG_IVAR_LIST)));
4114 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
4115 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4116 chainon (field_decl_chain, field_decl);
4118 /* struct objc_method_list *methods; */
4120 decl_specs = build_tree_list (NULL_TREE,
4121 xref_tag (RECORD_TYPE,
4122 get_identifier (UTAG_METHOD_LIST)));
4123 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
4124 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4125 chainon (field_decl_chain, field_decl);
4127 if (flag_next_runtime)
4129 /* struct objc_cache *cache; */
4131 decl_specs = build_tree_list (NULL_TREE,
4132 xref_tag (RECORD_TYPE,
4133 get_identifier ("objc_cache")));
4134 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
4135 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4136 chainon (field_decl_chain, field_decl);
4140 /* struct sarray *dtable; */
4142 decl_specs = build_tree_list (NULL_TREE,
4143 xref_tag (RECORD_TYPE,
4144 get_identifier ("sarray")));
4145 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
4146 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4147 chainon (field_decl_chain, field_decl);
4149 /* struct objc_class *subclass_list; */
4151 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4153 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
4154 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4155 chainon (field_decl_chain, field_decl);
4157 /* struct objc_class *sibling_class; */
4159 decl_specs = build_tree_list (NULL_TREE, objc_class_template);
4161 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
4162 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4163 chainon (field_decl_chain, field_decl);
4166 /* struct objc_protocol **protocol_list; */
4168 decl_specs = build_tree_list (NULL_TREE,
4169 xref_tag (RECORD_TYPE,
4170 get_identifier (UTAG_PROTOCOL)));
4172 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
4174 = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4175 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4176 chainon (field_decl_chain, field_decl);
4178 if (flag_next_runtime)
4182 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4183 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
4185 = grokfield (field_decl, decl_specs, NULL_TREE);
4186 chainon (field_decl_chain, field_decl);
4189 /* void *gc_object_type; */
4191 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
4192 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
4193 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4194 chainon (field_decl_chain, field_decl);
4196 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4199 /* Generate appropriate forward declarations for an implementation. */
4202 synth_forward_declarations (void)
4206 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4207 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4208 objc_class_template);
4210 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4211 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4212 objc_class_template);
4214 /* Pre-build the following entities - for speed/convenience. */
4216 an_id = get_identifier ("super_class");
4217 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4218 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4222 error_with_ivar (const char *message, tree decl, tree rawdecl)
4224 error ("%J%s `%s'", decl,
4225 message, gen_declaration (rawdecl, errbuf));
4230 check_ivars (tree inter, tree imp)
4232 tree intdecls = CLASS_IVARS (inter);
4233 tree impdecls = CLASS_IVARS (imp);
4234 tree rawintdecls = CLASS_RAW_IVARS (inter);
4235 tree rawimpdecls = CLASS_RAW_IVARS (imp);
4242 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4243 intdecls = TREE_CHAIN (intdecls);
4245 if (intdecls == 0 && impdecls == 0)
4247 if (intdecls == 0 || impdecls == 0)
4249 error ("inconsistent instance variable specification");
4253 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4255 if (!comptypes (t1, t2, false)
4256 || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
4257 TREE_VALUE (TREE_VALUE (rawimpdecls))))
4259 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4261 error_with_ivar ("conflicting instance variable type",
4262 impdecls, rawimpdecls);
4263 error_with_ivar ("previous declaration of",
4264 intdecls, rawintdecls);
4266 else /* both the type and the name don't match */
4268 error ("inconsistent instance variable specification");
4273 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4275 error_with_ivar ("conflicting instance variable name",
4276 impdecls, rawimpdecls);
4277 error_with_ivar ("previous declaration of",
4278 intdecls, rawintdecls);
4281 intdecls = TREE_CHAIN (intdecls);
4282 impdecls = TREE_CHAIN (impdecls);
4283 rawintdecls = TREE_CHAIN (rawintdecls);
4284 rawimpdecls = TREE_CHAIN (rawimpdecls);
4288 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4289 This needs to be done just once per compilation. */
4292 build_super_template (void)
4294 tree decl_specs, field_decl, field_decl_chain;
4296 /* Suppress outputting debug symbols, because
4297 dbxout_init hasn't been called yet. */
4298 enum debug_info_type save_write_symbols = write_symbols;
4299 const struct gcc_debug_hooks *save_hooks = debug_hooks;
4301 write_symbols = NO_DEBUG;
4302 debug_hooks = &do_nothing_debug_hooks;
4304 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4306 /* struct objc_object *self; */
4308 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
4309 field_decl = get_identifier ("self");
4310 field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
4311 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4312 field_decl_chain = field_decl;
4315 /* struct objc_class *super_class; */
4317 /* struct objc_class *class; */
4320 decl_specs = get_identifier (UTAG_CLASS);
4321 decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
4323 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
4325 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
4328 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4329 chainon (field_decl_chain, field_decl);
4331 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4333 write_symbols = save_write_symbols;
4334 debug_hooks = save_hooks;
4337 /* struct objc_ivar {
4344 build_ivar_template (void)
4346 tree objc_ivar_id, objc_ivar_record;
4347 tree decl_specs, field_decl, field_decl_chain;
4349 objc_ivar_id = get_identifier (UTAG_IVAR);
4350 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4352 /* char *ivar_name; */
4354 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4355 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
4357 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4358 field_decl_chain = field_decl;
4360 /* char *ivar_type; */
4362 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
4363 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
4365 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4366 chainon (field_decl_chain, field_decl);
4368 /* int ivar_offset; */
4370 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4371 field_decl = get_identifier ("ivar_offset");
4373 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4374 chainon (field_decl_chain, field_decl);
4376 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4378 return objc_ivar_record;
4383 struct objc_ivar ivar_list[ivar_count];
4387 build_ivar_list_template (tree list_type, int size)
4389 tree objc_ivar_list_record;
4390 tree decl_specs, field_decl, field_decl_chain;
4392 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4394 /* int ivar_count; */
4396 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4397 field_decl = get_identifier ("ivar_count");
4399 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4400 field_decl_chain = field_decl;
4402 /* struct objc_ivar ivar_list[]; */
4404 decl_specs = build_tree_list (NULL_TREE, list_type);
4405 field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
4406 build_int_2 (size, 0));
4408 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4409 chainon (field_decl_chain, field_decl);
4411 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4413 return objc_ivar_list_record;
4419 struct objc_method method_list[method_count];
4423 build_method_list_template (tree list_type, int size)
4425 tree objc_ivar_list_record;
4426 tree decl_specs, field_decl, field_decl_chain;
4428 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4430 /* int method_next; */
4435 xref_tag (RECORD_TYPE,
4436 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
4438 = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
4439 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4440 field_decl_chain = field_decl;
4442 /* int method_count; */
4444 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
4445 field_decl = get_identifier ("method_count");
4447 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4448 chainon (field_decl_chain, field_decl);
4450 /* struct objc_method method_list[]; */
4452 decl_specs = build_tree_list (NULL_TREE, list_type);
4453 field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
4454 build_int_2 (size, 0));
4456 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4457 chainon (field_decl_chain, field_decl);
4459 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4461 return objc_ivar_list_record;
4465 build_ivar_list_initializer (tree type, tree field_decl)
4467 tree initlist = NULL_TREE;
4471 tree ivar = NULL_TREE;
4474 if (DECL_NAME (field_decl))
4475 ivar = tree_cons (NULL_TREE,
4476 add_objc_string (DECL_NAME (field_decl),
4480 /* Unnamed bit-field ivar (yuck). */
4481 ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar);
4484 encode_field_decl (field_decl,
4485 obstack_object_size (&util_obstack),
4486 OBJC_ENCODE_DONT_INLINE_DEFS);
4488 /* Null terminate string. */
4489 obstack_1grow (&util_obstack, 0);
4493 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4496 obstack_free (&util_obstack, util_firstobj);
4499 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4500 initlist = tree_cons (NULL_TREE,
4501 objc_build_constructor (type, nreverse (ivar)),
4504 field_decl = TREE_CHAIN (field_decl);
4505 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4509 return objc_build_constructor (build_array_type (type, 0),
4510 nreverse (initlist));
4514 generate_ivars_list (tree type, const char *name, int size, tree list)
4516 tree sc_spec, decl_specs, decl, initlist;
4518 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4519 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4521 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4522 decl_specs, 1, NULL_TREE);
4524 initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
4525 initlist = tree_cons (NULL_TREE, list, initlist);
4528 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4534 /* Count only the fields occurring in T. */
4536 ivar_list_length (tree t)
4540 for (; t; t = TREE_CHAIN (t))
4541 if (TREE_CODE (t) == FIELD_DECL)
4548 generate_ivar_lists (void)
4550 tree initlist, ivar_list_template, chain;
4551 tree cast, variable_length_type;
4554 generating_instance_variables = 1;
4556 if (!objc_ivar_template)
4557 objc_ivar_template = build_ivar_template ();
4561 (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
4562 get_identifier (UTAG_IVAR_LIST))),
4564 variable_length_type = groktypename (cast);
4566 /* Only generate class variables for the root of the inheritance
4567 hierarchy since these will be the same for every class. */
4569 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4570 && (chain = TYPE_FIELDS (objc_class_template)))
4572 size = ivar_list_length (chain);
4574 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4575 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4577 UOBJC_CLASS_VARIABLES_decl
4578 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4580 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4583 UOBJC_CLASS_VARIABLES_decl = 0;
4585 chain = CLASS_IVARS (implementation_template);
4588 size = ivar_list_length (chain);
4589 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4590 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4592 UOBJC_INSTANCE_VARIABLES_decl
4593 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4595 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4598 UOBJC_INSTANCE_VARIABLES_decl = 0;
4600 generating_instance_variables = 0;
4604 build_dispatch_table_initializer (tree type, tree entries)
4606 tree initlist = NULL_TREE;
4610 tree elemlist = NULL_TREE;
4612 elemlist = tree_cons (NULL_TREE,
4613 build_selector (METHOD_SEL_NAME (entries)),
4616 /* Generate the method encoding if we don't have one already. */
4617 if (! METHOD_ENCODING (entries))
4618 METHOD_ENCODING (entries) =
4619 encode_method_prototype (entries);
4621 elemlist = tree_cons (NULL_TREE,
4622 add_objc_string (METHOD_ENCODING (entries),
4626 elemlist = tree_cons (NULL_TREE,
4627 build_unary_op (ADDR_EXPR,
4628 METHOD_DEFINITION (entries), 1),
4631 initlist = tree_cons (NULL_TREE,
4632 objc_build_constructor (type, nreverse (elemlist)),
4635 entries = TREE_CHAIN (entries);
4639 return objc_build_constructor (build_array_type (type, 0),
4640 nreverse (initlist));
4643 /* To accomplish method prototyping without generating all kinds of
4644 inane warnings, the definition of the dispatch table entries were
4647 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4649 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4652 build_method_template (void)
4655 tree decl_specs, field_decl, field_decl_chain;
4657 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4659 /* struct objc_selector *_cmd; */
4660 decl_specs = tree_cons (NULL_TREE,
4661 xref_tag (RECORD_TYPE,
4662 get_identifier (TAG_SELECTOR)),
4664 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
4666 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4667 field_decl_chain = field_decl;
4669 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
4670 field_decl = build1 (INDIRECT_REF, NULL_TREE,
4671 get_identifier ("method_types"));
4672 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4673 chainon (field_decl_chain, field_decl);
4677 decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
4678 field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
4679 field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
4680 chainon (field_decl_chain, field_decl);
4682 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4689 generate_dispatch_table (tree type, const char *name, int size, tree list)
4691 tree sc_spec, decl_specs, decl, initlist;
4693 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4694 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
4696 decl = start_decl (synth_id_with_class_suffix (name, objc_implementation_context),
4697 decl_specs, 1, NULL_TREE);
4699 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
4700 initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist);
4701 initlist = tree_cons (NULL_TREE, list, initlist);
4704 objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
4711 mark_referenced_methods (void)
4713 struct imp_entry *impent;
4716 for (impent = imp_list; impent; impent = impent->next)
4718 chain = CLASS_CLS_METHODS (impent->imp_context);
4721 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4722 chain = TREE_CHAIN (chain);
4725 chain = CLASS_NST_METHODS (impent->imp_context);
4728 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4729 chain = TREE_CHAIN (chain);
4735 generate_dispatch_tables (void)
4737 tree initlist, chain, method_list_template;
4738 tree cast, variable_length_type;
4741 if (!objc_method_template)
4742 objc_method_template = build_method_template ();
4746 (build_tree_list (NULL_TREE,
4747 xref_tag (RECORD_TYPE,
4748 get_identifier (UTAG_METHOD_LIST))),
4751 variable_length_type = groktypename (cast);
4753 chain = CLASS_CLS_METHODS (objc_implementation_context);
4756 size = list_length (chain);
4758 method_list_template
4759 = build_method_list_template (objc_method_template, size);
4761 = build_dispatch_table_initializer (objc_method_template, chain);
4763 UOBJC_CLASS_METHODS_decl
4764 = generate_dispatch_table (method_list_template,
4765 ((TREE_CODE (objc_implementation_context)
4766 == CLASS_IMPLEMENTATION_TYPE)
4767 ? "_OBJC_CLASS_METHODS"
4768 : "_OBJC_CATEGORY_CLASS_METHODS"),
4770 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4773 UOBJC_CLASS_METHODS_decl = 0;
4775 chain = CLASS_NST_METHODS (objc_implementation_context);
4778 size = list_length (chain);
4780 method_list_template
4781 = build_method_list_template (objc_method_template, size);
4783 = build_dispatch_table_initializer (objc_method_template, chain);
4785 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4786 UOBJC_INSTANCE_METHODS_decl
4787 = generate_dispatch_table (method_list_template,
4788 "_OBJC_INSTANCE_METHODS",
4791 /* We have a category. */
4792 UOBJC_INSTANCE_METHODS_decl
4793 = generate_dispatch_table (method_list_template,
4794 "_OBJC_CATEGORY_INSTANCE_METHODS",
4796 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4799 UOBJC_INSTANCE_METHODS_decl = 0;
4803 generate_protocol_list (tree i_or_p)
4805 tree initlist, decl_specs, sc_spec;
4806 tree refs_decl, expr_decl, lproto, e, plist;
4810 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4811 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4812 plist = CLASS_PROTOCOL_LIST (i_or_p);
4813 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4814 plist = PROTOCOL_LIST (i_or_p);
4818 cast_type = groktypename
4820 (build_tree_list (NULL_TREE,
4821 xref_tag (RECORD_TYPE,
4822 get_identifier (UTAG_PROTOCOL))),
4823 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)));
4826 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4827 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4828 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4831 /* Build initializer. */
4832 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE);
4834 e = build_int_2 (size, 0);
4835 TREE_TYPE (e) = cast_type;
4836 initlist = tree_cons (NULL_TREE, e, initlist);
4838 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4840 tree pval = TREE_VALUE (lproto);
4842 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4843 && PROTOCOL_FORWARD_DECL (pval))
4845 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4846 initlist = tree_cons (NULL_TREE, e, initlist);
4850 /* static struct objc_protocol *refs[n]; */
4852 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
4853 decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
4854 get_identifier (UTAG_PROTOCOL)),
4857 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4858 expr_decl = build_nt (ARRAY_REF,
4859 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4861 build_int_2 (size + 2, 0));
4862 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4863 expr_decl = build_nt (ARRAY_REF,
4864 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4866 build_int_2 (size + 2, 0));
4867 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4869 = build_nt (ARRAY_REF,
4870 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4872 build_int_2 (size + 2, 0));
4876 expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
4878 refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
4879 DECL_CONTEXT (refs_decl) = NULL_TREE;
4881 finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4882 nreverse (initlist)),
4889 build_category_initializer (tree type, tree cat_name, tree class_name,
4890 tree instance_methods, tree class_methods,
4893 tree initlist = NULL_TREE, expr;
4895 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4896 initlist = tree_cons (NULL_TREE, class_name, initlist);
4898 if (!instance_methods)
4899 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4902 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4903 initlist = tree_cons (NULL_TREE, expr, initlist);
4906 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4909 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4910 initlist = tree_cons (NULL_TREE, expr, initlist);
4913 /* protocol_list = */
4915 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4918 tree cast_type2 = groktypename
4920 (build_tree_list (NULL_TREE,
4921 xref_tag (RECORD_TYPE,
4922 get_identifier (UTAG_PROTOCOL))),
4923 build1 (INDIRECT_REF, NULL_TREE,
4924 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
4926 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
4927 TREE_TYPE (expr) = cast_type2;
4928 initlist = tree_cons (NULL_TREE, expr, initlist);
4931 return objc_build_constructor (type, nreverse (initlist));
4934 /* struct objc_class {
4935 struct objc_class *isa;
4936 struct objc_class *super_class;
4941 struct objc_ivar_list *ivars;
4942 struct objc_method_list *methods;
4943 if (flag_next_runtime)
4944 struct objc_cache *cache;
4946 struct sarray *dtable;
4947 struct objc_class *subclass_list;
4948 struct objc_class *sibling_class;
4950 struct objc_protocol_list *protocols;
4951 if (flag_next_runtime)
4953 void *gc_object_type;
4957 build_shared_structure_initializer (tree type, tree isa, tree super,
4958 tree name, tree size, int status,
4959 tree dispatch_table, tree ivar_list,
4962 tree initlist = NULL_TREE, expr;
4965 initlist = tree_cons (NULL_TREE, isa, initlist);
4968 initlist = tree_cons (NULL_TREE, super, initlist);
4971 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4974 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4977 initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist);
4979 /* instance_size = */
4980 initlist = tree_cons (NULL_TREE, size, initlist);
4982 /* objc_ivar_list = */
4984 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4987 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4988 initlist = tree_cons (NULL_TREE, expr, initlist);
4991 /* objc_method_list = */
4992 if (!dispatch_table)
4993 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
4996 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4997 initlist = tree_cons (NULL_TREE, expr, initlist);
5000 if (flag_next_runtime)
5001 /* method_cache = */
5002 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5006 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5008 /* subclass_list = */
5009 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5011 /* sibling_class = */
5012 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5015 /* protocol_list = */
5016 if (! protocol_list)
5017 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5023 (build_tree_list (NULL_TREE,
5024 xref_tag (RECORD_TYPE,
5025 get_identifier (UTAG_PROTOCOL))),
5026 build1 (INDIRECT_REF, NULL_TREE,
5027 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))));
5029 expr = build_unary_op (ADDR_EXPR, protocol_list, 0);
5030 TREE_TYPE (expr) = cast_type2;
5031 initlist = tree_cons (NULL_TREE, expr, initlist);
5034 if (flag_next_runtime)
5036 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5038 /* gc_object_type = NULL */
5039 initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
5041 return objc_build_constructor (type, nreverse (initlist));
5044 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5047 lookup_category (tree class, tree cat_name)
5049 tree category = CLASS_CATEGORY_LIST (class);
5051 while (category && CLASS_SUPER_NAME (category) != cat_name)
5052 category = CLASS_CATEGORY_LIST (category);
5056 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5059 generate_category (tree cat)
5061 tree sc_spec, decl_specs, decl;
5062 tree initlist, cat_name_expr, class_name_expr;
5063 tree protocol_decl, category;
5065 add_class_reference (CLASS_NAME (cat));
5066 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5068 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5070 category = lookup_category (implementation_template,
5071 CLASS_SUPER_NAME (cat));
5073 if (category && CLASS_PROTOCOL_LIST (category))
5075 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5076 protocol_decl = generate_protocol_list (category);
5081 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
5082 decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
5084 decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
5085 objc_implementation_context),
5086 decl_specs, 1, NULL_TREE);
5088 initlist = build_category_initializer (TREE_TYPE (decl),
5089 cat_name_expr, class_name_expr,
5090 UOBJC_INSTANCE_METHODS_decl,
5091 UOBJC_CLASS_METHODS_decl,
5094 finish_decl (decl, initlist, NULL_TREE);
5097 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5098 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5101 generate_shared_structures (void)
5103 tree sc_spec, decl_specs, decl;
5104 tree name_expr, super_expr, root_expr;
5105 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5106 tree cast_type, initlist, protocol_decl;
5108 my_super_id = CLASS_SUPER_NAME (implementation_template);
5111 add_class_reference (my_super_id);
5113 /* Compute "my_root_id" - this is required for code generation.
5114 the "isa" for all meta class structures points to the root of
5115 the inheritance hierarchy (e.g. "__Object")... */
5116 my_root_id = my_super_id;
5119 tree my_root_int = lookup_interface (my_root_id);
5121 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5122 my_root_id = CLASS_SUPER_NAME (my_root_int);
5129 /* No super class. */
5130 my_root_id = CLASS_NAME (implementation_template);
5133 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5134 objc_class_template),
5135 build1 (INDIRECT_REF,
5136 NULL_TREE, NULL_TREE)));
5138 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5141 /* Install class `isa' and `super' pointers at runtime. */
5144 super_expr = add_objc_string (my_super_id, class_names);
5145 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5148 super_expr = build_int_2 (0, 0);
5150 root_expr = add_objc_string (my_root_id, class_names);
5151 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5153 if (CLASS_PROTOCOL_LIST (implementation_template))
5155 generate_protocol_references
5156 (CLASS_PROTOCOL_LIST (implementation_template));
5157 protocol_decl = generate_protocol_list (implementation_template);
5162 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5164 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5165 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5167 decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
5171 = build_shared_structure_initializer
5173 root_expr, super_expr, name_expr,
5174 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5176 UOBJC_CLASS_METHODS_decl,
5177 UOBJC_CLASS_VARIABLES_decl,
5180 finish_decl (decl, initlist, NULL_TREE);
5182 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5184 decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
5188 = build_shared_structure_initializer
5190 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5191 super_expr, name_expr,
5192 convert (integer_type_node,
5193 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5194 (implementation_template))),
5196 UOBJC_INSTANCE_METHODS_decl,
5197 UOBJC_INSTANCE_VARIABLES_decl,
5200 finish_decl (decl, initlist, NULL_TREE);
5204 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5207 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5208 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5210 const char *const class_name
5211 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5212 string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3);
5213 sprintf (string, "%s_%s", preamble,
5214 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5216 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5217 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5219 /* We have a category. */
5220 const char *const class_name
5221 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5222 const char *const class_super_name
5223 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5224 string = (char *) alloca (strlen (preamble)
5225 + strlen (class_name)
5226 + strlen (class_super_name)
5228 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5230 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5232 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5234 = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3);
5235 sprintf (string, "%s_%s", preamble, protocol_name);
5240 return get_identifier (string);
5244 is_objc_type_qualifier (tree node)
5246 return (TREE_CODE (node) == IDENTIFIER_NODE
5247 && (node == ridpointers [(int) RID_CONST]
5248 || node == ridpointers [(int) RID_VOLATILE]
5249 || node == ridpointers [(int) RID_IN]
5250 || node == ridpointers [(int) RID_OUT]
5251 || node == ridpointers [(int) RID_INOUT]
5252 || node == ridpointers [(int) RID_BYCOPY]
5253 || node == ridpointers [(int) RID_BYREF]
5254 || node == ridpointers [(int) RID_ONEWAY]));
5257 /* If type is empty or only type qualifiers are present, add default
5258 type of id (otherwise grokdeclarator will default to int). */
5261 adjust_type_for_id_default (tree type)
5263 tree declspecs, chain;
5266 return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference),
5267 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5269 declspecs = TREE_PURPOSE (type);
5271 /* Determine if a typespec is present. */
5272 for (chain = declspecs;
5274 chain = TREE_CHAIN (chain))
5276 if (TYPED_OBJECT (TREE_VALUE (chain))
5277 && !(TREE_VALUE (type)
5278 && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
5279 error ("can not use an object as parameter to a method\n");
5280 if (!is_objc_type_qualifier (TREE_VALUE (chain)))
5284 return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
5286 build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
5291 selector ':' '(' typename ')' identifier
5294 Transform an Objective-C keyword argument into
5295 the C equivalent parameter declarator.
5297 In: key_name, an "identifier_node" (optional).
5298 arg_type, a "tree_list" (optional).
5299 arg_name, an "identifier_node".
5301 Note: It would be really nice to strongly type the preceding
5302 arguments in the function prototype; however, then I
5303 could not use the "accessor" macros defined in "tree.h".
5305 Out: an instance of "keyword_decl". */
5308 build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5312 /* If no type is specified, default to "id". */
5313 arg_type = adjust_type_for_id_default (arg_type);
5315 keyword_decl = make_node (KEYWORD_DECL);
5317 TREE_TYPE (keyword_decl) = arg_type;
5318 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5319 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5321 return keyword_decl;
5324 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5327 build_keyword_selector (tree selector)
5330 tree key_chain, key_name;
5333 /* Scan the selector to see how much space we'll need. */
5334 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5336 if (TREE_CODE (selector) == KEYWORD_DECL)
5337 key_name = KEYWORD_KEY_NAME (key_chain);
5338 else if (TREE_CODE (selector) == TREE_LIST)
5339 key_name = TREE_PURPOSE (key_chain);
5344 len += IDENTIFIER_LENGTH (key_name) + 1;
5346 /* Just a ':' arg. */
5350 buf = (char *) alloca (len + 1);
5351 /* Start the buffer out as an empty string. */
5354 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5356 if (TREE_CODE (selector) == KEYWORD_DECL)
5357 key_name = KEYWORD_KEY_NAME (key_chain);
5358 else if (TREE_CODE (selector) == TREE_LIST)
5360 key_name = TREE_PURPOSE (key_chain);
5361 /* The keyword decl chain will later be used as a function argument
5362 chain. Unhook the selector itself so as to not confuse other
5363 parts of the compiler. */
5364 TREE_PURPOSE (key_chain) = NULL_TREE;
5370 strcat (buf, IDENTIFIER_POINTER (key_name));
5374 return get_identifier (buf);
5377 /* Used for declarations and definitions. */
5380 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5385 /* If no type is specified, default to "id". */
5386 ret_type = adjust_type_for_id_default (ret_type);
5388 method_decl = make_node (code);
5389 TREE_TYPE (method_decl) = ret_type;
5391 /* If we have a keyword selector, create an identifier_node that
5392 represents the full selector name (`:' included)... */
5393 if (TREE_CODE (selector) == KEYWORD_DECL)
5395 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5396 METHOD_SEL_ARGS (method_decl) = selector;
5397 METHOD_ADD_ARGS (method_decl) = add_args;
5401 METHOD_SEL_NAME (method_decl) = selector;
5402 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5403 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5409 #define METHOD_DEF 0
5410 #define METHOD_REF 1
5412 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5413 an argument list for method METH. CONTEXT is either METHOD_DEF or
5414 METHOD_REF, saying whether we are trying to define a method or call
5415 one. SUPERFLAG says this is for a send to super; this makes a
5416 difference for the NeXT calling sequence in which the lookup and
5417 the method call are done together. If METH is null, user-defined
5418 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5421 get_arg_type_list (tree meth, int context, int superflag)
5425 /* Receiver type. */
5426 if (flag_next_runtime && superflag)
5427 arglist = build_tree_list (NULL_TREE, super_type);
5428 else if (context == METHOD_DEF)
5429 arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
5431 arglist = build_tree_list (NULL_TREE, id_type);
5433 /* Selector type - will eventually change to `int'. */
5434 chainon (arglist, build_tree_list (NULL_TREE, selector_type));
5436 /* No actual method prototype given -- assume that remaining arguments
5441 /* Build a list of argument types. */
5442 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5444 tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
5445 chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
5448 if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
5449 /* We have a `, ...' immediately following the selector,
5450 finalize the arglist...simulate get_parm_info (true). */
5452 else if (METHOD_ADD_ARGS (meth))
5454 /* we have a variable length selector */
5455 tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5456 chainon (arglist, add_arg_list);
5459 /* finalize the arglist...simulate get_parm_info (false) */
5460 chainon (arglist, void_list_node);
5466 check_duplicates (hash hsh, int methods, int is_class)
5468 tree meth = NULL_TREE;
5476 /* We have two or more methods with the same name but
5480 warning ("multiple %s named `%c%s' found",
5481 methods ? "methods" : "selectors",
5482 (is_class ? '+' : '-'),
5483 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5485 warn_with_method (methods ? "using" : "found",
5486 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5490 for (loop = hsh->list; loop; loop = loop->next)
5491 warn_with_method ("also found",
5492 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5501 /* If RECEIVER is a class reference, return the identifier node for
5502 the referenced class. RECEIVER is created by get_class_reference,
5503 so we check the exact form created depending on which runtimes are
5507 receiver_is_class_object (tree receiver, int self, int super)
5509 tree chain, exp, arg;
5511 /* The receiver is 'self' or 'super' in the context of a class method. */
5512 if (objc_method_context
5513 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5516 ? CLASS_SUPER_NAME (implementation_template)
5517 : CLASS_NAME (implementation_template));
5519 if (flag_next_runtime)
5521 /* The receiver is a variable created by
5522 build_class_reference_decl. */
5523 if (TREE_CODE (receiver) == VAR_DECL
5524 && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
5525 /* Look up the identifier. */
5526 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5527 if (TREE_PURPOSE (chain) == receiver)
5528 return TREE_VALUE (chain);
5531 /* The receiver is a function call that returns an id. Check if
5532 it is a call to objc_getClass, if so, pick up the class name. */
5533 if (TREE_CODE (receiver) == CALL_EXPR
5534 && (exp = TREE_OPERAND (receiver, 0))
5535 && TREE_CODE (exp) == ADDR_EXPR
5536 && (exp = TREE_OPERAND (exp, 0))
5537 && TREE_CODE (exp) == FUNCTION_DECL
5538 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5539 prototypes for objc_get_class(). Thankfully, they seem to share the
5540 same function type. */
5541 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5542 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5543 /* We have a call to objc_get_class/objc_getClass! */
5544 && (arg = TREE_OPERAND (receiver, 1))
5545 && TREE_CODE (arg) == TREE_LIST
5546 && (arg = TREE_VALUE (arg)))
5549 if (TREE_CODE (arg) == ADDR_EXPR
5550 && (arg = TREE_OPERAND (arg, 0))
5551 && TREE_CODE (arg) == STRING_CST)
5552 /* Finally, we have the class name. */
5553 return get_identifier (TREE_STRING_POINTER (arg));
5558 /* If we are currently building a message expr, this holds
5559 the identifier of the selector of the message. This is
5560 used when printing warnings about argument mismatches. */
5562 static tree current_objc_message_selector = 0;
5565 objc_message_selector (void)
5567 return current_objc_message_selector;
5570 /* Construct an expression for sending a message.
5571 MESS has the object to send to in TREE_PURPOSE
5572 and the argument list (including selector) in TREE_VALUE.
5574 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5575 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5578 build_message_expr (tree mess)
5580 tree receiver = TREE_PURPOSE (mess);
5582 tree args = TREE_VALUE (mess);
5583 tree method_params = NULL_TREE;
5585 if (TREE_CODE (receiver) == ERROR_MARK)
5586 return error_mark_node;
5588 /* Obtain the full selector name. */
5589 if (TREE_CODE (args) == IDENTIFIER_NODE)
5590 /* A unary selector. */
5592 else if (TREE_CODE (args) == TREE_LIST)
5593 sel_name = build_keyword_selector (args);
5597 /* Build the parameter list to give to the method. */
5598 if (TREE_CODE (args) == TREE_LIST)
5600 tree chain = args, prev = NULL_TREE;
5602 /* We have a keyword selector--check for comma expressions. */
5605 tree element = TREE_VALUE (chain);
5607 /* We have a comma expression, must collapse... */
5608 if (TREE_CODE (element) == TREE_LIST)
5611 TREE_CHAIN (prev) = element;
5616 chain = TREE_CHAIN (chain);
5618 method_params = args;
5622 if (processing_template_decl)
5623 /* Must wait until template instantiation time. */
5624 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5628 return finish_message_expr (receiver, sel_name, method_params);
5631 /* Look up method SEL_NAME that would be suitable for receiver
5632 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5633 nonzero), and report on any duplicates. */
5636 lookup_method_in_hash_lists (tree sel_name, int is_class)
5638 hash method_prototype = NULL;
5641 method_prototype = hash_lookup (nst_method_hash_list,
5644 if (!method_prototype)
5646 method_prototype = hash_lookup (cls_method_hash_list,
5651 return check_duplicates (method_prototype, 1, is_class);
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)
5729 = lookup_method_in_hash_lists (sel_name,
5730 is_class != NULL_TREE);
5734 tree orig_rtype = rtype, saved_rtype;
5736 if (TREE_CODE (rtype) == POINTER_TYPE)
5737 rtype = TREE_TYPE (rtype);
5738 /* Traverse typedef aliases */
5739 while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
5740 && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
5741 && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
5742 rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
5743 saved_rtype = rtype;
5744 if (TYPED_OBJECT (rtype))
5746 rprotos = TYPE_PROTOCOL_LIST (rtype);
5747 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5749 /* If we could not find an @interface declaration, we must have
5750 only seen a @class declaration; so, we cannot say anything
5751 more intelligent about which methods the receiver will
5754 rtype = saved_rtype;
5755 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5756 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5758 /* We have a valid ObjC class name. Look up the method name
5759 in the published @interface for the class (and its
5762 = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
5764 /* If the method was not found in the @interface, it may still
5765 exist locally as part of the @implementation. */
5766 if (!method_prototype && objc_implementation_context
5767 && CLASS_NAME (objc_implementation_context)
5768 == OBJC_TYPE_NAME (rtype))
5772 ? CLASS_CLS_METHODS (objc_implementation_context)
5773 : CLASS_NST_METHODS (objc_implementation_context)),
5776 /* If we haven't found a candidate method by now, try looking for
5777 it in the protocol list. */
5778 if (!method_prototype && rprotos)
5780 = lookup_method_in_protocol_list (rprotos, sel_name,
5781 is_class != NULL_TREE);
5785 warning ("invalid receiver type `%s'",
5786 gen_declaration (orig_rtype, errbuf));
5787 rtype = rprotos = NULL_TREE;
5791 if (!method_prototype)
5793 static bool warn_missing_methods = false;
5796 warning ("`%s' may not respond to `%c%s'",
5797 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5798 (is_class ? '+' : '-'),
5799 IDENTIFIER_POINTER (sel_name));
5801 warning ("`%c%s' not implemented by protocol(s)",
5802 (is_class ? '+' : '-'),
5803 IDENTIFIER_POINTER (sel_name));
5804 if (!warn_missing_methods)
5806 warning ("(Messages without a matching method signature");
5807 warning ("will be assumed to return `id' and accept");
5808 warning ("`...' as arguments.)");
5809 warn_missing_methods = true;
5813 /* Save the selector name for printing error messages. */
5814 current_objc_message_selector = sel_name;
5816 /* Build the parameters list for looking up the method.
5817 These are the object itself and the selector. */
5819 if (flag_typed_selectors)
5820 selector = build_typed_selector_reference (sel_name, method_prototype);
5822 selector = build_selector_reference (sel_name);
5824 retval = build_objc_method_call (super, method_prototype,
5826 selector, method_params);
5828 current_objc_message_selector = 0;
5833 /* Build a tree expression to send OBJECT the operation SELECTOR,
5834 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5835 assuming the method has prototype METHOD_PROTOTYPE.
5836 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5837 Use METHOD_PARAMS as list of args to pass to the method.
5838 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5841 build_objc_method_call (int super_flag, tree method_prototype,
5842 tree lookup_object, tree selector,
5845 tree sender = (super_flag ? umsg_super_decl :
5846 (!flag_next_runtime || flag_nil_receivers
5848 : umsg_nonnil_decl));
5849 tree rcv_p = (super_flag ? super_type : id_type);
5851 /* If a prototype for the method to be called exists, then cast
5852 the sender's return type and arguments to match that of the method.
5853 Otherwise, leave sender as is. */
5856 ? groktypename (TREE_TYPE (method_prototype))
5859 = build_pointer_type
5860 (build_function_type
5863 (method_prototype, METHOD_REF, super_flag)));
5865 lookup_object = build_c_cast (rcv_p, lookup_object);
5867 if (flag_next_runtime)
5869 /* If we are returning a struct in memory, and the address
5870 of that memory location is passed as a hidden first
5871 argument, then change which messenger entry point this
5872 expr will call. NB: Note that sender_cast remains
5873 unchanged (it already has a struct return type). */
5874 if (!targetm.calls.struct_value_rtx (0, 0)
5875 && (TREE_CODE (ret_type) == RECORD_TYPE
5876 || TREE_CODE (ret_type) == UNION_TYPE)
5877 && targetm.calls.return_in_memory (ret_type, 0))
5878 sender = (super_flag ? umsg_super_stret_decl :
5879 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5881 method_params = tree_cons (NULL_TREE, lookup_object,
5882 tree_cons (NULL_TREE, selector,
5884 TREE_USED (sender) = 1;
5885 assemble_external (sender);
5886 /* We want to cast the sender, not convert it. */
5887 return build_function_call (build_c_cast (sender_cast, sender),
5892 /* This is the portable (GNU) way. */
5893 tree method, object;
5895 /* First, call the lookup function to get a pointer to the method,
5896 then cast the pointer, then call it with the method arguments.
5897 Use SAVE_EXPR to avoid evaluating the receiver twice. */
5898 lookup_object = save_expr (lookup_object);
5899 object = (super_flag ? self_decl : lookup_object);
5900 TREE_USED (sender) = 1;
5901 assemble_external (sender);
5903 = build_function_call (sender,
5904 tree_cons (NULL_TREE, lookup_object,
5905 tree_cons (NULL_TREE, selector,
5908 /* Pass the object to the method. */
5909 TREE_USED (method) = 1;
5910 assemble_external (method);
5911 return build_function_call
5912 (build_c_cast (sender_cast, method),
5913 tree_cons (NULL_TREE, object,
5914 tree_cons (NULL_TREE, selector, method_params)));
5919 build_protocol_reference (tree p)
5921 tree decl, ident, ptype;
5923 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5925 ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5927 = groktypename (build_tree_list (build_tree_list (NULL_TREE,
5928 objc_protocol_template),
5931 if (identifier_global_value (ident))
5932 decl = identifier_global_value (ident); /* Set by pushdecl. */
5935 decl = build_decl (VAR_DECL, ident, ptype);
5936 DECL_EXTERNAL (decl) = 1;
5937 TREE_PUBLIC (decl) = 0;
5938 TREE_USED (decl) = 1;
5939 DECL_ARTIFICIAL (decl) = 1;
5941 make_decl_rtl (decl, 0);
5942 pushdecl_top_level (decl);
5945 PROTOCOL_FORWARD_DECL (p) = decl;
5948 /* This function is called by the parser when (and only when) a
5949 @protocol() expression is found, in order to compile it. */
5951 build_protocol_expr (tree protoname)
5954 tree p = lookup_protocol (protoname);
5958 error ("cannot find protocol declaration for `%s'",
5959 IDENTIFIER_POINTER (protoname));
5960 return error_mark_node;
5963 if (!PROTOCOL_FORWARD_DECL (p))
5964 build_protocol_reference (p);
5966 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5968 TREE_TYPE (expr) = protocol_type;
5970 /* The @protocol() expression is being compiled into a pointer to a
5971 statically allocated instance of the Protocol class. To become
5972 usable at runtime, the 'isa' pointer of the instance need to be
5973 fixed up at runtime by the runtime library, to point to the
5974 actual 'Protocol' class. */
5976 /* For the GNU runtime, put the static Protocol instance in the list
5977 of statically allocated instances, so that we make sure that its
5978 'isa' pointer is fixed up at runtime by the GNU runtime library
5979 to point to the Protocol class (at runtime, when loading the
5980 module, the GNU runtime library loops on the statically allocated
5981 instances (as found in the defs field in objc_symtab) and fixups
5982 all the 'isa' pointers of those objects). */
5983 if (! flag_next_runtime)
5985 /* This type is a struct containing the fields of a Protocol
5986 object. (Cfr. protocol_type instead is the type of a pointer
5987 to such a struct). */
5988 tree protocol_struct_type = xref_tag
5989 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5992 /* Look for the list of Protocol statically allocated instances
5993 to fixup at runtime. Create a new list to hold Protocol
5994 statically allocated instances, if the list is not found. At
5995 present there is only another list, holding NSConstantString
5996 static instances to be fixed up at runtime. */
5997 for (chain = &objc_static_instances;
5998 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5999 chain = &TREE_CHAIN (*chain));
6002 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6003 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6007 /* Add this statically allocated instance to the Protocol list. */
6008 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6009 PROTOCOL_FORWARD_DECL (p),
6010 TREE_PURPOSE (*chain));
6017 /* This function is called by the parser when a @selector() expression
6018 is found, in order to compile it. It is only called by the parser
6019 and only to compile a @selector(). */
6021 build_selector_expr (tree selnamelist)
6025 /* Obtain the full selector name. */
6026 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6027 /* A unary selector. */
6028 selname = selnamelist;
6029 else if (TREE_CODE (selnamelist) == TREE_LIST)
6030 selname = build_keyword_selector (selnamelist);
6034 /* If we are required to check @selector() expressions as they
6035 are found, check that the selector has been declared. */
6036 if (warn_undeclared_selector)
6038 /* Look the selector up in the list of all known class and
6039 instance methods (up to this line) to check that the selector
6043 /* First try with instance methods. */
6044 hsh = hash_lookup (nst_method_hash_list, selname);
6046 /* If not found, try with class methods. */
6049 hsh = hash_lookup (cls_method_hash_list, selname);
6052 /* If still not found, print out a warning. */
6055 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
6060 if (flag_typed_selectors)
6061 return build_typed_selector_reference (selname, 0);
6063 return build_selector_reference (selname);
6067 build_encode_expr (tree type)
6072 encode_type (type, obstack_object_size (&util_obstack),
6073 OBJC_ENCODE_INLINE_DEFS);
6074 obstack_1grow (&util_obstack, 0); /* null terminate string */
6075 string = obstack_finish (&util_obstack);
6077 /* Synthesize a string that represents the encoded struct/union. */
6078 result = my_build_string (strlen (string) + 1, string);
6079 obstack_free (&util_obstack, util_firstobj);
6084 build_ivar_reference (tree id)
6086 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6088 /* Historically, a class method that produced objects (factory
6089 method) would assign `self' to the instance that it
6090 allocated. This would effectively turn the class method into
6091 an instance method. Following this assignment, the instance
6092 variables could be accessed. That practice, while safe,
6093 violates the simple rule that a class method should not refer
6094 to an instance variable. It's better to catch the cases
6095 where this is done unknowingly than to support the above
6097 warning ("instance variable `%s' accessed in class method",
6098 IDENTIFIER_POINTER (id));
6099 TREE_TYPE (self_decl) = instance_type; /* cast */
6102 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
6105 /* Compute a hash value for a given method SEL_NAME. */
6108 hash_func (tree sel_name)
6110 const unsigned char *s
6111 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6115 h = h * 67 + *s++ - 113;
6122 nst_method_hash_list
6123 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6124 cls_method_hash_list
6125 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6128 /* WARNING!!!! hash_enter is called with a method, and will peek
6129 inside to find its selector! But hash_lookup is given a selector
6130 directly, and looks for the selector that's inside the found
6131 entry's key (method) for comparison. */
6134 hash_enter (hash *hashlist, tree method)
6137 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6139 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6141 obj->next = hashlist[slot];
6144 hashlist[slot] = obj; /* append to front */
6148 hash_lookup (hash *hashlist, tree sel_name)
6152 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6156 if (sel_name == METHOD_SEL_NAME (target->key))
6159 target = target->next;
6165 hash_add_attr (hash entry, tree value)
6169 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6170 obj->next = entry->list;
6173 entry->list = obj; /* append to front */
6177 lookup_method (tree mchain, tree method)
6181 if (TREE_CODE (method) == IDENTIFIER_NODE)
6184 key = METHOD_SEL_NAME (method);
6188 if (METHOD_SEL_NAME (mchain) == key)
6191 mchain = TREE_CHAIN (mchain);
6197 lookup_method_static (tree interface, tree ident, int is_class)
6199 tree meth = NULL_TREE, root_inter = NULL_TREE;
6200 tree inter = interface;
6204 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6205 tree category = inter;
6207 /* First, look up the method in the class itself. */
6208 if ((meth = lookup_method (chain, ident)))
6211 /* Failing that, look for the method in each category of the class. */
6212 while ((category = CLASS_CATEGORY_LIST (category)))
6214 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6216 /* Check directly in each category. */
6217 if ((meth = lookup_method (chain, ident)))
6220 /* Failing that, check in each category's protocols. */
6221 if (CLASS_PROTOCOL_LIST (category))
6223 if ((meth = (lookup_method_in_protocol_list
6224 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6229 /* If not found in categories, check in protocols of the main class. */
6230 if (CLASS_PROTOCOL_LIST (inter))
6232 if ((meth = (lookup_method_in_protocol_list
6233 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6237 /* Failing that, climb up the inheritance hierarchy. */
6239 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6243 /* If no class (factory) method was found, check if an _instance_
6244 method of the same name exists in the root class. This is what
6245 the Objective-C runtime will do. If an instance method was not
6247 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6250 /* Add the method to the hash list if it doesn't contain an identical
6253 add_method_to_hash_list (hash *hash_list, tree method)
6257 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6259 /* Install on a global chain. */
6260 hash_enter (hash_list, method);
6264 /* Check types against those; if different, add to a list. */
6266 int already_there = comp_proto_with_proto (method, hsh->key);
6267 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6268 already_there |= comp_proto_with_proto (method, loop->value);
6270 hash_add_attr (hsh, method);
6275 objc_add_method (tree class, tree method, int is_class)
6279 if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
6281 /* put method on list in reverse order */
6284 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6285 CLASS_CLS_METHODS (class) = method;
6289 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6290 CLASS_NST_METHODS (class) = method;
6295 /* When processing an @interface for a class or category, give hard
6296 errors on methods with identical selectors but differing argument
6297 and/or return types. We do not do this for @implementations, because
6298 C/C++ will do it for us (i.e., there will be duplicate function
6299 definition errors). */
6300 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6301 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6302 && !comp_proto_with_proto (method, mth))
6303 error ("duplicate declaration of method `%c%s'",
6304 is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6308 add_method_to_hash_list (cls_method_hash_list, method);
6311 add_method_to_hash_list (nst_method_hash_list, method);
6313 /* Instance methods in root classes (and categories thereof)
6314 may acts as class methods as a last resort. */
6315 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6316 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6317 class = lookup_interface (CLASS_NAME (class));
6319 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6320 && !CLASS_SUPER_NAME (class))
6321 add_method_to_hash_list (cls_method_hash_list, method);
6328 add_class (tree class)
6330 /* Put interfaces on list in reverse order. */
6331 TREE_CHAIN (class) = interface_chain;
6332 interface_chain = class;
6333 return interface_chain;
6337 add_category (tree class, tree category)
6339 /* Put categories on list in reverse order. */
6340 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6344 warning ("duplicate interface declaration for category `%s(%s)'",
6345 IDENTIFIER_POINTER (CLASS_NAME (class)),
6346 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6350 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6351 CLASS_CATEGORY_LIST (class) = category;
6355 /* Called after parsing each instance variable declaration. Necessary to
6356 preserve typedefs and implement public/private...
6358 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6361 add_instance_variable (tree class, int public, tree declarator,
6362 tree declspecs, tree width)
6364 tree field_decl = grokfield (declarator, declspecs, width);
6365 tree field_type = TREE_TYPE (field_decl);
6366 const char *ivar_name = DECL_NAME (field_decl)
6367 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6372 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6374 error ("illegal reference type specified for instance variable `%s'",
6376 /* Return class as is without adding this ivar. */
6381 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6382 || TYPE_SIZE (field_type) == error_mark_node
6383 /* 'type[0]' is allowed, but 'type[]' is not! */
6385 || (TYPE_SIZE (field_type) == bitsize_zero_node
6386 && !TREE_OPERAND (declarator, 1))
6390 error ("instance variable `%s' has unknown size", ivar_name);
6391 /* Return class as is without adding this ivar. */
6396 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6397 cannot be ivars; ditto for classes with vtables. */
6398 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6399 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6401 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6402 if(TYPE_POLYMORPHIC_P (field_type)) {
6403 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6404 error ("type `%s' has virtual member functions", type_name);
6405 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6406 type_name, ivar_name);
6407 /* Return class as is without adding this ivar. */
6410 /* user-defined constructors and destructors are not known to Obj-C and
6411 hence will not be called. This may or may not be a problem. */
6412 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6413 warning ("type `%s' has a user-defined constructor", type_name);
6414 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6415 warning ("type `%s' has a user-defined destructor", type_name);
6416 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6420 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6424 TREE_PUBLIC (field_decl) = 0;
6425 TREE_PRIVATE (field_decl) = 0;
6426 TREE_PROTECTED (field_decl) = 1;
6430 TREE_PUBLIC (field_decl) = 1;
6431 TREE_PRIVATE (field_decl) = 0;
6432 TREE_PROTECTED (field_decl) = 0;
6436 TREE_PUBLIC (field_decl) = 0;
6437 TREE_PRIVATE (field_decl) = 1;
6438 TREE_PROTECTED (field_decl) = 0;
6443 raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
6444 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
6445 CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
6450 is_ivar (tree decl_chain, tree ident)
6452 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6453 if (DECL_NAME (decl_chain) == ident)
6458 /* True if the ivar is private and we are not in its implementation. */
6461 is_private (tree decl)
6463 if (TREE_PRIVATE (decl)
6464 && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
6466 error ("instance variable `%s' is declared private",
6467 IDENTIFIER_POINTER (DECL_NAME (decl)));
6474 /* We have an instance variable reference;, check to see if it is public. */
6477 is_public (tree expr, tree identifier)
6479 tree basetype = TREE_TYPE (expr);
6480 enum tree_code code = TREE_CODE (basetype);
6483 if (code == RECORD_TYPE)
6485 if (TREE_STATIC_TEMPLATE (basetype))
6487 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6489 error ("cannot find interface declaration for `%s'",
6490 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6494 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6496 if (TREE_PUBLIC (decl))
6499 /* Important difference between the Stepstone translator:
6500 all instance variables should be public within the context
6501 of the implementation. */
6502 if (objc_implementation_context
6503 && (((TREE_CODE (objc_implementation_context)
6504 == CLASS_IMPLEMENTATION_TYPE)
6505 || (TREE_CODE (objc_implementation_context)
6506 == CATEGORY_IMPLEMENTATION_TYPE))
6507 && (CLASS_NAME (objc_implementation_context)
6508 == OBJC_TYPE_NAME (basetype))))
6509 return ! is_private (decl);
6511 /* The 2.95.2 compiler sometimes allowed C functions to access
6512 non-@public ivars. We will let this slide for now... */
6513 if (!objc_method_context)
6515 warning ("instance variable `%s' is %s; "
6516 "this will be a hard error in the future",
6517 IDENTIFIER_POINTER (identifier),
6518 TREE_PRIVATE (decl) ? "@private" : "@protected");
6522 error ("instance variable `%s' is declared %s",
6523 IDENTIFIER_POINTER (identifier),
6524 TREE_PRIVATE (decl) ? "private" : "protected");
6529 else if (objc_implementation_context && (basetype == objc_object_reference))
6531 TREE_TYPE (expr) = uprivate_record;
6532 warning ("static access to object of type `id'");
6539 /* Make sure all entries in CHAIN are also in LIST. */
6542 check_methods (tree chain, tree list, int mtype)
6548 if (!lookup_method (list, chain))
6552 if (TREE_CODE (objc_implementation_context)
6553 == CLASS_IMPLEMENTATION_TYPE)
6554 warning ("incomplete implementation of class `%s'",
6555 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6556 else if (TREE_CODE (objc_implementation_context)
6557 == CATEGORY_IMPLEMENTATION_TYPE)
6558 warning ("incomplete implementation of category `%s'",
6559 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6563 warning ("method definition for `%c%s' not found",
6564 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6567 chain = TREE_CHAIN (chain);
6573 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6576 conforms_to_protocol (tree class, tree protocol)
6578 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6580 tree p = CLASS_PROTOCOL_LIST (class);
6581 while (p && TREE_VALUE (p) != protocol)
6586 tree super = (CLASS_SUPER_NAME (class)
6587 ? lookup_interface (CLASS_SUPER_NAME (class))
6589 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6598 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6599 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6602 check_methods_accessible (tree chain, tree context, int mtype)
6606 tree base_context = context;
6610 context = base_context;
6614 list = CLASS_CLS_METHODS (context);
6616 list = CLASS_NST_METHODS (context);
6618 if (lookup_method (list, chain))
6621 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6622 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6623 context = (CLASS_SUPER_NAME (context)
6624 ? lookup_interface (CLASS_SUPER_NAME (context))
6627 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6628 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6629 context = (CLASS_NAME (context)
6630 ? lookup_interface (CLASS_NAME (context))
6636 if (context == NULL_TREE)
6640 if (TREE_CODE (objc_implementation_context)
6641 == CLASS_IMPLEMENTATION_TYPE)
6642 warning ("incomplete implementation of class `%s'",
6644 (CLASS_NAME (objc_implementation_context)));
6645 else if (TREE_CODE (objc_implementation_context)
6646 == CATEGORY_IMPLEMENTATION_TYPE)
6647 warning ("incomplete implementation of category `%s'",
6649 (CLASS_SUPER_NAME (objc_implementation_context)));
6652 warning ("method definition for `%c%s' not found",
6653 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6656 chain = TREE_CHAIN (chain); /* next method... */
6661 /* Check whether the current interface (accessible via
6662 'objc_implementation_context') actually implements protocol P, along
6663 with any protocols that P inherits. */
6666 check_protocol (tree p, const char *type, const char *name)
6668 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6672 /* Ensure that all protocols have bodies! */
6675 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6676 CLASS_CLS_METHODS (objc_implementation_context),
6678 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6679 CLASS_NST_METHODS (objc_implementation_context),
6684 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6685 objc_implementation_context,
6687 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6688 objc_implementation_context,
6693 warning ("%s `%s' does not fully implement the `%s' protocol",
6694 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6697 /* Check protocols recursively. */
6698 if (PROTOCOL_LIST (p))
6700 tree subs = PROTOCOL_LIST (p);
6702 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6706 tree sub = TREE_VALUE (subs);
6708 /* If the superclass does not conform to the protocols
6709 inherited by P, then we must! */
6710 if (!super_class || !conforms_to_protocol (super_class, sub))
6711 check_protocol (sub, type, name);
6712 subs = TREE_CHAIN (subs);
6717 /* Check whether the current interface (accessible via
6718 'objc_implementation_context') actually implements the protocols listed
6722 check_protocols (tree proto_list, const char *type, const char *name)
6724 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6726 tree p = TREE_VALUE (proto_list);
6728 check_protocol (p, type, name);
6732 /* Make sure that the class CLASS_NAME is defined
6733 CODE says which kind of thing CLASS_NAME ought to be.
6734 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6735 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6738 start_class (enum tree_code code, tree class_name, tree super_name,
6744 if (current_namespace != global_namespace) {
6745 error ("Objective-C declarations may only appear in global scope");
6747 #endif /* OBJCPLUS */
6749 if (objc_implementation_context)
6751 warning ("`@end' missing in implementation context");
6752 finish_class (objc_implementation_context);
6753 objc_ivar_chain = NULL_TREE;
6754 objc_implementation_context = NULL_TREE;
6757 class = make_node (code);
6758 TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
6760 CLASS_NAME (class) = class_name;
6761 CLASS_SUPER_NAME (class) = super_name;
6762 CLASS_CLS_METHODS (class) = NULL_TREE;
6764 if (! is_class_name (class_name)
6765 && (decl = lookup_name (class_name)))
6767 error ("`%s' redeclared as different kind of symbol",
6768 IDENTIFIER_POINTER (class_name));
6769 error ("%Jprevious declaration of '%D'",
6773 if (code == CLASS_IMPLEMENTATION_TYPE)
6778 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6779 if (TREE_VALUE (chain) == class_name)
6781 error ("reimplementation of class `%s'",
6782 IDENTIFIER_POINTER (class_name));
6783 return error_mark_node;
6785 implemented_classes = tree_cons (NULL_TREE, class_name,
6786 implemented_classes);
6789 /* Reset for multiple classes per file. */
6792 objc_implementation_context = class;
6794 /* Lookup the interface for this implementation. */
6796 if (!(implementation_template = lookup_interface (class_name)))
6798 warning ("cannot find interface declaration for `%s'",
6799 IDENTIFIER_POINTER (class_name));
6800 add_class (implementation_template = objc_implementation_context);
6803 /* If a super class has been specified in the implementation,
6804 insure it conforms to the one specified in the interface. */
6807 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6809 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6810 const char *const name =
6811 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6812 error ("conflicting super class name `%s'",
6813 IDENTIFIER_POINTER (super_name));
6814 error ("previous declaration of `%s'", name);
6817 else if (! super_name)
6819 CLASS_SUPER_NAME (objc_implementation_context)
6820 = CLASS_SUPER_NAME (implementation_template);
6824 else if (code == CLASS_INTERFACE_TYPE)
6826 if (lookup_interface (class_name))
6828 error ("duplicate interface declaration for class `%s'",
6830 warning ("duplicate interface declaration for class `%s'",
6832 IDENTIFIER_POINTER (class_name));
6837 CLASS_PROTOCOL_LIST (class)
6838 = lookup_and_install_protocols (protocol_list);
6841 else if (code == CATEGORY_INTERFACE_TYPE)
6843 tree class_category_is_assoc_with;
6845 /* For a category, class_name is really the name of the class that
6846 the following set of methods will be associated with. We must
6847 find the interface so that can derive the objects template. */
6849 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6851 error ("cannot find interface declaration for `%s'",
6852 IDENTIFIER_POINTER (class_name));
6853 exit (FATAL_EXIT_CODE);
6856 add_category (class_category_is_assoc_with, class);
6859 CLASS_PROTOCOL_LIST (class)
6860 = lookup_and_install_protocols (protocol_list);
6863 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6865 /* Reset for multiple classes per file. */
6868 objc_implementation_context = class;
6870 /* For a category, class_name is really the name of the class that
6871 the following set of methods will be associated with. We must
6872 find the interface so that can derive the objects template. */
6874 if (!(implementation_template = lookup_interface (class_name)))
6876 error ("cannot find interface declaration for `%s'",
6877 IDENTIFIER_POINTER (class_name));
6878 exit (FATAL_EXIT_CODE);
6885 continue_class (tree class)
6887 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6888 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6890 struct imp_entry *imp_entry;
6893 /* Check consistency of the instance variables. */
6895 if (CLASS_IVARS (class))
6896 check_ivars (implementation_template, class);
6898 /* code generation */
6900 ivar_context = build_private_template (implementation_template);
6902 if (!objc_class_template)
6903 build_class_template ();
6905 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6907 imp_entry->next = imp_list;
6908 imp_entry->imp_context = class;
6909 imp_entry->imp_template = implementation_template;
6911 synth_forward_declarations ();
6912 imp_entry->class_decl = UOBJC_CLASS_decl;
6913 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6915 /* Append to front and increment count. */
6916 imp_list = imp_entry;
6917 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6922 return ivar_context;
6925 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6927 if (!CLASS_STATIC_TEMPLATE (class))
6929 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6930 finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
6931 CLASS_STATIC_TEMPLATE (class) = record;
6933 /* Mark this record as a class template for static typing. */
6934 TREE_STATIC_TEMPLATE (record) = 1;
6941 return error_mark_node;
6944 /* This is called once we see the "@end" in an interface/implementation. */
6947 finish_class (tree class)
6949 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6951 /* All code generation is done in finish_objc. */
6953 if (implementation_template != objc_implementation_context)
6955 /* Ensure that all method listed in the interface contain bodies. */
6956 check_methods (CLASS_CLS_METHODS (implementation_template),
6957 CLASS_CLS_METHODS (objc_implementation_context), '+');
6958 check_methods (CLASS_NST_METHODS (implementation_template),
6959 CLASS_NST_METHODS (objc_implementation_context), '-');
6961 if (CLASS_PROTOCOL_LIST (implementation_template))
6962 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6964 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6968 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6970 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6974 /* Ensure all method listed in the interface contain bodies. */
6975 check_methods (CLASS_CLS_METHODS (category),
6976 CLASS_CLS_METHODS (objc_implementation_context), '+');
6977 check_methods (CLASS_NST_METHODS (category),
6978 CLASS_NST_METHODS (objc_implementation_context), '-');
6980 if (CLASS_PROTOCOL_LIST (category))
6981 check_protocols (CLASS_PROTOCOL_LIST (category),
6983 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6987 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6990 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6991 char *string = (char *) alloca (strlen (class_name) + 3);
6993 /* extern struct objc_object *_<my_name>; */
6995 sprintf (string, "_%s", class_name);
6997 decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
6998 decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs);
6999 define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)),
7005 add_protocol (tree protocol)
7007 /* Put protocol on list in reverse order. */
7008 TREE_CHAIN (protocol) = protocol_chain;
7009 protocol_chain = protocol;
7010 return protocol_chain;
7014 lookup_protocol (tree ident)
7018 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7019 if (ident == PROTOCOL_NAME (chain))
7025 /* This function forward declares the protocols named by NAMES. If
7026 they are already declared or defined, the function has no effect. */
7029 objc_declare_protocols (tree names)
7034 if (current_namespace != global_namespace) {
7035 error ("Objective-C declarations may only appear in global scope");
7037 #endif /* OBJCPLUS */
7039 for (list = names; list; list = TREE_CHAIN (list))
7041 tree name = TREE_VALUE (list);
7043 if (lookup_protocol (name) == NULL_TREE)
7045 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7047 TYPE_BINFO (protocol) = make_tree_vec (2);
7048 PROTOCOL_NAME (protocol) = name;
7049 PROTOCOL_LIST (protocol) = NULL_TREE;
7050 add_protocol (protocol);
7051 PROTOCOL_DEFINED (protocol) = 0;
7052 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7058 start_protocol (enum tree_code code, tree name, tree list)
7063 if (current_namespace != global_namespace) {
7064 error ("Objective-C declarations may only appear in global scope");
7066 #endif /* OBJCPLUS */
7068 /* This is as good a place as any. Need to invoke
7069 push_tag_toplevel. */
7070 if (!objc_protocol_template)
7071 objc_protocol_template = build_protocol_template ();
7073 protocol = lookup_protocol (name);
7077 protocol = make_node (code);
7078 TYPE_BINFO (protocol) = make_tree_vec (2);
7080 PROTOCOL_NAME (protocol) = name;
7081 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7082 add_protocol (protocol);
7083 PROTOCOL_DEFINED (protocol) = 1;
7084 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7086 check_protocol_recursively (protocol, list);
7088 else if (! PROTOCOL_DEFINED (protocol))
7090 PROTOCOL_DEFINED (protocol) = 1;
7091 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7093 check_protocol_recursively (protocol, list);
7097 warning ("duplicate declaration for protocol `%s'",
7098 IDENTIFIER_POINTER (name));
7104 finish_protocol (tree protocol ATTRIBUTE_UNUSED)
7109 /* "Encode" a data type into a string, which grows in util_obstack.
7110 ??? What is the FORMAT? Someone please document this! */
7113 encode_type_qualifiers (tree declspecs)
7117 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7119 if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
7120 obstack_1grow (&util_obstack, 'r');
7121 else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7122 obstack_1grow (&util_obstack, 'n');
7123 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7124 obstack_1grow (&util_obstack, 'N');
7125 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7126 obstack_1grow (&util_obstack, 'o');
7127 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7128 obstack_1grow (&util_obstack, 'O');
7129 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7130 obstack_1grow (&util_obstack, 'R');
7131 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7132 obstack_1grow (&util_obstack, 'V');
7136 /* Encode a pointer type. */
7139 encode_pointer (tree type, int curtype, int format)
7141 tree pointer_to = TREE_TYPE (type);
7143 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7145 if (OBJC_TYPE_NAME (pointer_to)
7146 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7148 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7150 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7152 obstack_1grow (&util_obstack, '@');
7155 else if (TREE_STATIC_TEMPLATE (pointer_to))
7157 if (generating_instance_variables)
7159 obstack_1grow (&util_obstack, '@');
7160 obstack_1grow (&util_obstack, '"');
7161 obstack_grow (&util_obstack, name, strlen (name));
7162 obstack_1grow (&util_obstack, '"');
7167 obstack_1grow (&util_obstack, '@');
7171 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7173 obstack_1grow (&util_obstack, '#');
7176 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7178 obstack_1grow (&util_obstack, ':');
7183 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7184 && TYPE_MODE (pointer_to) == QImode)
7186 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7187 ? OBJC_TYPE_NAME (pointer_to)
7188 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7190 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7192 obstack_1grow (&util_obstack, '*');
7197 /* We have a type that does not get special treatment. */
7199 /* NeXT extension */
7200 obstack_1grow (&util_obstack, '^');
7201 encode_type (pointer_to, curtype, format);
7205 encode_array (tree type, int curtype, int format)
7207 tree an_int_cst = TYPE_SIZE (type);
7208 tree array_of = TREE_TYPE (type);
7211 /* An incomplete array is treated like a pointer. */
7212 if (an_int_cst == NULL)
7214 encode_pointer (type, curtype, format);
7218 sprintf (buffer, "[%ld",
7219 (long) (TREE_INT_CST_LOW (an_int_cst)
7220 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7222 obstack_grow (&util_obstack, buffer, strlen (buffer));
7223 encode_type (array_of, curtype, format);
7224 obstack_1grow (&util_obstack, ']');
7229 encode_aggregate_within (tree type, int curtype, int format, int left,
7233 /* NB: aggregates that are pointed to have slightly different encoding
7234 rules in that you never encode the names of instance variables. */
7236 = (obstack_object_size (&util_obstack) > 0
7237 && *(obstack_next_free (&util_obstack) - 1) == '^');
7239 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7240 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7242 /* Traverse struct aliases; it is important to get the
7243 original struct and its tag name (if any). */
7244 type = TYPE_MAIN_VARIANT (type);
7245 name = OBJC_TYPE_NAME (type);
7246 /* Open parenth/bracket. */
7247 obstack_1grow (&util_obstack, left);
7249 /* Encode the struct/union tag name, or '?' if a tag was
7250 not provided. Typedef aliases do not qualify. */
7251 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7253 /* Did this struct have a tag? */
7254 && !TYPE_WAS_ANONYMOUS (type)
7257 obstack_grow (&util_obstack,
7258 IDENTIFIER_POINTER (name),
7259 strlen (IDENTIFIER_POINTER (name)));
7261 obstack_1grow (&util_obstack, '?');
7263 /* Encode the types (and possibly names) of the inner fields,
7265 if (inline_contents)
7267 tree fields = TYPE_FIELDS (type);
7269 obstack_1grow (&util_obstack, '=');
7270 for (; fields; fields = TREE_CHAIN (fields))
7273 /* C++ static members, and things that are not fields at all,
7274 should not appear in the encoding. */
7275 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7278 if (generating_instance_variables && !pointed_to)
7280 tree fname = DECL_NAME (fields);
7282 obstack_1grow (&util_obstack, '"');
7283 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7284 obstack_grow (&util_obstack,
7285 IDENTIFIER_POINTER (fname),
7286 strlen (IDENTIFIER_POINTER (fname)));
7287 obstack_1grow (&util_obstack, '"');
7289 encode_field_decl (fields, curtype, format);
7292 /* Close parenth/bracket. */
7293 obstack_1grow (&util_obstack, right);
7297 encode_aggregate (tree type, int curtype, int format)
7299 enum tree_code code = TREE_CODE (type);
7305 encode_aggregate_within (type, curtype, format, '{', '}');
7310 encode_aggregate_within (type, curtype, format, '(', ')');
7315 obstack_1grow (&util_obstack, 'i');
7323 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7327 encode_next_bitfield (int width)
7330 sprintf (buffer, "b%d", width);
7331 obstack_grow (&util_obstack, buffer, strlen (buffer));
7334 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7336 encode_type (tree type, int curtype, int format)
7338 enum tree_code code = TREE_CODE (type);
7341 if (code == INTEGER_TYPE)
7343 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7345 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7346 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7348 if (type == long_unsigned_type_node
7349 || type == long_integer_type_node)
7350 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7352 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7354 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7357 obstack_1grow (&util_obstack, c);
7360 else if (code == REAL_TYPE)
7362 /* Floating point types. */
7363 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7365 case 32: c = 'f'; break;
7367 case 128: c = 'd'; break;
7370 obstack_1grow (&util_obstack, c);
7373 else if (code == VOID_TYPE)
7374 obstack_1grow (&util_obstack, 'v');
7376 else if (code == BOOLEAN_TYPE)
7377 obstack_1grow (&util_obstack, 'B');
7379 else if (code == ARRAY_TYPE)
7380 encode_array (type, curtype, format);
7382 else if (code == POINTER_TYPE)
7383 encode_pointer (type, curtype, format);
7385 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7386 encode_aggregate (type, curtype, format);
7388 else if (code == FUNCTION_TYPE) /* '?' */
7389 obstack_1grow (&util_obstack, '?');
7393 encode_gnu_bitfield (int position, tree type, int size)
7395 enum tree_code code = TREE_CODE (type);
7397 char charType = '?';
7399 if (code == INTEGER_TYPE)
7401 if (integer_zerop (TYPE_MIN_VALUE (type)))
7403 /* Unsigned integer types. */
7405 if (TYPE_MODE (type) == QImode)
7407 else if (TYPE_MODE (type) == HImode)
7409 else if (TYPE_MODE (type) == SImode)
7411 if (type == long_unsigned_type_node)
7416 else if (TYPE_MODE (type) == DImode)
7421 /* Signed integer types. */
7423 if (TYPE_MODE (type) == QImode)
7425 else if (TYPE_MODE (type) == HImode)
7427 else if (TYPE_MODE (type) == SImode)
7429 if (type == long_integer_type_node)
7435 else if (TYPE_MODE (type) == DImode)
7439 else if (code == ENUMERAL_TYPE)
7444 sprintf (buffer, "b%d%c%d", position, charType, size);
7445 obstack_grow (&util_obstack, buffer, strlen (buffer));
7449 encode_field_decl (tree field_decl, int curtype, int format)
7454 /* C++ static members, and things that are not fields at all,
7455 should not appear in the encoding. */
7456 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7460 type = TREE_TYPE (field_decl);
7462 /* Generate the bitfield typing information, if needed. Note the difference
7463 between GNU and NeXT runtimes. */
7464 if (DECL_BIT_FIELD_TYPE (field_decl))
7466 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7468 if (flag_next_runtime)
7469 encode_next_bitfield (size);
7471 encode_gnu_bitfield (int_bit_position (field_decl),
7472 DECL_BIT_FIELD_TYPE (field_decl), size);
7475 encode_type (TREE_TYPE (field_decl), curtype, format);
7479 objc_expr_last (tree complex_expr)
7484 while ((next = TREE_OPERAND (complex_expr, 0)))
7485 complex_expr = next;
7487 return complex_expr;
7491 synth_self_and_ucmd_args (void)
7495 if (objc_method_context
7496 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7497 decl_specs = build_tree_list (NULL_TREE, uprivate_record);
7499 /* Really a `struct objc_class *'. However, we allow people to
7500 assign to self, which changes its type midstream. */
7501 decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
7503 push_parm_decl (build_tree_list
7504 (build_tree_list (decl_specs,
7505 build1 (INDIRECT_REF, NULL_TREE, self_id)),
7508 decl_specs = build_tree_list (NULL_TREE, TREE_TYPE (selector_type));
7509 push_parm_decl (build_tree_list
7510 (build_tree_list (decl_specs,
7511 build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
7515 /* Transform a method definition into a function definition as follows:
7516 - synthesize the first two arguments, "self" and "_cmd". */
7519 start_method_def (tree method)
7521 /* Required to implement _msgSuper. */
7522 objc_method_context = method;
7523 UOBJC_SUPER_decl = NULL_TREE;
7525 /* Must be called BEFORE start_function. */
7527 declare_parm_level ();
7529 /* Generate prototype declarations for arguments..."new-style". */
7530 synth_self_and_ucmd_args ();
7532 /* Generate argument declarations if a keyword_decl. */
7533 if (METHOD_SEL_ARGS (method))
7535 tree arglist = METHOD_SEL_ARGS (method);
7538 tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
7539 tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
7543 tree last_expr = objc_expr_last (arg_decl);
7545 /* Unite the abstract decl with its name. */
7546 TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
7547 push_parm_decl (build_tree_list
7548 (build_tree_list (arg_spec, arg_decl),
7552 /* Unhook: restore the abstract declarator. */
7553 TREE_OPERAND (last_expr, 0) = NULL_TREE;
7558 push_parm_decl (build_tree_list
7559 (build_tree_list (arg_spec,
7560 KEYWORD_ARG_NAME (arglist)),
7563 arglist = TREE_CHAIN (arglist);
7568 if (METHOD_ADD_ARGS (method) != NULL_TREE
7569 && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
7571 /* We have a variable length selector - in "prototype" format. */
7572 tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
7575 /* This must be done prior to calling pushdecl. pushdecl is
7576 going to change our chain on us. */
7577 tree nextkey = TREE_CHAIN (akey);
7585 warn_with_method (const char *message, int mtype, tree method)
7587 /* Add a readable method name to the warning. */
7588 warning ("%J%s `%c%s'", method,
7589 message, mtype, gen_method_decl (method, errbuf));
7592 /* Return 1 if METHOD is consistent with PROTO. */
7595 comp_method_with_proto (tree method, tree proto)
7597 /* Create a function template node at most once. */
7598 if (!function1_template)
7599 function1_template = make_node (FUNCTION_TYPE);
7601 /* Install argument types - normally set by build_function_type. */
7602 TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto, METHOD_DEF, 0);
7604 /* install return type */
7605 TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
7607 return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
7611 /* Return 1 if TYPE1 is equivalent to TYPE2. */
7614 objc_types_are_equivalent (tree type1, tree type2)
7618 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7620 type1 = TYPE_PROTOCOL_LIST (type1);
7621 type2 = TYPE_PROTOCOL_LIST (type2);
7622 if (list_length (type1) == list_length (type2))
7624 for (; type2; type2 = TREE_CHAIN (type2))
7625 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7632 /* Return 1 if PROTO1 is equivalent to PROTO2. */
7635 comp_proto_with_proto (tree proto1, tree proto2)
7639 /* The following test is needed in case there are hashing
7641 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7644 /* Compare return types. */
7645 type1 = groktypename (TREE_TYPE (proto1));
7646 type2 = groktypename (TREE_TYPE (proto2));
7648 if (!objc_types_are_equivalent (type1, type2))
7651 /* Compare argument types. */
7652 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7653 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7655 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7657 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7661 return (!type1 && !type2);
7664 /* - Generate an identifier for the function. the format is "_n_cls",
7665 where 1 <= n <= nMethods, and cls is the name the implementation we
7667 - Install the return type from the method declaration.
7668 - If we have a prototype, check for type consistency. */
7671 really_start_method (tree method, tree parmlist)
7673 tree sc_spec, ret_spec, ret_decl, decl_specs;
7674 tree method_decl, method_id;
7675 const char *sel_name, *class_name, *cat_name;
7678 /* Synth the storage class & assemble the return type. */
7679 sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
7680 ret_spec = TREE_PURPOSE (TREE_TYPE (method));
7681 decl_specs = chainon (sc_spec, ret_spec);
7683 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7684 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7685 cat_name = ((TREE_CODE (objc_implementation_context)
7686 == CLASS_IMPLEMENTATION_TYPE)
7688 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7691 /* Make sure this is big enough for any plausible method label. */
7692 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7693 + (cat_name ? strlen (cat_name) : 0));
7695 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7696 class_name, cat_name, sel_name, method_slot);
7698 method_id = get_identifier (buf);
7701 /* Objective-C methods cannot be overloaded, so we don't need
7702 the type encoding appended. It looks bad anyway... */
7703 push_lang_context (lang_name_c);
7706 method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
7708 /* Check the declarator portion of the return type for the method. */
7709 if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
7711 /* Unite the complex decl (specified in the abstract decl) with the
7712 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7713 tree save_expr = objc_expr_last (ret_decl);
7715 TREE_OPERAND (save_expr, 0) = method_decl;
7716 method_decl = ret_decl;
7718 /* Fool the parser into thinking it is starting a function. */
7719 start_function (decl_specs, method_decl, NULL_TREE);
7721 /* Unhook: this has the effect of restoring the abstract declarator. */
7722 TREE_OPERAND (save_expr, 0) = NULL_TREE;
7727 TREE_VALUE (TREE_TYPE (method)) = method_decl;
7729 /* Fool the parser into thinking it is starting a function. */
7730 start_function (decl_specs, method_decl, NULL_TREE);
7732 /* Unhook: this has the effect of restoring the abstract declarator. */
7733 TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
7737 /* set self_decl from the first argument...this global is used by
7738 * build_ivar_reference().build_indirect_ref().
7740 self_decl = DECL_ARGUMENTS (current_function_decl);
7742 /* snaroff (3/28/96): when compiling with -Wall, this suppresses
7743 * the following: warning:unused parameter `struct objc_selector * _cmd'
7745 TREE_USED (self_decl) = 1;
7746 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7747 /* Ditto for the underlying (static) C function. */
7748 TREE_USED (current_function_decl) = 1;
7749 pop_lang_context ();
7752 METHOD_DEFINITION (method) = current_function_decl;
7754 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7756 if (implementation_template != objc_implementation_context)
7759 = lookup_method_static (implementation_template,
7760 METHOD_SEL_NAME (method),
7761 TREE_CODE (method) == CLASS_METHOD_DECL);
7765 if (!comp_method_with_proto (method, proto))
7767 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7769 warn_with_method ("conflicting types for", type, method);
7770 warn_with_method ("previous declaration of", type, proto);
7775 /* We have a method @implementation even though we did not
7776 see a corresponding @interface declaration (which is allowed
7777 by Objective-C rules). Go ahead and place the method in
7778 the @interface anyway, so that message dispatch lookups
7780 tree interface = implementation_template;
7782 if (TREE_CODE (objc_implementation_context)
7783 == CATEGORY_IMPLEMENTATION_TYPE)
7784 interface = lookup_category
7786 CLASS_SUPER_NAME (objc_implementation_context));
7789 objc_add_method (interface, copy_node (method),
7790 TREE_CODE (method) == CLASS_METHOD_DECL);
7795 /* The following routine is always called...this "architecture" is to
7796 accommodate "old-style" variable length selectors.
7798 - a:a b:b // prototype ; id c; id d; // old-style. */
7801 continue_method_def (void)
7805 if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
7806 /* We have a `, ...' immediately following the selector. */
7807 parmlist = get_parm_info (/*ellipsis=*/true);
7809 parmlist = get_parm_info (/*ellipsis=*/false);
7812 /* Set self_decl from the first argument...this global is used by
7813 build_ivar_reference calling build_indirect_ref. */
7814 self_decl = TREE_PURPOSE (parmlist);
7815 #endif /* !OBJCPLUS */
7818 really_start_method (objc_method_context, parmlist);
7819 store_parm_decls ();
7822 static void *UOBJC_SUPER_scope = 0;
7824 /* _n_Method (id self, SEL sel, ...)
7826 struct objc_super _S;
7827 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7831 get_super_receiver (void)
7833 if (objc_method_context)
7835 tree super_expr, super_expr_list;
7837 if (!UOBJC_SUPER_decl)
7839 UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
7840 build_tree_list (NULL_TREE,
7841 objc_super_template),
7844 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7846 /* This prevents `unused variable' warnings when compiling with -Wall. */
7847 TREE_USED (UOBJC_SUPER_decl) = 1;
7848 DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
7850 UOBJC_SUPER_scope = get_current_scope ();
7853 /* Set receiver to self. */
7854 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7855 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7856 super_expr_list = build_tree_list (NULL_TREE, super_expr);
7858 /* Set class to begin searching. */
7860 super_expr = build_component_ref (UOBJC_SUPER_decl,
7861 get_identifier ("super_class"));
7863 super_expr = build_component_ref (UOBJC_SUPER_decl,
7864 get_identifier ("class"));
7867 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7869 /* [_cls, __cls]Super are "pre-built" in
7870 synth_forward_declarations. */
7872 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7873 ((TREE_CODE (objc_method_context)
7874 == INSTANCE_METHOD_DECL)
7876 : uucls_super_ref));
7880 /* We have a category. */
7882 tree super_name = CLASS_SUPER_NAME (implementation_template);
7885 /* Barf if super used in a category of Object. */
7888 error ("no super class declared in interface for `%s'",
7889 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7890 return error_mark_node;
7893 if (flag_next_runtime && !flag_zero_link)
7895 super_class = get_class_reference (super_name);
7896 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7897 /* If we are in a class method, we must retrieve the
7898 _metaclass_ for the current class, pointed at by
7899 the class's "isa" pointer. The following assumes that
7900 "isa" is the first ivar in a class (which it must be). */
7902 = build_indirect_ref
7903 (build_c_cast (build_pointer_type (objc_class_type),
7904 super_class), "unary *");
7908 add_class_reference (super_name);
7909 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7910 ? objc_get_class_decl : objc_get_meta_class_decl);
7911 assemble_external (super_class);
7913 = build_function_call
7917 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7918 IDENTIFIER_POINTER (super_name))));
7922 = build_modify_expr (super_expr, NOP_EXPR,
7923 build_c_cast (TREE_TYPE (super_expr),
7927 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7929 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7930 chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
7932 return build_compound_expr (super_expr_list);
7936 error ("[super ...] must appear in a method context");
7937 return error_mark_node;
7941 /* When exiting a scope, sever links to a 'super' declaration (if any)
7942 therein contained. */
7945 objc_clear_super_receiver (void)
7947 if (objc_method_context
7948 && UOBJC_SUPER_scope == get_current_scope ()) {
7949 UOBJC_SUPER_decl = 0;
7950 UOBJC_SUPER_scope = 0;
7955 objc_expand_function_end (void)
7957 /* This routine may also get called for C functions, including those
7958 nested within ObjC methods. In such cases, method encoding is
7960 if (objc_method_context == NULL_TREE
7961 || DECL_INITIAL (objc_method_context) != current_function_decl)
7964 METHOD_ENCODING (objc_method_context)
7965 = encode_method_prototype (objc_method_context);
7969 finish_method_def (void)
7971 lang_expand_function_end = objc_expand_function_end;
7972 /* We cannot validly inline ObjC methods, at least not without a language
7973 extension to declare that a method need not be dynamically
7974 dispatched, so suppress all thoughts of doing so. */
7975 DECL_INLINE (current_function_decl) = 0;
7976 DECL_UNINLINABLE (current_function_decl) = 1;
7977 current_function_cannot_inline = "methods cannot be inlined";
7980 lang_expand_function_end = NULL;
7982 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7983 since the optimizer may find "may be used before set" errors. */
7984 objc_method_context = NULL_TREE;
7989 lang_report_error_function (tree decl)
7991 if (objc_method_context)
7993 fprintf (stderr, "In method `%s'\n",
7994 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8004 is_complex_decl (tree type)
8006 return (TREE_CODE (type) == ARRAY_TYPE
8007 || TREE_CODE (type) == FUNCTION_TYPE
8008 || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
8012 /* Code to convert a decl node into text for a declaration in C. */
8014 static char tmpbuf[256];
8017 adorn_decl (tree decl, char *str)
8019 enum tree_code code = TREE_CODE (decl);
8021 if (code == ARRAY_REF)
8023 tree an_int_cst = TREE_OPERAND (decl, 1);
8025 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
8026 sprintf (str + strlen (str), "[%ld]",
8027 (long) TREE_INT_CST_LOW (an_int_cst));
8032 else if (code == ARRAY_TYPE)
8034 tree an_int_cst = TYPE_SIZE (decl);
8035 tree array_of = TREE_TYPE (decl);
8037 if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
8038 sprintf (str + strlen (str), "[%ld]",
8039 (long) (TREE_INT_CST_LOW (an_int_cst)
8040 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
8045 else if (code == CALL_EXPR)
8047 tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
8052 gen_declaration_1 (chain, str);
8053 chain = TREE_CHAIN (chain);
8060 else if (code == FUNCTION_TYPE)
8062 tree chain = TYPE_ARG_TYPES (decl);
8065 while (chain && TREE_VALUE (chain) != void_type_node)
8067 gen_declaration_1 (TREE_VALUE (chain), str);
8068 chain = TREE_CHAIN (chain);
8069 if (chain && TREE_VALUE (chain) != void_type_node)
8075 else if (code == INDIRECT_REF)
8077 strcpy (tmpbuf, "*");
8078 if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST)
8082 for (chain = nreverse (copy_list (TREE_TYPE (decl)));
8084 chain = TREE_CHAIN (chain))
8086 if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
8088 strcat (tmpbuf, " ");
8089 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain)));
8093 strcat (tmpbuf, " ");
8095 strcat (tmpbuf, str);
8096 strcpy (str, tmpbuf);
8099 else if (code == POINTER_TYPE)
8101 strcpy (tmpbuf, "*");
8102 if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
8104 if (TYPE_READONLY (decl))
8105 strcat (tmpbuf, " const");
8106 if (TYPE_VOLATILE (decl))
8107 strcat (tmpbuf, " volatile");
8109 strcat (tmpbuf, " ");
8111 strcat (tmpbuf, str);
8112 strcpy (str, tmpbuf);
8117 gen_declarator (tree decl, char *buf, const char *name)
8121 enum tree_code code = TREE_CODE (decl);
8131 op = TREE_OPERAND (decl, 0);
8133 /* We have a pointer to a function or array...(*)(), (*)[] */
8134 if ((code == ARRAY_REF || code == CALL_EXPR)
8135 && op && TREE_CODE (op) == INDIRECT_REF)
8138 str = gen_declarator (op, buf, name);
8142 strcpy (tmpbuf, "(");
8143 strcat (tmpbuf, str);
8144 strcat (tmpbuf, ")");
8145 strcpy (str, tmpbuf);
8148 adorn_decl (decl, str);
8157 /* This clause is done iteratively rather than recursively. */
8160 op = (is_complex_decl (TREE_TYPE (decl))
8161 ? TREE_TYPE (decl) : NULL_TREE);
8163 adorn_decl (decl, str);
8165 /* We have a pointer to a function or array...(*)(), (*)[] */
8166 if (code == POINTER_TYPE
8167 && op && (TREE_CODE (op) == FUNCTION_TYPE
8168 || TREE_CODE (op) == ARRAY_TYPE))
8170 strcpy (tmpbuf, "(");
8171 strcat (tmpbuf, str);
8172 strcat (tmpbuf, ")");
8173 strcpy (str, tmpbuf);
8176 decl = (is_complex_decl (TREE_TYPE (decl))
8177 ? TREE_TYPE (decl) : NULL_TREE);
8180 while (decl && (code = TREE_CODE (decl)))
8185 case IDENTIFIER_NODE:
8186 /* Will only happen if we are processing a "raw" expr-decl. */
8187 strcpy (buf, IDENTIFIER_POINTER (decl));
8198 /* We have an abstract declarator or a _DECL node. */
8206 gen_declspecs (tree declspecs, char *buf, int raw)
8212 for (chain = nreverse (copy_list (declspecs));
8213 chain; chain = TREE_CHAIN (chain))
8215 tree aspec = TREE_VALUE (chain);
8217 if (TREE_CODE (aspec) == IDENTIFIER_NODE)
8218 strcat (buf, IDENTIFIER_POINTER (aspec));
8219 else if (TREE_CODE (aspec) == RECORD_TYPE)
8221 if (OBJC_TYPE_NAME (aspec))
8223 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8225 if (! TREE_STATIC_TEMPLATE (aspec))
8226 strcat (buf, "struct ");
8227 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8232 tree chain = protocol_list;
8239 (PROTOCOL_NAME (TREE_VALUE (chain))));
8240 chain = TREE_CHAIN (chain);
8249 strcat (buf, "untagged struct");
8252 else if (TREE_CODE (aspec) == UNION_TYPE)
8254 if (OBJC_TYPE_NAME (aspec))
8256 if (! TREE_STATIC_TEMPLATE (aspec))
8257 strcat (buf, "union ");
8258 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8261 strcat (buf, "untagged union");
8264 else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
8266 if (OBJC_TYPE_NAME (aspec))
8268 if (! TREE_STATIC_TEMPLATE (aspec))
8269 strcat (buf, "enum ");
8270 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
8273 strcat (buf, "untagged enum");
8276 else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
8277 strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
8279 else if (IS_ID (aspec))
8281 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
8286 tree chain = protocol_list;
8293 (PROTOCOL_NAME (TREE_VALUE (chain))));
8294 chain = TREE_CHAIN (chain);
8301 if (TREE_CHAIN (chain))
8307 /* Type qualifiers. */
8308 if (TYPE_READONLY (declspecs))
8309 strcat (buf, "const ");
8310 if (TYPE_VOLATILE (declspecs))
8311 strcat (buf, "volatile ");
8313 switch (TREE_CODE (declspecs))
8315 /* Type specifiers. */
8318 declspecs = TYPE_MAIN_VARIANT (declspecs);
8320 /* Signed integer types. */
8322 if (declspecs == short_integer_type_node)
8323 strcat (buf, "short int ");
8324 else if (declspecs == integer_type_node)
8325 strcat (buf, "int ");
8326 else if (declspecs == long_integer_type_node)
8327 strcat (buf, "long int ");
8328 else if (declspecs == long_long_integer_type_node)
8329 strcat (buf, "long long int ");
8330 else if (declspecs == signed_char_type_node
8331 || declspecs == char_type_node)
8332 strcat (buf, "char ");
8334 /* Unsigned integer types. */
8336 else if (declspecs == short_unsigned_type_node)
8337 strcat (buf, "unsigned short ");
8338 else if (declspecs == unsigned_type_node)
8339 strcat (buf, "unsigned int ");
8340 else if (declspecs == long_unsigned_type_node)
8341 strcat (buf, "unsigned long ");
8342 else if (declspecs == long_long_unsigned_type_node)
8343 strcat (buf, "unsigned long long ");
8344 else if (declspecs == unsigned_char_type_node)
8345 strcat (buf, "unsigned char ");
8349 declspecs = TYPE_MAIN_VARIANT (declspecs);
8351 if (declspecs == float_type_node)
8352 strcat (buf, "float ");
8353 else if (declspecs == double_type_node)
8354 strcat (buf, "double ");
8355 else if (declspecs == long_double_type_node)
8356 strcat (buf, "long double ");
8360 if (OBJC_TYPE_NAME (declspecs)
8361 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8363 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8365 if (! TREE_STATIC_TEMPLATE (declspecs))
8366 strcat (buf, "struct ");
8367 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8371 tree chain = protocol_list;
8378 (PROTOCOL_NAME (TREE_VALUE (chain))));
8379 chain = TREE_CHAIN (chain);
8388 strcat (buf, "untagged struct");
8394 if (OBJC_TYPE_NAME (declspecs)
8395 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8397 strcat (buf, "union ");
8398 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8403 strcat (buf, "untagged union ");
8407 if (OBJC_TYPE_NAME (declspecs)
8408 && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
8410 strcat (buf, "enum ");
8411 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
8416 strcat (buf, "untagged enum ");
8420 strcat (buf, "void ");
8425 tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
8430 tree chain = protocol_list;
8437 (PROTOCOL_NAME (TREE_VALUE (chain))));
8438 chain = TREE_CHAIN (chain);
8454 /* Given a tree node, produce a printable description of it in the given
8455 buffer, overwriting the buffer. */
8458 gen_declaration (tree atype_or_adecl, char *buf)
8461 gen_declaration_1 (atype_or_adecl, buf);
8465 /* Given a tree node, append a printable description to the end of the
8469 gen_declaration_1 (tree atype_or_adecl, char *buf)
8473 if (TREE_CODE (atype_or_adecl) == TREE_LIST)
8475 tree declspecs; /* "identifier_node", "record_type" */
8476 tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
8477 tree width = NULL_TREE; /* for bitfields */
8479 /* We have a "raw", abstract declarator (typename). */
8480 declarator = TREE_VALUE (atype_or_adecl);
8481 /* In the case of raw ivars, the declarator itself is a list,
8482 and contains bitfield widths. */
8483 if (declarator && TREE_CODE (declarator) == TREE_LIST)
8485 width = TREE_VALUE (declarator);
8486 declarator = TREE_PURPOSE (declarator);
8488 declspecs = TREE_PURPOSE (atype_or_adecl);
8490 gen_declspecs (declspecs, buf, 1);
8494 strcat (buf, gen_declarator (declarator, declbuf, ""));
8497 sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
8498 TREE_INT_CST_LOW (width));
8504 tree declspecs; /* "integer_type", "real_type", "record_type"... */
8505 tree declarator; /* "array_type", "function_type", "pointer_type". */
8507 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8508 || TREE_CODE (atype_or_adecl) == PARM_DECL
8509 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8510 atype = TREE_TYPE (atype_or_adecl);
8512 /* Assume we have a *_type node. */
8513 atype = atype_or_adecl;
8515 if (is_complex_decl (atype))
8519 /* Get the declaration specifier; it is at the end of the list. */
8520 declarator = chain = atype;
8522 chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
8523 while (is_complex_decl (chain));
8530 declarator = NULL_TREE;
8533 gen_declspecs (declspecs, buf, 0);
8535 if (TREE_CODE (atype_or_adecl) == FIELD_DECL
8536 || TREE_CODE (atype_or_adecl) == PARM_DECL
8537 || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
8539 const char *const decl_name =
8540 (DECL_NAME (atype_or_adecl)
8541 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
8546 strcat (buf, gen_declarator (declarator, declbuf, decl_name));
8549 else if (decl_name[0])
8552 strcat (buf, decl_name);
8555 else if (declarator)
8558 strcat (buf, gen_declarator (declarator, declbuf, ""));
8563 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8565 /* Given a method tree, put a printable description into the given
8566 buffer (overwriting) and return a pointer to the buffer. */
8569 gen_method_decl (tree method, char *buf)
8574 if (RAW_TYPESPEC (method) != objc_object_reference)
8577 gen_declaration_1 (TREE_TYPE (method), buf);
8581 chain = METHOD_SEL_ARGS (method);
8584 /* We have a chain of keyword_decls. */
8587 if (KEYWORD_KEY_NAME (chain))
8588 strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8591 if (RAW_TYPESPEC (chain) != objc_object_reference)
8594 gen_declaration_1 (TREE_TYPE (chain), buf);
8598 strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8599 if ((chain = TREE_CHAIN (chain)))
8604 if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
8605 strcat (buf, ", ...");
8606 else if (METHOD_ADD_ARGS (method))
8608 /* We have a tree list node as generate by get_parm_info. */
8609 chain = TREE_PURPOSE (METHOD_ADD_ARGS (method));
8611 /* Know we have a chain of parm_decls. */
8615 gen_declaration_1 (chain, buf);
8616 chain = TREE_CHAIN (chain);
8622 /* We have a unary selector. */
8623 strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8631 /* Dump an @interface declaration of the supplied class CHAIN to the
8632 supplied file FP. Used to implement the -gen-decls option (which
8633 prints out an @interface declaration of all classes compiled in
8634 this run); potentially useful for debugging the compiler too. */
8636 dump_interface (FILE *fp, tree chain)
8638 /* FIXME: A heap overflow here whenever a method (or ivar)
8639 declaration is so long that it doesn't fit in the buffer. The
8640 code and all the related functions should be rewritten to avoid
8641 using fixed size buffers. */
8642 char *buf = (char *) xmalloc (1024 * 10);
8643 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8644 tree ivar_decls = CLASS_RAW_IVARS (chain);
8645 tree nst_methods = CLASS_NST_METHODS (chain);
8646 tree cls_methods = CLASS_CLS_METHODS (chain);
8648 fprintf (fp, "\n@interface %s", my_name);
8650 /* CLASS_SUPER_NAME is used to store the superclass name for
8651 classes, and the category name for categories. */
8652 if (CLASS_SUPER_NAME (chain))
8654 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8656 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8657 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8659 fprintf (fp, " (%s)\n", name);
8663 fprintf (fp, " : %s\n", name);
8669 /* FIXME - the following doesn't seem to work at the moment. */
8672 fprintf (fp, "{\n");
8675 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf));
8676 ivar_decls = TREE_CHAIN (ivar_decls);
8679 fprintf (fp, "}\n");
8684 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf));
8685 nst_methods = TREE_CHAIN (nst_methods);
8690 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf));
8691 cls_methods = TREE_CHAIN (cls_methods);
8694 fprintf (fp, "@end\n");
8697 /* Demangle function for Objective-C */
8699 objc_demangle (const char *mangled)
8701 char *demangled, *cp;
8703 if (mangled[0] == '_' &&
8704 (mangled[1] == 'i' || mangled[1] == 'c') &&
8707 cp = demangled = xmalloc(strlen(mangled) + 2);
8708 if (mangled[1] == 'i')
8709 *cp++ = '-'; /* for instance method */
8711 *cp++ = '+'; /* for class method */
8712 *cp++ = '['; /* opening left brace */
8713 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8714 while (*cp && *cp == '_')
8715 cp++; /* skip any initial underbars in class name */
8716 cp = strchr(cp, '_'); /* find first non-initial underbar */
8719 free(demangled); /* not mangled name */
8722 if (cp[1] == '_') /* easy case: no category name */
8724 *cp++ = ' '; /* replace two '_' with one ' ' */
8725 strcpy(cp, mangled + (cp - demangled) + 2);
8729 *cp++ = '('; /* less easy case: category name */
8730 cp = strchr(cp, '_');
8733 free(demangled); /* not mangled name */
8737 *cp++ = ' '; /* overwriting 1st char of method name... */
8738 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8740 while (*cp && *cp == '_')
8741 cp++; /* skip any initial underbars in method name */
8744 *cp = ':'; /* replace remaining '_' with ':' */
8745 *cp++ = ']'; /* closing right brace */
8746 *cp++ = 0; /* string terminator */
8750 return mangled; /* not an objc mangled name */
8754 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8756 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8762 gcc_obstack_init (&util_obstack);
8763 util_firstobj = (char *) obstack_finish (&util_obstack);
8765 errbuf = (char *) xmalloc (BUFSIZE);
8767 synth_module_prologue ();
8773 struct imp_entry *impent;
8775 /* The internally generated initializers appear to have missing braces.
8776 Don't warn about this. */
8777 int save_warn_missing_braces = warn_missing_braces;
8778 warn_missing_braces = 0;
8780 /* A missing @end may not be detected by the parser. */
8781 if (objc_implementation_context)
8783 warning ("`@end' missing in implementation context");
8784 finish_class (objc_implementation_context);
8785 objc_ivar_chain = NULL_TREE;
8786 objc_implementation_context = NULL_TREE;
8789 /* Process the static instances here because initialization of objc_symtab
8791 if (objc_static_instances)
8792 generate_static_references ();
8794 if (imp_list || class_names_chain
8795 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8796 generate_objc_symtab_decl ();
8798 for (impent = imp_list; impent; impent = impent->next)
8800 objc_implementation_context = impent->imp_context;
8801 implementation_template = impent->imp_template;
8803 UOBJC_CLASS_decl = impent->class_decl;
8804 UOBJC_METACLASS_decl = impent->meta_decl;
8806 /* Dump the @interface of each class as we compile it, if the
8807 -gen-decls option is in use. TODO: Dump the classes in the
8808 order they were found, rather than in reverse order as we
8810 if (flag_gen_declaration)
8812 dump_interface (gen_declaration_file, objc_implementation_context);
8815 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8817 /* all of the following reference the string pool... */
8818 generate_ivar_lists ();
8819 generate_dispatch_tables ();
8820 generate_shared_structures ();
8824 generate_dispatch_tables ();
8825 generate_category (objc_implementation_context);
8829 /* If we are using an array of selectors, we must always
8830 finish up the array decl even if no selectors were used. */
8831 if (! flag_next_runtime || sel_ref_chain)
8832 build_selector_translation_table ();
8835 generate_protocols ();
8837 if (flag_replace_objc_classes && imp_list)
8838 generate_objc_image_info ();
8840 if (objc_implementation_context || class_names_chain || objc_static_instances
8841 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8843 /* Arrange for ObjC data structures to be initialized at run time. */
8844 rtx init_sym = build_module_descriptor ();
8845 if (init_sym && targetm.have_ctors_dtors)
8846 (* targetm.asm_out.constructor) (init_sym, DEFAULT_INIT_PRIORITY);
8849 /* Dump the class references. This forces the appropriate classes
8850 to be linked into the executable image, preserving unix archive
8851 semantics. This can be removed when we move to a more dynamically
8852 linked environment. */
8854 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8856 handle_class_ref (chain);
8857 if (TREE_PURPOSE (chain))
8858 generate_classref_translation_entry (chain);
8861 for (impent = imp_list; impent; impent = impent->next)
8862 handle_impent (impent);
8864 /* Dump the string table last. */
8866 generate_strings ();
8873 /* Run through the selector hash tables and print a warning for any
8874 selector which has multiple methods. */
8876 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8878 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8879 check_duplicates (hsh, 0, 1);
8880 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8881 check_duplicates (hsh, 0, 1);
8885 warn_missing_braces = save_warn_missing_braces;
8888 /* Subroutines of finish_objc. */
8891 generate_classref_translation_entry (tree chain)
8893 tree expr, name, decl_specs, decl, sc_spec;
8896 type = TREE_TYPE (TREE_PURPOSE (chain));
8898 expr = add_objc_string (TREE_VALUE (chain), class_names);
8899 expr = build_c_cast (type, expr); /* cast! */
8901 name = DECL_NAME (TREE_PURPOSE (chain));
8903 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
8905 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8906 decl_specs = tree_cons (NULL_TREE, type, sc_spec);
8908 /* The decl that is returned from start_decl is the one that we
8909 forward declared in build_class_reference. */
8910 decl = start_decl (name, decl_specs, 1, NULL_TREE);
8911 DECL_CONTEXT (decl) = NULL_TREE;
8912 finish_decl (decl, expr, NULL_TREE);
8917 handle_class_ref (tree chain)
8919 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8920 char *string = (char *) alloca (strlen (name) + 30);
8924 sprintf (string, "%sobjc_class_name_%s",
8925 (flag_next_runtime ? "." : "__"), name);
8927 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8928 if (flag_next_runtime)
8930 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8935 /* Make a decl for this name, so we can use its address in a tree. */
8936 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8937 DECL_EXTERNAL (decl) = 1;
8938 TREE_PUBLIC (decl) = 1;
8941 rest_of_decl_compilation (decl, 0, 0, 0);
8943 /* Make a decl for the address. */
8944 sprintf (string, "%sobjc_class_ref_%s",
8945 (flag_next_runtime ? "." : "__"), name);
8946 exp = build1 (ADDR_EXPR, string_type_node, decl);
8947 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8948 DECL_INITIAL (decl) = exp;
8949 TREE_STATIC (decl) = 1;
8950 TREE_USED (decl) = 1;
8953 rest_of_decl_compilation (decl, 0, 0, 0);
8957 handle_impent (struct imp_entry *impent)
8961 objc_implementation_context = impent->imp_context;
8962 implementation_template = impent->imp_template;
8964 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8966 const char *const class_name =
8967 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8969 string = (char *) alloca (strlen (class_name) + 30);
8971 sprintf (string, "%sobjc_class_name_%s",
8972 (flag_next_runtime ? "." : "__"), class_name);
8974 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8976 const char *const class_name =
8977 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8978 const char *const class_super_name =
8979 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8981 string = (char *) alloca (strlen (class_name)
8982 + strlen (class_super_name) + 30);
8984 /* Do the same for categories. Even though no references to
8985 these symbols are generated automatically by the compiler, it
8986 gives you a handle to pull them into an archive by hand. */
8987 sprintf (string, "*%sobjc_category_name_%s_%s",
8988 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8993 #ifdef ASM_DECLARE_CLASS_REFERENCE
8994 if (flag_next_runtime)
8996 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9004 init = build_int_2 (0, 0);
9005 TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1);
9006 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9007 TREE_PUBLIC (decl) = 1;
9008 TREE_READONLY (decl) = 1;
9009 TREE_USED (decl) = 1;
9010 TREE_CONSTANT (decl) = 1;
9011 DECL_CONTEXT (decl) = 0;
9012 DECL_ARTIFICIAL (decl) = 1;
9013 DECL_INITIAL (decl) = init;
9014 assemble_variable (decl, 1, 0, 0);
9018 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9019 later requires that ObjC translation units participating in F&C be
9020 specially marked. The following routine accomplishes this. */
9022 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9025 generate_objc_image_info (void)
9027 tree sc_spec, decl, initlist;
9029 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
9031 = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
9032 tree_cons (NULL_TREE,
9035 build_index_type (build_int_2 (1, 0))),
9040 initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
9041 initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
9042 initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
9044 TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
9045 TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
9046 finish_decl (decl, initlist, NULL_TREE);
9049 /* Look up ID as an instance variable. */
9052 lookup_objc_ivar (tree id)
9056 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
9057 /* We have a message to super. */
9058 return get_super_receiver ();
9059 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
9061 if (is_private (decl))
9062 return error_mark_node;
9064 return build_ivar_reference (id);
9070 #include "gt-objc-objc-act.h"
9071 #include "gtype-objc.h"