1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
59 #include "langhooks.h"
70 #include "diagnostic.h"
72 #include "tree-iterator.h"
76 #define OBJC_VOID_AT_END void_list_node
78 /* When building Objective-C++, we are not linking against the C front-end
79 and so need to replicate the C tree-construction functions in some way. */
81 #define OBJCP_REMAP_FUNCTIONS
82 #include "objcp-decl.h"
85 /* This is the default way of generating a method name. */
86 /* I am not sure it is really correct.
87 Perhaps there's a danger that it will make name conflicts
88 if method names contain underscores. -- rms. */
89 #ifndef OBJC_GEN_METHOD_LABEL
90 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
93 sprintf ((BUF), "_%s_%s_%s_%s", \
94 ((IS_INST) ? "i" : "c"), \
96 ((CAT_NAME)? (CAT_NAME) : ""), \
98 for (temp = (BUF); *temp; temp++) \
99 if (*temp == ':') *temp = '_'; \
103 /* These need specifying. */
104 #ifndef OBJC_FORWARDING_STACK_OFFSET
105 #define OBJC_FORWARDING_STACK_OFFSET 0
108 #ifndef OBJC_FORWARDING_MIN_OFFSET
109 #define OBJC_FORWARDING_MIN_OFFSET 0
112 /* Set up for use of obstacks. */
116 /* This obstack is used to accumulate the encoding of a data type. */
117 static struct obstack util_obstack;
119 /* This points to the beginning of obstack contents, so we can free
120 the whole contents. */
123 /* The version identifies which language generation and runtime
124 the module (file) was compiled for, and is recorded in the
125 module descriptor. */
127 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
128 #define PROTOCOL_VERSION 2
130 /* (Decide if these can ever be validly changed.) */
131 #define OBJC_ENCODE_INLINE_DEFS 0
132 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
134 /*** Private Interface (procedures) ***/
136 /* Used by compile_file. */
138 static void init_objc (void);
139 static void finish_objc (void);
141 /* Code generation. */
143 static void synth_module_prologue (void);
144 static tree objc_build_constructor (tree, tree);
145 static void build_module_descriptor (void);
146 static void build_module_initializer_routine (void);
147 static tree init_module_descriptor (tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static void generate_strings (void);
150 static tree get_proto_encoding (tree);
151 static void build_selector_translation_table (void);
152 static tree lookup_interface (tree);
153 static tree objc_add_static_instance (tree, tree);
155 static tree start_class (enum tree_code, tree, tree, tree);
156 static tree continue_class (tree);
157 static void finish_class (tree);
158 static void start_method_def (tree);
159 static void objc_start_function (tree, tree, tree, tree);
160 static tree start_protocol (enum tree_code, tree, tree);
161 static tree build_method_decl (enum tree_code, tree, tree, tree);
162 static tree objc_add_method (tree, tree, int);
163 static tree add_instance_variable (tree, int, tree);
164 static tree build_ivar_reference (tree);
165 static tree is_ivar (tree, tree);
166 static int is_private (tree);
167 static tree get_super_receiver (void);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 static tree build_ivar_template (void);
173 static tree build_method_template (void);
174 static tree build_private_template (tree);
175 static void build_class_template (void);
176 static void build_selector_template (void);
177 static void build_category_template (void);
178 static tree lookup_method_in_hash_lists (tree, int);
179 static void build_super_template (void);
180 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
181 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
182 static void synth_forward_declarations (void);
183 static int ivar_list_length (tree);
184 static tree get_class_ivars (tree);
185 static void generate_ivar_lists (void);
186 static void generate_dispatch_tables (void);
187 static void generate_shared_structures (void);
188 static tree generate_protocol_list (tree);
189 static void build_protocol_reference (tree);
191 static tree build_keyword_selector (tree);
192 static const char *synth_id_with_class_suffix (const char *, tree);
194 static void generate_static_references (void);
195 static int check_methods_accessible (tree, tree, int);
196 static void encode_aggregate_within (tree, int, int, int, int);
197 static const char *objc_demangle (const char *);
199 /* Hash tables to manage the global pool of method prototypes. */
201 hash *nst_method_hash_list = 0;
202 hash *cls_method_hash_list = 0;
204 static size_t hash_func (tree);
205 static void hash_init (void);
206 static void hash_enter (hash *, tree);
207 static hash hash_lookup (hash *, tree);
208 static void hash_add_attr (hash, tree);
209 static tree lookup_method (tree, tree);
210 static tree lookup_method_static (tree, tree, int);
211 static void add_method_to_hash_list (hash *, tree);
212 static tree add_class (tree);
213 static void add_category (tree, tree);
214 static inline tree lookup_category (tree, tree);
218 class_names, /* class, category, protocol, module names */
219 meth_var_names, /* method and variable names */
220 meth_var_types /* method and variable type descriptors */
223 static tree add_objc_string (tree, enum string_section);
224 static tree get_objc_string_decl (tree, enum string_section);
225 static tree build_objc_string_decl (enum string_section);
226 static tree build_selector_reference_decl (void);
227 static void build_selector_table_decl (void);
229 /* Protocol additions. */
231 static tree add_protocol (tree);
232 static tree lookup_protocol (tree);
233 static void check_protocol_recursively (tree, tree);
234 static tree lookup_and_install_protocols (tree);
238 static void encode_type_qualifiers (tree);
239 static void encode_pointer (tree, int, int);
240 static void encode_array (tree, int, int);
241 static void encode_aggregate (tree, int, int);
242 static void encode_next_bitfield (int);
243 static void encode_gnu_bitfield (int, tree, int);
244 static void encode_type (tree, int, int);
245 static void encode_field_decl (tree, int, int);
247 static void really_start_method (tree, tree);
248 static int objc_types_are_equivalent (tree, tree);
249 static int comp_proto_with_proto (tree, tree);
250 static tree get_arg_type_list (tree, int, int);
251 static void objc_push_parm (tree);
252 static tree objc_get_parm_info (int);
253 static void synth_self_and_ucmd_args (void);
255 /* Utilities for debugging and error diagnostics. */
257 static void warn_with_method (const char *, int, tree);
258 static void error_with_ivar (const char *, tree);
259 static char *gen_type_name (tree);
260 static char *gen_type_name_0 (tree);
261 static char *gen_method_decl (tree);
262 static char *gen_declaration (tree);
263 static void dump_interface (FILE *, tree);
265 /* Everything else. */
267 static tree lookup_method_in_protocol_list (tree, tree, int);
268 static tree lookup_protocol_in_reflist (tree, tree);
269 static tree start_var_decl (tree, const char *);
270 static void finish_var_decl (tree, tree);
271 static tree create_field_decl (tree, const char *);
272 static tree setup_string_decl (void);
273 static int check_string_class_template (void);
274 static tree my_build_string (int, const char *);
275 static void build_objc_symtab_template (void);
276 static tree init_def_list (tree);
277 static tree init_objc_symtab (tree);
278 static tree build_metadata_decl (const char *, tree);
279 static void forward_declare_categories (void);
280 static void generate_objc_symtab_decl (void);
281 static tree build_selector (tree);
282 static tree build_typed_selector_reference (tree, tree);
283 static tree build_selector_reference (tree);
284 static tree build_class_reference_decl (void);
285 static void add_class_reference (tree);
286 static void build_protocol_template (void);
287 static tree build_descriptor_table_initializer (tree, tree);
288 static tree build_method_prototype_list_template (tree, int);
289 static tree build_method_prototype_template (void);
290 static tree objc_method_parm_type (tree);
291 static int objc_encoded_type_size (tree);
292 static tree encode_method_prototype (tree);
293 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
294 static void generate_method_descriptors (tree);
295 static void generate_protocol_references (tree);
296 static void generate_protocols (void);
297 static void check_ivars (tree, tree);
298 static tree build_ivar_list_template (tree, int);
299 static tree build_method_list_template (tree, int);
300 static tree build_ivar_list_initializer (tree, tree);
301 static tree generate_ivars_list (tree, const char *, int, tree);
302 static tree build_dispatch_table_initializer (tree, tree);
303 static tree generate_dispatch_table (tree, const char *, int, tree);
304 static tree build_shared_structure_initializer (tree, tree, tree, tree,
305 tree, int, tree, tree, tree);
306 static void generate_category (tree);
307 static tree adjust_type_for_id_default (tree);
308 static tree check_duplicates (hash, int, int);
309 static tree receiver_is_class_object (tree, int, int);
310 static int check_methods (tree, tree, int);
311 static int conforms_to_protocol (tree, tree);
312 static void check_protocol (tree, const char *, const char *);
313 static void check_protocols (tree, const char *, const char *);
314 static void generate_classref_translation_entry (tree);
315 static void handle_class_ref (tree);
316 static void generate_struct_by_value_array (void)
318 static void mark_referenced_methods (void);
319 static void generate_objc_image_info (void);
321 /*** Private Interface (data) ***/
323 /* Reserved tag definitions. */
325 #define OBJECT_TYPEDEF_NAME "id"
326 #define CLASS_TYPEDEF_NAME "Class"
328 #define TAG_OBJECT "objc_object"
329 #define TAG_CLASS "objc_class"
330 #define TAG_SUPER "objc_super"
331 #define TAG_SELECTOR "objc_selector"
333 #define UTAG_CLASS "_objc_class"
334 #define UTAG_IVAR "_objc_ivar"
335 #define UTAG_IVAR_LIST "_objc_ivar_list"
336 #define UTAG_METHOD "_objc_method"
337 #define UTAG_METHOD_LIST "_objc_method_list"
338 #define UTAG_CATEGORY "_objc_category"
339 #define UTAG_MODULE "_objc_module"
340 #define UTAG_SYMTAB "_objc_symtab"
341 #define UTAG_SUPER "_objc_super"
342 #define UTAG_SELECTOR "_objc_selector"
344 #define UTAG_PROTOCOL "_objc_protocol"
345 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
346 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
348 /* Note that the string object global name is only needed for the
350 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
352 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
354 static const char *TAG_GETCLASS;
355 static const char *TAG_GETMETACLASS;
356 static const char *TAG_MSGSEND;
357 static const char *TAG_MSGSENDSUPER;
358 /* The NeXT Objective-C messenger may have two extra entry points, for use
359 when returning a structure. */
360 static const char *TAG_MSGSEND_STRET;
361 static const char *TAG_MSGSENDSUPER_STRET;
362 static const char *default_constant_string_class_name;
364 /* Runtime metadata flags. */
365 #define CLS_FACTORY 0x0001L
366 #define CLS_META 0x0002L
368 #define OBJC_MODIFIER_STATIC 0x00000001
369 #define OBJC_MODIFIER_FINAL 0x00000002
370 #define OBJC_MODIFIER_PUBLIC 0x00000004
371 #define OBJC_MODIFIER_PRIVATE 0x00000008
372 #define OBJC_MODIFIER_PROTECTED 0x00000010
373 #define OBJC_MODIFIER_NATIVE 0x00000020
374 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
375 #define OBJC_MODIFIER_ABSTRACT 0x00000080
376 #define OBJC_MODIFIER_VOLATILE 0x00000100
377 #define OBJC_MODIFIER_TRANSIENT 0x00000200
378 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
380 /* NeXT-specific tags. */
382 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
383 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
384 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
385 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
386 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
387 #define TAG_EXCEPTIONMATCH "objc_exception_match"
388 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
389 #define TAG_SYNCENTER "objc_sync_enter"
390 #define TAG_SYNCEXIT "objc_sync_exit"
391 #define TAG_SETJMP "_setjmp"
392 #define UTAG_EXCDATA "_objc_exception_data"
394 /* GNU-specific tags. */
396 #define TAG_EXECCLASS "__objc_exec_class"
397 #define TAG_GNUINIT "__objc_gnu_init"
399 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
400 tree objc_global_trees[OCTI_MAX];
402 static void handle_impent (struct imp_entry *);
404 struct imp_entry *imp_list = 0;
405 int imp_count = 0; /* `@implementation' */
406 int cat_count = 0; /* `@category' */
408 enum tree_code objc_inherit_code;
409 int objc_public_flag;
411 /* Use to generate method labels. */
412 static int method_slot = 0;
416 static char *errbuf; /* Buffer for error diagnostics */
418 /* Data imported from tree.c. */
420 extern enum debug_info_type write_symbols;
422 /* Data imported from toplev.c. */
424 extern const char *dump_base_name;
426 static int flag_typed_selectors;
428 /* Store all constructed constant strings in a hash table so that
429 they get uniqued properly. */
431 struct string_descriptor GTY(())
433 /* The literal argument . */
436 /* The resulting constant string. */
440 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
442 static hashval_t string_hash (const void *);
443 static int string_eq (const void *, const void *);
445 FILE *gen_declaration_file;
447 /* Tells "encode_pointer/encode_aggregate" whether we are generating
448 type descriptors for instance variables (as opposed to methods).
449 Type descriptors for instance variables contain more information
450 than methods (for static typing and embedded structures). */
452 static int generating_instance_variables = 0;
454 /* Some platforms pass small structures through registers versus
455 through an invisible pointer. Determine at what size structure is
456 the transition point between the two possibilities. */
459 generate_struct_by_value_array (void)
462 tree field_decl, field_decl_chain;
464 int aggregate_in_mem[32];
467 /* Presumably no platform passes 32 byte structures in a register. */
468 for (i = 1; i < 32; i++)
472 /* Create an unnamed struct that has `i' character components */
473 type = start_struct (RECORD_TYPE, NULL_TREE);
475 strcpy (buffer, "c1");
476 field_decl = create_field_decl (char_type_node,
478 field_decl_chain = field_decl;
480 for (j = 1; j < i; j++)
482 sprintf (buffer, "c%d", j + 1);
483 field_decl = create_field_decl (char_type_node,
485 chainon (field_decl_chain, field_decl);
487 finish_struct (type, field_decl_chain, NULL_TREE);
489 aggregate_in_mem[i] = aggregate_value_p (type, 0);
490 if (!aggregate_in_mem[i])
494 /* We found some structures that are returned in registers instead of memory
495 so output the necessary data. */
498 for (i = 31; i >= 0; i--)
499 if (!aggregate_in_mem[i])
501 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
503 /* The first member of the structure is always 0 because we don't handle
504 structures with 0 members */
505 printf ("static int struct_forward_array[] = {\n 0");
507 for (j = 1; j <= i; j++)
508 printf (", %d", aggregate_in_mem[j]);
519 if (cxx_init () == false)
521 if (c_objc_common_init () == false)
525 /* Force the line number back to 0; check_newline will have
526 raised it to 1, which will make the builtin functions appear
527 not to be built in. */
530 /* If gen_declaration desired, open the output file. */
531 if (flag_gen_declaration)
533 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
534 gen_declaration_file = fopen (dumpname, "w");
535 if (gen_declaration_file == 0)
536 fatal_error ("can't open %s: %m", dumpname);
540 if (flag_next_runtime)
542 TAG_GETCLASS = "objc_getClass";
543 TAG_GETMETACLASS = "objc_getMetaClass";
544 TAG_MSGSEND = "objc_msgSend";
545 TAG_MSGSENDSUPER = "objc_msgSendSuper";
546 TAG_MSGSEND_STRET = "objc_msgSend_stret";
547 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
548 default_constant_string_class_name = "NSConstantString";
552 TAG_GETCLASS = "objc_get_class";
553 TAG_GETMETACLASS = "objc_get_meta_class";
554 TAG_MSGSEND = "objc_msg_lookup";
555 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
556 /* GNU runtime does not provide special functions to support
557 structure-returning methods. */
558 default_constant_string_class_name = "NXConstantString";
559 flag_typed_selectors = 1;
564 if (print_struct_values)
565 generate_struct_by_value_array ();
571 objc_finish_file (void)
573 mark_referenced_methods ();
576 /* We need to instantiate templates _before_ we emit ObjC metadata;
577 if we do not, some metadata (such as selectors) may go missing. */
578 instantiate_pending_templates (0);
581 /* Finalize Objective-C runtime data. No need to generate tables
582 and code if only checking syntax. */
583 if (!flag_syntax_only)
586 if (gen_declaration_file)
587 fclose (gen_declaration_file);
594 /* Return the first occurrence of a method declaration corresponding
595 to sel_name in rproto_list. Search rproto_list recursively.
596 If is_class is 0, search for instance methods, otherwise for class
599 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
605 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
607 p = TREE_VALUE (rproto);
609 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
611 if ((fnd = lookup_method (is_class
612 ? PROTOCOL_CLS_METHODS (p)
613 : PROTOCOL_NST_METHODS (p), sel_name)))
615 else if (PROTOCOL_LIST (p))
616 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
621 ; /* An identifier...if we could not find a protocol. */
632 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
636 /* Make sure the protocol is supported by the object on the rhs. */
637 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
640 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
642 p = TREE_VALUE (rproto);
644 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
649 else if (PROTOCOL_LIST (p))
650 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
659 ; /* An identifier...if we could not find a protocol. */
666 objc_start_class_interface (tree class, tree super_class, tree protos)
668 objc_interface_context
670 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
671 objc_public_flag = 0;
675 objc_start_category_interface (tree class, tree categ, tree protos)
677 objc_interface_context
678 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
680 = continue_class (objc_interface_context);
684 objc_start_protocol (tree name, tree protos)
686 objc_interface_context
687 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
691 objc_continue_interface (void)
694 = continue_class (objc_interface_context);
698 objc_finish_interface (void)
700 finish_class (objc_interface_context);
701 objc_interface_context = NULL_TREE;
705 objc_start_class_implementation (tree class, tree super_class)
707 objc_implementation_context
709 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
710 objc_public_flag = 0;
714 objc_start_category_implementation (tree class, tree categ)
716 objc_implementation_context
717 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
719 = continue_class (objc_implementation_context);
723 objc_continue_implementation (void)
726 = continue_class (objc_implementation_context);
730 objc_finish_implementation (void)
732 if (objc_implementation_context)
734 finish_class (objc_implementation_context);
735 objc_ivar_chain = NULL_TREE;
736 objc_implementation_context = NULL_TREE;
739 warning ("`@end' must appear in an @implementation context");
743 objc_set_visibility (int visibility)
745 objc_public_flag = visibility;
749 objc_set_method_type (enum tree_code type)
751 objc_inherit_code = (type == PLUS_EXPR
753 : INSTANCE_METHOD_DECL);
757 objc_build_method_signature (tree rettype, tree selector, tree optparms)
759 return build_method_decl (objc_inherit_code, rettype, selector, optparms);
763 objc_add_method_declaration (tree decl)
765 if (!objc_interface_context)
766 fatal_error ("method declaration not in @interface context");
768 objc_add_method (objc_interface_context,
770 objc_inherit_code == CLASS_METHOD_DECL);
774 objc_start_method_definition (tree decl)
776 if (!objc_implementation_context)
777 fatal_error ("method definition not in @implementation context");
779 objc_add_method (objc_implementation_context,
781 objc_inherit_code == CLASS_METHOD_DECL);
782 start_method_def (decl);
786 objc_add_instance_variable (tree decl)
788 (void) add_instance_variable (objc_ivar_context,
793 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
797 objc_is_reserved_word (tree ident)
799 unsigned char code = C_RID_CODE (ident);
801 return (OBJC_IS_AT_KEYWORD (code)
803 || code == RID_CLASS || code == RID_PUBLIC
804 || code == RID_PROTECTED || code == RID_PRIVATE
805 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
810 /* Return true if TYPE is 'id'. */
813 objc_is_object_id (tree type)
815 return OBJC_TYPE_NAME (type) == objc_object_id;
819 objc_is_class_id (tree type)
821 return OBJC_TYPE_NAME (type) == objc_class_id;
824 /* Return 1 if LHS and RHS are compatible types for assignment or
825 various other operations. Return 0 if they are incompatible, and
826 return -1 if we choose to not decide (because the types are really
827 just C types, not ObjC specific ones). When the operation is
828 REFLEXIVE (typically comparisons), check for compatibility in
829 either direction; when it's not (typically assignments), don't.
831 This function is called in two cases: when both lhs and rhs are
832 pointers to records (in which case we check protocols too), and
833 when both lhs and rhs are records (in which case we check class
836 Warnings about classes/protocols not implementing a protocol are
837 emitted here (multiple of those warnings might be emitted for a
838 single line!); generic warnings about incompatible assignments and
839 lacks of casts in comparisons are/must be emitted by the caller if
844 objc_comptypes (tree lhs, tree rhs, int reflexive)
846 /* New clause for protocols. */
848 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
849 manage the ObjC ones, and leave the rest to the C code. */
850 if (TREE_CODE (lhs) == POINTER_TYPE
851 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
852 && TREE_CODE (rhs) == POINTER_TYPE
853 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
855 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
856 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
860 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
861 tree rproto, rproto_list;
864 /* <Protocol> = <Protocol> */
867 rproto_list = TYPE_PROTOCOL_LIST (rhs);
871 /* An assignment between objects of type 'id
872 <Protocol>'; make sure the protocol on the lhs is
873 supported by the object on the rhs. */
874 for (lproto = lproto_list; lproto;
875 lproto = TREE_CHAIN (lproto))
877 p = TREE_VALUE (lproto);
878 rproto = lookup_protocol_in_reflist (rproto_list, p);
882 ("object does not conform to the `%s' protocol",
883 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
889 /* Obscure case - a comparison between two objects
890 of type 'id <Protocol>'. Check that either the
891 protocol on the lhs is supported by the object on
892 the rhs, or viceversa. */
894 /* Check if the protocol on the lhs is supported by the
895 object on the rhs. */
896 for (lproto = lproto_list; lproto;
897 lproto = TREE_CHAIN (lproto))
899 p = TREE_VALUE (lproto);
900 rproto = lookup_protocol_in_reflist (rproto_list, p);
904 /* Check failed - check if the protocol on the rhs
905 is supported by the object on the lhs. */
906 for (rproto = rproto_list; rproto;
907 rproto = TREE_CHAIN (rproto))
909 p = TREE_VALUE (rproto);
910 lproto = lookup_protocol_in_reflist (lproto_list,
915 /* This check failed too: incompatible */
925 /* <Protocol> = <class> * */
926 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
928 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
931 /* Make sure the protocol is supported by the object on
933 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
935 p = TREE_VALUE (lproto);
937 rinter = lookup_interface (rname);
939 while (rinter && !rproto)
943 rproto_list = CLASS_PROTOCOL_LIST (rinter);
944 rproto = lookup_protocol_in_reflist (rproto_list, p);
945 /* If the underlying ObjC class does not have
946 the protocol we're looking for, check for "one-off"
947 protocols (e.g., `NSObject<MyProt> *foo;') attached
951 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
952 rproto = lookup_protocol_in_reflist (rproto_list, p);
955 /* Check for protocols adopted by categories. */
956 cat = CLASS_CATEGORY_LIST (rinter);
957 while (cat && !rproto)
959 rproto_list = CLASS_PROTOCOL_LIST (cat);
960 rproto = lookup_protocol_in_reflist (rproto_list, p);
961 cat = CLASS_CATEGORY_LIST (cat);
964 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
968 warning ("class `%s' does not implement the `%s' protocol",
969 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
970 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
974 /* <Protocol> = id */
975 else if (objc_is_object_id (TREE_TYPE (rhs)))
979 /* <Protocol> = Class */
980 else if (objc_is_class_id (TREE_TYPE (rhs)))
984 /* <Protocol> = ?? : let comptypes decide. */
987 else if (rhs_is_proto)
989 /* <class> * = <Protocol> */
990 if (TYPED_OBJECT (TREE_TYPE (lhs)))
994 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
996 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
998 /* Make sure the protocol is supported by the object on
1000 for (rproto = rproto_list; rproto;
1001 rproto = TREE_CHAIN (rproto))
1003 tree p = TREE_VALUE (rproto);
1005 rinter = lookup_interface (rname);
1007 while (rinter && !lproto)
1011 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
1012 lproto = lookup_protocol_in_reflist (lproto_list, p);
1013 /* If the underlying ObjC class does not
1014 have the protocol we're looking for,
1015 check for "one-off" protocols (e.g.,
1016 `NSObject<MyProt> *foo;') attached to the
1020 lproto_list = TYPE_PROTOCOL_LIST
1022 lproto = lookup_protocol_in_reflist
1026 /* Check for protocols adopted by categories. */
1027 cat = CLASS_CATEGORY_LIST (rinter);
1028 while (cat && !lproto)
1030 lproto_list = CLASS_PROTOCOL_LIST (cat);
1031 lproto = lookup_protocol_in_reflist (lproto_list,
1033 cat = CLASS_CATEGORY_LIST (cat);
1036 rinter = lookup_interface (CLASS_SUPER_NAME
1041 warning ("class `%s' does not implement the `%s' protocol",
1042 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1044 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1051 /* id = <Protocol> */
1052 else if (objc_is_object_id (TREE_TYPE (lhs)))
1056 /* Class = <Protocol> */
1057 else if (objc_is_class_id (TREE_TYPE (lhs)))
1061 /* ??? = <Protocol> : let comptypes decide */
1069 /* Attention: we shouldn't defer to comptypes here. One bad
1070 side effect would be that we might loose the REFLEXIVE
1073 lhs = TREE_TYPE (lhs);
1074 rhs = TREE_TYPE (rhs);
1078 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
1080 /* Nothing to do with ObjC - let immediately comptypes take
1081 responsibility for checking. */
1085 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1087 'Object *o = [[Object alloc] init]; falls
1088 in the case <class> * = `id'.
1090 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
1091 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
1094 /* `id' = `Class', `Class' = `id' */
1096 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
1097 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
1100 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1101 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
1102 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
1105 /* `<class> *' = `<class> *' */
1107 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1109 tree lname = OBJC_TYPE_NAME (lhs);
1110 tree rname = OBJC_TYPE_NAME (rhs);
1116 /* If the left hand side is a super class of the right hand side,
1118 for (inter = lookup_interface (rname); inter;
1119 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1120 if (lname == CLASS_SUPER_NAME (inter))
1123 /* Allow the reverse when reflexive. */
1125 for (inter = lookup_interface (lname); inter;
1126 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1127 if (rname == CLASS_SUPER_NAME (inter))
1133 /* Not an ObjC type - let comptypes do the check. */
1137 /* Called from finish_decl. */
1140 objc_check_decl (tree decl)
1142 tree type = TREE_TYPE (decl);
1144 if (TREE_CODE (type) != RECORD_TYPE)
1146 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1147 error ("statically allocated instance of Objective-C class `%s'",
1148 IDENTIFIER_POINTER (type));
1151 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1152 either name an Objective-C class, or refer to the special 'id' or 'Class'
1153 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1156 objc_get_protocol_qualified_type (tree interface, tree protocols)
1161 type = objc_object_type;
1162 else if (!(type = objc_is_id (interface)))
1164 type = objc_is_class_name (interface);
1167 type = xref_tag (RECORD_TYPE, type);
1174 type = build_variant_type_copy (type);
1175 /* Look up protocols and install in lang specific list. Note
1176 that the protocol list can have a different lifetime than T! */
1177 SET_TYPE_PROTOCOL_LIST (type, lookup_and_install_protocols (protocols));
1179 /* Establish the ObjC-ness of this record. */
1180 if (TREE_CODE (type) == RECORD_TYPE)
1181 TREE_STATIC_TEMPLATE (type) = 1;
1187 /* Check for circular dependencies in protocols. The arguments are
1188 PROTO, the protocol to check, and LIST, a list of protocol it
1192 check_protocol_recursively (tree proto, tree list)
1196 for (p = list; p; p = TREE_CHAIN (p))
1198 tree pp = TREE_VALUE (p);
1200 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1201 pp = lookup_protocol (pp);
1204 fatal_error ("protocol `%s' has circular dependency",
1205 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1207 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1211 /* Look up PROTOCOLS, and return a list of those that are found.
1212 If none are found, return NULL. */
1215 lookup_and_install_protocols (tree protocols)
1218 tree return_value = NULL_TREE;
1220 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1222 tree ident = TREE_VALUE (proto);
1223 tree p = lookup_protocol (ident);
1226 error ("cannot find protocol declaration for `%s'",
1227 IDENTIFIER_POINTER (ident));
1229 return_value = chainon (return_value,
1230 build_tree_list (NULL_TREE, p));
1233 return return_value;
1236 /* Create a declaration for field NAME of a given TYPE. */
1239 create_field_decl (tree type, const char *name)
1241 return build_decl (FIELD_DECL, get_identifier (name), type);
1244 /* Create a global, static declaration for variable NAME of a given TYPE. The
1245 finish_var_decl() routine will need to be called on it afterwards. */
1248 start_var_decl (tree type, const char *name)
1250 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1252 TREE_STATIC (var) = 1;
1253 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1254 DECL_IGNORED_P (var) = 1;
1255 DECL_ARTIFICIAL (var) = 1;
1256 DECL_CONTEXT (var) = NULL_TREE;
1258 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1264 /* Finish off the variable declaration created by start_var_decl(). */
1267 finish_var_decl (tree var, tree initializer)
1269 finish_decl (var, initializer, NULL_TREE);
1270 /* Ensure that the variable actually gets output. */
1271 mark_decl_referenced (var);
1272 /* Mark the decl to avoid "defined but not used" warning. */
1273 TREE_USED (var) = 1;
1276 /* Find the decl for the constant string class refernce. This is only
1277 used for the NeXT runtime. */
1280 setup_string_decl (void)
1285 /* %s in format will provide room for terminating null */
1286 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1287 + strlen (constant_string_class_name);
1288 name = xmalloc (length);
1289 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1290 constant_string_class_name);
1291 constant_string_global_id = get_identifier (name);
1292 string_class_decl = lookup_name (constant_string_global_id);
1294 return string_class_decl;
1297 /* Purpose: "play" parser, creating/installing representations
1298 of the declarations that are required by Objective-C.
1302 type_spec--------->sc_spec
1303 (tree_list) (tree_list)
1306 identifier_node identifier_node */
1309 synth_module_prologue (void)
1312 enum debug_info_type save_write_symbols = write_symbols;
1313 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1315 /* Suppress outputting debug symbols, because
1316 dbxout_init hasn'r been called yet. */
1317 write_symbols = NO_DEBUG;
1318 debug_hooks = &do_nothing_debug_hooks;
1321 push_lang_context (lang_name_c); /* extern "C" */
1324 /* The following are also defined in <objc/objc.h> and friends. */
1326 objc_object_id = get_identifier (TAG_OBJECT);
1327 objc_class_id = get_identifier (TAG_CLASS);
1329 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1330 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1332 objc_object_type = build_pointer_type (objc_object_reference);
1333 objc_class_type = build_pointer_type (objc_class_reference);
1335 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1336 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1338 /* Declare the 'id' and 'Class' typedefs. */
1340 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1343 DECL_IN_SYSTEM_HEADER (type) = 1;
1344 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1347 DECL_IN_SYSTEM_HEADER (type) = 1;
1349 /* Forward-declare '@interface Protocol'. */
1351 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1352 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1353 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1356 /* Declare type of selector-objects that represent an operation name. */
1358 if (flag_next_runtime)
1359 /* `struct objc_selector *' */
1361 = build_pointer_type (xref_tag (RECORD_TYPE,
1362 get_identifier (TAG_SELECTOR)));
1364 /* `const struct objc_selector *' */
1366 = build_pointer_type
1367 (build_qualified_type (xref_tag (RECORD_TYPE,
1368 get_identifier (TAG_SELECTOR)),
1371 /* Declare receiver type used for dispatching messages to 'super'. */
1373 /* `struct objc_super *' */
1374 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1375 get_identifier (TAG_SUPER)));
1377 if (flag_next_runtime)
1379 /* NB: In order to call one of the ..._stret (struct-returning)
1380 functions, the function *MUST* first be cast to a signature that
1381 corresponds to the actual ObjC method being invoked. This is
1382 what is done by the build_objc_method_call() routine below. */
1384 /* id objc_msgSend (id, SEL, ...); */
1385 /* id objc_msgSendNonNil (id, SEL, ...); */
1386 /* id objc_msgSend_stret (id, SEL, ...); */
1387 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1389 = build_function_type (objc_object_type,
1390 tree_cons (NULL_TREE, objc_object_type,
1391 tree_cons (NULL_TREE, objc_selector_type,
1393 umsg_decl = builtin_function (TAG_MSGSEND,
1394 type, 0, NOT_BUILT_IN,
1396 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1397 type, 0, NOT_BUILT_IN,
1399 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1400 type, 0, NOT_BUILT_IN,
1402 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1403 type, 0, NOT_BUILT_IN,
1406 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1407 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1409 = build_function_type (objc_object_type,
1410 tree_cons (NULL_TREE, objc_super_type,
1411 tree_cons (NULL_TREE, objc_selector_type,
1413 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1414 type, 0, NOT_BUILT_IN,
1416 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1417 type, 0, NOT_BUILT_IN, 0,
1422 /* GNU runtime messenger entry points. */
1424 /* typedef id (*IMP)(id, SEL, ...); */
1426 = build_pointer_type
1427 (build_function_type (objc_object_type,
1428 tree_cons (NULL_TREE, objc_object_type,
1429 tree_cons (NULL_TREE, objc_selector_type,
1432 /* IMP objc_msg_lookup (id, SEL); */
1434 = build_function_type (IMP_type,
1435 tree_cons (NULL_TREE, objc_object_type,
1436 tree_cons (NULL_TREE, objc_selector_type,
1437 OBJC_VOID_AT_END)));
1438 umsg_decl = builtin_function (TAG_MSGSEND,
1439 type, 0, NOT_BUILT_IN,
1442 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1444 = build_function_type (IMP_type,
1445 tree_cons (NULL_TREE, objc_super_type,
1446 tree_cons (NULL_TREE, objc_selector_type,
1447 OBJC_VOID_AT_END)));
1448 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1449 type, 0, NOT_BUILT_IN,
1452 /* The following GNU runtime entry point is called to initialize
1455 __objc_exec_class (void *); */
1457 = build_function_type (void_type_node,
1458 tree_cons (NULL_TREE, ptr_type_node,
1460 execclass_decl = builtin_function (TAG_EXECCLASS,
1461 type, 0, NOT_BUILT_IN,
1465 /* id objc_getClass (const char *); */
1467 type = build_function_type (objc_object_type,
1468 tree_cons (NULL_TREE,
1469 const_string_type_node,
1473 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1476 /* id objc_getMetaClass (const char *); */
1478 objc_get_meta_class_decl
1479 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1481 build_class_template ();
1482 build_super_template ();
1483 build_protocol_template ();
1484 build_category_template ();
1485 build_objc_exception_stuff ();
1487 if (flag_next_runtime)
1488 build_next_objc_exception_stuff ();
1490 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1492 if (! flag_next_runtime)
1493 build_selector_table_decl ();
1495 /* Forward declare constant_string_id and constant_string_type. */
1496 if (!constant_string_class_name)
1497 constant_string_class_name = default_constant_string_class_name;
1499 constant_string_id = get_identifier (constant_string_class_name);
1500 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1502 /* Pre-build the following entities - for speed/convenience. */
1503 self_id = get_identifier ("self");
1504 ucmd_id = get_identifier ("_cmd");
1506 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1507 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1511 pop_lang_context ();
1514 write_symbols = save_write_symbols;
1515 debug_hooks = save_hooks;
1518 /* Ensure that the ivar list for NSConstantString/NXConstantString
1519 (or whatever was specified via `-fconstant-string-class')
1520 contains fields at least as large as the following three, so that
1521 the runtime can stomp on them with confidence:
1523 struct STRING_OBJECT_CLASS_NAME
1527 unsigned int length;
1531 check_string_class_template (void)
1533 tree field_decl = TYPE_FIELDS (constant_string_type);
1535 #define AT_LEAST_AS_LARGE_AS(F, T) \
1536 (F && TREE_CODE (F) == FIELD_DECL \
1537 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1538 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1540 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1543 field_decl = TREE_CHAIN (field_decl);
1544 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1547 field_decl = TREE_CHAIN (field_decl);
1548 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1550 #undef AT_LEAST_AS_LARGE_AS
1553 /* Avoid calling `check_string_class_template ()' more than once. */
1554 static GTY(()) int string_layout_checked;
1556 /* Custom build_string which sets TREE_TYPE! */
1559 my_build_string (int len, const char *str)
1561 return fix_string_type (build_string (len, str));
1566 string_hash (const void *ptr)
1568 tree str = ((struct string_descriptor *)ptr)->literal;
1569 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1570 int i, len = TREE_STRING_LENGTH (str);
1573 for (i = 0; i < len; i++)
1574 h = ((h * 613) + p[i]);
1580 string_eq (const void *ptr1, const void *ptr2)
1582 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1583 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1584 int len1 = TREE_STRING_LENGTH (str1);
1586 return (len1 == TREE_STRING_LENGTH (str2)
1587 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1591 /* Given a chain of STRING_CST's, build a static instance of
1592 NXConstantString which points at the concatenation of those
1593 strings. We place the string object in the __string_objects
1594 section of the __OBJC segment. The Objective-C runtime will
1595 initialize the isa pointers of the string objects to point at the
1596 NXConstantString class object. */
1599 objc_build_string_object (tree string)
1601 tree initlist, constructor, constant_string_class;
1604 struct string_descriptor *desc, key;
1607 /* Prep the string argument. */
1608 string = fix_string_type (string);
1609 TREE_SET_CODE (string, STRING_CST);
1610 length = TREE_STRING_LENGTH (string) - 1;
1612 /* Check whether the string class being used actually exists and has the
1613 correct ivar layout. */
1614 if (!string_layout_checked)
1616 string_layout_checked = -1;
1617 constant_string_class = lookup_interface (constant_string_id);
1619 if (!constant_string_class
1620 || !(constant_string_type
1621 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1622 error ("cannot find interface declaration for `%s'",
1623 IDENTIFIER_POINTER (constant_string_id));
1624 /* The NSConstantString/NXConstantString ivar layout is now known. */
1625 else if (!check_string_class_template ())
1626 error ("interface `%s' does not have valid constant string layout",
1627 IDENTIFIER_POINTER (constant_string_id));
1628 /* For the NeXT runtime, we can generate a literal reference
1629 to the string class, don't need to run a constructor. */
1630 else if (flag_next_runtime && !setup_string_decl ())
1631 error ("cannot find reference tag for class `%s'",
1632 IDENTIFIER_POINTER (constant_string_id));
1635 string_layout_checked = 1; /* Success! */
1636 add_class_reference (constant_string_id);
1640 if (string_layout_checked == -1)
1641 return error_mark_node;
1643 /* Perhaps we already constructed a constant string just like this one? */
1644 key.literal = string;
1645 loc = htab_find_slot (string_htab, &key, INSERT);
1650 *loc = desc = ggc_alloc (sizeof (*desc));
1651 desc->literal = string;
1653 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1654 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1655 fields = TYPE_FIELDS (constant_string_type);
1657 = build_tree_list (fields,
1659 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1660 : build_int_cst (NULL_TREE, 0));
1661 fields = TREE_CHAIN (fields);
1662 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1664 fields = TREE_CHAIN (fields);
1665 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1667 constructor = objc_build_constructor (constant_string_type,
1668 nreverse (initlist));
1669 TREE_INVARIANT (constructor) = true;
1671 if (!flag_next_runtime)
1673 = objc_add_static_instance (constructor, constant_string_type);
1675 desc->constructor = constructor;
1678 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1679 TREE_CONSTANT (addr) = true;
1680 TREE_INVARIANT (addr) = true;
1681 TREE_STATIC (addr) = true;
1686 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1688 static GTY(()) int num_static_inst;
1691 objc_add_static_instance (tree constructor, tree class_decl)
1696 /* Find the list of static instances for the CLASS_DECL. Create one if
1698 for (chain = &objc_static_instances;
1699 *chain && TREE_VALUE (*chain) != class_decl;
1700 chain = &TREE_CHAIN (*chain));
1703 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1704 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1707 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1708 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1709 DECL_COMMON (decl) = 1;
1710 TREE_STATIC (decl) = 1;
1711 DECL_ARTIFICIAL (decl) = 1;
1712 DECL_INITIAL (decl) = constructor;
1714 /* We may be writing something else just now.
1715 Postpone till end of input. */
1716 DECL_DEFER_OUTPUT (decl) = 1;
1717 pushdecl_top_level (decl);
1718 rest_of_decl_compilation (decl, 1, 0);
1720 /* Add the DECL to the head of this CLASS' list. */
1721 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1726 /* Build a static constant CONSTRUCTOR
1727 with type TYPE and elements ELTS. */
1730 objc_build_constructor (tree type, tree elts)
1732 tree constructor = build_constructor (type, elts);
1734 TREE_CONSTANT (constructor) = 1;
1735 TREE_STATIC (constructor) = 1;
1736 TREE_READONLY (constructor) = 1;
1739 /* Adjust for impedance mismatch. We should figure out how to build
1740 CONSTRUCTORs that consistently please both the C and C++ gods. */
1741 if (!TREE_PURPOSE (elts))
1742 TREE_TYPE (constructor) = NULL_TREE;
1743 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1749 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1751 /* Predefine the following data type:
1759 void *defs[cls_def_cnt + cat_def_cnt];
1763 build_objc_symtab_template (void)
1765 tree field_decl, field_decl_chain;
1767 objc_symtab_template
1768 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1770 /* long sel_ref_cnt; */
1771 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1772 field_decl_chain = field_decl;
1775 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1777 chainon (field_decl_chain, field_decl);
1779 /* short cls_def_cnt; */
1780 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1781 chainon (field_decl_chain, field_decl);
1783 /* short cat_def_cnt; */
1784 field_decl = create_field_decl (short_integer_type_node,
1786 chainon (field_decl_chain, field_decl);
1788 if (imp_count || cat_count || !flag_next_runtime)
1790 /* void *defs[imp_count + cat_count (+ 1)]; */
1791 /* NB: The index is one less than the size of the array. */
1792 int index = imp_count + cat_count
1793 + (flag_next_runtime? -1: 0);
1794 field_decl = create_field_decl
1797 build_index_type (build_int_cst (NULL_TREE, index))),
1799 chainon (field_decl_chain, field_decl);
1802 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1805 /* Create the initial value for the `defs' field of _objc_symtab.
1806 This is a CONSTRUCTOR. */
1809 init_def_list (tree type)
1811 tree expr, initlist = NULL_TREE;
1812 struct imp_entry *impent;
1815 for (impent = imp_list; impent; impent = impent->next)
1817 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1819 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1820 initlist = tree_cons (NULL_TREE, expr, initlist);
1825 for (impent = imp_list; impent; impent = impent->next)
1827 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1829 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1830 initlist = tree_cons (NULL_TREE, expr, initlist);
1834 if (!flag_next_runtime)
1836 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1839 if (static_instances_decl)
1840 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1842 expr = build_int_cst (NULL_TREE, 0);
1844 initlist = tree_cons (NULL_TREE, expr, initlist);
1847 return objc_build_constructor (type, nreverse (initlist));
1850 /* Construct the initial value for all of _objc_symtab. */
1853 init_objc_symtab (tree type)
1857 /* sel_ref_cnt = { ..., 5, ... } */
1859 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
1861 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1863 if (flag_next_runtime || ! sel_ref_chain)
1864 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1867 = tree_cons (NULL_TREE,
1868 convert (build_pointer_type (objc_selector_type),
1869 build_unary_op (ADDR_EXPR,
1870 UOBJC_SELECTOR_TABLE_decl, 1)),
1873 /* cls_def_cnt = { ..., 5, ... } */
1875 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1877 /* cat_def_cnt = { ..., 5, ... } */
1879 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1881 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1883 if (imp_count || cat_count || !flag_next_runtime)
1886 tree field = TYPE_FIELDS (type);
1887 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1889 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1893 return objc_build_constructor (type, nreverse (initlist));
1896 /* Generate forward declarations for metadata such as
1897 'OBJC_CLASS_...'. */
1900 build_metadata_decl (const char *name, tree type)
1904 /* struct TYPE NAME_<name>; */
1905 decl = start_var_decl (type, synth_id_with_class_suffix
1907 objc_implementation_context));
1912 /* Push forward-declarations of all the categories so that
1913 init_def_list can use them in a CONSTRUCTOR. */
1916 forward_declare_categories (void)
1918 struct imp_entry *impent;
1919 tree sav = objc_implementation_context;
1921 for (impent = imp_list; impent; impent = impent->next)
1923 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1925 /* Set an invisible arg to synth_id_with_class_suffix. */
1926 objc_implementation_context = impent->imp_context;
1927 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1928 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1929 objc_category_template);
1932 objc_implementation_context = sav;
1935 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1936 and initialized appropriately. */
1939 generate_objc_symtab_decl (void)
1941 /* forward declare categories */
1943 forward_declare_categories ();
1945 build_objc_symtab_template ();
1946 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
1947 finish_var_decl (UOBJC_SYMBOLS_decl,
1948 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
1952 init_module_descriptor (tree type)
1954 tree initlist, expr;
1956 /* version = { 1, ... } */
1958 expr = build_int_cst (NULL_TREE, OBJC_VERSION);
1959 initlist = build_tree_list (NULL_TREE, expr);
1961 /* size = { ..., sizeof (struct _objc_module), ... } */
1963 expr = size_in_bytes (objc_module_template);
1964 initlist = tree_cons (NULL_TREE, expr, initlist);
1966 /* name = { ..., "foo.m", ... } */
1968 expr = add_objc_string (get_identifier (input_filename), class_names);
1969 initlist = tree_cons (NULL_TREE, expr, initlist);
1971 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1973 if (UOBJC_SYMBOLS_decl)
1974 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1976 expr = build_int_cst (NULL_TREE, 0);
1977 initlist = tree_cons (NULL_TREE, expr, initlist);
1979 return objc_build_constructor (type, nreverse (initlist));
1982 /* Write out the data structures to describe Objective C classes defined.
1984 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
1987 build_module_descriptor (void)
1989 tree field_decl, field_decl_chain;
1992 push_lang_context (lang_name_c); /* extern "C" */
1995 objc_module_template
1996 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
1999 field_decl = create_field_decl (long_integer_type_node, "version");
2000 field_decl_chain = field_decl;
2003 field_decl = create_field_decl (long_integer_type_node, "size");
2004 chainon (field_decl_chain, field_decl);
2007 field_decl = create_field_decl (string_type_node, "name");
2008 chainon (field_decl_chain, field_decl);
2010 /* struct _objc_symtab *symtab; */
2012 = create_field_decl (build_pointer_type
2013 (xref_tag (RECORD_TYPE,
2014 get_identifier (UTAG_SYMTAB))),
2016 chainon (field_decl_chain, field_decl);
2018 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2020 /* Create an instance of "_objc_module". */
2021 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2022 finish_var_decl (UOBJC_MODULES_decl,
2023 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2026 pop_lang_context ();
2030 /* The GNU runtime requires us to provide a static initializer function
2033 static void __objc_gnu_init (void) {
2034 __objc_exec_class (&L_OBJC_MODULES);
2038 build_module_initializer_routine (void)
2043 push_lang_context (lang_name_c); /* extern "C" */
2046 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2047 objc_start_function (get_identifier (TAG_GNUINIT),
2048 build_function_type (void_type_node,
2050 NULL_TREE, objc_get_parm_info (0));
2052 body = c_begin_compound_stmt (true);
2053 add_stmt (build_function_call
2057 build_unary_op (ADDR_EXPR,
2058 UOBJC_MODULES_decl, 0))));
2059 add_stmt (c_end_compound_stmt (body, true));
2061 TREE_PUBLIC (current_function_decl) = 0;
2064 /* For Objective-C++, we will need to call __objc_gnu_init
2065 from objc_generate_static_init_call() below. */
2066 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2069 GNU_INIT_decl = current_function_decl;
2073 pop_lang_context ();
2078 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2079 to be called by the module initializer routine. */
2082 objc_static_init_needed_p (void)
2084 return (GNU_INIT_decl != NULL_TREE);
2087 /* Generate a call to the __objc_gnu_init initializer function. */
2090 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2092 add_stmt (build_stmt (EXPR_STMT,
2093 build_function_call (GNU_INIT_decl, NULL_TREE)));
2097 #endif /* OBJCPLUS */
2099 /* Return the DECL of the string IDENT in the SECTION. */
2102 get_objc_string_decl (tree ident, enum string_section section)
2106 if (section == class_names)
2107 chain = class_names_chain;
2108 else if (section == meth_var_names)
2109 chain = meth_var_names_chain;
2110 else if (section == meth_var_types)
2111 chain = meth_var_types_chain;
2115 for (; chain != 0; chain = TREE_CHAIN (chain))
2116 if (TREE_VALUE (chain) == ident)
2117 return (TREE_PURPOSE (chain));
2123 /* Output references to all statically allocated objects. Return the DECL
2124 for the array built. */
2127 generate_static_references (void)
2129 tree decls = NULL_TREE, expr = NULL_TREE;
2130 tree class_name, class, decl, initlist;
2131 tree cl_chain, in_chain, type
2132 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2133 int num_inst, num_class;
2136 if (flag_next_runtime)
2139 for (cl_chain = objc_static_instances, num_class = 0;
2140 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2142 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2143 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2145 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2146 decl = start_var_decl (type, buf);
2148 /* Output {class_name, ...}. */
2149 class = TREE_VALUE (cl_chain);
2150 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2151 initlist = build_tree_list (NULL_TREE,
2152 build_unary_op (ADDR_EXPR, class_name, 1));
2154 /* Output {..., instance, ...}. */
2155 for (in_chain = TREE_PURPOSE (cl_chain);
2156 in_chain; in_chain = TREE_CHAIN (in_chain))
2158 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2159 initlist = tree_cons (NULL_TREE, expr, initlist);
2162 /* Output {..., NULL}. */
2163 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2165 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2166 finish_var_decl (decl, expr);
2168 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2171 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2172 expr = objc_build_constructor (type, nreverse (decls));
2173 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2174 finish_var_decl (static_instances_decl, expr);
2177 /* Output all strings. */
2180 generate_strings (void)
2182 tree chain, string_expr;
2183 tree string, decl, type;
2185 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2187 string = TREE_VALUE (chain);
2188 decl = TREE_PURPOSE (chain);
2189 type = build_array_type
2192 (build_int_cst (NULL_TREE,
2193 IDENTIFIER_LENGTH (string))));
2194 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2195 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2196 IDENTIFIER_POINTER (string));
2197 finish_var_decl (decl, string_expr);
2200 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2202 string = TREE_VALUE (chain);
2203 decl = TREE_PURPOSE (chain);
2204 type = build_array_type
2207 (build_int_cst (NULL_TREE,
2208 IDENTIFIER_LENGTH (string))));
2209 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2210 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2211 IDENTIFIER_POINTER (string));
2212 finish_var_decl (decl, string_expr);
2215 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2217 string = TREE_VALUE (chain);
2218 decl = TREE_PURPOSE (chain);
2219 type = build_array_type
2222 (build_int_cst (NULL_TREE,
2223 IDENTIFIER_LENGTH (string))));
2224 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2225 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2226 IDENTIFIER_POINTER (string));
2227 finish_var_decl (decl, string_expr);
2231 static GTY(()) int selector_reference_idx;
2234 build_selector_reference_decl (void)
2239 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2240 decl = start_var_decl (objc_selector_type, buf);
2246 build_selector_table_decl (void)
2250 if (flag_typed_selectors)
2252 build_selector_template ();
2253 temp = build_array_type (objc_selector_template, NULL_TREE);
2256 temp = build_array_type (objc_selector_type, NULL_TREE);
2258 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2261 /* Just a handy wrapper for add_objc_string. */
2264 build_selector (tree ident)
2266 return convert (objc_selector_type,
2267 add_objc_string (ident, meth_var_names));
2271 build_selector_translation_table (void)
2273 tree chain, initlist = NULL_TREE;
2275 tree decl = NULL_TREE;
2277 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2281 if (warn_selector && objc_implementation_context)
2285 for (method_chain = meth_var_names_chain;
2287 method_chain = TREE_CHAIN (method_chain))
2289 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2297 /* Adjust line number for warning message. */
2298 int save_lineno = input_line;
2299 if (flag_next_runtime && TREE_PURPOSE (chain))
2300 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2301 warning ("creating selector for non existant method %s",
2302 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2303 input_line = save_lineno;
2307 expr = build_selector (TREE_VALUE (chain));
2308 /* add one for the '\0' character */
2309 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2311 if (flag_next_runtime)
2313 decl = TREE_PURPOSE (chain);
2314 finish_var_decl (decl, expr);
2318 if (flag_typed_selectors)
2320 tree eltlist = NULL_TREE;
2321 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2322 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2323 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2324 expr = objc_build_constructor (objc_selector_template,
2325 nreverse (eltlist));
2328 initlist = tree_cons (NULL_TREE, expr, initlist);
2332 if (! flag_next_runtime)
2334 /* Cause the selector table (previously forward-declared)
2335 to be actually output. */
2336 initlist = tree_cons (NULL_TREE,
2337 flag_typed_selectors
2338 ? objc_build_constructor
2339 (objc_selector_template,
2340 tree_cons (NULL_TREE,
2341 build_int_cst (NULL_TREE, 0),
2342 tree_cons (NULL_TREE,
2343 build_int_cst (NULL_TREE, 0),
2345 : build_int_cst (NULL_TREE, 0), initlist);
2346 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2347 nreverse (initlist));
2348 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2353 get_proto_encoding (tree proto)
2358 if (! METHOD_ENCODING (proto))
2360 encoding = encode_method_prototype (proto);
2361 METHOD_ENCODING (proto) = encoding;
2364 encoding = METHOD_ENCODING (proto);
2366 return add_objc_string (encoding, meth_var_types);
2369 return build_int_cst (NULL_TREE, 0);
2372 /* sel_ref_chain is a list whose "value" fields will be instances of
2373 identifier_node that represent the selector. */
2376 build_typed_selector_reference (tree ident, tree prototype)
2378 tree *chain = &sel_ref_chain;
2384 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2385 goto return_at_index;
2388 chain = &TREE_CHAIN (*chain);
2391 *chain = tree_cons (prototype, ident, NULL_TREE);
2394 expr = build_unary_op (ADDR_EXPR,
2395 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2396 build_int_cst (NULL_TREE, index)),
2398 return convert (objc_selector_type, expr);
2402 build_selector_reference (tree ident)
2404 tree *chain = &sel_ref_chain;
2410 if (TREE_VALUE (*chain) == ident)
2411 return (flag_next_runtime
2412 ? TREE_PURPOSE (*chain)
2413 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2414 build_int_cst (NULL_TREE, index)));
2417 chain = &TREE_CHAIN (*chain);
2420 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2422 *chain = tree_cons (expr, ident, NULL_TREE);
2424 return (flag_next_runtime
2426 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2427 build_int_cst (NULL_TREE, index)));
2430 static GTY(()) int class_reference_idx;
2433 build_class_reference_decl (void)
2438 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2439 decl = start_var_decl (objc_class_type, buf);
2444 /* Create a class reference, but don't create a variable to reference
2448 add_class_reference (tree ident)
2452 if ((chain = cls_ref_chain))
2457 if (ident == TREE_VALUE (chain))
2461 chain = TREE_CHAIN (chain);
2465 /* Append to the end of the list */
2466 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2469 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2472 /* Get a class reference, creating it if necessary. Also create the
2473 reference variable. */
2476 objc_get_class_reference (tree ident)
2481 if (processing_template_decl)
2482 /* Must wait until template instantiation time. */
2483 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2484 if (TREE_CODE (ident) == TYPE_DECL)
2485 ident = DECL_NAME (ident);
2489 if (!(ident = objc_is_class_name (ident)))
2491 error ("`%s' is not an Objective-C class name or alias",
2492 IDENTIFIER_POINTER (orig_ident));
2493 return error_mark_node;
2496 if (flag_next_runtime && !flag_zero_link)
2501 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2502 if (TREE_VALUE (*chain) == ident)
2504 if (! TREE_PURPOSE (*chain))
2505 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2507 return TREE_PURPOSE (*chain);
2510 decl = build_class_reference_decl ();
2511 *chain = tree_cons (decl, ident, NULL_TREE);
2518 add_class_reference (ident);
2520 params = build_tree_list (NULL_TREE,
2521 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2522 IDENTIFIER_POINTER (ident)));
2524 assemble_external (objc_get_class_decl);
2525 return build_function_call (objc_get_class_decl, params);
2529 /* For each string section we have a chain which maps identifier nodes
2530 to decls for the strings. */
2533 add_objc_string (tree ident, enum string_section section)
2537 if (section == class_names)
2538 chain = &class_names_chain;
2539 else if (section == meth_var_names)
2540 chain = &meth_var_names_chain;
2541 else if (section == meth_var_types)
2542 chain = &meth_var_types_chain;
2548 if (TREE_VALUE (*chain) == ident)
2549 return convert (string_type_node,
2550 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2552 chain = &TREE_CHAIN (*chain);
2555 decl = build_objc_string_decl (section);
2557 *chain = tree_cons (decl, ident, NULL_TREE);
2559 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2562 static GTY(()) int class_names_idx;
2563 static GTY(()) int meth_var_names_idx;
2564 static GTY(()) int meth_var_types_idx;
2567 build_objc_string_decl (enum string_section section)
2572 if (section == class_names)
2573 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2574 else if (section == meth_var_names)
2575 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2576 else if (section == meth_var_types)
2577 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2579 ident = get_identifier (buf);
2581 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2582 DECL_EXTERNAL (decl) = 1;
2583 TREE_PUBLIC (decl) = 0;
2584 TREE_USED (decl) = 1;
2585 TREE_CONSTANT (decl) = 1;
2586 DECL_CONTEXT (decl) = 0;
2587 DECL_ARTIFICIAL (decl) = 1;
2589 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2592 make_decl_rtl (decl);
2593 pushdecl_top_level (decl);
2600 objc_declare_alias (tree alias_ident, tree class_ident)
2602 tree underlying_class;
2605 if (current_namespace != global_namespace) {
2606 error ("Objective-C declarations may only appear in global scope");
2608 #endif /* OBJCPLUS */
2610 if (!(underlying_class = objc_is_class_name (class_ident)))
2611 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2612 else if (objc_is_class_name (alias_ident))
2613 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2615 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2619 objc_declare_class (tree ident_list)
2623 if (current_namespace != global_namespace) {
2624 error ("Objective-C declarations may only appear in global scope");
2626 #endif /* OBJCPLUS */
2628 for (list = ident_list; list; list = TREE_CHAIN (list))
2630 tree ident = TREE_VALUE (list);
2632 if (! objc_is_class_name (ident))
2634 tree record = lookup_name (ident);
2636 if (record && ! TREE_STATIC_TEMPLATE (record))
2638 error ("`%s' redeclared as different kind of symbol",
2639 IDENTIFIER_POINTER (ident));
2640 error ("%Jprevious declaration of '%D'",
2644 record = xref_tag (RECORD_TYPE, ident);
2645 TREE_STATIC_TEMPLATE (record) = 1;
2646 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2652 objc_is_class_name (tree ident)
2656 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2657 && identifier_global_value (ident))
2658 ident = identifier_global_value (ident);
2659 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2660 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2662 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2663 ident = OBJC_TYPE_NAME (ident);
2665 if (ident && TREE_CODE (ident) == TYPE_DECL)
2666 ident = DECL_NAME (ident);
2668 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2671 if (lookup_interface (ident))
2674 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2676 if (ident == TREE_VALUE (chain))
2680 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2682 if (ident == TREE_VALUE (chain))
2683 return TREE_PURPOSE (chain);
2689 /* Check whether TYPE is either 'id' or 'Class'. */
2692 objc_is_id (tree type)
2694 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2695 && identifier_global_value (type))
2696 type = identifier_global_value (type);
2698 if (type && TREE_CODE (type) == TYPE_DECL)
2699 type = TREE_TYPE (type);
2701 /* NB: This function may be called before the ObjC front-end has
2702 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2703 return (objc_object_type && type && (IS_ID (type) || IS_CLASS (type))
2708 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2709 class instance. This is needed by other parts of the compiler to
2710 handle ObjC types gracefully. */
2713 objc_is_object_ptr (tree type)
2717 type = TYPE_MAIN_VARIANT (type);
2718 if (!POINTER_TYPE_P (type))
2721 ret = objc_is_id (type);
2723 ret = objc_is_class_name (TREE_TYPE (type));
2729 lookup_interface (tree ident)
2734 if (ident && TREE_CODE (ident) == TYPE_DECL)
2735 ident = DECL_NAME (ident);
2737 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2739 if (ident == CLASS_NAME (chain))
2745 /* Implement @defs (<classname>) within struct bodies. */
2748 objc_get_class_ivars (tree class_name)
2750 tree interface = lookup_interface (class_name);
2753 return get_class_ivars (interface);
2755 error ("cannot find interface declaration for `%s'",
2756 IDENTIFIER_POINTER (class_name));
2758 return error_mark_node;
2761 /* Used by: build_private_template, continue_class,
2762 and for @defs constructs. */
2765 get_class_ivars (tree interface)
2767 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
2769 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2770 by the current class (i.e., they do not include super-class ivars).
2771 However, the CLASS_IVARS list will be side-effected by a call to
2772 finish_struct(), which will fill in field offsets. */
2773 if (!CLASS_IVARS (interface))
2774 CLASS_IVARS (interface) = ivar_chain;
2776 while (CLASS_SUPER_NAME (interface))
2778 /* Prepend super-class ivars. */
2779 interface = lookup_interface (CLASS_SUPER_NAME (interface));
2780 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
2788 objc_create_temporary_var (tree type)
2792 decl = build_decl (VAR_DECL, NULL_TREE, type);
2793 TREE_USED (decl) = 1;
2794 DECL_ARTIFICIAL (decl) = 1;
2795 DECL_IGNORED_P (decl) = 1;
2796 DECL_CONTEXT (decl) = current_function_decl;
2801 /* Exception handling constructs. We begin by having the parser do most
2802 of the work and passing us blocks. What we do next depends on whether
2803 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2804 We abstract all of this in a handful of appropriately named routines. */
2806 /* Stack of open try blocks. */
2808 struct objc_try_context
2810 struct objc_try_context *outer;
2812 /* Statements (or statement lists) as processed by the parser. */
2816 /* Some file position locations. */
2817 location_t try_locus;
2818 location_t end_try_locus;
2819 location_t end_catch_locus;
2820 location_t finally_locus;
2821 location_t end_finally_locus;
2823 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2824 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2827 /* The CATCH_EXPR of an open @catch clause. */
2830 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2836 static struct objc_try_context *cur_try_context;
2838 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2839 that represents TYPE. For Objective-C, this is just the class name. */
2840 /* ??? Isn't there a class object or some such? Is it easy to get? */
2844 objc_eh_runtime_type (tree type)
2846 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2850 /* Initialize exception handling. */
2853 objc_init_exceptions (void)
2855 static bool done = false;
2860 if (flag_objc_sjlj_exceptions)
2862 /* On Darwin, ObjC exceptions require a sufficiently recent
2863 version of the runtime, so the user must ask for them explicitly. */
2864 if (!flag_objc_exceptions)
2865 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2866 "exception syntax");
2871 c_eh_initialized_p = true;
2872 eh_personality_libfunc
2873 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2874 ? "__gnu_objc_personality_sj0"
2875 : "__gnu_objc_personality_v0");
2876 using_eh_for_cleanups ();
2877 lang_eh_runtime_type = objc_eh_runtime_type;
2882 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2883 we'll arrange for it to be initialized (and associated with a binding)
2887 objc_build_exc_ptr (void)
2889 if (flag_objc_sjlj_exceptions)
2891 tree var = cur_try_context->caught_decl;
2894 var = objc_create_temporary_var (objc_object_type);
2895 cur_try_context->caught_decl = var;
2900 return build (EXC_PTR_EXPR, objc_object_type);
2903 /* Build "objc_exception_try_exit(&_stack)". */
2906 next_sjlj_build_try_exit (void)
2909 t = build_fold_addr_expr (cur_try_context->stack_decl);
2910 t = tree_cons (NULL, t, NULL);
2911 t = build_function_call (objc_exception_try_exit_decl, t);
2916 objc_exception_try_enter (&_stack);
2917 if (_setjmp(&_stack.buf))
2921 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2922 empty, ready for the caller to fill them in. */
2925 next_sjlj_build_enter_and_setjmp (void)
2927 tree t, enter, sj, cond;
2929 t = build_fold_addr_expr (cur_try_context->stack_decl);
2930 t = tree_cons (NULL, t, NULL);
2931 enter = build_function_call (objc_exception_try_enter_decl, t);
2933 t = build_component_ref (cur_try_context->stack_decl,
2934 get_identifier ("buf"));
2935 t = build_fold_addr_expr (t);
2936 t = convert (ptr_type_node, t);
2937 t = tree_cons (NULL, t, NULL);
2938 sj = build_function_call (objc_setjmp_decl, t);
2940 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2941 cond = lang_hooks.truthvalue_conversion (cond);
2943 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2947 DECL = objc_exception_extract(&_stack);
2951 next_sjlj_build_exc_extract (tree decl)
2955 t = build_fold_addr_expr (cur_try_context->stack_decl);
2956 t = tree_cons (NULL, t, NULL);
2957 t = build_function_call (objc_exception_extract_decl, t);
2958 t = convert (TREE_TYPE (decl), t);
2959 t = build (MODIFY_EXPR, void_type_node, decl, t);
2965 if (objc_exception_match(obj_get_class(TYPE), _caught)
2972 objc_exception_try_exit(&_stack);
2974 from the sequence of CATCH_EXPRs in the current try context. */
2977 next_sjlj_build_catch_list (void)
2979 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
2981 tree *last = &catch_seq;
2982 bool saw_id = false;
2984 for (; !tsi_end_p (i); tsi_next (&i))
2986 tree stmt = tsi_stmt (i);
2987 tree type = CATCH_TYPES (stmt);
2988 tree body = CATCH_BODY (stmt);
3000 if (type == error_mark_node)
3001 cond = error_mark_node;
3004 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3005 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3006 args = tree_cons (NULL, t, args);
3007 t = build_function_call (objc_exception_match_decl, args);
3008 cond = lang_hooks.truthvalue_conversion (t);
3010 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3011 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3014 last = &COND_EXPR_ELSE (t);
3020 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3021 cur_try_context->caught_decl);
3022 annotate_with_locus (t, cur_try_context->end_catch_locus);
3023 append_to_statement_list (t, last);
3025 t = next_sjlj_build_try_exit ();
3026 annotate_with_locus (t, cur_try_context->end_catch_locus);
3027 append_to_statement_list (t, last);
3033 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3034 exception handling. We aim to build:
3037 struct _objc_exception_data _stack;
3038 id volatile _rethrow = 0;
3041 objc_exception_try_enter (&_stack);
3042 if (_setjmp(&_stack.buf))
3044 id _caught = objc_exception_extract(&_stack);
3045 objc_exception_try_enter (&_stack);
3046 if (_setjmp(&_stack.buf))
3047 _rethrow = objc_exception_extract(&_stack);
3057 objc_exception_try_exit(&_stack);
3060 objc_exception_throw(_rethrow);
3064 If CATCH-LIST is empty, we can omit all of the block containing
3065 "_caught" except for the setting of _rethrow. Note the use of
3066 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3067 but handles goto and other exits from the block. */
3070 next_sjlj_build_try_catch_finally (void)
3072 tree rethrow_decl, stack_decl, t;
3073 tree catch_seq, try_fin, bind;
3075 /* Create the declarations involved. */
3076 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3077 stack_decl = objc_create_temporary_var (t);
3078 cur_try_context->stack_decl = stack_decl;
3080 rethrow_decl = objc_create_temporary_var (objc_object_type);
3081 cur_try_context->rethrow_decl = rethrow_decl;
3082 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3083 TREE_CHAIN (rethrow_decl) = stack_decl;
3085 /* Build the outermost varible binding level. */
3086 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3087 annotate_with_locus (bind, cur_try_context->try_locus);
3088 TREE_SIDE_EFFECTS (bind) = 1;
3090 /* Initialize rethrow_decl. */
3091 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3092 convert (objc_object_type, null_pointer_node));
3093 annotate_with_locus (t, cur_try_context->try_locus);
3094 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3096 /* Build the outermost TRY_FINALLY_EXPR. */
3097 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3098 annotate_with_locus (try_fin, cur_try_context->try_locus);
3099 TREE_SIDE_EFFECTS (try_fin) = 1;
3100 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3102 /* Create the complete catch sequence. */
3103 if (cur_try_context->catch_list)
3105 tree caught_decl = objc_build_exc_ptr ();
3106 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3108 t = next_sjlj_build_exc_extract (caught_decl);
3109 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3111 t = next_sjlj_build_enter_and_setjmp ();
3112 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3113 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3114 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3117 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3118 annotate_with_locus (catch_seq, cur_try_context->end_try_locus);
3120 /* Build the main register-and-try if statement. */
3121 t = next_sjlj_build_enter_and_setjmp ();
3122 annotate_with_locus (t, cur_try_context->try_locus);
3123 COND_EXPR_THEN (t) = catch_seq;
3124 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3125 TREE_OPERAND (try_fin, 0) = t;
3127 /* Build the complete FINALLY statement list. */
3128 t = next_sjlj_build_try_exit ();
3129 t = build_stmt (COND_EXPR,
3130 lang_hooks.truthvalue_conversion (rethrow_decl),
3132 annotate_with_locus (t, cur_try_context->finally_locus);
3133 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3135 append_to_statement_list (cur_try_context->finally_body,
3136 &TREE_OPERAND (try_fin, 1));
3138 t = tree_cons (NULL, rethrow_decl, NULL);
3139 t = build_function_call (objc_exception_throw_decl, t);
3140 t = build_stmt (COND_EXPR,
3141 lang_hooks.truthvalue_conversion (rethrow_decl),
3143 annotate_with_locus (t, cur_try_context->end_finally_locus);
3144 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3149 /* Called just after parsing the @try and its associated BODY. We now
3150 must prepare for the tricky bits -- handling the catches and finally. */
3153 objc_begin_try_stmt (location_t try_locus, tree body)
3155 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3156 c->outer = cur_try_context;
3158 c->try_locus = try_locus;
3159 c->end_try_locus = input_location;
3160 cur_try_context = c;
3162 objc_init_exceptions ();
3165 /* Called just after parsing "@catch (parm)". Open a binding level,
3166 enter DECL into the binding level, and initialize it. Leave the
3167 binding level open while the body of the compound statement is parsed. */
3170 objc_begin_catch_clause (tree decl)
3172 tree compound, type, t;
3174 /* Begin a new scope that the entire catch clause will live in. */
3175 compound = c_begin_compound_stmt (true);
3177 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3178 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3179 lang_hooks.decls.pushdecl (decl);
3181 /* Since a decl is required here by syntax, don't warn if its unused. */
3182 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3183 be what the previous objc implementation did. */
3184 TREE_USED (decl) = 1;
3186 /* Verify that the type of the catch is valid. It must be a pointer
3187 to an Objective-C class, or "id" (which is catch-all). */
3188 type = TREE_TYPE (decl);
3190 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3192 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3194 error ("@catch parameter is not a known Objective-C class type");
3195 type = error_mark_node;
3197 else if (cur_try_context->catch_list)
3199 /* Examine previous @catch clauses and see if we've already
3200 caught the type in question. */
3201 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3202 for (; !tsi_end_p (i); tsi_next (&i))
3204 tree stmt = tsi_stmt (i);
3205 t = CATCH_TYPES (stmt);
3206 if (t == error_mark_node)
3208 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3210 warning ("exception of type %<%T%> will be caught",
3212 warning ("%H by earlier handler for %<%T%>",
3213 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3219 /* Record the data for the catch in the try context so that we can
3220 finalize it later. */
3221 t = build_stmt (CATCH_EXPR, type, compound);
3222 cur_try_context->current_catch = t;
3224 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3225 t = objc_build_exc_ptr ();
3226 t = convert (TREE_TYPE (decl), t);
3227 t = build (MODIFY_EXPR, void_type_node, decl, t);
3231 /* Called just after parsing the closing brace of a @catch clause. Close
3232 the open binding level, and record a CATCH_EXPR for it. */
3235 objc_finish_catch_clause (void)
3237 tree c = cur_try_context->current_catch;
3238 cur_try_context->current_catch = NULL;
3239 cur_try_context->end_catch_locus = input_location;
3241 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3242 append_to_statement_list (c, &cur_try_context->catch_list);
3245 /* Called after parsing a @finally clause and its associated BODY.
3246 Record the body for later placement. */
3249 objc_build_finally_clause (location_t finally_locus, tree body)
3251 cur_try_context->finally_body = body;
3252 cur_try_context->finally_locus = finally_locus;
3253 cur_try_context->end_finally_locus = input_location;
3256 /* Called to finalize a @try construct. */
3259 objc_finish_try_stmt (void)
3261 struct objc_try_context *c = cur_try_context;
3264 if (c->catch_list == NULL && c->finally_body == NULL)
3265 error ("`@try' without `@catch' or `@finally'");
3267 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3268 if (flag_objc_sjlj_exceptions)
3270 if (!cur_try_context->finally_body)
3272 cur_try_context->finally_locus = input_location;
3273 cur_try_context->end_finally_locus = input_location;
3275 stmt = next_sjlj_build_try_catch_finally ();
3279 /* Otherwise, nest the CATCH inside a FINALLY. */
3283 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3284 annotate_with_locus (stmt, cur_try_context->try_locus);
3286 if (c->finally_body)
3288 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3289 annotate_with_locus (stmt, cur_try_context->try_locus);
3294 cur_try_context = c->outer;
3299 objc_build_throw_stmt (tree throw_expr)
3303 objc_init_exceptions ();
3305 if (throw_expr == NULL)
3307 /* If we're not inside a @catch block, there is no "current
3308 exception" to be rethrown. */
3309 if (cur_try_context == NULL
3310 || cur_try_context->current_catch == NULL)
3312 error ("%<@throw%> (rethrow) used outside of a @catch block");
3316 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3317 value that we get from the runtime. */
3318 throw_expr = objc_build_exc_ptr ();
3321 /* A throw is just a call to the runtime throw function with the
3322 object as a parameter. */
3323 args = tree_cons (NULL, throw_expr, NULL);
3324 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3328 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3332 /* First lock the mutex. */
3333 mutex = save_expr (mutex);
3334 args = tree_cons (NULL, mutex, NULL);
3335 call = build_function_call (objc_sync_enter_decl, args);
3336 annotate_with_locus (call, start_locus);
3339 /* Build the mutex unlock. */
3340 args = tree_cons (NULL, mutex, NULL);
3341 call = build_function_call (objc_sync_exit_decl, args);
3342 annotate_with_locus (call, input_location);
3344 /* Put the that and the body in a TRY_FINALLY. */
3345 objc_begin_try_stmt (start_locus, body);
3346 objc_build_finally_clause (input_location, call);
3347 objc_finish_try_stmt ();
3351 /* Predefine the following data type:
3353 struct _objc_exception_data
3359 /* The following yuckiness should prevent users from having to #include
3360 <setjmp.h> in their code... */
3362 #ifdef TARGET_POWERPC
3363 /* snarfed from /usr/include/ppc/setjmp.h */
3364 #define _JBLEN (26 + 36 + 129 + 1)
3366 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3371 build_next_objc_exception_stuff (void)
3373 tree field_decl, field_decl_chain, index, temp_type;
3375 objc_exception_data_template
3376 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3378 /* int buf[_JBLEN]; */
3380 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3381 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3383 field_decl_chain = field_decl;
3385 /* void *pointers[4]; */
3387 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3388 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3390 chainon (field_decl_chain, field_decl);
3392 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3394 /* int _setjmp(...); */
3395 /* If the user includes <setjmp.h>, this shall be superseded by
3396 'int _setjmp(jmp_buf);' */
3397 temp_type = build_function_type (integer_type_node, NULL_TREE);
3399 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3401 /* id objc_exception_extract(struct _objc_exception_data *); */
3403 = build_function_type (objc_object_type,
3404 tree_cons (NULL_TREE,
3405 build_pointer_type (objc_exception_data_template),
3407 objc_exception_extract_decl
3408 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3409 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3410 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3412 = build_function_type (void_type_node,
3413 tree_cons (NULL_TREE,
3414 build_pointer_type (objc_exception_data_template),
3416 objc_exception_try_enter_decl
3417 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3418 objc_exception_try_exit_decl
3419 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3421 /* int objc_exception_match(id, id); */
3423 = build_function_type (integer_type_node,
3424 tree_cons (NULL_TREE, objc_object_type,
3425 tree_cons (NULL_TREE, objc_object_type,
3426 OBJC_VOID_AT_END)));
3427 objc_exception_match_decl
3428 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3432 build_objc_exception_stuff (void)
3434 tree noreturn_list, nothrow_list, temp_type;
3436 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3437 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3439 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3440 /* void objc_sync_enter(id); */
3441 /* void objc_sync_exit(id); */
3442 temp_type = build_function_type (void_type_node,
3443 tree_cons (NULL_TREE, objc_object_type,
3445 objc_exception_throw_decl
3446 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3448 objc_sync_enter_decl
3449 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3450 NULL, nothrow_list);
3452 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3453 NULL, nothrow_list);
3457 /* struct <classname> {
3458 struct _objc_class *isa;
3463 build_private_template (tree class)
3467 if (CLASS_STATIC_TEMPLATE (class))
3469 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3470 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3474 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3475 ivar_context = get_class_ivars (class);
3477 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3479 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3481 /* mark this record as class template - for class type checking */
3482 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3485 objc_instance_type = build_pointer_type (uprivate_record);
3487 return ivar_context;
3490 /* Begin code generation for protocols... */
3492 /* struct _objc_protocol {
3493 struct _objc_class *isa;
3494 char *protocol_name;
3495 struct _objc_protocol **protocol_list;
3496 struct _objc__method_prototype_list *instance_methods;
3497 struct _objc__method_prototype_list *class_methods;
3501 build_protocol_template (void)
3503 tree field_decl, field_decl_chain;
3505 objc_protocol_template = start_struct (RECORD_TYPE,
3506 get_identifier (UTAG_PROTOCOL));
3508 /* struct _objc_class *isa; */
3509 field_decl = create_field_decl (build_pointer_type
3510 (xref_tag (RECORD_TYPE,
3511 get_identifier (UTAG_CLASS))),
3513 field_decl_chain = field_decl;
3515 /* char *protocol_name; */
3516 field_decl = create_field_decl (string_type_node, "protocol_name");
3517 chainon (field_decl_chain, field_decl);
3519 /* struct _objc_protocol **protocol_list; */
3520 field_decl = create_field_decl (build_pointer_type
3522 (objc_protocol_template)),
3524 chainon (field_decl_chain, field_decl);
3526 /* struct objc_method_list *instance_methods; */
3527 field_decl = create_field_decl (build_pointer_type
3528 (xref_tag (RECORD_TYPE,
3530 (UTAG_METHOD_PROTOTYPE_LIST))),
3531 "instance_methods");
3532 chainon (field_decl_chain, field_decl);
3534 /* struct objc_method_list *class_methods; */
3535 field_decl = create_field_decl (build_pointer_type
3536 (xref_tag (RECORD_TYPE,
3538 (UTAG_METHOD_PROTOTYPE_LIST))),
3540 chainon (field_decl_chain, field_decl);
3542 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
3546 build_descriptor_table_initializer (tree type, tree entries)
3548 tree initlist = NULL_TREE;
3552 tree eltlist = NULL_TREE;
3555 = tree_cons (NULL_TREE,
3556 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3558 = tree_cons (NULL_TREE,
3559 add_objc_string (METHOD_ENCODING (entries),
3564 = tree_cons (NULL_TREE,
3565 objc_build_constructor (type, nreverse (eltlist)),
3568 entries = TREE_CHAIN (entries);
3572 return objc_build_constructor (build_array_type (type, 0),
3573 nreverse (initlist));
3576 /* struct objc_method_prototype_list {
3578 struct objc_method_prototype {
3585 build_method_prototype_list_template (tree list_type, int size)
3587 tree objc_ivar_list_record;
3588 tree field_decl, field_decl_chain;
3590 /* Generate an unnamed struct definition. */
3592 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3594 /* int method_count; */
3595 field_decl = create_field_decl (integer_type_node, "method_count");
3596 field_decl_chain = field_decl;
3598 /* struct objc_method method_list[]; */
3599 field_decl = create_field_decl (build_array_type
3602 (build_int_cst (NULL_TREE, size - 1))),
3604 chainon (field_decl_chain, field_decl);
3606 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3608 return objc_ivar_list_record;
3612 build_method_prototype_template (void)
3615 tree field_decl, field_decl_chain;
3618 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3621 field_decl = create_field_decl (objc_selector_type, "_cmd");
3622 field_decl_chain = field_decl;
3624 /* char *method_types; */
3625 field_decl = create_field_decl (string_type_node, "method_types");
3626 chainon (field_decl_chain, field_decl);
3628 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3630 return proto_record;
3634 objc_method_parm_type (tree type)
3636 type = TREE_VALUE (TREE_TYPE (type));
3637 if (TREE_CODE (type) == TYPE_DECL)
3638 type = TREE_TYPE (type);
3639 return TYPE_MAIN_VARIANT (type);
3643 objc_encoded_type_size (tree type)
3645 int sz = int_size_in_bytes (type);
3647 /* Make all integer and enum types at least as large
3649 if (sz > 0 && INTEGRAL_TYPE_P (type))
3650 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3651 /* Treat arrays as pointers, since that's how they're
3653 else if (TREE_CODE (type) == ARRAY_TYPE)
3654 sz = int_size_in_bytes (ptr_type_node);
3659 encode_method_prototype (tree method_decl)
3666 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3667 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3669 /* Encode return type. */
3670 encode_type (objc_method_parm_type (method_decl),
3671 obstack_object_size (&util_obstack),
3672 OBJC_ENCODE_INLINE_DEFS);
3675 /* The first two arguments (self and _cmd) are pointers; account for
3677 i = int_size_in_bytes (ptr_type_node);
3678 parm_offset = 2 * i;
3679 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3680 parms = TREE_CHAIN (parms))
3682 tree type = objc_method_parm_type (parms);
3683 int sz = objc_encoded_type_size (type);
3685 /* If a type size is not known, bail out. */
3688 error ("%Jtype '%D' does not have a known size",
3690 /* Pretend that the encoding succeeded; the compilation will
3691 fail nevertheless. */
3692 goto finish_encoding;
3697 sprintf (buf, "%d@0:%d", parm_offset, i);
3698 obstack_grow (&util_obstack, buf, strlen (buf));
3700 /* Argument types. */
3701 parm_offset = 2 * i;
3702 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3703 parms = TREE_CHAIN (parms))
3705 tree type = objc_method_parm_type (parms);
3707 /* Process argument qualifiers for user supplied arguments. */
3708 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3711 encode_type (type, obstack_object_size (&util_obstack),
3712 OBJC_ENCODE_INLINE_DEFS);
3714 /* Compute offset. */
3715 sprintf (buf, "%d", parm_offset);
3716 parm_offset += objc_encoded_type_size (type);
3718 obstack_grow (&util_obstack, buf, strlen (buf));
3722 obstack_1grow (&util_obstack, '\0');
3723 result = get_identifier (obstack_finish (&util_obstack));
3724 obstack_free (&util_obstack, util_firstobj);
3729 generate_descriptor_table (tree type, const char *name, int size, tree list,
3732 tree decl, initlist;
3734 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
3736 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
3737 initlist = tree_cons (NULL_TREE, list, initlist);
3739 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
3745 generate_method_descriptors (tree protocol)
3747 tree initlist, chain, method_list_template;
3748 tree variable_length_type
3749 = xref_tag (RECORD_TYPE,
3750 get_identifier (UTAG_METHOD_PROTOTYPE_LIST));
3753 if (!objc_method_prototype_template)
3754 objc_method_prototype_template = build_method_prototype_template ();
3756 chain = PROTOCOL_CLS_METHODS (protocol);
3759 size = list_length (chain);
3761 method_list_template
3762 = build_method_prototype_list_template (objc_method_prototype_template,
3766 = build_descriptor_table_initializer (objc_method_prototype_template,
3769 UOBJC_CLASS_METHODS_decl
3770 = generate_descriptor_table (method_list_template,
3771 "_OBJC_PROTOCOL_CLASS_METHODS",
3772 size, initlist, protocol);
3773 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
3776 UOBJC_CLASS_METHODS_decl = 0;
3778 chain = PROTOCOL_NST_METHODS (protocol);
3781 size = list_length (chain);
3783 method_list_template
3784 = build_method_prototype_list_template (objc_method_prototype_template,
3787 = build_descriptor_table_initializer (objc_method_prototype_template,
3790 UOBJC_INSTANCE_METHODS_decl
3791 = generate_descriptor_table (method_list_template,
3792 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3793 size, initlist, protocol);
3794 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
3797 UOBJC_INSTANCE_METHODS_decl = 0;
3801 generate_protocol_references (tree plist)
3805 /* Forward declare protocols referenced. */
3806 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3808 tree proto = TREE_VALUE (lproto);
3810 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3811 && PROTOCOL_NAME (proto))
3813 if (! PROTOCOL_FORWARD_DECL (proto))
3814 build_protocol_reference (proto);
3816 if (PROTOCOL_LIST (proto))
3817 generate_protocol_references (PROTOCOL_LIST (proto));
3822 /* For each protocol which was referenced either from a @protocol()
3823 expression, or because a class/category implements it (then a
3824 pointer to the protocol is stored in the struct describing the
3825 class/category), we create a statically allocated instance of the
3826 Protocol class. The code is written in such a way as to generate
3827 as few Protocol objects as possible; we generate a unique Protocol
3828 instance for each protocol, and we don't generate a Protocol
3829 instance if the protocol is never referenced (either from a
3830 @protocol() or from a class/category implementation). These
3831 statically allocated objects can be referred to via the static
3832 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3834 The statically allocated Protocol objects that we generate here
3835 need to be fixed up at runtime in order to be used: the 'isa'
3836 pointer of the objects need to be set up to point to the 'Protocol'
3837 class, as known at runtime.
3839 The NeXT runtime fixes up all protocols at program startup time,
3840 before main() is entered. It uses a low-level trick to look up all
3841 those symbols, then loops on them and fixes them up.
3843 The GNU runtime as well fixes up all protocols before user code
3844 from the module is executed; it requires pointers to those symbols
3845 to be put in the objc_symtab (which is then passed as argument to
3846 the function __objc_exec_class() which the compiler sets up to be
3847 executed automatically when the module is loaded); setup of those
3848 Protocol objects happen in two ways in the GNU runtime: all
3849 Protocol objects referred to by a class or category implementation
3850 are fixed up when the class/category is loaded; all Protocol
3851 objects referred to by a @protocol() expression are added by the
3852 compiler to the list of statically allocated instances to fixup
3853 (the same list holding the statically allocated constant string
3854 objects). Because, as explained above, the compiler generates as
3855 few Protocol objects as possible, some Protocol object might end up
3856 being referenced multiple times when compiled with the GNU runtime,
3857 and end up being fixed up multiple times at runtime inizialization.
3858 But that doesn't hurt, it's just a little inefficient. */
3861 generate_protocols (void)
3865 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3867 /* If a protocol was directly referenced, pull in indirect references. */
3868 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3869 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3870 generate_protocol_references (PROTOCOL_LIST (p));
3872 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3874 tree nst_methods = PROTOCOL_NST_METHODS (p);
3875 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3877 /* If protocol wasn't referenced, don't generate any code. */
3878 decl = PROTOCOL_FORWARD_DECL (p);
3883 /* Make sure we link in the Protocol class. */
3884 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3888 if (! METHOD_ENCODING (nst_methods))
3890 encoding = encode_method_prototype (nst_methods);
3891 METHOD_ENCODING (nst_methods) = encoding;
3893 nst_methods = TREE_CHAIN (nst_methods);
3898 if (! METHOD_ENCODING (cls_methods))
3900 encoding = encode_method_prototype (cls_methods);
3901 METHOD_ENCODING (cls_methods) = encoding;
3904 cls_methods = TREE_CHAIN (cls_methods);
3906 generate_method_descriptors (p);
3908 if (PROTOCOL_LIST (p))
3909 refs_decl = generate_protocol_list (p);
3913 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3914 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3917 refs_expr = convert (build_pointer_type (build_pointer_type
3918 (objc_protocol_template)),
3919 build_unary_op (ADDR_EXPR, refs_decl, 0));
3921 refs_expr = build_int_cst (NULL_TREE, 0);
3923 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3924 by generate_method_descriptors, which is called above. */
3925 initlist = build_protocol_initializer (TREE_TYPE (decl),
3926 protocol_name_expr, refs_expr,
3927 UOBJC_INSTANCE_METHODS_decl,
3928 UOBJC_CLASS_METHODS_decl);
3929 finish_var_decl (decl, initlist);
3934 build_protocol_initializer (tree type, tree protocol_name,
3935 tree protocol_list, tree instance_methods,
3938 tree initlist = NULL_TREE, expr;
3939 tree cast_type = build_pointer_type
3940 (xref_tag (RECORD_TYPE,
3941 get_identifier (UTAG_CLASS)));
3943 /* Filling the "isa" in with one allows the runtime system to
3944 detect that the version change...should remove before final release. */
3946 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
3947 initlist = tree_cons (NULL_TREE, expr, initlist);
3948 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3949 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3951 if (!instance_methods)
3952 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3955 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3956 initlist = tree_cons (NULL_TREE, expr, initlist);
3960 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3963 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3964 initlist = tree_cons (NULL_TREE, expr, initlist);
3967 return objc_build_constructor (type, nreverse (initlist));
3970 /* struct _objc_category {
3971 char *category_name;
3973 struct _objc_method_list *instance_methods;
3974 struct _objc_method_list *class_methods;
3975 struct _objc_protocol_list *protocols;
3979 build_category_template (void)
3981 tree field_decl, field_decl_chain;
3983 objc_category_template = start_struct (RECORD_TYPE,
3984 get_identifier (UTAG_CATEGORY));
3986 /* char *category_name; */
3987 field_decl = create_field_decl (string_type_node, "category_name");
3988 field_decl_chain = field_decl;
3990 /* char *class_name; */
3991 field_decl = create_field_decl (string_type_node, "class_name");
3992 chainon (field_decl_chain, field_decl);
3994 /* struct _objc_method_list *instance_methods; */
3995 field_decl = create_field_decl (build_pointer_type
3996 (xref_tag (RECORD_TYPE,
3998 (UTAG_METHOD_LIST))),
3999 "instance_methods");
4000 chainon (field_decl_chain, field_decl);
4002 /* struct _objc_method_list *class_methods; */
4003 field_decl = create_field_decl (build_pointer_type
4004 (xref_tag (RECORD_TYPE,
4006 (UTAG_METHOD_LIST))),
4008 chainon (field_decl_chain, field_decl);
4010 /* struct _objc_protocol **protocol_list; */
4011 field_decl = create_field_decl (build_pointer_type
4013 (objc_protocol_template)),
4015 chainon (field_decl_chain, field_decl);
4017 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4020 /* struct _objc_selector {
4026 build_selector_template (void)
4029 tree field_decl, field_decl_chain;
4031 objc_selector_template
4032 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4035 field_decl = create_field_decl (objc_selector_type, "sel_id");
4036 field_decl_chain = field_decl;
4038 /* char *sel_type; */
4039 field_decl = create_field_decl (string_type_node, "sel_type");
4040 chainon (field_decl_chain, field_decl);
4042 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4045 /* struct _objc_class {
4046 struct _objc_class *isa;
4047 struct _objc_class *super_class;
4052 struct _objc_ivar_list *ivars;
4053 struct _objc_method_list *methods;
4054 #ifdef __NEXT_RUNTIME__
4055 struct objc_cache *cache;
4057 struct sarray *dtable;
4058 struct _objc_class *subclass_list;
4059 struct _objc_class *sibling_class;
4061 struct _objc_protocol_list *protocols;
4062 #ifdef __NEXT_RUNTIME__
4065 void *gc_object_type;
4068 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4069 the NeXT/Apple runtime; still, the compiler must generate them to
4070 maintain backward binary compatibility (and to allow for future
4074 build_class_template (void)
4076 tree field_decl, field_decl_chain;
4079 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4081 /* struct _objc_class *isa; */
4082 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4084 field_decl_chain = field_decl;
4086 /* struct _objc_class *super_class; */
4087 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4089 chainon (field_decl_chain, field_decl);
4092 field_decl = create_field_decl (string_type_node, "name");
4093 chainon (field_decl_chain, field_decl);
4096 field_decl = create_field_decl (long_integer_type_node, "version");
4097 chainon (field_decl_chain, field_decl);
4100 field_decl = create_field_decl (long_integer_type_node, "info");
4101 chainon (field_decl_chain, field_decl);
4103 /* long instance_size; */
4104 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4105 chainon (field_decl_chain, field_decl);
4107 /* struct _objc_ivar_list *ivars; */
4108 field_decl = create_field_decl (build_pointer_type
4109 (xref_tag (RECORD_TYPE,
4113 chainon (field_decl_chain, field_decl);
4115 /* struct _objc_method_list *methods; */
4116 field_decl = create_field_decl (build_pointer_type
4117 (xref_tag (RECORD_TYPE,
4119 (UTAG_METHOD_LIST))),
4121 chainon (field_decl_chain, field_decl);
4123 if (flag_next_runtime)
4125 /* struct objc_cache *cache; */
4126 field_decl = create_field_decl (build_pointer_type
4127 (xref_tag (RECORD_TYPE,
4131 chainon (field_decl_chain, field_decl);
4135 /* struct sarray *dtable; */
4136 field_decl = create_field_decl (build_pointer_type
4137 (xref_tag (RECORD_TYPE,
4141 chainon (field_decl_chain, field_decl);
4143 /* struct objc_class *subclass_list; */
4144 field_decl = create_field_decl (build_pointer_type
4145 (objc_class_template),
4147 chainon (field_decl_chain, field_decl);
4149 /* struct objc_class *sibling_class; */
4150 field_decl = create_field_decl (build_pointer_type
4151 (objc_class_template),
4153 chainon (field_decl_chain, field_decl);
4156 /* struct _objc_protocol **protocol_list; */
4157 field_decl = create_field_decl (build_pointer_type
4159 (xref_tag (RECORD_TYPE,
4163 chainon (field_decl_chain, field_decl);
4165 if (flag_next_runtime)
4168 field_decl = create_field_decl (build_pointer_type (void_type_node),
4170 chainon (field_decl_chain, field_decl);
4173 /* void *gc_object_type; */
4174 field_decl = create_field_decl (build_pointer_type (void_type_node),
4176 chainon (field_decl_chain, field_decl);
4178 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4181 /* Generate appropriate forward declarations for an implementation. */
4184 synth_forward_declarations (void)
4188 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4189 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4190 objc_class_template);
4192 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4193 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4194 objc_class_template);
4196 /* Pre-build the following entities - for speed/convenience. */
4198 an_id = get_identifier ("super_class");
4199 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4200 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4204 error_with_ivar (const char *message, tree decl)
4206 error ("%J%s `%s'", decl,
4207 message, gen_declaration (decl));
4212 check_ivars (tree inter, tree imp)
4214 tree intdecls = CLASS_RAW_IVARS (inter);
4215 tree impdecls = CLASS_RAW_IVARS (imp);
4222 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4223 intdecls = TREE_CHAIN (intdecls);
4225 if (intdecls == 0 && impdecls == 0)
4227 if (intdecls == 0 || impdecls == 0)
4229 error ("inconsistent instance variable specification");
4233 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4235 if (!comptypes (t1, t2)
4236 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4237 DECL_INITIAL (impdecls)))
4239 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4241 error_with_ivar ("conflicting instance variable type",
4243 error_with_ivar ("previous declaration of",
4246 else /* both the type and the name don't match */
4248 error ("inconsistent instance variable specification");
4253 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4255 error_with_ivar ("conflicting instance variable name",
4257 error_with_ivar ("previous declaration of",
4261 intdecls = TREE_CHAIN (intdecls);
4262 impdecls = TREE_CHAIN (impdecls);
4266 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4267 This needs to be done just once per compilation. */
4269 /* struct _objc_super {
4270 struct _objc_object *self;
4271 struct _objc_class *super_class;
4275 build_super_template (void)
4277 tree field_decl, field_decl_chain;
4279 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4281 /* struct _objc_object *self; */
4282 field_decl = create_field_decl (objc_object_type, "self");
4283 field_decl_chain = field_decl;
4285 /* struct _objc_class *super_class; */
4286 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4288 chainon (field_decl_chain, field_decl);
4290 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4293 /* struct _objc_ivar {
4300 build_ivar_template (void)
4302 tree objc_ivar_id, objc_ivar_record;
4303 tree field_decl, field_decl_chain;
4305 objc_ivar_id = get_identifier (UTAG_IVAR);
4306 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4308 /* char *ivar_name; */
4309 field_decl = create_field_decl (string_type_node, "ivar_name");
4310 field_decl_chain = field_decl;
4312 /* char *ivar_type; */
4313 field_decl = create_field_decl (string_type_node, "ivar_type");
4314 chainon (field_decl_chain, field_decl);
4316 /* int ivar_offset; */
4317 field_decl = create_field_decl (integer_type_node, "ivar_offset");
4318 chainon (field_decl_chain, field_decl);
4320 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4322 return objc_ivar_record;
4327 struct objc_ivar ivar_list[ivar_count];
4331 build_ivar_list_template (tree list_type, int size)
4333 tree objc_ivar_list_record;
4334 tree field_decl, field_decl_chain;
4336 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4338 /* int ivar_count; */
4339 field_decl = create_field_decl (integer_type_node, "ivar_count");
4340 field_decl_chain = field_decl;
4342 /* struct objc_ivar ivar_list[]; */
4343 field_decl = create_field_decl (build_array_type
4346 (build_int_cst (NULL_TREE, size - 1))),
4348 chainon (field_decl_chain, field_decl);
4350 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4352 return objc_ivar_list_record;
4356 struct _objc__method_prototype_list *method_next;
4358 struct objc_method method_list[method_count];
4362 build_method_list_template (tree list_type, int size)
4364 tree objc_ivar_list_record;
4365 tree field_decl, field_decl_chain;
4367 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4369 /* struct _objc__method_prototype_list *method_next; */
4370 field_decl = create_field_decl (build_pointer_type
4371 (xref_tag (RECORD_TYPE,
4373 (UTAG_METHOD_PROTOTYPE_LIST))),
4375 field_decl_chain = field_decl;
4377 /* int method_count; */
4378 field_decl = create_field_decl (integer_type_node, "method_count");
4379 chainon (field_decl_chain, field_decl);
4381 /* struct objc_method method_list[]; */
4382 field_decl = create_field_decl (build_array_type
4385 (build_int_cst (NULL_TREE, size - 1))),
4387 chainon (field_decl_chain, field_decl);
4389 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4391 return objc_ivar_list_record;
4395 build_ivar_list_initializer (tree type, tree field_decl)
4397 tree initlist = NULL_TREE;
4401 tree ivar = NULL_TREE;
4404 if (DECL_NAME (field_decl))
4405 ivar = tree_cons (NULL_TREE,
4406 add_objc_string (DECL_NAME (field_decl),
4410 /* Unnamed bit-field ivar (yuck). */
4411 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
4414 encode_field_decl (field_decl,
4415 obstack_object_size (&util_obstack),
4416 OBJC_ENCODE_DONT_INLINE_DEFS);
4418 /* Null terminate string. */
4419 obstack_1grow (&util_obstack, 0);
4423 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4426 obstack_free (&util_obstack, util_firstobj);
4429 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4430 initlist = tree_cons (NULL_TREE,
4431 objc_build_constructor (type, nreverse (ivar)),
4434 field_decl = TREE_CHAIN (field_decl);
4435 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4439 return objc_build_constructor (build_array_type (type, 0),
4440 nreverse (initlist));
4444 generate_ivars_list (tree type, const char *name, int size, tree list)
4446 tree decl, initlist;
4448 decl = start_var_decl (type, synth_id_with_class_suffix
4449 (name, objc_implementation_context));
4451 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4452 initlist = tree_cons (NULL_TREE, list, initlist);
4454 finish_var_decl (decl,
4455 objc_build_constructor (TREE_TYPE (decl),
4456 nreverse (initlist)));
4461 /* Count only the fields occurring in T. */
4463 ivar_list_length (tree t)
4467 for (; t; t = TREE_CHAIN (t))
4468 if (TREE_CODE (t) == FIELD_DECL)
4475 generate_ivar_lists (void)
4477 tree initlist, ivar_list_template, chain;
4478 tree variable_length_type
4479 = xref_tag (RECORD_TYPE, get_identifier (UTAG_IVAR_LIST));
4482 generating_instance_variables = 1;
4484 if (!objc_ivar_template)
4485 objc_ivar_template = build_ivar_template ();
4487 /* Only generate class variables for the root of the inheritance
4488 hierarchy since these will be the same for every class. */
4490 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4491 && (chain = TYPE_FIELDS (objc_class_template)))
4493 size = ivar_list_length (chain);
4495 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4496 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4498 UOBJC_CLASS_VARIABLES_decl
4499 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4501 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type;
4504 UOBJC_CLASS_VARIABLES_decl = 0;
4506 chain = CLASS_IVARS (implementation_template);
4509 size = ivar_list_length (chain);
4510 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4511 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4513 UOBJC_INSTANCE_VARIABLES_decl
4514 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4516 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type;
4519 UOBJC_INSTANCE_VARIABLES_decl = 0;
4521 generating_instance_variables = 0;
4525 build_dispatch_table_initializer (tree type, tree entries)
4527 tree initlist = NULL_TREE;
4531 tree elemlist = NULL_TREE;
4533 elemlist = tree_cons (NULL_TREE,
4534 build_selector (METHOD_SEL_NAME (entries)),
4537 /* Generate the method encoding if we don't have one already. */
4538 if (! METHOD_ENCODING (entries))
4539 METHOD_ENCODING (entries) =
4540 encode_method_prototype (entries);
4542 elemlist = tree_cons (NULL_TREE,
4543 add_objc_string (METHOD_ENCODING (entries),
4548 = tree_cons (NULL_TREE,
4549 convert (ptr_type_node,
4550 build_unary_op (ADDR_EXPR,
4551 METHOD_DEFINITION (entries), 1)),
4554 initlist = tree_cons (NULL_TREE,
4555 objc_build_constructor (type, nreverse (elemlist)),
4558 entries = TREE_CHAIN (entries);
4562 return objc_build_constructor (build_array_type (type, 0),
4563 nreverse (initlist));
4566 /* To accomplish method prototyping without generating all kinds of
4567 inane warnings, the definition of the dispatch table entries were
4570 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4572 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4575 build_method_template (void)
4578 tree field_decl, field_decl_chain;
4580 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4583 field_decl = create_field_decl (objc_selector_type, "_cmd");
4584 field_decl_chain = field_decl;
4586 /* char *method_types; */
4587 field_decl = create_field_decl (string_type_node, "method_types");
4588 chainon (field_decl_chain, field_decl);
4591 field_decl = create_field_decl (build_pointer_type (void_type_node),
4593 chainon (field_decl_chain, field_decl);
4595 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4602 generate_dispatch_table (tree type, const char *name, int size, tree list)
4604 tree decl, initlist;
4606 decl = start_var_decl (type, synth_id_with_class_suffix
4607 (name, objc_implementation_context));
4609 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
4610 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
4611 initlist = tree_cons (NULL_TREE, list, initlist);
4613 finish_var_decl (decl,
4614 objc_build_constructor (TREE_TYPE (decl),
4615 nreverse (initlist)));
4621 mark_referenced_methods (void)
4623 struct imp_entry *impent;
4626 for (impent = imp_list; impent; impent = impent->next)
4628 chain = CLASS_CLS_METHODS (impent->imp_context);
4631 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4632 chain = TREE_CHAIN (chain);
4635 chain = CLASS_NST_METHODS (impent->imp_context);
4638 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4639 chain = TREE_CHAIN (chain);
4645 generate_dispatch_tables (void)
4647 tree initlist, chain, method_list_template;
4648 tree variable_length_type
4649 = xref_tag (RECORD_TYPE, get_identifier (UTAG_METHOD_LIST));
4652 if (!objc_method_template)
4653 objc_method_template = build_method_template ();
4655 chain = CLASS_CLS_METHODS (objc_implementation_context);
4658 size = list_length (chain);
4660 method_list_template
4661 = build_method_list_template (objc_method_template, size);
4663 = build_dispatch_table_initializer (objc_method_template, chain);
4665 UOBJC_CLASS_METHODS_decl
4666 = generate_dispatch_table (method_list_template,
4667 ((TREE_CODE (objc_implementation_context)
4668 == CLASS_IMPLEMENTATION_TYPE)
4669 ? "_OBJC_CLASS_METHODS"
4670 : "_OBJC_CATEGORY_CLASS_METHODS"),
4672 TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type;
4675 UOBJC_CLASS_METHODS_decl = 0;
4677 chain = CLASS_NST_METHODS (objc_implementation_context);
4680 size = list_length (chain);
4682 method_list_template
4683 = build_method_list_template (objc_method_template, size);
4685 = build_dispatch_table_initializer (objc_method_template, chain);
4687 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4688 UOBJC_INSTANCE_METHODS_decl
4689 = generate_dispatch_table (method_list_template,
4690 "_OBJC_INSTANCE_METHODS",
4693 /* We have a category. */
4694 UOBJC_INSTANCE_METHODS_decl
4695 = generate_dispatch_table (method_list_template,
4696 "_OBJC_CATEGORY_INSTANCE_METHODS",
4698 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type;
4701 UOBJC_INSTANCE_METHODS_decl = 0;
4705 generate_protocol_list (tree i_or_p)
4708 tree refs_decl, lproto, e, plist;
4710 const char *ref_name;
4712 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4713 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4714 plist = CLASS_PROTOCOL_LIST (i_or_p);
4715 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4716 plist = PROTOCOL_LIST (i_or_p);
4721 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4722 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4723 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4726 /* Build initializer. */
4727 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
4728 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
4729 initlist = tree_cons (NULL_TREE, e, initlist);
4731 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4733 tree pval = TREE_VALUE (lproto);
4735 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4736 && PROTOCOL_FORWARD_DECL (pval))
4738 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4739 initlist = tree_cons (NULL_TREE, e, initlist);
4743 /* static struct objc_protocol *refs[n]; */
4745 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4746 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
4747 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4748 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
4749 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4750 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
4754 refs_decl = start_var_decl
4756 (build_pointer_type (objc_protocol_template),
4757 build_index_type (build_int_cst (NULL_TREE, size + 2))),
4760 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4761 nreverse (initlist)));
4767 build_category_initializer (tree type, tree cat_name, tree class_name,
4768 tree instance_methods, tree class_methods,
4771 tree initlist = NULL_TREE, expr;
4773 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4774 initlist = tree_cons (NULL_TREE, class_name, initlist);
4776 if (!instance_methods)
4777 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4780 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4781 initlist = tree_cons (NULL_TREE, expr, initlist);
4784 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4787 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4788 initlist = tree_cons (NULL_TREE, expr, initlist);
4791 /* protocol_list = */
4793 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4796 expr = convert (build_pointer_type
4798 (objc_protocol_template)),
4799 build_unary_op (ADDR_EXPR, protocol_list, 0));
4800 initlist = tree_cons (NULL_TREE, expr, initlist);
4803 return objc_build_constructor (type, nreverse (initlist));
4806 /* struct _objc_class {
4807 struct objc_class *isa;
4808 struct objc_class *super_class;
4813 struct objc_ivar_list *ivars;
4814 struct objc_method_list *methods;
4815 if (flag_next_runtime)
4816 struct objc_cache *cache;
4818 struct sarray *dtable;
4819 struct objc_class *subclass_list;
4820 struct objc_class *sibling_class;
4822 struct objc_protocol_list *protocols;
4823 if (flag_next_runtime)
4825 void *gc_object_type;
4829 build_shared_structure_initializer (tree type, tree isa, tree super,
4830 tree name, tree size, int status,
4831 tree dispatch_table, tree ivar_list,
4834 tree initlist = NULL_TREE, expr;
4837 initlist = tree_cons (NULL_TREE, isa, initlist);
4840 initlist = tree_cons (NULL_TREE, super, initlist);
4843 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4846 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4849 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, status), initlist);
4851 /* instance_size = */
4852 initlist = tree_cons (NULL_TREE, size, initlist);
4854 /* objc_ivar_list = */
4856 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4859 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4860 initlist = tree_cons (NULL_TREE, expr, initlist);
4863 /* objc_method_list = */
4864 if (!dispatch_table)
4865 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4868 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4869 initlist = tree_cons (NULL_TREE, expr, initlist);
4872 if (flag_next_runtime)
4873 /* method_cache = */
4874 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4878 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4880 /* subclass_list = */
4881 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4883 /* sibling_class = */
4884 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4887 /* protocol_list = */
4888 if (! protocol_list)
4889 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4892 expr = convert (build_pointer_type
4894 (objc_protocol_template)),
4895 build_unary_op (ADDR_EXPR, protocol_list, 0));
4896 initlist = tree_cons (NULL_TREE, expr, initlist);
4899 if (flag_next_runtime)
4901 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4903 /* gc_object_type = NULL */
4904 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4906 return objc_build_constructor (type, nreverse (initlist));
4909 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4912 lookup_category (tree class, tree cat_name)
4914 tree category = CLASS_CATEGORY_LIST (class);
4916 while (category && CLASS_SUPER_NAME (category) != cat_name)
4917 category = CLASS_CATEGORY_LIST (category);
4921 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4924 generate_category (tree cat)
4927 tree initlist, cat_name_expr, class_name_expr;
4928 tree protocol_decl, category;
4930 add_class_reference (CLASS_NAME (cat));
4931 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4933 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4935 category = lookup_category (implementation_template,
4936 CLASS_SUPER_NAME (cat));
4938 if (category && CLASS_PROTOCOL_LIST (category))
4940 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4941 protocol_decl = generate_protocol_list (category);
4946 decl = start_var_decl (objc_category_template,
4947 synth_id_with_class_suffix
4948 ("_OBJC_CATEGORY", objc_implementation_context));
4950 initlist = build_category_initializer (TREE_TYPE (decl),
4951 cat_name_expr, class_name_expr,
4952 UOBJC_INSTANCE_METHODS_decl,
4953 UOBJC_CLASS_METHODS_decl,
4956 finish_var_decl (decl, initlist);
4959 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4960 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4963 generate_shared_structures (void)
4965 tree sc_spec, decl_specs, decl;
4966 tree name_expr, super_expr, root_expr;
4967 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4968 tree cast_type, initlist, protocol_decl;
4970 my_super_id = CLASS_SUPER_NAME (implementation_template);
4973 add_class_reference (my_super_id);
4975 /* Compute "my_root_id" - this is required for code generation.
4976 the "isa" for all meta class structures points to the root of
4977 the inheritance hierarchy (e.g. "__Object")... */
4978 my_root_id = my_super_id;
4981 tree my_root_int = lookup_interface (my_root_id);
4983 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
4984 my_root_id = CLASS_SUPER_NAME (my_root_int);
4991 /* No super class. */
4992 my_root_id = CLASS_NAME (implementation_template);
4994 cast_type = build_pointer_type (objc_class_template);
4995 name_expr = add_objc_string (CLASS_NAME (implementation_template),
4998 /* Install class `isa' and `super' pointers at runtime. */
5001 super_expr = add_objc_string (my_super_id, class_names);
5002 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5005 super_expr = build_int_cst (NULL_TREE, 0);
5007 root_expr = add_objc_string (my_root_id, class_names);
5008 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5010 if (CLASS_PROTOCOL_LIST (implementation_template))
5012 generate_protocol_references
5013 (CLASS_PROTOCOL_LIST (implementation_template));
5014 protocol_decl = generate_protocol_list (implementation_template);
5019 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5021 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5022 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5024 decl = start_var_decl (objc_class_template,
5026 (DECL_NAME (UOBJC_METACLASS_decl)));
5029 = build_shared_structure_initializer
5031 root_expr, super_expr, name_expr,
5032 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5034 UOBJC_CLASS_METHODS_decl,
5035 UOBJC_CLASS_VARIABLES_decl,
5038 finish_var_decl (decl, initlist);
5040 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5042 decl = start_var_decl (objc_class_template,
5044 (DECL_NAME (UOBJC_CLASS_decl)));
5047 = build_shared_structure_initializer
5049 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5050 super_expr, name_expr,
5051 convert (integer_type_node,
5052 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5053 (implementation_template))),
5055 UOBJC_INSTANCE_METHODS_decl,
5056 UOBJC_INSTANCE_VARIABLES_decl,
5059 finish_var_decl (decl, initlist);
5064 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5066 static char string[BUFSIZE];
5068 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5069 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5071 sprintf (string, "%s_%s", preamble,
5072 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5074 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5075 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5077 /* We have a category. */
5078 const char *const class_name
5079 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5080 const char *const class_super_name
5081 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5082 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5084 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5086 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5087 sprintf (string, "%s_%s", preamble, protocol_name);
5095 /* If type is empty or only type qualifiers are present, add default
5096 type of id (otherwise grokdeclarator will default to int). */
5099 adjust_type_for_id_default (tree type)
5102 type = make_node (TREE_LIST);
5104 if (!TREE_VALUE (type))
5105 TREE_VALUE (type) = objc_object_type;
5106 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5107 && TYPED_OBJECT (TREE_VALUE (type)))
5108 error ("can not use an object as parameter to a method");
5115 selector ':' '(' typename ')' identifier
5118 Transform an Objective-C keyword argument into
5119 the C equivalent parameter declarator.
5121 In: key_name, an "identifier_node" (optional).
5122 arg_type, a "tree_list" (optional).
5123 arg_name, an "identifier_node".
5125 Note: It would be really nice to strongly type the preceding
5126 arguments in the function prototype; however, then I
5127 could not use the "accessor" macros defined in "tree.h".
5129 Out: an instance of "keyword_decl". */
5132 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5136 /* If no type is specified, default to "id". */
5137 arg_type = adjust_type_for_id_default (arg_type);
5139 keyword_decl = make_node (KEYWORD_DECL);
5141 TREE_TYPE (keyword_decl) = arg_type;
5142 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5143 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5145 return keyword_decl;
5148 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5151 build_keyword_selector (tree selector)
5154 tree key_chain, key_name;
5157 /* Scan the selector to see how much space we'll need. */
5158 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5160 if (TREE_CODE (selector) == KEYWORD_DECL)
5161 key_name = KEYWORD_KEY_NAME (key_chain);
5162 else if (TREE_CODE (selector) == TREE_LIST)
5163 key_name = TREE_PURPOSE (key_chain);
5168 len += IDENTIFIER_LENGTH (key_name) + 1;
5170 /* Just a ':' arg. */
5174 buf = (char *) alloca (len + 1);
5175 /* Start the buffer out as an empty string. */
5178 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5180 if (TREE_CODE (selector) == KEYWORD_DECL)
5181 key_name = KEYWORD_KEY_NAME (key_chain);
5182 else if (TREE_CODE (selector) == TREE_LIST)
5184 key_name = TREE_PURPOSE (key_chain);
5185 /* The keyword decl chain will later be used as a function argument
5186 chain. Unhook the selector itself so as to not confuse other
5187 parts of the compiler. */
5188 TREE_PURPOSE (key_chain) = NULL_TREE;
5194 strcat (buf, IDENTIFIER_POINTER (key_name));
5198 return get_identifier (buf);
5201 /* Used for declarations and definitions. */
5204 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5209 /* If no type is specified, default to "id". */
5210 ret_type = adjust_type_for_id_default (ret_type);
5212 method_decl = make_node (code);
5213 TREE_TYPE (method_decl) = ret_type;
5215 /* If we have a keyword selector, create an identifier_node that
5216 represents the full selector name (`:' included)... */
5217 if (TREE_CODE (selector) == KEYWORD_DECL)
5219 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5220 METHOD_SEL_ARGS (method_decl) = selector;
5221 METHOD_ADD_ARGS (method_decl) = add_args;
5225 METHOD_SEL_NAME (method_decl) = selector;
5226 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5227 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5233 #define METHOD_DEF 0
5234 #define METHOD_REF 1
5236 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5237 an argument list for method METH. CONTEXT is either METHOD_DEF or
5238 METHOD_REF, saying whether we are trying to define a method or call
5239 one. SUPERFLAG says this is for a send to super; this makes a
5240 difference for the NeXT calling sequence in which the lookup and
5241 the method call are done together. If METH is null, user-defined
5242 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5245 get_arg_type_list (tree meth, int context, int superflag)
5249 /* Receiver type. */
5250 if (flag_next_runtime && superflag)
5251 arglist = build_tree_list (NULL_TREE, objc_super_type);
5252 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5253 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5255 arglist = build_tree_list (NULL_TREE, objc_object_type);
5257 /* Selector type - will eventually change to `int'. */
5258 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5260 /* No actual method prototype given -- assume that remaining arguments
5265 /* Build a list of argument types. */
5266 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5268 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5270 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5273 if (METHOD_ADD_ARGS (meth))
5275 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5276 akey; akey = TREE_CHAIN (akey))
5278 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
5280 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5283 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth)))
5284 goto lack_of_ellipsis;
5289 chainon (arglist, OBJC_VOID_AT_END);
5296 check_duplicates (hash hsh, int methods, int is_class)
5298 tree meth = NULL_TREE;
5306 /* We have two or more methods with the same name but
5310 warning ("multiple %s named `%c%s' found",
5311 methods ? "methods" : "selectors",
5312 (is_class ? '+' : '-'),
5313 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5315 warn_with_method (methods ? "using" : "found",
5316 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5320 for (loop = hsh->list; loop; loop = loop->next)
5321 warn_with_method ("also found",
5322 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5331 /* If RECEIVER is a class reference, return the identifier node for
5332 the referenced class. RECEIVER is created by objc_get_class_reference,
5333 so we check the exact form created depending on which runtimes are
5337 receiver_is_class_object (tree receiver, int self, int super)
5339 tree chain, exp, arg;
5341 /* The receiver is 'self' or 'super' in the context of a class method. */
5342 if (objc_method_context
5343 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5346 ? CLASS_SUPER_NAME (implementation_template)
5347 : CLASS_NAME (implementation_template));
5349 if (flag_next_runtime)
5351 /* The receiver is a variable created by
5352 build_class_reference_decl. */
5353 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
5354 /* Look up the identifier. */
5355 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5356 if (TREE_PURPOSE (chain) == receiver)
5357 return TREE_VALUE (chain);
5360 /* The receiver is a function call that returns an id. Check if
5361 it is a call to objc_getClass, if so, pick up the class name. */
5362 if (TREE_CODE (receiver) == CALL_EXPR
5363 && (exp = TREE_OPERAND (receiver, 0))
5364 && TREE_CODE (exp) == ADDR_EXPR
5365 && (exp = TREE_OPERAND (exp, 0))
5366 && TREE_CODE (exp) == FUNCTION_DECL
5367 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5368 prototypes for objc_get_class(). Thankfully, they seem to share the
5369 same function type. */
5370 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5371 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5372 /* We have a call to objc_get_class/objc_getClass! */
5373 && (arg = TREE_OPERAND (receiver, 1))
5374 && TREE_CODE (arg) == TREE_LIST
5375 && (arg = TREE_VALUE (arg)))
5378 if (TREE_CODE (arg) == ADDR_EXPR
5379 && (arg = TREE_OPERAND (arg, 0))
5380 && TREE_CODE (arg) == STRING_CST)
5381 /* Finally, we have the class name. */
5382 return get_identifier (TREE_STRING_POINTER (arg));
5387 /* If we are currently building a message expr, this holds
5388 the identifier of the selector of the message. This is
5389 used when printing warnings about argument mismatches. */
5391 static tree current_objc_message_selector = 0;
5394 objc_message_selector (void)
5396 return current_objc_message_selector;
5399 /* Construct an expression for sending a message.
5400 MESS has the object to send to in TREE_PURPOSE
5401 and the argument list (including selector) in TREE_VALUE.
5403 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5404 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5407 objc_build_message_expr (tree mess)
5409 tree receiver = TREE_PURPOSE (mess);
5412 tree args = TREE_PURPOSE (TREE_VALUE (mess));
5414 tree args = TREE_VALUE (mess);
5416 tree method_params = NULL_TREE;
5418 if (TREE_CODE (receiver) == ERROR_MARK)
5419 return error_mark_node;
5421 /* Obtain the full selector name. */
5422 if (TREE_CODE (args) == IDENTIFIER_NODE)
5423 /* A unary selector. */
5425 else if (TREE_CODE (args) == TREE_LIST)
5426 sel_name = build_keyword_selector (args);
5430 /* Build the parameter list to give to the method. */
5431 if (TREE_CODE (args) == TREE_LIST)
5433 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
5436 tree chain = args, prev = NULL_TREE;
5438 /* We have a keyword selector--check for comma expressions. */
5441 tree element = TREE_VALUE (chain);
5443 /* We have a comma expression, must collapse... */
5444 if (TREE_CODE (element) == TREE_LIST)
5447 TREE_CHAIN (prev) = element;
5452 chain = TREE_CHAIN (chain);
5454 method_params = args;
5459 if (processing_template_decl)
5460 /* Must wait until template instantiation time. */
5461 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5465 return objc_finish_message_expr (receiver, sel_name, method_params);
5468 /* Look up method SEL_NAME that would be suitable for receiver
5469 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5470 nonzero), and report on any duplicates. */
5473 lookup_method_in_hash_lists (tree sel_name, int is_class)
5475 hash method_prototype = NULL;
5478 method_prototype = hash_lookup (nst_method_hash_list,
5481 if (!method_prototype)
5483 method_prototype = hash_lookup (cls_method_hash_list,
5488 return check_duplicates (method_prototype, 1, is_class);
5491 /* The 'objc_finish_message_expr' routine is called from within
5492 'objc_build_message_expr' for non-template functions. In the case of
5493 C++ template functions, it is called from 'build_expr_from_tree'
5494 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5497 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
5499 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5500 tree selector, retval, class_tree;
5501 int self, super, have_cast;
5503 /* Extract the receiver of the message, as well as its type
5504 (where the latter may take the form of a cast or be inferred
5505 from the implementation context). */
5507 while (TREE_CODE (rtype) == COMPOUND_EXPR
5508 || TREE_CODE (rtype) == MODIFY_EXPR
5509 || TREE_CODE (rtype) == NOP_EXPR
5510 || TREE_CODE (rtype) == CONVERT_EXPR
5511 || TREE_CODE (rtype) == COMPONENT_REF)
5512 rtype = TREE_OPERAND (rtype, 0);
5513 self = (rtype == self_decl);
5514 super = (rtype == UOBJC_SUPER_decl);
5515 rtype = TREE_TYPE (receiver);
5516 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5517 || (TREE_CODE (receiver) == COMPOUND_EXPR
5518 && !IS_SUPER (rtype)));
5520 /* If the receiver is a class object, retrieve the corresponding
5521 @interface, if one exists. */
5522 class_tree = receiver_is_class_object (receiver, self, super);
5524 /* Now determine the receiver type (if an explicit cast has not been
5529 rtype = lookup_interface (class_tree);
5530 /* Handle `self' and `super'. */
5533 if (!CLASS_SUPER_NAME (implementation_template))
5535 error ("no super class declared in @interface for `%s'",
5536 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5537 return error_mark_node;
5539 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5542 rtype = lookup_interface (CLASS_NAME (implementation_template));
5545 /* If receiver is of type `id' or `Class' (or if the @interface for a
5546 class is not visible), we shall be satisfied with the existence of
5547 any instance or class method. */
5548 if (!rtype || objc_is_id (rtype))
5551 rtype = xref_tag (RECORD_TYPE, class_tree);
5552 else if (IS_ID (rtype))
5554 rprotos = TYPE_PROTOCOL_LIST (rtype);
5559 class_tree = objc_class_name;
5560 OBJC_SET_TYPE_NAME (rtype, class_tree);
5565 = lookup_method_in_protocol_list (rprotos, sel_name,
5566 class_tree != NULL_TREE);
5567 if (!method_prototype && !rprotos)
5569 = lookup_method_in_hash_lists (sel_name,
5570 class_tree != NULL_TREE);
5574 tree orig_rtype = rtype, saved_rtype;
5576 if (TREE_CODE (rtype) == POINTER_TYPE)
5577 rtype = TREE_TYPE (rtype);
5578 /* Traverse typedef aliases */
5579 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
5580 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
5581 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
5582 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
5583 saved_rtype = rtype;
5584 if (TYPED_OBJECT (rtype))
5586 rprotos = TYPE_PROTOCOL_LIST (rtype);
5587 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5589 /* If we could not find an @interface declaration, we must have
5590 only seen a @class declaration; so, we cannot say anything
5591 more intelligent about which methods the receiver will
5594 rtype = saved_rtype;
5595 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5596 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5598 /* We have a valid ObjC class name. Look up the method name
5599 in the published @interface for the class (and its
5602 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5604 /* If the method was not found in the @interface, it may still
5605 exist locally as part of the @implementation. */
5606 if (!method_prototype && objc_implementation_context
5607 && CLASS_NAME (objc_implementation_context)
5608 == OBJC_TYPE_NAME (rtype))
5612 ? CLASS_CLS_METHODS (objc_implementation_context)
5613 : CLASS_NST_METHODS (objc_implementation_context)),
5616 /* If we haven't found a candidate method by now, try looking for
5617 it in the protocol list. */
5618 if (!method_prototype && rprotos)
5620 = lookup_method_in_protocol_list (rprotos, sel_name,
5621 class_tree != NULL_TREE);
5625 warning ("invalid receiver type `%s'",
5626 gen_type_name (orig_rtype));
5627 rtype = rprotos = NULL_TREE;
5631 if (!method_prototype)
5633 static bool warn_missing_methods = false;
5636 warning ("`%s' may not respond to `%c%s'",
5637 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5638 (class_tree ? '+' : '-'),
5639 IDENTIFIER_POINTER (sel_name));
5641 warning ("`%c%s' not implemented by protocol(s)",
5642 (class_tree ? '+' : '-'),
5643 IDENTIFIER_POINTER (sel_name));
5644 if (!warn_missing_methods)
5646 warning ("(Messages without a matching method signature");
5647 warning ("will be assumed to return `id' and accept");
5648 warning ("`...' as arguments.)");
5649 warn_missing_methods = true;
5653 /* Save the selector name for printing error messages. */
5654 current_objc_message_selector = sel_name;
5656 /* Build the parameters list for looking up the method.
5657 These are the object itself and the selector. */
5659 if (flag_typed_selectors)
5660 selector = build_typed_selector_reference (sel_name, method_prototype);
5662 selector = build_selector_reference (sel_name);
5664 retval = build_objc_method_call (super, method_prototype,
5666 selector, method_params);
5668 current_objc_message_selector = 0;
5673 /* Build a tree expression to send OBJECT the operation SELECTOR,
5674 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5675 assuming the method has prototype METHOD_PROTOTYPE.
5676 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5677 Use METHOD_PARAMS as list of args to pass to the method.
5678 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5681 build_objc_method_call (int super_flag, tree method_prototype,
5682 tree lookup_object, tree selector,
5685 tree sender = (super_flag ? umsg_super_decl :
5686 (!flag_next_runtime || flag_nil_receivers
5688 : umsg_nonnil_decl));
5689 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
5691 /* If a prototype for the method to be called exists, then cast
5692 the sender's return type and arguments to match that of the method.
5693 Otherwise, leave sender as is. */
5696 ? TREE_VALUE (TREE_TYPE (method_prototype))
5697 : objc_object_type);
5699 = build_pointer_type
5700 (build_function_type
5703 (method_prototype, METHOD_REF, super_flag)));
5706 lookup_object = build_c_cast (rcv_p, lookup_object);
5708 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5709 lookup_object = save_expr (lookup_object);
5711 if (flag_next_runtime)
5713 /* If we are returning a struct in memory, and the address
5714 of that memory location is passed as a hidden first
5715 argument, then change which messenger entry point this
5716 expr will call. NB: Note that sender_cast remains
5717 unchanged (it already has a struct return type). */
5718 if (!targetm.calls.struct_value_rtx (0, 0)
5719 && (TREE_CODE (ret_type) == RECORD_TYPE
5720 || TREE_CODE (ret_type) == UNION_TYPE)
5721 && targetm.calls.return_in_memory (ret_type, 0))
5722 sender = (super_flag ? umsg_super_stret_decl :
5723 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5725 method_params = tree_cons (NULL_TREE, lookup_object,
5726 tree_cons (NULL_TREE, selector,
5728 method = build_fold_addr_expr (sender);
5732 /* This is the portable (GNU) way. */
5735 /* First, call the lookup function to get a pointer to the method,
5736 then cast the pointer, then call it with the method arguments. */
5738 object = (super_flag ? self_decl : lookup_object);
5740 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5741 t = tree_cons (NULL_TREE, lookup_object, t);
5742 method = build_function_call (sender, t);
5744 /* Pass the object to the method. */
5745 method_params = tree_cons (NULL_TREE, object,
5746 tree_cons (NULL_TREE, selector,
5750 /* ??? Selector is not at this point something we can use inside
5751 the compiler itself. Set it to garbage for the nonce. */
5752 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5753 return build_function_call (t, method_params);
5757 build_protocol_reference (tree p)
5760 const char *proto_name;
5762 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5764 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5765 decl = start_var_decl (objc_protocol_template, proto_name);
5767 PROTOCOL_FORWARD_DECL (p) = decl;
5770 /* This function is called by the parser when (and only when) a
5771 @protocol() expression is found, in order to compile it. */
5773 objc_build_protocol_expr (tree protoname)
5776 tree p = lookup_protocol (protoname);
5780 error ("cannot find protocol declaration for `%s'",
5781 IDENTIFIER_POINTER (protoname));
5782 return error_mark_node;
5785 if (!PROTOCOL_FORWARD_DECL (p))
5786 build_protocol_reference (p);
5788 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5790 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5791 if we have it, rather than converting it here. */
5792 expr = convert (objc_protocol_type, expr);
5794 /* The @protocol() expression is being compiled into a pointer to a
5795 statically allocated instance of the Protocol class. To become
5796 usable at runtime, the 'isa' pointer of the instance need to be
5797 fixed up at runtime by the runtime library, to point to the
5798 actual 'Protocol' class. */
5800 /* For the GNU runtime, put the static Protocol instance in the list
5801 of statically allocated instances, so that we make sure that its
5802 'isa' pointer is fixed up at runtime by the GNU runtime library
5803 to point to the Protocol class (at runtime, when loading the
5804 module, the GNU runtime library loops on the statically allocated
5805 instances (as found in the defs field in objc_symtab) and fixups
5806 all the 'isa' pointers of those objects). */
5807 if (! flag_next_runtime)
5809 /* This type is a struct containing the fields of a Protocol
5810 object. (Cfr. objc_protocol_type instead is the type of a pointer
5811 to such a struct). */
5812 tree protocol_struct_type = xref_tag
5813 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5816 /* Look for the list of Protocol statically allocated instances
5817 to fixup at runtime. Create a new list to hold Protocol
5818 statically allocated instances, if the list is not found. At
5819 present there is only another list, holding NSConstantString
5820 static instances to be fixed up at runtime. */
5821 for (chain = &objc_static_instances;
5822 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5823 chain = &TREE_CHAIN (*chain));
5826 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5827 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
5831 /* Add this statically allocated instance to the Protocol list. */
5832 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5833 PROTOCOL_FORWARD_DECL (p),
5834 TREE_PURPOSE (*chain));
5841 /* This function is called by the parser when a @selector() expression
5842 is found, in order to compile it. It is only called by the parser
5843 and only to compile a @selector(). */
5845 objc_build_selector_expr (tree selnamelist)
5849 /* Obtain the full selector name. */
5850 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5851 /* A unary selector. */
5852 selname = selnamelist;
5853 else if (TREE_CODE (selnamelist) == TREE_LIST)
5854 selname = build_keyword_selector (selnamelist);
5858 /* If we are required to check @selector() expressions as they
5859 are found, check that the selector has been declared. */
5860 if (warn_undeclared_selector)
5862 /* Look the selector up in the list of all known class and
5863 instance methods (up to this line) to check that the selector
5867 /* First try with instance methods. */
5868 hsh = hash_lookup (nst_method_hash_list, selname);
5870 /* If not found, try with class methods. */
5873 hsh = hash_lookup (cls_method_hash_list, selname);
5876 /* If still not found, print out a warning. */
5879 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5884 if (flag_typed_selectors)
5885 return build_typed_selector_reference (selname, 0);
5887 return build_selector_reference (selname);
5891 objc_build_encode_expr (tree type)
5896 encode_type (type, obstack_object_size (&util_obstack),
5897 OBJC_ENCODE_INLINE_DEFS);
5898 obstack_1grow (&util_obstack, 0); /* null terminate string */
5899 string = obstack_finish (&util_obstack);
5901 /* Synthesize a string that represents the encoded struct/union. */
5902 result = my_build_string (strlen (string) + 1, string);
5903 obstack_free (&util_obstack, util_firstobj);
5908 build_ivar_reference (tree id)
5910 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5912 /* Historically, a class method that produced objects (factory
5913 method) would assign `self' to the instance that it
5914 allocated. This would effectively turn the class method into
5915 an instance method. Following this assignment, the instance
5916 variables could be accessed. That practice, while safe,
5917 violates the simple rule that a class method should not refer
5918 to an instance variable. It's better to catch the cases
5919 where this is done unknowingly than to support the above
5921 warning ("instance variable `%s' accessed in class method",
5922 IDENTIFIER_POINTER (id));
5923 self_decl = convert (objc_instance_type, self_decl); /* cast */
5926 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5929 /* Compute a hash value for a given method SEL_NAME. */
5932 hash_func (tree sel_name)
5934 const unsigned char *s
5935 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5939 h = h * 67 + *s++ - 113;
5946 nst_method_hash_list
5947 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
5948 cls_method_hash_list
5949 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
5951 /* Initialize the hash table used to hold the constant string objects. */
5952 string_htab = htab_create_ggc (31, string_hash,
5956 /* WARNING!!!! hash_enter is called with a method, and will peek
5957 inside to find its selector! But hash_lookup is given a selector
5958 directly, and looks for the selector that's inside the found
5959 entry's key (method) for comparison. */
5962 hash_enter (hash *hashlist, tree method)
5965 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
5967 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
5969 obj->next = hashlist[slot];
5972 hashlist[slot] = obj; /* append to front */
5976 hash_lookup (hash *hashlist, tree sel_name)
5980 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
5984 if (sel_name == METHOD_SEL_NAME (target->key))
5987 target = target->next;
5993 hash_add_attr (hash entry, tree value)
5997 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
5998 obj->next = entry->list;
6001 entry->list = obj; /* append to front */
6005 lookup_method (tree mchain, tree method)
6009 if (TREE_CODE (method) == IDENTIFIER_NODE)
6012 key = METHOD_SEL_NAME (method);
6016 if (METHOD_SEL_NAME (mchain) == key)
6019 mchain = TREE_CHAIN (mchain);
6025 lookup_method_static (tree interface, tree ident, int is_class)
6027 tree meth = NULL_TREE, root_inter = NULL_TREE;
6028 tree inter = interface;
6032 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6033 tree category = inter;
6035 /* First, look up the method in the class itself. */
6036 if ((meth = lookup_method (chain, ident)))
6039 /* Failing that, look for the method in each category of the class. */
6040 while ((category = CLASS_CATEGORY_LIST (category)))
6042 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6044 /* Check directly in each category. */
6045 if ((meth = lookup_method (chain, ident)))
6048 /* Failing that, check in each category's protocols. */
6049 if (CLASS_PROTOCOL_LIST (category))
6051 if ((meth = (lookup_method_in_protocol_list
6052 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6057 /* If not found in categories, check in protocols of the main class. */
6058 if (CLASS_PROTOCOL_LIST (inter))
6060 if ((meth = (lookup_method_in_protocol_list
6061 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6065 /* Failing that, climb up the inheritance hierarchy. */
6067 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6071 /* If no class (factory) method was found, check if an _instance_
6072 method of the same name exists in the root class. This is what
6073 the Objective-C runtime will do. If an instance method was not
6075 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6078 /* Add the method to the hash list if it doesn't contain an identical
6081 add_method_to_hash_list (hash *hash_list, tree method)
6085 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6087 /* Install on a global chain. */
6088 hash_enter (hash_list, method);
6092 /* Check types against those; if different, add to a list. */
6094 int already_there = comp_proto_with_proto (method, hsh->key);
6095 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6096 already_there |= comp_proto_with_proto (method, loop->value);
6098 hash_add_attr (hsh, method);
6103 objc_add_method (tree class, tree method, int is_class)
6107 if (!(mth = lookup_method (is_class
6108 ? CLASS_CLS_METHODS (class)
6109 : CLASS_NST_METHODS (class), method)))
6111 /* put method on list in reverse order */
6114 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6115 CLASS_CLS_METHODS (class) = method;
6119 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6120 CLASS_NST_METHODS (class) = method;
6125 /* When processing an @interface for a class or category, give hard
6126 errors on methods with identical selectors but differing argument
6127 and/or return types. We do not do this for @implementations, because
6128 C/C++ will do it for us (i.e., there will be duplicate function
6129 definition errors). */
6130 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6131 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6132 && !comp_proto_with_proto (method, mth))
6133 error ("duplicate declaration of method `%c%s'",
6134 is_class ? '+' : '-',
6135 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6139 add_method_to_hash_list (cls_method_hash_list, method);
6142 add_method_to_hash_list (nst_method_hash_list, method);
6144 /* Instance methods in root classes (and categories thereof)
6145 may acts as class methods as a last resort. */
6146 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6147 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6148 class = lookup_interface (CLASS_NAME (class));
6150 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6151 && !CLASS_SUPER_NAME (class))
6152 add_method_to_hash_list (cls_method_hash_list, method);
6159 add_class (tree class)
6161 /* Put interfaces on list in reverse order. */
6162 TREE_CHAIN (class) = interface_chain;
6163 interface_chain = class;
6164 return interface_chain;
6168 add_category (tree class, tree category)
6170 /* Put categories on list in reverse order. */
6171 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6175 warning ("duplicate interface declaration for category `%s(%s)'",
6176 IDENTIFIER_POINTER (CLASS_NAME (class)),
6177 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6181 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6182 CLASS_CATEGORY_LIST (class) = category;
6186 /* Called after parsing each instance variable declaration. Necessary to
6187 preserve typedefs and implement public/private...
6189 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6192 add_instance_variable (tree class, int public, tree field_decl)
6194 tree field_type = TREE_TYPE (field_decl);
6195 const char *ivar_name = DECL_NAME (field_decl)
6196 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6200 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6202 error ("illegal reference type specified for instance variable `%s'",
6204 /* Return class as is without adding this ivar. */
6209 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6210 || TYPE_SIZE (field_type) == error_mark_node)
6211 /* 'type[0]' is allowed, but 'type[]' is not! */
6213 error ("instance variable `%s' has unknown size", ivar_name);
6214 /* Return class as is without adding this ivar. */
6219 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6220 cannot be ivars; ditto for classes with vtables. */
6221 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6222 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6224 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6225 if(TYPE_POLYMORPHIC_P (field_type)) {
6226 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6227 error ("type `%s' has virtual member functions", type_name);
6228 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6229 type_name, ivar_name);
6230 /* Return class as is without adding this ivar. */
6233 /* user-defined constructors and destructors are not known to Obj-C and
6234 hence will not be called. This may or may not be a problem. */
6235 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6236 warning ("type `%s' has a user-defined constructor", type_name);
6237 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6238 warning ("type `%s' has a user-defined destructor", type_name);
6239 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6243 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6247 TREE_PUBLIC (field_decl) = 0;
6248 TREE_PRIVATE (field_decl) = 0;
6249 TREE_PROTECTED (field_decl) = 1;
6253 TREE_PUBLIC (field_decl) = 1;
6254 TREE_PRIVATE (field_decl) = 0;
6255 TREE_PROTECTED (field_decl) = 0;
6259 TREE_PUBLIC (field_decl) = 0;
6260 TREE_PRIVATE (field_decl) = 1;
6261 TREE_PROTECTED (field_decl) = 0;
6266 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
6272 is_ivar (tree decl_chain, tree ident)
6274 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6275 if (DECL_NAME (decl_chain) == ident)
6280 /* True if the ivar is private and we are not in its implementation. */
6283 is_private (tree decl)
6285 return (TREE_PRIVATE (decl)
6286 && ! is_ivar (CLASS_IVARS (implementation_template),
6290 /* We have an instance variable reference;, check to see if it is public. */
6293 objc_is_public (tree expr, tree identifier)
6295 tree basetype = TREE_TYPE (expr);
6296 enum tree_code code = TREE_CODE (basetype);
6299 if (code == RECORD_TYPE)
6301 if (TREE_STATIC_TEMPLATE (basetype))
6303 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6305 error ("cannot find interface declaration for `%s'",
6306 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6310 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6312 if (TREE_PUBLIC (decl))
6315 /* Important difference between the Stepstone translator:
6316 all instance variables should be public within the context
6317 of the implementation. */
6318 if (objc_implementation_context
6319 && (((TREE_CODE (objc_implementation_context)
6320 == CLASS_IMPLEMENTATION_TYPE)
6321 || (TREE_CODE (objc_implementation_context)
6322 == CATEGORY_IMPLEMENTATION_TYPE))
6323 && (CLASS_NAME (objc_implementation_context)
6324 == OBJC_TYPE_NAME (basetype))))
6326 int private = is_private (decl);
6329 error ("instance variable `%s' is declared private",
6330 IDENTIFIER_POINTER (DECL_NAME (decl)));
6334 /* The 2.95.2 compiler sometimes allowed C functions to access
6335 non-@public ivars. We will let this slide for now... */
6336 if (!objc_method_context)
6338 warning ("instance variable `%s' is %s; "
6339 "this will be a hard error in the future",
6340 IDENTIFIER_POINTER (identifier),
6341 TREE_PRIVATE (decl) ? "@private" : "@protected");
6345 error ("instance variable `%s' is declared %s",
6346 IDENTIFIER_POINTER (identifier),
6347 TREE_PRIVATE (decl) ? "private" : "protected");
6352 else if (objc_implementation_context && (basetype == objc_object_reference))
6354 expr = convert (uprivate_record, expr);
6355 warning ("static access to object of type `id'");
6362 /* Make sure all entries in CHAIN are also in LIST. */
6365 check_methods (tree chain, tree list, int mtype)
6371 if (!lookup_method (list, chain))
6375 if (TREE_CODE (objc_implementation_context)
6376 == CLASS_IMPLEMENTATION_TYPE)
6377 warning ("incomplete implementation of class `%s'",
6378 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6379 else if (TREE_CODE (objc_implementation_context)
6380 == CATEGORY_IMPLEMENTATION_TYPE)
6381 warning ("incomplete implementation of category `%s'",
6382 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6386 warning ("method definition for `%c%s' not found",
6387 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6390 chain = TREE_CHAIN (chain);
6396 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6399 conforms_to_protocol (tree class, tree protocol)
6401 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6403 tree p = CLASS_PROTOCOL_LIST (class);
6404 while (p && TREE_VALUE (p) != protocol)
6409 tree super = (CLASS_SUPER_NAME (class)
6410 ? lookup_interface (CLASS_SUPER_NAME (class))
6412 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6421 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6422 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6425 check_methods_accessible (tree chain, tree context, int mtype)
6429 tree base_context = context;
6433 context = base_context;
6437 list = CLASS_CLS_METHODS (context);
6439 list = CLASS_NST_METHODS (context);
6441 if (lookup_method (list, chain))
6444 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6445 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6446 context = (CLASS_SUPER_NAME (context)
6447 ? lookup_interface (CLASS_SUPER_NAME (context))
6450 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6451 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6452 context = (CLASS_NAME (context)
6453 ? lookup_interface (CLASS_NAME (context))
6459 if (context == NULL_TREE)
6463 if (TREE_CODE (objc_implementation_context)
6464 == CLASS_IMPLEMENTATION_TYPE)
6465 warning ("incomplete implementation of class `%s'",
6467 (CLASS_NAME (objc_implementation_context)));
6468 else if (TREE_CODE (objc_implementation_context)
6469 == CATEGORY_IMPLEMENTATION_TYPE)
6470 warning ("incomplete implementation of category `%s'",
6472 (CLASS_SUPER_NAME (objc_implementation_context)));
6475 warning ("method definition for `%c%s' not found",
6476 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6479 chain = TREE_CHAIN (chain); /* next method... */
6484 /* Check whether the current interface (accessible via
6485 'objc_implementation_context') actually implements protocol P, along
6486 with any protocols that P inherits. */
6489 check_protocol (tree p, const char *type, const char *name)
6491 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6495 /* Ensure that all protocols have bodies! */
6498 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6499 CLASS_CLS_METHODS (objc_implementation_context),
6501 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6502 CLASS_NST_METHODS (objc_implementation_context),
6507 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6508 objc_implementation_context,
6510 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6511 objc_implementation_context,
6516 warning ("%s `%s' does not fully implement the `%s' protocol",
6517 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6520 /* Check protocols recursively. */
6521 if (PROTOCOL_LIST (p))
6523 tree subs = PROTOCOL_LIST (p);
6525 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6529 tree sub = TREE_VALUE (subs);
6531 /* If the superclass does not conform to the protocols
6532 inherited by P, then we must! */
6533 if (!super_class || !conforms_to_protocol (super_class, sub))
6534 check_protocol (sub, type, name);
6535 subs = TREE_CHAIN (subs);
6540 /* Check whether the current interface (accessible via
6541 'objc_implementation_context') actually implements the protocols listed
6545 check_protocols (tree proto_list, const char *type, const char *name)
6547 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6549 tree p = TREE_VALUE (proto_list);
6551 check_protocol (p, type, name);
6555 /* Make sure that the class CLASS_NAME is defined
6556 CODE says which kind of thing CLASS_NAME ought to be.
6557 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6558 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6561 start_class (enum tree_code code, tree class_name, tree super_name,
6567 if (current_namespace != global_namespace) {
6568 error ("Objective-C declarations may only appear in global scope");
6570 #endif /* OBJCPLUS */
6572 if (objc_implementation_context)
6574 warning ("`@end' missing in implementation context");
6575 finish_class (objc_implementation_context);
6576 objc_ivar_chain = NULL_TREE;
6577 objc_implementation_context = NULL_TREE;
6580 class = make_node (code);
6581 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6583 /* Check for existence of the super class, if one was specified. */
6584 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
6585 && super_name && !objc_is_class_name (super_name))
6587 error ("cannot find interface declaration for `%s', superclass of `%s'",
6588 IDENTIFIER_POINTER (super_name),
6589 IDENTIFIER_POINTER (class_name));
6590 super_name = NULL_TREE;
6593 CLASS_NAME (class) = class_name;
6594 CLASS_SUPER_NAME (class) = super_name;
6595 CLASS_CLS_METHODS (class) = NULL_TREE;
6597 if (! objc_is_class_name (class_name)
6598 && (decl = lookup_name (class_name)))
6600 error ("`%s' redeclared as different kind of symbol",
6601 IDENTIFIER_POINTER (class_name));
6602 error ("%Jprevious declaration of '%D'",
6606 if (code == CLASS_IMPLEMENTATION_TYPE)
6611 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6612 if (TREE_VALUE (chain) == class_name)
6614 error ("reimplementation of class `%s'",
6615 IDENTIFIER_POINTER (class_name));
6616 return error_mark_node;
6618 implemented_classes = tree_cons (NULL_TREE, class_name,
6619 implemented_classes);
6622 /* Reset for multiple classes per file. */
6625 objc_implementation_context = class;
6627 /* Lookup the interface for this implementation. */
6629 if (!(implementation_template = lookup_interface (class_name)))
6631 warning ("cannot find interface declaration for `%s'",
6632 IDENTIFIER_POINTER (class_name));
6633 add_class (implementation_template = objc_implementation_context);
6636 /* If a super class has been specified in the implementation,
6637 insure it conforms to the one specified in the interface. */
6640 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6642 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6643 const char *const name =
6644 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6645 error ("conflicting super class name `%s'",
6646 IDENTIFIER_POINTER (super_name));
6647 error ("previous declaration of `%s'", name);
6650 else if (! super_name)
6652 CLASS_SUPER_NAME (objc_implementation_context)
6653 = CLASS_SUPER_NAME (implementation_template);
6657 else if (code == CLASS_INTERFACE_TYPE)
6659 if (lookup_interface (class_name))
6661 error ("duplicate interface declaration for class `%s'",
6663 warning ("duplicate interface declaration for class `%s'",
6665 IDENTIFIER_POINTER (class_name));
6670 CLASS_PROTOCOL_LIST (class)
6671 = lookup_and_install_protocols (protocol_list);
6674 else if (code == CATEGORY_INTERFACE_TYPE)
6676 tree class_category_is_assoc_with;
6678 /* For a category, class_name is really the name of the class that
6679 the following set of methods will be associated with. We must
6680 find the interface so that can derive the objects template. */
6682 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6684 error ("cannot find interface declaration for `%s'",
6685 IDENTIFIER_POINTER (class_name));
6686 exit (FATAL_EXIT_CODE);
6689 add_category (class_category_is_assoc_with, class);
6692 CLASS_PROTOCOL_LIST (class)
6693 = lookup_and_install_protocols (protocol_list);
6696 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6698 /* Reset for multiple classes per file. */
6701 objc_implementation_context = class;
6703 /* For a category, class_name is really the name of the class that
6704 the following set of methods will be associated with. We must
6705 find the interface so that can derive the objects template. */
6707 if (!(implementation_template = lookup_interface (class_name)))
6709 error ("cannot find interface declaration for `%s'",
6710 IDENTIFIER_POINTER (class_name));
6711 exit (FATAL_EXIT_CODE);
6718 continue_class (tree class)
6720 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6721 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6723 struct imp_entry *imp_entry;
6726 /* Check consistency of the instance variables. */
6728 if (CLASS_RAW_IVARS (class))
6729 check_ivars (implementation_template, class);
6731 /* code generation */
6734 push_lang_context (lang_name_c);
6737 ivar_context = build_private_template (implementation_template);
6739 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6741 imp_entry->next = imp_list;
6742 imp_entry->imp_context = class;
6743 imp_entry->imp_template = implementation_template;
6745 synth_forward_declarations ();
6746 imp_entry->class_decl = UOBJC_CLASS_decl;
6747 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6749 /* Append to front and increment count. */
6750 imp_list = imp_entry;
6751 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6757 pop_lang_context ();
6758 #endif /* OBJCPLUS */
6760 return ivar_context;
6763 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6766 push_lang_context (lang_name_c);
6767 #endif /* OBJCPLUS */
6769 if (!CLASS_STATIC_TEMPLATE (class))
6771 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6772 finish_struct (record, get_class_ivars (class), NULL_TREE);
6773 CLASS_STATIC_TEMPLATE (class) = record;
6775 /* Mark this record as a class template for static typing. */
6776 TREE_STATIC_TEMPLATE (record) = 1;
6780 pop_lang_context ();
6781 #endif /* OBJCPLUS */
6787 return error_mark_node;
6790 /* This is called once we see the "@end" in an interface/implementation. */
6793 finish_class (tree class)
6795 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6797 /* All code generation is done in finish_objc. */
6799 if (implementation_template != objc_implementation_context)
6801 /* Ensure that all method listed in the interface contain bodies. */
6802 check_methods (CLASS_CLS_METHODS (implementation_template),
6803 CLASS_CLS_METHODS (objc_implementation_context), '+');
6804 check_methods (CLASS_NST_METHODS (implementation_template),
6805 CLASS_NST_METHODS (objc_implementation_context), '-');
6807 if (CLASS_PROTOCOL_LIST (implementation_template))
6808 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6810 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6814 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6816 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6820 /* Ensure all method listed in the interface contain bodies. */
6821 check_methods (CLASS_CLS_METHODS (category),
6822 CLASS_CLS_METHODS (objc_implementation_context), '+');
6823 check_methods (CLASS_NST_METHODS (category),
6824 CLASS_NST_METHODS (objc_implementation_context), '-');
6826 if (CLASS_PROTOCOL_LIST (category))
6827 check_protocols (CLASS_PROTOCOL_LIST (category),
6829 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6833 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6836 const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
6837 char *string = (char *) alloca (strlen (class_name) + 3);
6839 /* extern struct objc_object *_<my_name>; */
6841 sprintf (string, "_%s", class_name);
6843 decl = build_decl (VAR_DECL, get_identifier (string),
6844 build_pointer_type (objc_object_reference));
6845 DECL_EXTERNAL (decl) = 1;
6846 lang_hooks.decls.pushdecl (decl);
6847 finish_decl (decl, NULL_TREE, NULL_TREE);
6852 add_protocol (tree protocol)
6854 /* Put protocol on list in reverse order. */
6855 TREE_CHAIN (protocol) = protocol_chain;
6856 protocol_chain = protocol;
6857 return protocol_chain;
6861 lookup_protocol (tree ident)
6865 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6866 if (ident == PROTOCOL_NAME (chain))
6872 /* This function forward declares the protocols named by NAMES. If
6873 they are already declared or defined, the function has no effect. */
6876 objc_declare_protocols (tree names)
6881 if (current_namespace != global_namespace) {
6882 error ("Objective-C declarations may only appear in global scope");
6884 #endif /* OBJCPLUS */
6886 for (list = names; list; list = TREE_CHAIN (list))
6888 tree name = TREE_VALUE (list);
6890 if (lookup_protocol (name) == NULL_TREE)
6892 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6894 TYPE_LANG_SLOT_1 (protocol)
6895 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6896 PROTOCOL_NAME (protocol) = name;
6897 PROTOCOL_LIST (protocol) = NULL_TREE;
6898 add_protocol (protocol);
6899 PROTOCOL_DEFINED (protocol) = 0;
6900 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6906 start_protocol (enum tree_code code, tree name, tree list)
6911 if (current_namespace != global_namespace) {
6912 error ("Objective-C declarations may only appear in global scope");
6914 #endif /* OBJCPLUS */
6916 protocol = lookup_protocol (name);
6920 protocol = make_node (code);
6921 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6923 PROTOCOL_NAME (protocol) = name;
6924 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6925 add_protocol (protocol);
6926 PROTOCOL_DEFINED (protocol) = 1;
6927 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6929 check_protocol_recursively (protocol, list);
6931 else if (! PROTOCOL_DEFINED (protocol))
6933 PROTOCOL_DEFINED (protocol) = 1;
6934 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6936 check_protocol_recursively (protocol, list);
6940 warning ("duplicate declaration for protocol `%s'",
6941 IDENTIFIER_POINTER (name));
6947 /* "Encode" a data type into a string, which grows in util_obstack.
6948 ??? What is the FORMAT? Someone please document this! */
6951 encode_type_qualifiers (tree declspecs)
6955 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6957 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6958 obstack_1grow (&util_obstack, 'n');
6959 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6960 obstack_1grow (&util_obstack, 'N');
6961 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6962 obstack_1grow (&util_obstack, 'o');
6963 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
6964 obstack_1grow (&util_obstack, 'O');
6965 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
6966 obstack_1grow (&util_obstack, 'R');
6967 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
6968 obstack_1grow (&util_obstack, 'V');
6972 /* Encode a pointer type. */
6975 encode_pointer (tree type, int curtype, int format)
6977 tree pointer_to = TREE_TYPE (type);
6979 if (TREE_CODE (pointer_to) == RECORD_TYPE)
6981 if (OBJC_TYPE_NAME (pointer_to)
6982 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
6984 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
6986 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
6988 obstack_1grow (&util_obstack, '@');
6991 else if (TREE_STATIC_TEMPLATE (pointer_to))
6993 if (generating_instance_variables)
6995 obstack_1grow (&util_obstack, '@');
6996 obstack_1grow (&util_obstack, '"');
6997 obstack_grow (&util_obstack, name, strlen (name));
6998 obstack_1grow (&util_obstack, '"');
7003 obstack_1grow (&util_obstack, '@');
7007 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7009 obstack_1grow (&util_obstack, '#');
7012 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7014 obstack_1grow (&util_obstack, ':');
7019 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7020 && TYPE_MODE (pointer_to) == QImode)
7022 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7023 ? OBJC_TYPE_NAME (pointer_to)
7024 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7026 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7028 /* It appears that "r*" means "const char *" rather than
7030 if (TYPE_READONLY (pointer_to))
7031 obstack_1grow (&util_obstack, 'r');
7033 obstack_1grow (&util_obstack, '*');
7038 /* We have a type that does not get special treatment. */
7040 /* NeXT extension */
7041 obstack_1grow (&util_obstack, '^');
7042 encode_type (pointer_to, curtype, format);
7046 encode_array (tree type, int curtype, int format)
7048 tree an_int_cst = TYPE_SIZE (type);
7049 tree array_of = TREE_TYPE (type);
7052 /* An incomplete array is treated like a pointer. */
7053 if (an_int_cst == NULL)
7055 encode_pointer (type, curtype, format);
7059 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7060 (TREE_INT_CST_LOW (an_int_cst)
7061 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7063 obstack_grow (&util_obstack, buffer, strlen (buffer));
7064 encode_type (array_of, curtype, format);
7065 obstack_1grow (&util_obstack, ']');
7070 encode_aggregate_within (tree type, int curtype, int format, int left,
7074 /* NB: aggregates that are pointed to have slightly different encoding
7075 rules in that you never encode the names of instance variables. */
7077 = (obstack_object_size (&util_obstack) > 0
7078 && *(obstack_next_free (&util_obstack) - 1) == '^');
7080 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7081 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7083 /* Traverse struct aliases; it is important to get the
7084 original struct and its tag name (if any). */
7085 type = TYPE_MAIN_VARIANT (type);
7086 name = OBJC_TYPE_NAME (type);
7087 /* Open parenth/bracket. */
7088 obstack_1grow (&util_obstack, left);
7090 /* Encode the struct/union tag name, or '?' if a tag was
7091 not provided. Typedef aliases do not qualify. */
7092 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7094 /* Did this struct have a tag? */
7095 && !TYPE_WAS_ANONYMOUS (type)
7098 obstack_grow (&util_obstack,
7099 IDENTIFIER_POINTER (name),
7100 strlen (IDENTIFIER_POINTER (name)));
7102 obstack_1grow (&util_obstack, '?');
7104 /* Encode the types (and possibly names) of the inner fields,
7106 if (inline_contents)
7108 tree fields = TYPE_FIELDS (type);
7110 obstack_1grow (&util_obstack, '=');
7111 for (; fields; fields = TREE_CHAIN (fields))
7114 /* C++ static members, and things that are not fields at all,
7115 should not appear in the encoding. */
7116 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7119 if (generating_instance_variables && !pointed_to)
7121 tree fname = DECL_NAME (fields);
7123 obstack_1grow (&util_obstack, '"');
7124 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7125 obstack_grow (&util_obstack,
7126 IDENTIFIER_POINTER (fname),
7127 strlen (IDENTIFIER_POINTER (fname)));
7128 obstack_1grow (&util_obstack, '"');
7130 encode_field_decl (fields, curtype, format);
7133 /* Close parenth/bracket. */
7134 obstack_1grow (&util_obstack, right);
7138 encode_aggregate (tree type, int curtype, int format)
7140 enum tree_code code = TREE_CODE (type);
7146 encode_aggregate_within (type, curtype, format, '{', '}');
7151 encode_aggregate_within (type, curtype, format, '(', ')');
7156 obstack_1grow (&util_obstack, 'i');
7164 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7168 encode_next_bitfield (int width)
7171 sprintf (buffer, "b%d", width);
7172 obstack_grow (&util_obstack, buffer, strlen (buffer));
7175 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7177 encode_type (tree type, int curtype, int format)
7179 enum tree_code code = TREE_CODE (type);
7182 if (TYPE_READONLY (type))
7183 obstack_1grow (&util_obstack, 'r');
7185 if (code == INTEGER_TYPE)
7187 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7189 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7190 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7192 if (type == long_unsigned_type_node
7193 || type == long_integer_type_node)
7194 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7196 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7198 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7201 obstack_1grow (&util_obstack, c);
7204 else if (code == REAL_TYPE)
7206 /* Floating point types. */
7207 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7209 case 32: c = 'f'; break;
7211 case 128: c = 'd'; break;
7214 obstack_1grow (&util_obstack, c);
7217 else if (code == VOID_TYPE)
7218 obstack_1grow (&util_obstack, 'v');
7220 else if (code == BOOLEAN_TYPE)
7221 obstack_1grow (&util_obstack, 'B');
7223 else if (code == ARRAY_TYPE)
7224 encode_array (type, curtype, format);
7226 else if (code == POINTER_TYPE)
7227 encode_pointer (type, curtype, format);
7229 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7230 encode_aggregate (type, curtype, format);
7232 else if (code == FUNCTION_TYPE) /* '?' */
7233 obstack_1grow (&util_obstack, '?');
7237 encode_gnu_bitfield (int position, tree type, int size)
7239 enum tree_code code = TREE_CODE (type);
7241 char charType = '?';
7243 if (code == INTEGER_TYPE)
7245 if (integer_zerop (TYPE_MIN_VALUE (type)))
7247 /* Unsigned integer types. */
7249 if (TYPE_MODE (type) == QImode)
7251 else if (TYPE_MODE (type) == HImode)
7253 else if (TYPE_MODE (type) == SImode)
7255 if (type == long_unsigned_type_node)
7260 else if (TYPE_MODE (type) == DImode)
7265 /* Signed integer types. */
7267 if (TYPE_MODE (type) == QImode)
7269 else if (TYPE_MODE (type) == HImode)
7271 else if (TYPE_MODE (type) == SImode)
7273 if (type == long_integer_type_node)
7279 else if (TYPE_MODE (type) == DImode)
7283 else if (code == ENUMERAL_TYPE)
7288 sprintf (buffer, "b%d%c%d", position, charType, size);
7289 obstack_grow (&util_obstack, buffer, strlen (buffer));
7293 encode_field_decl (tree field_decl, int curtype, int format)
7298 /* C++ static members, and things that are not fields at all,
7299 should not appear in the encoding. */
7300 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7304 type = TREE_TYPE (field_decl);
7306 /* Generate the bitfield typing information, if needed. Note the difference
7307 between GNU and NeXT runtimes. */
7308 if (DECL_BIT_FIELD_TYPE (field_decl))
7310 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7312 if (flag_next_runtime)
7313 encode_next_bitfield (size);
7315 encode_gnu_bitfield (int_bit_position (field_decl),
7316 DECL_BIT_FIELD_TYPE (field_decl), size);
7319 encode_type (TREE_TYPE (field_decl), curtype, format);
7322 static GTY(()) tree objc_parmlist = NULL_TREE;
7324 /* Append PARM to a list of formal parameters of a method, making a necessary
7325 array-to-pointer adjustment along the way. */
7328 objc_push_parm (tree parm)
7330 /* Convert array parameters of unknown size into pointers. */
7331 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
7332 && !TYPE_SIZE (TREE_TYPE (parm)))
7333 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
7335 objc_parmlist = chainon (objc_parmlist, parm);
7338 /* Retrieve the formal paramter list constructed via preceding calls to
7339 objc_push_parm(). */
7343 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
7345 objc_get_parm_info (int have_ellipsis)
7348 tree parm_info = objc_parmlist;
7351 /* The C front-end requires an elaborate song and dance at
7354 declare_parm_level ();
7357 tree next = TREE_CHAIN (parm_info);
7359 TREE_CHAIN (parm_info) = NULL_TREE;
7360 pushdecl (parm_info);
7363 parm_info = get_parm_info (have_ellipsis);
7366 objc_parmlist = NULL_TREE;
7371 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7372 method definitions. In the case of instance methods, we can be more
7373 specific as to the type of 'self'. */
7376 synth_self_and_ucmd_args (void)
7380 if (objc_method_context
7381 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7382 self_type = objc_instance_type;
7384 /* Really a `struct objc_class *'. However, we allow people to
7385 assign to self, which changes its type midstream. */
7386 self_type = objc_object_type;
7389 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
7392 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
7395 /* Transform an Objective-C method definition into a static C function
7396 definition, synthesizing the first two arguments, "self" and "_cmd",
7400 start_method_def (tree method)
7403 int have_ellipsis = 0;
7405 /* Required to implement _msgSuper. */
7406 objc_method_context = method;
7407 UOBJC_SUPER_decl = NULL_TREE;
7409 /* Generate prototype declarations for arguments..."new-style". */
7410 synth_self_and_ucmd_args ();
7412 /* Generate argument declarations if a keyword_decl. */
7413 parmlist = METHOD_SEL_ARGS (method);
7416 tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
7417 TREE_VALUE (TREE_TYPE (parmlist)));
7419 objc_push_parm (parm);
7420 parmlist = TREE_CHAIN (parmlist);
7423 if (METHOD_ADD_ARGS (method))
7427 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
7428 akey; akey = TREE_CHAIN (akey))
7430 objc_push_parm (TREE_VALUE (akey));
7433 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
7437 parmlist = objc_get_parm_info (have_ellipsis);
7439 really_start_method (objc_method_context, parmlist);
7443 warn_with_method (const char *message, int mtype, tree method)
7445 /* Add a readable method name to the warning. */
7446 warning ("%J%s `%c%s'", method,
7447 message, mtype, gen_method_decl (method));
7450 /* Return 1 if TYPE1 is equivalent to TYPE2
7451 for purposes of method overloading. */
7454 objc_types_are_equivalent (tree type1, tree type2)
7459 /* Strip away indirections. */
7460 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
7461 && (TREE_CODE (type1) == TREE_CODE (type2)))
7462 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
7463 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7466 type1 = TYPE_PROTOCOL_LIST (type1);
7467 type2 = TYPE_PROTOCOL_LIST (type2);
7468 if (list_length (type1) == list_length (type2))
7470 for (; type2; type2 = TREE_CHAIN (type2))
7471 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7478 /* Return 1 if PROTO1 is equivalent to PROTO2
7479 for purposes of method overloading. */
7482 comp_proto_with_proto (tree proto1, tree proto2)
7486 /* The following test is needed in case there are hashing
7488 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7491 /* Compare return types. */
7492 type1 = TREE_VALUE (TREE_TYPE (proto1));
7493 type2 = TREE_VALUE (TREE_TYPE (proto2));
7495 if (!objc_types_are_equivalent (type1, type2))
7498 /* Compare argument types. */
7499 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7500 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7502 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7504 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7508 return (!type1 && !type2);
7512 objc_start_function (tree name, tree type, tree attrs, tree params)
7514 tree fndecl = build_decl (FUNCTION_DECL, name, type);
7516 DECL_ARGUMENTS (fndecl) = params;
7517 DECL_INITIAL (fndecl) = error_mark_node;
7518 DECL_EXTERNAL (fndecl) = 0;
7519 TREE_STATIC (fndecl) = 1;
7522 retrofit_lang_decl (fndecl);
7523 cplus_decl_attributes (&fndecl, attrs, 0);
7524 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
7526 decl_attributes (&fndecl, attrs, 0);
7527 announce_function (fndecl);
7528 current_function_decl = pushdecl (fndecl);
7530 declare_parm_level ();
7531 DECL_RESULT (current_function_decl)
7532 = build_decl (RESULT_DECL, NULL_TREE,
7533 TREE_TYPE (TREE_TYPE (current_function_decl)));
7534 start_fname_decls ();
7535 store_parm_decls_from (DECL_ARGUMENTS (current_function_decl));
7538 TREE_USED (current_function_decl) = 1;
7541 /* - Generate an identifier for the function. the format is "_n_cls",
7542 where 1 <= n <= nMethods, and cls is the name the implementation we
7544 - Install the return type from the method declaration.
7545 - If we have a prototype, check for type consistency. */
7548 really_start_method (tree method, tree parmlist)
7550 tree ret_type, meth_type;
7552 const char *sel_name, *class_name, *cat_name;
7555 /* Synth the storage class & assemble the return type. */
7556 ret_type = TREE_VALUE (TREE_TYPE (method));
7558 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7559 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7560 cat_name = ((TREE_CODE (objc_implementation_context)
7561 == CLASS_IMPLEMENTATION_TYPE)
7563 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7566 /* Make sure this is big enough for any plausible method label. */
7567 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7568 + (cat_name ? strlen (cat_name) : 0));
7570 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7571 class_name, cat_name, sel_name, method_slot);
7573 method_id = get_identifier (buf);
7576 /* Objective-C methods cannot be overloaded, so we don't need
7577 the type encoding appended. It looks bad anyway... */
7578 push_lang_context (lang_name_c);
7582 = build_function_type (ret_type,
7583 get_arg_type_list (method, METHOD_DEF, 0));
7584 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
7586 /* Set self_decl from the first argument. */
7587 self_decl = DECL_ARGUMENTS (current_function_decl);
7589 /* Suppress unused warnings. */
7590 TREE_USED (self_decl) = 1;
7591 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7593 pop_lang_context ();
7596 METHOD_DEFINITION (method) = current_function_decl;
7598 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7600 if (implementation_template != objc_implementation_context)
7603 = lookup_method_static (implementation_template,
7604 METHOD_SEL_NAME (method),
7605 TREE_CODE (method) == CLASS_METHOD_DECL);
7609 if (!comp_proto_with_proto (method, proto))
7611 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7613 warn_with_method ("conflicting types for", type, method);
7614 warn_with_method ("previous declaration of", type, proto);
7619 /* We have a method @implementation even though we did not
7620 see a corresponding @interface declaration (which is allowed
7621 by Objective-C rules). Go ahead and place the method in
7622 the @interface anyway, so that message dispatch lookups
7624 tree interface = implementation_template;
7626 if (TREE_CODE (objc_implementation_context)
7627 == CATEGORY_IMPLEMENTATION_TYPE)
7628 interface = lookup_category
7630 CLASS_SUPER_NAME (objc_implementation_context));
7633 objc_add_method (interface, copy_node (method),
7634 TREE_CODE (method) == CLASS_METHOD_DECL);
7639 static void *UOBJC_SUPER_scope = 0;
7641 /* _n_Method (id self, SEL sel, ...)
7643 struct objc_super _S;
7644 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7648 get_super_receiver (void)
7650 if (objc_method_context)
7652 tree super_expr, super_expr_list;
7654 if (!UOBJC_SUPER_decl)
7656 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
7657 objc_super_template);
7658 /* This prevents `unused variable' warnings when compiling with -Wall. */
7659 TREE_USED (UOBJC_SUPER_decl) = 1;
7660 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
7661 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7662 UOBJC_SUPER_scope = objc_get_current_scope ();
7665 /* Set receiver to self. */
7666 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7667 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7668 super_expr_list = super_expr;
7670 /* Set class to begin searching. */
7671 super_expr = build_component_ref (UOBJC_SUPER_decl,
7672 get_identifier ("super_class"));
7674 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7676 /* [_cls, __cls]Super are "pre-built" in
7677 synth_forward_declarations. */
7679 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7680 ((TREE_CODE (objc_method_context)
7681 == INSTANCE_METHOD_DECL)
7683 : uucls_super_ref));
7687 /* We have a category. */
7689 tree super_name = CLASS_SUPER_NAME (implementation_template);
7692 /* Barf if super used in a category of Object. */
7695 error ("no super class declared in interface for `%s'",
7696 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7697 return error_mark_node;
7700 if (flag_next_runtime && !flag_zero_link)
7702 super_class = objc_get_class_reference (super_name);
7703 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7704 /* If we are in a class method, we must retrieve the
7705 _metaclass_ for the current class, pointed at by
7706 the class's "isa" pointer. The following assumes that
7707 "isa" is the first ivar in a class (which it must be). */
7709 = build_indirect_ref
7710 (build_c_cast (build_pointer_type (objc_class_type),
7711 super_class), "unary *");
7715 add_class_reference (super_name);
7716 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7717 ? objc_get_class_decl : objc_get_meta_class_decl);
7718 assemble_external (super_class);
7720 = build_function_call
7724 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7725 IDENTIFIER_POINTER (super_name))));
7729 = build_modify_expr (super_expr, NOP_EXPR,
7730 build_c_cast (TREE_TYPE (super_expr),
7734 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7736 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7737 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7739 return super_expr_list;
7743 error ("[super ...] must appear in a method context");
7744 return error_mark_node;
7748 /* When exiting a scope, sever links to a 'super' declaration (if any)
7749 therein contained. */
7752 objc_clear_super_receiver (void)
7754 if (objc_method_context
7755 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
7756 UOBJC_SUPER_decl = 0;
7757 UOBJC_SUPER_scope = 0;
7762 objc_finish_method_definition (tree fndecl)
7764 /* We cannot validly inline ObjC methods, at least not without a language
7765 extension to declare that a method need not be dynamically
7766 dispatched, so suppress all thoughts of doing so. */
7767 DECL_INLINE (fndecl) = 0;
7768 DECL_UNINLINABLE (fndecl) = 1;
7771 /* The C++ front-end will have called finish_function() for us. */
7775 METHOD_ENCODING (objc_method_context)
7776 = encode_method_prototype (objc_method_context);
7778 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7779 since the optimizer may find "may be used before set" errors. */
7780 objc_method_context = NULL_TREE;
7785 lang_report_error_function (tree decl)
7787 if (objc_method_context)
7789 fprintf (stderr, "In method `%s'\n",
7790 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7799 /* Given a tree DECL node, produce a printable description of it in the given
7800 buffer, overwriting the buffer. */
7803 gen_declaration (tree decl)
7809 gen_type_name_0 (TREE_TYPE (decl));
7811 if (DECL_NAME (decl))
7813 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
7814 strcat (errbuf, " ");
7816 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
7819 if (DECL_INITIAL (decl)
7820 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
7821 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
7822 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
7828 /* Given a tree TYPE node, produce a printable description of it in the given
7829 buffer, overwriting the buffer. */
7832 gen_type_name_0 (tree type)
7834 tree orig = type, proto;
7836 if (TYPE_P (type) && TYPE_NAME (type))
7837 type = TYPE_NAME (type);
7838 else if (POINTER_TYPE_P (type))
7840 gen_type_name_0 (TREE_TYPE (type));
7842 if (!POINTER_TYPE_P (TREE_TYPE (type)))
7843 strcat (errbuf, " ");
7845 strcat (errbuf, "*");
7849 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
7850 type = DECL_NAME (type);
7852 strcat (errbuf, IDENTIFIER_POINTER (type));
7853 proto = TYPE_PROTOCOL_LIST (orig);
7857 strcat (errbuf, " <");
7861 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
7862 proto = TREE_CHAIN (proto);
7863 strcat (errbuf, proto ? ", " : ">");
7872 gen_type_name (tree type)
7876 return gen_type_name_0 (type);
7879 /* Given a method tree, put a printable description into the given
7880 buffer (overwriting) and return a pointer to the buffer. */
7883 gen_method_decl (tree method)
7887 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
7888 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
7889 strcat (errbuf, ")");
7890 chain = METHOD_SEL_ARGS (method);
7894 /* We have a chain of keyword_decls. */
7897 if (KEYWORD_KEY_NAME (chain))
7898 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7900 strcat (errbuf, ":(");
7901 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
7902 strcat (errbuf, ")");
7904 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7905 if ((chain = TREE_CHAIN (chain)))
7906 strcat (errbuf, " ");
7910 if (METHOD_ADD_ARGS (method))
7912 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
7914 /* Know we have a chain of parm_decls. */
7917 strcat (errbuf, ", ");
7918 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
7919 chain = TREE_CHAIN (chain);
7922 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
7923 strcat (errbuf, ", ...");
7928 /* We have a unary selector. */
7929 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
7937 /* Dump an @interface declaration of the supplied class CHAIN to the
7938 supplied file FP. Used to implement the -gen-decls option (which
7939 prints out an @interface declaration of all classes compiled in
7940 this run); potentially useful for debugging the compiler too. */
7942 dump_interface (FILE *fp, tree chain)
7944 /* FIXME: A heap overflow here whenever a method (or ivar)
7945 declaration is so long that it doesn't fit in the buffer. The
7946 code and all the related functions should be rewritten to avoid
7947 using fixed size buffers. */
7948 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
7949 tree ivar_decls = CLASS_RAW_IVARS (chain);
7950 tree nst_methods = CLASS_NST_METHODS (chain);
7951 tree cls_methods = CLASS_CLS_METHODS (chain);
7953 fprintf (fp, "\n@interface %s", my_name);
7955 /* CLASS_SUPER_NAME is used to store the superclass name for
7956 classes, and the category name for categories. */
7957 if (CLASS_SUPER_NAME (chain))
7959 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
7961 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
7962 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
7964 fprintf (fp, " (%s)\n", name);
7968 fprintf (fp, " : %s\n", name);
7974 /* FIXME - the following doesn't seem to work at the moment. */
7977 fprintf (fp, "{\n");
7980 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
7981 ivar_decls = TREE_CHAIN (ivar_decls);
7984 fprintf (fp, "}\n");
7989 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
7990 nst_methods = TREE_CHAIN (nst_methods);
7995 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
7996 cls_methods = TREE_CHAIN (cls_methods);
7999 fprintf (fp, "@end\n");
8002 /* Demangle function for Objective-C */
8004 objc_demangle (const char *mangled)
8006 char *demangled, *cp;
8008 if (mangled[0] == '_' &&
8009 (mangled[1] == 'i' || mangled[1] == 'c') &&
8012 cp = demangled = xmalloc(strlen(mangled) + 2);
8013 if (mangled[1] == 'i')
8014 *cp++ = '-'; /* for instance method */
8016 *cp++ = '+'; /* for class method */
8017 *cp++ = '['; /* opening left brace */
8018 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8019 while (*cp && *cp == '_')
8020 cp++; /* skip any initial underbars in class name */
8021 cp = strchr(cp, '_'); /* find first non-initial underbar */
8024 free(demangled); /* not mangled name */
8027 if (cp[1] == '_') /* easy case: no category name */
8029 *cp++ = ' '; /* replace two '_' with one ' ' */
8030 strcpy(cp, mangled + (cp - demangled) + 2);
8034 *cp++ = '('; /* less easy case: category name */
8035 cp = strchr(cp, '_');
8038 free(demangled); /* not mangled name */
8042 *cp++ = ' '; /* overwriting 1st char of method name... */
8043 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8045 while (*cp && *cp == '_')
8046 cp++; /* skip any initial underbars in method name */
8049 *cp = ':'; /* replace remaining '_' with ':' */
8050 *cp++ = ']'; /* closing right brace */
8051 *cp++ = 0; /* string terminator */
8055 return mangled; /* not an objc mangled name */
8059 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8061 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8067 gcc_obstack_init (&util_obstack);
8068 util_firstobj = (char *) obstack_finish (&util_obstack);
8070 errbuf = (char *) xmalloc (1024 * 10);
8072 synth_module_prologue ();
8078 struct imp_entry *impent;
8080 /* The internally generated initializers appear to have missing braces.
8081 Don't warn about this. */
8082 int save_warn_missing_braces = warn_missing_braces;
8083 warn_missing_braces = 0;
8085 /* A missing @end may not be detected by the parser. */
8086 if (objc_implementation_context)
8088 warning ("`@end' missing in implementation context");
8089 finish_class (objc_implementation_context);
8090 objc_ivar_chain = NULL_TREE;
8091 objc_implementation_context = NULL_TREE;
8094 /* Process the static instances here because initialization of objc_symtab
8096 if (objc_static_instances)
8097 generate_static_references ();
8099 if (imp_list || class_names_chain
8100 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8101 generate_objc_symtab_decl ();
8103 for (impent = imp_list; impent; impent = impent->next)
8105 objc_implementation_context = impent->imp_context;
8106 implementation_template = impent->imp_template;
8108 UOBJC_CLASS_decl = impent->class_decl;
8109 UOBJC_METACLASS_decl = impent->meta_decl;
8111 /* Dump the @interface of each class as we compile it, if the
8112 -gen-decls option is in use. TODO: Dump the classes in the
8113 order they were found, rather than in reverse order as we
8115 if (flag_gen_declaration)
8117 dump_interface (gen_declaration_file, objc_implementation_context);
8120 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8122 /* all of the following reference the string pool... */
8123 generate_ivar_lists ();
8124 generate_dispatch_tables ();
8125 generate_shared_structures ();
8129 generate_dispatch_tables ();
8130 generate_category (objc_implementation_context);
8134 /* If we are using an array of selectors, we must always
8135 finish up the array decl even if no selectors were used. */
8136 if (! flag_next_runtime || sel_ref_chain)
8137 build_selector_translation_table ();
8140 generate_protocols ();
8142 if (flag_replace_objc_classes && imp_list)
8143 generate_objc_image_info ();
8145 /* Arrange for ObjC data structures to be initialized at run time. */
8146 if (objc_implementation_context || class_names_chain || objc_static_instances
8147 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8149 build_module_descriptor ();
8151 if (!flag_next_runtime)
8152 build_module_initializer_routine ();
8155 /* Dump the class references. This forces the appropriate classes
8156 to be linked into the executable image, preserving unix archive
8157 semantics. This can be removed when we move to a more dynamically
8158 linked environment. */
8160 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8162 handle_class_ref (chain);
8163 if (TREE_PURPOSE (chain))
8164 generate_classref_translation_entry (chain);
8167 for (impent = imp_list; impent; impent = impent->next)
8168 handle_impent (impent);
8170 /* Dump the string table last. */
8172 generate_strings ();
8179 /* Run through the selector hash tables and print a warning for any
8180 selector which has multiple methods. */
8182 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8184 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8185 check_duplicates (hsh, 0, 1);
8186 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8187 check_duplicates (hsh, 0, 1);
8191 warn_missing_braces = save_warn_missing_braces;
8194 /* Subroutines of finish_objc. */
8197 generate_classref_translation_entry (tree chain)
8199 tree expr, decl, type;
8201 decl = TREE_PURPOSE (chain);
8202 type = TREE_TYPE (decl);
8204 expr = add_objc_string (TREE_VALUE (chain), class_names);
8205 expr = convert (type, expr); /* cast! */
8207 /* The decl that is the one that we
8208 forward declared in build_class_reference. */
8209 finish_var_decl (decl, expr);
8214 handle_class_ref (tree chain)
8216 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8217 char *string = (char *) alloca (strlen (name) + 30);
8221 sprintf (string, "%sobjc_class_name_%s",
8222 (flag_next_runtime ? "." : "__"), name);
8224 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8225 if (flag_next_runtime)
8227 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8232 /* Make a decl for this name, so we can use its address in a tree. */
8233 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8234 DECL_EXTERNAL (decl) = 1;
8235 TREE_PUBLIC (decl) = 1;
8238 rest_of_decl_compilation (decl, 0, 0);
8240 /* Make a decl for the address. */
8241 sprintf (string, "%sobjc_class_ref_%s",
8242 (flag_next_runtime ? "." : "__"), name);
8243 exp = build1 (ADDR_EXPR, string_type_node, decl);
8244 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8245 DECL_INITIAL (decl) = exp;
8246 TREE_STATIC (decl) = 1;
8247 TREE_USED (decl) = 1;
8250 rest_of_decl_compilation (decl, 0, 0);
8254 handle_impent (struct imp_entry *impent)
8258 objc_implementation_context = impent->imp_context;
8259 implementation_template = impent->imp_template;
8261 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8263 const char *const class_name =
8264 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8266 string = (char *) alloca (strlen (class_name) + 30);
8268 sprintf (string, "%sobjc_class_name_%s",
8269 (flag_next_runtime ? "." : "__"), class_name);
8271 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8273 const char *const class_name =
8274 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8275 const char *const class_super_name =
8276 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8278 string = (char *) alloca (strlen (class_name)
8279 + strlen (class_super_name) + 30);
8281 /* Do the same for categories. Even though no references to
8282 these symbols are generated automatically by the compiler, it
8283 gives you a handle to pull them into an archive by hand. */
8284 sprintf (string, "*%sobjc_category_name_%s_%s",
8285 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8290 #ifdef ASM_DECLARE_CLASS_REFERENCE
8291 if (flag_next_runtime)
8293 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8301 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
8302 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8303 TREE_PUBLIC (decl) = 1;
8304 TREE_READONLY (decl) = 1;
8305 TREE_USED (decl) = 1;
8306 TREE_CONSTANT (decl) = 1;
8307 DECL_CONTEXT (decl) = 0;
8308 DECL_ARTIFICIAL (decl) = 1;
8309 DECL_INITIAL (decl) = init;
8310 assemble_variable (decl, 1, 0, 0);
8314 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8315 later requires that ObjC translation units participating in F&C be
8316 specially marked. The following routine accomplishes this. */
8318 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8321 generate_objc_image_info (void)
8323 tree decl, initlist;
8325 decl = start_var_decl (build_array_type
8327 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
8328 "_OBJC_IMAGE_INFO");
8330 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
8331 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1), initlist);
8332 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
8334 finish_var_decl (decl, initlist);
8337 /* Look up ID as an instance variable. */
8340 objc_lookup_ivar (tree id)
8344 if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
8345 /* We have a message to super. */
8346 return get_super_receiver ();
8347 else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
8349 if (is_private (decl))
8352 return build_ivar_reference (id);
8358 #include "gt-objc-objc-act.h"