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, 2005 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"
60 #include "langhooks.h"
71 #include "diagnostic.h"
73 #include "tree-iterator.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc = 0;
82 /* When building Objective-C++, we are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
116 /* Set up for use of obstacks. */
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree objc_build_constructor (tree, tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static tree get_proto_encoding (tree);
150 static tree lookup_interface (tree);
151 static tree objc_add_static_instance (tree, tree);
153 static tree start_class (enum tree_code, tree, tree, tree);
154 static tree continue_class (tree);
155 static void finish_class (tree);
156 static void start_method_def (tree);
158 static void objc_start_function (tree, tree, tree, tree);
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
190 static void objc_generate_cxx_cdtors (void);
193 static const char *synth_id_with_class_suffix (const char *, tree);
195 /* Hash tables to manage the global pool of method prototypes. */
197 hash *nst_method_hash_list = 0;
198 hash *cls_method_hash_list = 0;
200 static hash hash_lookup (hash *, tree);
201 static tree lookup_method (tree, tree);
202 static tree lookup_method_static (tree, tree, int);
206 class_names, /* class, category, protocol, module names */
207 meth_var_names, /* method and variable names */
208 meth_var_types /* method and variable type descriptors */
211 static tree add_objc_string (tree, enum string_section);
212 static tree build_objc_string_decl (enum string_section);
213 static void build_selector_table_decl (void);
215 /* Protocol additions. */
217 static tree lookup_protocol (tree);
218 static tree lookup_and_install_protocols (tree);
222 static void encode_type_qualifiers (tree);
223 static void encode_type (tree, int, int);
224 static void encode_field_decl (tree, int, int);
227 static void really_start_method (tree, tree);
229 static void really_start_method (tree, struct c_arg_info *);
231 static int comp_proto_with_proto (tree, tree, int);
232 static void objc_push_parm (tree);
234 static tree objc_get_parm_info (int);
236 static struct c_arg_info *objc_get_parm_info (int);
239 /* Utilities for debugging and error diagnostics. */
241 static void warn_with_method (const char *, int, tree);
242 static char *gen_type_name (tree);
243 static char *gen_type_name_0 (tree);
244 static char *gen_method_decl (tree);
245 static char *gen_declaration (tree);
247 /* Everything else. */
249 static tree create_field_decl (tree, const char *);
250 static void add_class_reference (tree);
251 static void build_protocol_template (void);
252 static tree encode_method_prototype (tree);
253 static void generate_classref_translation_entry (tree);
254 static void handle_class_ref (tree);
255 static void generate_struct_by_value_array (void)
257 static void mark_referenced_methods (void);
258 static void generate_objc_image_info (void);
260 /*** Private Interface (data) ***/
262 /* Reserved tag definitions. */
264 #define OBJECT_TYPEDEF_NAME "id"
265 #define CLASS_TYPEDEF_NAME "Class"
267 #define TAG_OBJECT "objc_object"
268 #define TAG_CLASS "objc_class"
269 #define TAG_SUPER "objc_super"
270 #define TAG_SELECTOR "objc_selector"
272 #define UTAG_CLASS "_objc_class"
273 #define UTAG_IVAR "_objc_ivar"
274 #define UTAG_IVAR_LIST "_objc_ivar_list"
275 #define UTAG_METHOD "_objc_method"
276 #define UTAG_METHOD_LIST "_objc_method_list"
277 #define UTAG_CATEGORY "_objc_category"
278 #define UTAG_MODULE "_objc_module"
279 #define UTAG_SYMTAB "_objc_symtab"
280 #define UTAG_SUPER "_objc_super"
281 #define UTAG_SELECTOR "_objc_selector"
283 #define UTAG_PROTOCOL "_objc_protocol"
284 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
285 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
287 /* Note that the string object global name is only needed for the
289 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
291 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
293 static const char *TAG_GETCLASS;
294 static const char *TAG_GETMETACLASS;
295 static const char *TAG_MSGSEND;
296 static const char *TAG_MSGSENDSUPER;
297 /* The NeXT Objective-C messenger may have two extra entry points, for use
298 when returning a structure. */
299 static const char *TAG_MSGSEND_STRET;
300 static const char *TAG_MSGSENDSUPER_STRET;
301 static const char *default_constant_string_class_name;
303 /* Runtime metadata flags. */
304 #define CLS_FACTORY 0x0001L
305 #define CLS_META 0x0002L
306 #define CLS_HAS_CXX_STRUCTORS 0x2000L
308 #define OBJC_MODIFIER_STATIC 0x00000001
309 #define OBJC_MODIFIER_FINAL 0x00000002
310 #define OBJC_MODIFIER_PUBLIC 0x00000004
311 #define OBJC_MODIFIER_PRIVATE 0x00000008
312 #define OBJC_MODIFIER_PROTECTED 0x00000010
313 #define OBJC_MODIFIER_NATIVE 0x00000020
314 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
315 #define OBJC_MODIFIER_ABSTRACT 0x00000080
316 #define OBJC_MODIFIER_VOLATILE 0x00000100
317 #define OBJC_MODIFIER_TRANSIENT 0x00000200
318 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
320 /* NeXT-specific tags. */
322 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
323 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
324 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
325 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
326 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
327 #define TAG_EXCEPTIONMATCH "objc_exception_match"
328 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
329 #define TAG_SYNCENTER "objc_sync_enter"
330 #define TAG_SYNCEXIT "objc_sync_exit"
331 #define TAG_SETJMP "_setjmp"
332 #define UTAG_EXCDATA "_objc_exception_data"
334 #define TAG_ASSIGNIVAR "objc_assign_ivar"
335 #define TAG_ASSIGNGLOBAL "objc_assign_global"
336 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
338 /* Branch entry points. All that matters here are the addresses;
339 functions with these names do not really exist in libobjc. */
341 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
342 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
344 #define TAG_CXX_CONSTRUCT ".cxx_construct"
345 #define TAG_CXX_DESTRUCT ".cxx_destruct"
347 /* GNU-specific tags. */
349 #define TAG_EXECCLASS "__objc_exec_class"
350 #define TAG_GNUINIT "__objc_gnu_init"
352 /* Flags for lookup_method_static(). */
353 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
354 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
356 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
357 tree objc_global_trees[OCTI_MAX];
359 static void handle_impent (struct imp_entry *);
361 struct imp_entry *imp_list = 0;
362 int imp_count = 0; /* `@implementation' */
363 int cat_count = 0; /* `@category' */
365 enum tree_code objc_inherit_code;
366 int objc_public_flag;
368 /* Use to generate method labels. */
369 static int method_slot = 0;
373 static char *errbuf; /* Buffer for error diagnostics */
375 /* Data imported from tree.c. */
377 extern enum debug_info_type write_symbols;
379 /* Data imported from toplev.c. */
381 extern const char *dump_base_name;
383 static int flag_typed_selectors;
385 /* Store all constructed constant strings in a hash table so that
386 they get uniqued properly. */
388 struct string_descriptor GTY(())
390 /* The literal argument . */
393 /* The resulting constant string. */
397 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
400 struct volatilized_type GTY(())
405 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
407 FILE *gen_declaration_file;
409 /* Tells "encode_pointer/encode_aggregate" whether we are generating
410 type descriptors for instance variables (as opposed to methods).
411 Type descriptors for instance variables contain more information
412 than methods (for static typing and embedded structures). */
414 static int generating_instance_variables = 0;
416 /* Some platforms pass small structures through registers versus
417 through an invisible pointer. Determine at what size structure is
418 the transition point between the two possibilities. */
421 generate_struct_by_value_array (void)
424 tree field_decl, field_decl_chain;
426 int aggregate_in_mem[32];
429 /* Presumably no platform passes 32 byte structures in a register. */
430 for (i = 1; i < 32; i++)
434 /* Create an unnamed struct that has `i' character components */
435 type = start_struct (RECORD_TYPE, NULL_TREE);
437 strcpy (buffer, "c1");
438 field_decl = create_field_decl (char_type_node,
440 field_decl_chain = field_decl;
442 for (j = 1; j < i; j++)
444 sprintf (buffer, "c%d", j + 1);
445 field_decl = create_field_decl (char_type_node,
447 chainon (field_decl_chain, field_decl);
449 finish_struct (type, field_decl_chain, NULL_TREE);
451 aggregate_in_mem[i] = aggregate_value_p (type, 0);
452 if (!aggregate_in_mem[i])
456 /* We found some structures that are returned in registers instead of memory
457 so output the necessary data. */
460 for (i = 31; i >= 0; i--)
461 if (!aggregate_in_mem[i])
463 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
465 /* The first member of the structure is always 0 because we don't handle
466 structures with 0 members */
467 printf ("static int struct_forward_array[] = {\n 0");
469 for (j = 1; j <= i; j++)
470 printf (", %d", aggregate_in_mem[j]);
481 if (cxx_init () == false)
483 if (c_objc_common_init () == false)
487 #ifndef USE_MAPPED_LOCATION
488 /* Force the line number back to 0; check_newline will have
489 raised it to 1, which will make the builtin functions appear
490 not to be built in. */
494 /* If gen_declaration desired, open the output file. */
495 if (flag_gen_declaration)
497 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
498 gen_declaration_file = fopen (dumpname, "w");
499 if (gen_declaration_file == 0)
500 fatal_error ("can't open %s: %m", dumpname);
504 if (flag_next_runtime)
506 TAG_GETCLASS = "objc_getClass";
507 TAG_GETMETACLASS = "objc_getMetaClass";
508 TAG_MSGSEND = "objc_msgSend";
509 TAG_MSGSENDSUPER = "objc_msgSendSuper";
510 TAG_MSGSEND_STRET = "objc_msgSend_stret";
511 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
512 default_constant_string_class_name = "NSConstantString";
516 TAG_GETCLASS = "objc_get_class";
517 TAG_GETMETACLASS = "objc_get_meta_class";
518 TAG_MSGSEND = "objc_msg_lookup";
519 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
520 /* GNU runtime does not provide special functions to support
521 structure-returning methods. */
522 default_constant_string_class_name = "NXConstantString";
523 flag_typed_selectors = 1;
528 if (print_struct_values)
529 generate_struct_by_value_array ();
535 objc_finish_file (void)
537 mark_referenced_methods ();
540 /* We need to instantiate templates _before_ we emit ObjC metadata;
541 if we do not, some metadata (such as selectors) may go missing. */
543 instantiate_pending_templates (0);
546 /* Finalize Objective-C runtime data. No need to generate tables
547 and code if only checking syntax, or if generating a PCH file. */
548 if (!flag_syntax_only && !pch_file)
551 if (gen_declaration_file)
552 fclose (gen_declaration_file);
559 /* Return the first occurrence of a method declaration corresponding
560 to sel_name in rproto_list. Search rproto_list recursively.
561 If is_class is 0, search for instance methods, otherwise for class
564 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
570 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
572 p = TREE_VALUE (rproto);
574 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
576 if ((fnd = lookup_method (is_class
577 ? PROTOCOL_CLS_METHODS (p)
578 : PROTOCOL_NST_METHODS (p), sel_name)))
580 else if (PROTOCOL_LIST (p))
581 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
586 ; /* An identifier...if we could not find a protocol. */
597 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
601 /* Make sure the protocol is supported by the object on the rhs. */
602 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
605 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
607 p = TREE_VALUE (rproto);
609 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
614 else if (PROTOCOL_LIST (p))
615 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
624 ; /* An identifier...if we could not find a protocol. */
631 objc_start_class_interface (tree class, tree super_class, tree protos)
633 objc_interface_context
635 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
636 objc_public_flag = 0;
640 objc_start_category_interface (tree class, tree categ, tree protos)
642 objc_interface_context
643 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
645 = continue_class (objc_interface_context);
649 objc_start_protocol (tree name, tree protos)
651 objc_interface_context
652 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
656 objc_continue_interface (void)
659 = continue_class (objc_interface_context);
663 objc_finish_interface (void)
665 finish_class (objc_interface_context);
666 objc_interface_context = NULL_TREE;
670 objc_start_class_implementation (tree class, tree super_class)
672 objc_implementation_context
674 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
675 objc_public_flag = 0;
679 objc_start_category_implementation (tree class, tree categ)
681 objc_implementation_context
682 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
684 = continue_class (objc_implementation_context);
688 objc_continue_implementation (void)
691 = continue_class (objc_implementation_context);
695 objc_finish_implementation (void)
698 if (flag_objc_call_cxx_cdtors)
699 objc_generate_cxx_cdtors ();
702 if (objc_implementation_context)
704 finish_class (objc_implementation_context);
705 objc_ivar_chain = NULL_TREE;
706 objc_implementation_context = NULL_TREE;
709 warning (0, "%<@end%> must appear in an @implementation context");
713 objc_set_visibility (int visibility)
715 objc_public_flag = visibility;
719 objc_set_method_type (enum tree_code type)
721 objc_inherit_code = (type == PLUS_EXPR
723 : INSTANCE_METHOD_DECL);
727 objc_build_method_signature (tree rettype, tree selector,
728 tree optparms, bool ellipsis)
730 return build_method_decl (objc_inherit_code, rettype, selector,
735 objc_add_method_declaration (tree decl)
737 if (!objc_interface_context)
738 fatal_error ("method declaration not in @interface context");
740 objc_add_method (objc_interface_context,
742 objc_inherit_code == CLASS_METHOD_DECL);
746 objc_start_method_definition (tree decl)
748 if (!objc_implementation_context)
749 fatal_error ("method definition not in @implementation context");
751 objc_add_method (objc_implementation_context,
753 objc_inherit_code == CLASS_METHOD_DECL);
754 start_method_def (decl);
758 objc_add_instance_variable (tree decl)
760 (void) add_instance_variable (objc_ivar_context,
765 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
769 objc_is_reserved_word (tree ident)
771 unsigned char code = C_RID_CODE (ident);
773 return (OBJC_IS_AT_KEYWORD (code)
775 || code == RID_CLASS || code == RID_PUBLIC
776 || code == RID_PROTECTED || code == RID_PRIVATE
777 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
782 /* Return true if TYPE is 'id'. */
785 objc_is_object_id (tree type)
787 return OBJC_TYPE_NAME (type) == objc_object_id;
791 objc_is_class_id (tree type)
793 return OBJC_TYPE_NAME (type) == objc_class_id;
796 /* Construct a C struct with tag NAME, a base struct with tag
797 SUPER_NAME (if any), and FIELDS indicated. */
800 objc_build_struct (tree name, tree fields, tree super_name)
802 tree s = start_struct (RECORD_TYPE, name);
803 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
807 /* Prepend a packed variant of the base class into the layout. This
808 is necessary to preserve ObjC ABI compatibility. */
809 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
810 tree field = TYPE_FIELDS (super);
812 while (field && TREE_CHAIN (field)
813 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
814 field = TREE_CHAIN (field);
816 /* For ObjC ABI purposes, the "packed" size of a base class is
817 the the sum of the offset and the size (in bits) of the last
818 field in the class. */
820 = (field && TREE_CODE (field) == FIELD_DECL
821 ? size_binop (PLUS_EXPR,
822 size_binop (PLUS_EXPR,
825 convert (bitsizetype,
826 DECL_FIELD_OFFSET (field)),
827 bitsize_int (BITS_PER_UNIT)),
828 DECL_FIELD_BIT_OFFSET (field)),
830 : bitsize_zero_node);
831 DECL_SIZE_UNIT (base)
832 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
833 size_int (BITS_PER_UNIT));
834 DECL_ARTIFICIAL (base) = 1;
835 DECL_ALIGN (base) = 1;
836 DECL_FIELD_CONTEXT (base) = s;
838 DECL_FIELD_IS_BASE (base) = 1;
841 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
842 #endif /* are following the ObjC ABI here. */
843 TREE_CHAIN (base) = fields;
847 s = finish_struct (s, fields, NULL_TREE);
849 /* Use TYPE_BINFO structures to point at the super class, if any. */
850 objc_xref_basetypes (s, super);
855 /* Mark DECL as being 'volatile' for purposes of Darwin
856 _setjmp()/_longjmp() exception handling. Called from
857 objc_mark_locals_volatile(). */
859 objc_volatilize_decl (tree decl)
861 /* Do not mess with variables that are 'static' or (already)
863 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
864 && (TREE_CODE (decl) == VAR_DECL
865 || TREE_CODE (decl) == PARM_DECL))
867 tree t = TREE_TYPE (decl);
868 struct volatilized_type key;
871 t = build_qualified_type (t, (TYPE_QUALS (t)
872 | TYPE_QUAL_VOLATILE));
874 loc = htab_find_slot (volatilized_htab, &key, INSERT);
878 *loc = ggc_alloc (sizeof (key));
879 ((struct volatilized_type *) *loc)->type = t;
882 TREE_TYPE (decl) = t;
883 TREE_THIS_VOLATILE (decl) = 1;
884 TREE_SIDE_EFFECTS (decl) = 1;
885 DECL_REGISTER (decl) = 0;
887 C_DECL_REGISTER (decl) = 0;
892 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
893 (including its categoreis and superclasses) or by object type TYP.
894 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
897 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
899 bool class_type = (cls != NULL_TREE);
905 /* Check protocols adopted by the class and its categories. */
906 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
908 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
912 /* Repeat for superclasses. */
913 cls = lookup_interface (CLASS_SUPER_NAME (cls));
916 /* Check for any protocols attached directly to the object type. */
917 if (TYPE_HAS_OBJC_INFO (typ))
919 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
925 strcpy (errbuf, class_type ? "class \'" : "type \'");
926 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
927 strcat (errbuf, "\' does not ");
928 /* NB: Types 'id' and 'Class' cannot reasonably be described as
929 "implementing" a given protocol, since they do not have an
931 strcat (errbuf, class_type ? "implement" : "conform to");
932 strcat (errbuf, " the \'");
933 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
934 strcat (errbuf, "\' protocol");
941 /* Check if class RCLS and instance struct type RTYP conform to at least the
942 same protocols that LCLS and LTYP conform to. */
945 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
948 bool have_lproto = false;
952 /* NB: We do _not_ look at categories defined for LCLS; these may or
953 may not get loaded in, and therefore it is unreasonable to require
954 that RCLS/RTYP must implement any of their protocols. */
955 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
959 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
963 /* Repeat for superclasses. */
964 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
967 /* Check for any protocols attached directly to the object type. */
968 if (TYPE_HAS_OBJC_INFO (ltyp))
970 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
974 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
979 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
980 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
981 away with simply checking for 'id' or 'Class' (!RCLS), since this
982 routine will not get called in other cases. */
983 return have_lproto || (rcls != NULL_TREE);
986 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
987 an instance of RTYP to an instance of LTYP or to compare the two
988 (if ARGNO is equal to -3), per ObjC type system rules. Before
989 returning 'true', this routine may issue warnings related to, e.g.,
990 protocol conformance. When returning 'false', the routine must
991 produce absolutely no warnings; the C or C++ front-end will do so
992 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
993 the routine must return 'false'.
995 The ARGNO parameter is encoded as follows:
996 >= 1 Parameter number (CALLEE contains function being called);
1000 -3 Comparison (LTYP and RTYP may match in either direction). */
1003 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1005 tree lcls, rcls, lproto, rproto;
1006 bool pointers_compatible;
1008 /* We must be dealing with pointer types */
1009 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1014 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1015 rtyp = TREE_TYPE (rtyp);
1017 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1019 /* Past this point, we are only interested in ObjC class instances,
1020 or 'id' or 'Class'. */
1021 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1024 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1025 && !TYPE_HAS_OBJC_INFO (ltyp))
1028 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1029 && !TYPE_HAS_OBJC_INFO (rtyp))
1032 /* Past this point, we are committed to returning 'true' to the caller.
1033 However, we can still warn about type and/or protocol mismatches. */
1035 if (TYPE_HAS_OBJC_INFO (ltyp))
1037 lcls = TYPE_OBJC_INTERFACE (ltyp);
1038 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1041 lcls = lproto = NULL_TREE;
1043 if (TYPE_HAS_OBJC_INFO (rtyp))
1045 rcls = TYPE_OBJC_INTERFACE (rtyp);
1046 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1049 rcls = rproto = NULL_TREE;
1051 /* If either type is an unqualified 'id', we're done. */
1052 if ((!lproto && objc_is_object_id (ltyp))
1053 || (!rproto && objc_is_object_id (rtyp)))
1056 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1058 /* If the underlying types are the same, and at most one of them has
1059 a protocol list, we do not need to issue any diagnostics. */
1060 if (pointers_compatible && (!lproto || !rproto))
1063 /* If exactly one of the types is 'Class', issue a diagnostic; any
1064 exceptions of this rule have already been handled. */
1065 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1066 pointers_compatible = false;
1067 /* Otherwise, check for inheritance relations. */
1070 if (!pointers_compatible)
1072 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1074 if (!pointers_compatible)
1075 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1077 if (!pointers_compatible && argno == -3)
1078 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1081 /* If the pointers match modulo protocols, check for protocol conformance
1083 if (pointers_compatible)
1085 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1088 if (!pointers_compatible && argno == -3)
1089 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1093 if (!pointers_compatible)
1095 /* NB: For the time being, we shall make our warnings look like their
1096 C counterparts. In the future, we may wish to make them more
1101 warning (0, "comparison of distinct Objective-C types lacks a cast");
1105 warning (0, "initialization from distinct Objective-C type");
1109 warning (0, "assignment from distinct Objective-C type");
1113 warning (0, "distinct Objective-C type in return");
1117 warning (0, "passing argument %d of %qE from distinct "
1118 "Objective-C type", argno, callee);
1126 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1127 lives in the volatilized hash table, ignore the 'volatile' bit when
1128 making the comparison. */
1131 objc_type_quals_match (tree ltyp, tree rtyp)
1133 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1134 struct volatilized_type key;
1138 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1139 lquals &= ~TYPE_QUAL_VOLATILE;
1143 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1144 rquals &= ~TYPE_QUAL_VOLATILE;
1146 return (lquals == rquals);
1150 /* Determine if CHILD is derived from PARENT. The routine assumes that
1151 both parameters are RECORD_TYPEs, and is non-reflexive. */
1154 objc_derived_from_p (tree parent, tree child)
1156 parent = TYPE_MAIN_VARIANT (parent);
1158 for (child = TYPE_MAIN_VARIANT (child);
1159 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1161 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1162 (TYPE_BINFO (child),
1165 if (child == parent)
1174 objc_build_component_ref (tree datum, tree component)
1176 /* If COMPONENT is NULL, the caller is referring to the anonymous
1177 base class field. */
1180 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1182 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1185 /* The 'build_component_ref' routine has been removed from the C++
1186 front-end, but 'finish_class_member_access_expr' seems to be
1187 a worthy substitute. */
1189 return finish_class_member_access_expr (datum, component);
1191 return build_component_ref (datum, component);
1195 /* Recursively copy inheritance information rooted at BINFO. To do this,
1196 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1199 objc_copy_binfo (tree binfo)
1201 tree btype = BINFO_TYPE (binfo);
1202 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1206 BINFO_TYPE (binfo2) = btype;
1207 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1208 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1210 /* Recursively copy base binfos of BINFO. */
1211 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1213 tree base_binfo2 = objc_copy_binfo (base_binfo);
1215 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1216 BINFO_BASE_APPEND (binfo2, base_binfo2);
1222 /* Record superclass information provided in BASETYPE for ObjC class REF.
1223 This is loosely based on cp/decl.c:xref_basetypes(). */
1226 objc_xref_basetypes (tree ref, tree basetype)
1228 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1230 TYPE_BINFO (ref) = binfo;
1231 BINFO_OFFSET (binfo) = size_zero_node;
1232 BINFO_TYPE (binfo) = ref;
1236 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1238 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1239 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1240 BINFO_BASE_APPEND (binfo, base_binfo);
1241 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1246 volatilized_hash (const void *ptr)
1248 tree typ = ((struct volatilized_type *)ptr)->type;
1250 return (hashval_t) typ;
1254 volatilized_eq (const void *ptr1, const void *ptr2)
1256 tree typ1 = ((struct volatilized_type *)ptr1)->type;
1257 tree typ2 = ((struct volatilized_type *)ptr2)->type;
1259 return typ1 == typ2;
1262 /* Called from finish_decl. */
1265 objc_check_decl (tree decl)
1267 tree type = TREE_TYPE (decl);
1269 if (TREE_CODE (type) != RECORD_TYPE)
1271 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1272 error ("statically allocated instance of Objective-C class %qs",
1273 IDENTIFIER_POINTER (type));
1276 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1277 either name an Objective-C class, or refer to the special 'id' or 'Class'
1278 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1281 objc_get_protocol_qualified_type (tree interface, tree protocols)
1283 /* If INTERFACE is not provided, default to 'id'. */
1284 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1285 bool is_ptr = (type != NULL_TREE);
1289 type = objc_is_class_name (interface);
1292 type = xref_tag (RECORD_TYPE, type);
1299 type = build_variant_type_copy (type);
1301 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1305 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1306 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1307 type = TREE_TYPE (type);
1310 /* Look up protocols and install in lang specific list. */
1311 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1312 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1314 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1315 return the pointer to the new pointee variant. */
1317 type = TYPE_POINTER_TO (type);
1319 TYPE_OBJC_INTERFACE (type)
1320 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1326 /* Check for circular dependencies in protocols. The arguments are
1327 PROTO, the protocol to check, and LIST, a list of protocol it
1331 check_protocol_recursively (tree proto, tree list)
1335 for (p = list; p; p = TREE_CHAIN (p))
1337 tree pp = TREE_VALUE (p);
1339 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1340 pp = lookup_protocol (pp);
1343 fatal_error ("protocol %qs has circular dependency",
1344 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1346 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1350 /* Look up PROTOCOLS, and return a list of those that are found.
1351 If none are found, return NULL. */
1354 lookup_and_install_protocols (tree protocols)
1357 tree return_value = NULL_TREE;
1359 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1361 tree ident = TREE_VALUE (proto);
1362 tree p = lookup_protocol (ident);
1365 error ("cannot find protocol declaration for %qs",
1366 IDENTIFIER_POINTER (ident));
1368 return_value = chainon (return_value,
1369 build_tree_list (NULL_TREE, p));
1372 return return_value;
1375 /* Create a declaration for field NAME of a given TYPE. */
1378 create_field_decl (tree type, const char *name)
1380 return build_decl (FIELD_DECL, get_identifier (name), type);
1383 /* Create a global, static declaration for variable NAME of a given TYPE. The
1384 finish_var_decl() routine will need to be called on it afterwards. */
1387 start_var_decl (tree type, const char *name)
1389 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1391 TREE_STATIC (var) = 1;
1392 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1393 DECL_IGNORED_P (var) = 1;
1394 DECL_ARTIFICIAL (var) = 1;
1395 DECL_CONTEXT (var) = NULL_TREE;
1397 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1403 /* Finish off the variable declaration created by start_var_decl(). */
1406 finish_var_decl (tree var, tree initializer)
1408 finish_decl (var, initializer, NULL_TREE);
1409 /* Ensure that the variable actually gets output. */
1410 mark_decl_referenced (var);
1411 /* Mark the decl to avoid "defined but not used" warning. */
1412 TREE_USED (var) = 1;
1415 /* Find the decl for the constant string class reference. This is only
1416 used for the NeXT runtime. */
1419 setup_string_decl (void)
1424 /* %s in format will provide room for terminating null */
1425 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1426 + strlen (constant_string_class_name);
1427 name = xmalloc (length);
1428 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1429 constant_string_class_name);
1430 constant_string_global_id = get_identifier (name);
1431 string_class_decl = lookup_name (constant_string_global_id);
1433 return string_class_decl;
1436 /* Purpose: "play" parser, creating/installing representations
1437 of the declarations that are required by Objective-C.
1441 type_spec--------->sc_spec
1442 (tree_list) (tree_list)
1445 identifier_node identifier_node */
1448 synth_module_prologue (void)
1451 enum debug_info_type save_write_symbols = write_symbols;
1452 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1454 /* Suppress outputting debug symbols, because
1455 dbxout_init hasn'r been called yet. */
1456 write_symbols = NO_DEBUG;
1457 debug_hooks = &do_nothing_debug_hooks;
1460 push_lang_context (lang_name_c); /* extern "C" */
1463 /* The following are also defined in <objc/objc.h> and friends. */
1465 objc_object_id = get_identifier (TAG_OBJECT);
1466 objc_class_id = get_identifier (TAG_CLASS);
1468 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1469 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1471 objc_object_type = build_pointer_type (objc_object_reference);
1472 objc_class_type = build_pointer_type (objc_class_reference);
1474 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1475 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1477 /* Declare the 'id' and 'Class' typedefs. */
1479 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1482 DECL_IN_SYSTEM_HEADER (type) = 1;
1483 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1486 DECL_IN_SYSTEM_HEADER (type) = 1;
1488 /* Forward-declare '@interface Protocol'. */
1490 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1491 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1492 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1495 /* Declare type of selector-objects that represent an operation name. */
1497 if (flag_next_runtime)
1498 /* `struct objc_selector *' */
1500 = build_pointer_type (xref_tag (RECORD_TYPE,
1501 get_identifier (TAG_SELECTOR)));
1503 /* `const struct objc_selector *' */
1505 = build_pointer_type
1506 (build_qualified_type (xref_tag (RECORD_TYPE,
1507 get_identifier (TAG_SELECTOR)),
1510 /* Declare receiver type used for dispatching messages to 'super'. */
1512 /* `struct objc_super *' */
1513 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1514 get_identifier (TAG_SUPER)));
1516 /* Declare pointers to method and ivar lists. */
1517 objc_method_list_ptr = build_pointer_type
1518 (xref_tag (RECORD_TYPE,
1519 get_identifier (UTAG_METHOD_LIST)));
1520 objc_method_proto_list_ptr
1521 = build_pointer_type (xref_tag (RECORD_TYPE,
1522 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1523 objc_ivar_list_ptr = build_pointer_type
1524 (xref_tag (RECORD_TYPE,
1525 get_identifier (UTAG_IVAR_LIST)));
1527 if (flag_next_runtime)
1529 /* NB: In order to call one of the ..._stret (struct-returning)
1530 functions, the function *MUST* first be cast to a signature that
1531 corresponds to the actual ObjC method being invoked. This is
1532 what is done by the build_objc_method_call() routine below. */
1534 /* id objc_msgSend (id, SEL, ...); */
1535 /* id objc_msgSendNonNil (id, SEL, ...); */
1536 /* id objc_msgSend_stret (id, SEL, ...); */
1537 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1539 = build_function_type (objc_object_type,
1540 tree_cons (NULL_TREE, objc_object_type,
1541 tree_cons (NULL_TREE, objc_selector_type,
1543 umsg_decl = builtin_function (TAG_MSGSEND,
1544 type, 0, NOT_BUILT_IN,
1546 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1547 type, 0, NOT_BUILT_IN,
1549 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1550 type, 0, NOT_BUILT_IN,
1552 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1553 type, 0, NOT_BUILT_IN,
1556 /* id objc_msgSend_Fast (id, SEL, ...)
1557 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1558 #ifdef OFFS_MSGSEND_FAST
1559 umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
1560 type, 0, NOT_BUILT_IN,
1562 DECL_ATTRIBUTES (umsg_fast_decl)
1563 = tree_cons (get_identifier ("hard_coded_address"),
1564 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1567 /* No direct dispatch availible. */
1568 umsg_fast_decl = umsg_decl;
1571 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1572 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1574 = build_function_type (objc_object_type,
1575 tree_cons (NULL_TREE, objc_super_type,
1576 tree_cons (NULL_TREE, objc_selector_type,
1578 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1579 type, 0, NOT_BUILT_IN,
1581 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1582 type, 0, NOT_BUILT_IN, 0,
1587 /* GNU runtime messenger entry points. */
1589 /* typedef id (*IMP)(id, SEL, ...); */
1591 = build_pointer_type
1592 (build_function_type (objc_object_type,
1593 tree_cons (NULL_TREE, objc_object_type,
1594 tree_cons (NULL_TREE, objc_selector_type,
1597 /* IMP objc_msg_lookup (id, SEL); */
1599 = build_function_type (IMP_type,
1600 tree_cons (NULL_TREE, objc_object_type,
1601 tree_cons (NULL_TREE, objc_selector_type,
1602 OBJC_VOID_AT_END)));
1603 umsg_decl = builtin_function (TAG_MSGSEND,
1604 type, 0, NOT_BUILT_IN,
1607 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1609 = build_function_type (IMP_type,
1610 tree_cons (NULL_TREE, objc_super_type,
1611 tree_cons (NULL_TREE, objc_selector_type,
1612 OBJC_VOID_AT_END)));
1613 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1614 type, 0, NOT_BUILT_IN,
1617 /* The following GNU runtime entry point is called to initialize
1620 __objc_exec_class (void *); */
1622 = build_function_type (void_type_node,
1623 tree_cons (NULL_TREE, ptr_type_node,
1625 execclass_decl = builtin_function (TAG_EXECCLASS,
1626 type, 0, NOT_BUILT_IN,
1630 /* id objc_getClass (const char *); */
1632 type = build_function_type (objc_object_type,
1633 tree_cons (NULL_TREE,
1634 const_string_type_node,
1638 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1641 /* id objc_getMetaClass (const char *); */
1643 objc_get_meta_class_decl
1644 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1646 build_class_template ();
1647 build_super_template ();
1648 build_protocol_template ();
1649 build_category_template ();
1650 build_objc_exception_stuff ();
1652 if (flag_next_runtime)
1653 build_next_objc_exception_stuff ();
1655 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1657 if (! flag_next_runtime)
1658 build_selector_table_decl ();
1660 /* Forward declare constant_string_id and constant_string_type. */
1661 if (!constant_string_class_name)
1662 constant_string_class_name = default_constant_string_class_name;
1664 constant_string_id = get_identifier (constant_string_class_name);
1665 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1667 /* Pre-build the following entities - for speed/convenience. */
1668 self_id = get_identifier ("self");
1669 ucmd_id = get_identifier ("_cmd");
1672 pop_lang_context ();
1675 write_symbols = save_write_symbols;
1676 debug_hooks = save_hooks;
1679 /* Ensure that the ivar list for NSConstantString/NXConstantString
1680 (or whatever was specified via `-fconstant-string-class')
1681 contains fields at least as large as the following three, so that
1682 the runtime can stomp on them with confidence:
1684 struct STRING_OBJECT_CLASS_NAME
1688 unsigned int length;
1692 check_string_class_template (void)
1694 tree field_decl = TYPE_FIELDS (constant_string_type);
1696 #define AT_LEAST_AS_LARGE_AS(F, T) \
1697 (F && TREE_CODE (F) == FIELD_DECL \
1698 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1699 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1701 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1704 field_decl = TREE_CHAIN (field_decl);
1705 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1708 field_decl = TREE_CHAIN (field_decl);
1709 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1711 #undef AT_LEAST_AS_LARGE_AS
1714 /* Avoid calling `check_string_class_template ()' more than once. */
1715 static GTY(()) int string_layout_checked;
1717 /* Custom build_string which sets TREE_TYPE! */
1720 my_build_string (int len, const char *str)
1722 return fix_string_type (build_string (len, str));
1727 string_hash (const void *ptr)
1729 tree str = ((struct string_descriptor *)ptr)->literal;
1730 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1731 int i, len = TREE_STRING_LENGTH (str);
1734 for (i = 0; i < len; i++)
1735 h = ((h * 613) + p[i]);
1741 string_eq (const void *ptr1, const void *ptr2)
1743 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1744 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1745 int len1 = TREE_STRING_LENGTH (str1);
1747 return (len1 == TREE_STRING_LENGTH (str2)
1748 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1752 /* Given a chain of STRING_CST's, build a static instance of
1753 NXConstantString which points at the concatenation of those
1754 strings. We place the string object in the __string_objects
1755 section of the __OBJC segment. The Objective-C runtime will
1756 initialize the isa pointers of the string objects to point at the
1757 NXConstantString class object. */
1760 objc_build_string_object (tree string)
1762 tree initlist, constructor, constant_string_class;
1765 struct string_descriptor *desc, key;
1768 /* Prep the string argument. */
1769 string = fix_string_type (string);
1770 TREE_SET_CODE (string, STRING_CST);
1771 length = TREE_STRING_LENGTH (string) - 1;
1773 /* Check whether the string class being used actually exists and has the
1774 correct ivar layout. */
1775 if (!string_layout_checked)
1777 string_layout_checked = -1;
1778 constant_string_class = lookup_interface (constant_string_id);
1780 if (!constant_string_class
1781 || !(constant_string_type
1782 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1783 error ("cannot find interface declaration for %qs",
1784 IDENTIFIER_POINTER (constant_string_id));
1785 /* The NSConstantString/NXConstantString ivar layout is now known. */
1786 else if (!check_string_class_template ())
1787 error ("interface %qs does not have valid constant string layout",
1788 IDENTIFIER_POINTER (constant_string_id));
1789 /* For the NeXT runtime, we can generate a literal reference
1790 to the string class, don't need to run a constructor. */
1791 else if (flag_next_runtime && !setup_string_decl ())
1792 error ("cannot find reference tag for class %qs",
1793 IDENTIFIER_POINTER (constant_string_id));
1796 string_layout_checked = 1; /* Success! */
1797 add_class_reference (constant_string_id);
1801 if (string_layout_checked == -1)
1802 return error_mark_node;
1804 /* Perhaps we already constructed a constant string just like this one? */
1805 key.literal = string;
1806 loc = htab_find_slot (string_htab, &key, INSERT);
1812 *loc = desc = ggc_alloc (sizeof (*desc));
1813 desc->literal = string;
1815 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1816 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1817 fields = TYPE_FIELDS (constant_string_type);
1819 = build_tree_list (fields,
1821 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1822 : build_int_cst (NULL_TREE, 0));
1823 fields = TREE_CHAIN (fields);
1824 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1826 fields = TREE_CHAIN (fields);
1827 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1829 constructor = objc_build_constructor (constant_string_type,
1830 nreverse (initlist));
1831 TREE_INVARIANT (constructor) = true;
1833 if (!flag_next_runtime)
1835 = objc_add_static_instance (constructor, constant_string_type);
1838 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1839 DECL_INITIAL (var) = constructor;
1840 TREE_STATIC (var) = 1;
1841 pushdecl_top_level (var);
1844 desc->constructor = constructor;
1847 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1852 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1854 static GTY(()) int num_static_inst;
1857 objc_add_static_instance (tree constructor, tree class_decl)
1862 /* Find the list of static instances for the CLASS_DECL. Create one if
1864 for (chain = &objc_static_instances;
1865 *chain && TREE_VALUE (*chain) != class_decl;
1866 chain = &TREE_CHAIN (*chain));
1869 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1870 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1873 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1874 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1875 DECL_COMMON (decl) = 1;
1876 TREE_STATIC (decl) = 1;
1877 DECL_ARTIFICIAL (decl) = 1;
1878 DECL_INITIAL (decl) = constructor;
1880 /* We may be writing something else just now.
1881 Postpone till end of input. */
1882 DECL_DEFER_OUTPUT (decl) = 1;
1883 pushdecl_top_level (decl);
1884 rest_of_decl_compilation (decl, 1, 0);
1886 /* Add the DECL to the head of this CLASS' list. */
1887 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1892 /* Build a static constant CONSTRUCTOR
1893 with type TYPE and elements ELTS. */
1896 objc_build_constructor (tree type, tree elts)
1898 tree constructor = build_constructor (type, elts);
1900 TREE_CONSTANT (constructor) = 1;
1901 TREE_STATIC (constructor) = 1;
1902 TREE_READONLY (constructor) = 1;
1905 /* Adjust for impedance mismatch. We should figure out how to build
1906 CONSTRUCTORs that consistently please both the C and C++ gods. */
1907 if (!TREE_PURPOSE (elts))
1908 TREE_TYPE (constructor) = NULL_TREE;
1909 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1915 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1917 /* Predefine the following data type:
1925 void *defs[cls_def_cnt + cat_def_cnt];
1929 build_objc_symtab_template (void)
1931 tree field_decl, field_decl_chain;
1933 objc_symtab_template
1934 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1936 /* long sel_ref_cnt; */
1937 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1938 field_decl_chain = field_decl;
1941 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1943 chainon (field_decl_chain, field_decl);
1945 /* short cls_def_cnt; */
1946 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1947 chainon (field_decl_chain, field_decl);
1949 /* short cat_def_cnt; */
1950 field_decl = create_field_decl (short_integer_type_node,
1952 chainon (field_decl_chain, field_decl);
1954 if (imp_count || cat_count || !flag_next_runtime)
1956 /* void *defs[imp_count + cat_count (+ 1)]; */
1957 /* NB: The index is one less than the size of the array. */
1958 int index = imp_count + cat_count
1959 + (flag_next_runtime? -1: 0);
1960 field_decl = create_field_decl
1963 build_index_type (build_int_cst (NULL_TREE, index))),
1965 chainon (field_decl_chain, field_decl);
1968 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1971 /* Create the initial value for the `defs' field of _objc_symtab.
1972 This is a CONSTRUCTOR. */
1975 init_def_list (tree type)
1977 tree expr, initlist = NULL_TREE;
1978 struct imp_entry *impent;
1981 for (impent = imp_list; impent; impent = impent->next)
1983 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1985 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1986 initlist = tree_cons (NULL_TREE, expr, initlist);
1991 for (impent = imp_list; impent; impent = impent->next)
1993 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1995 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1996 initlist = tree_cons (NULL_TREE, expr, initlist);
2000 if (!flag_next_runtime)
2002 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2005 if (static_instances_decl)
2006 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2008 expr = build_int_cst (NULL_TREE, 0);
2010 initlist = tree_cons (NULL_TREE, expr, initlist);
2013 return objc_build_constructor (type, nreverse (initlist));
2016 /* Construct the initial value for all of _objc_symtab. */
2019 init_objc_symtab (tree type)
2023 /* sel_ref_cnt = { ..., 5, ... } */
2025 initlist = build_tree_list (NULL_TREE,
2026 build_int_cst (long_integer_type_node, 0));
2028 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2030 if (flag_next_runtime || ! sel_ref_chain)
2031 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2034 = tree_cons (NULL_TREE,
2035 convert (build_pointer_type (objc_selector_type),
2036 build_unary_op (ADDR_EXPR,
2037 UOBJC_SELECTOR_TABLE_decl, 1)),
2040 /* cls_def_cnt = { ..., 5, ... } */
2042 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2044 /* cat_def_cnt = { ..., 5, ... } */
2046 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2048 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2050 if (imp_count || cat_count || !flag_next_runtime)
2053 tree field = TYPE_FIELDS (type);
2054 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2056 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2060 return objc_build_constructor (type, nreverse (initlist));
2063 /* Generate forward declarations for metadata such as
2064 'OBJC_CLASS_...'. */
2067 build_metadata_decl (const char *name, tree type)
2071 /* struct TYPE NAME_<name>; */
2072 decl = start_var_decl (type, synth_id_with_class_suffix
2074 objc_implementation_context));
2079 /* Push forward-declarations of all the categories so that
2080 init_def_list can use them in a CONSTRUCTOR. */
2083 forward_declare_categories (void)
2085 struct imp_entry *impent;
2086 tree sav = objc_implementation_context;
2088 for (impent = imp_list; impent; impent = impent->next)
2090 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2092 /* Set an invisible arg to synth_id_with_class_suffix. */
2093 objc_implementation_context = impent->imp_context;
2094 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2095 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2096 objc_category_template);
2099 objc_implementation_context = sav;
2102 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2103 and initialized appropriately. */
2106 generate_objc_symtab_decl (void)
2108 /* forward declare categories */
2110 forward_declare_categories ();
2112 build_objc_symtab_template ();
2113 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2114 finish_var_decl (UOBJC_SYMBOLS_decl,
2115 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2119 init_module_descriptor (tree type)
2121 tree initlist, expr;
2123 /* version = { 1, ... } */
2125 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2126 initlist = build_tree_list (NULL_TREE, expr);
2128 /* size = { ..., sizeof (struct _objc_module), ... } */
2130 expr = convert (long_integer_type_node,
2131 size_in_bytes (objc_module_template));
2132 initlist = tree_cons (NULL_TREE, expr, initlist);
2134 /* name = { ..., "foo.m", ... } */
2136 expr = add_objc_string (get_identifier (input_filename), class_names);
2137 initlist = tree_cons (NULL_TREE, expr, initlist);
2139 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2141 if (UOBJC_SYMBOLS_decl)
2142 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2144 expr = build_int_cst (NULL_TREE, 0);
2145 initlist = tree_cons (NULL_TREE, expr, initlist);
2147 return objc_build_constructor (type, nreverse (initlist));
2150 /* Write out the data structures to describe Objective C classes defined.
2152 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2155 build_module_descriptor (void)
2157 tree field_decl, field_decl_chain;
2160 push_lang_context (lang_name_c); /* extern "C" */
2163 objc_module_template
2164 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2167 field_decl = create_field_decl (long_integer_type_node, "version");
2168 field_decl_chain = field_decl;
2171 field_decl = create_field_decl (long_integer_type_node, "size");
2172 chainon (field_decl_chain, field_decl);
2175 field_decl = create_field_decl (string_type_node, "name");
2176 chainon (field_decl_chain, field_decl);
2178 /* struct _objc_symtab *symtab; */
2180 = create_field_decl (build_pointer_type
2181 (xref_tag (RECORD_TYPE,
2182 get_identifier (UTAG_SYMTAB))),
2184 chainon (field_decl_chain, field_decl);
2186 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2188 /* Create an instance of "_objc_module". */
2189 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2190 finish_var_decl (UOBJC_MODULES_decl,
2191 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2194 pop_lang_context ();
2198 /* The GNU runtime requires us to provide a static initializer function
2201 static void __objc_gnu_init (void) {
2202 __objc_exec_class (&L_OBJC_MODULES);
2206 build_module_initializer_routine (void)
2211 push_lang_context (lang_name_c); /* extern "C" */
2214 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2215 objc_start_function (get_identifier (TAG_GNUINIT),
2216 build_function_type (void_type_node,
2218 NULL_TREE, objc_get_parm_info (0));
2220 body = c_begin_compound_stmt (true);
2221 add_stmt (build_function_call
2225 build_unary_op (ADDR_EXPR,
2226 UOBJC_MODULES_decl, 0))));
2227 add_stmt (c_end_compound_stmt (body, true));
2229 TREE_PUBLIC (current_function_decl) = 0;
2232 /* For Objective-C++, we will need to call __objc_gnu_init
2233 from objc_generate_static_init_call() below. */
2234 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2237 GNU_INIT_decl = current_function_decl;
2241 pop_lang_context ();
2246 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2247 to be called by the module initializer routine. */
2250 objc_static_init_needed_p (void)
2252 return (GNU_INIT_decl != NULL_TREE);
2255 /* Generate a call to the __objc_gnu_init initializer function. */
2258 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2260 add_stmt (build_stmt (EXPR_STMT,
2261 build_function_call (GNU_INIT_decl, NULL_TREE)));
2265 #endif /* OBJCPLUS */
2267 /* Return the DECL of the string IDENT in the SECTION. */
2270 get_objc_string_decl (tree ident, enum string_section section)
2274 if (section == class_names)
2275 chain = class_names_chain;
2276 else if (section == meth_var_names)
2277 chain = meth_var_names_chain;
2278 else if (section == meth_var_types)
2279 chain = meth_var_types_chain;
2283 for (; chain != 0; chain = TREE_CHAIN (chain))
2284 if (TREE_VALUE (chain) == ident)
2285 return (TREE_PURPOSE (chain));
2291 /* Output references to all statically allocated objects. Return the DECL
2292 for the array built. */
2295 generate_static_references (void)
2297 tree decls = NULL_TREE, expr = NULL_TREE;
2298 tree class_name, class, decl, initlist;
2299 tree cl_chain, in_chain, type
2300 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2301 int num_inst, num_class;
2304 if (flag_next_runtime)
2307 for (cl_chain = objc_static_instances, num_class = 0;
2308 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2310 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2311 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2313 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2314 decl = start_var_decl (type, buf);
2316 /* Output {class_name, ...}. */
2317 class = TREE_VALUE (cl_chain);
2318 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2319 initlist = build_tree_list (NULL_TREE,
2320 build_unary_op (ADDR_EXPR, class_name, 1));
2322 /* Output {..., instance, ...}. */
2323 for (in_chain = TREE_PURPOSE (cl_chain);
2324 in_chain; in_chain = TREE_CHAIN (in_chain))
2326 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2327 initlist = tree_cons (NULL_TREE, expr, initlist);
2330 /* Output {..., NULL}. */
2331 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2333 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2334 finish_var_decl (decl, expr);
2336 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2339 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2340 expr = objc_build_constructor (type, nreverse (decls));
2341 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2342 finish_var_decl (static_instances_decl, expr);
2345 /* Output all strings. */
2348 generate_strings (void)
2350 tree chain, string_expr;
2351 tree string, decl, type;
2353 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2355 string = TREE_VALUE (chain);
2356 decl = TREE_PURPOSE (chain);
2357 type = build_array_type
2360 (build_int_cst (NULL_TREE,
2361 IDENTIFIER_LENGTH (string))));
2362 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2363 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2364 IDENTIFIER_POINTER (string));
2365 finish_var_decl (decl, string_expr);
2368 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2370 string = TREE_VALUE (chain);
2371 decl = TREE_PURPOSE (chain);
2372 type = build_array_type
2375 (build_int_cst (NULL_TREE,
2376 IDENTIFIER_LENGTH (string))));
2377 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2378 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2379 IDENTIFIER_POINTER (string));
2380 finish_var_decl (decl, string_expr);
2383 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2385 string = TREE_VALUE (chain);
2386 decl = TREE_PURPOSE (chain);
2387 type = build_array_type
2390 (build_int_cst (NULL_TREE,
2391 IDENTIFIER_LENGTH (string))));
2392 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2393 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2394 IDENTIFIER_POINTER (string));
2395 finish_var_decl (decl, string_expr);
2399 static GTY(()) int selector_reference_idx;
2402 build_selector_reference_decl (void)
2407 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2408 decl = start_var_decl (objc_selector_type, buf);
2414 build_selector_table_decl (void)
2418 if (flag_typed_selectors)
2420 build_selector_template ();
2421 temp = build_array_type (objc_selector_template, NULL_TREE);
2424 temp = build_array_type (objc_selector_type, NULL_TREE);
2426 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2429 /* Just a handy wrapper for add_objc_string. */
2432 build_selector (tree ident)
2434 return convert (objc_selector_type,
2435 add_objc_string (ident, meth_var_names));
2439 build_selector_translation_table (void)
2441 tree chain, initlist = NULL_TREE;
2443 tree decl = NULL_TREE;
2445 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2449 if (warn_selector && objc_implementation_context)
2453 for (method_chain = meth_var_names_chain;
2455 method_chain = TREE_CHAIN (method_chain))
2457 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2466 if (flag_next_runtime && TREE_PURPOSE (chain))
2467 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2469 loc = &input_location;
2470 warning (0, "%Hcreating selector for nonexistent method %qE",
2471 loc, TREE_VALUE (chain));
2475 expr = build_selector (TREE_VALUE (chain));
2476 /* add one for the '\0' character */
2477 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2479 if (flag_next_runtime)
2481 decl = TREE_PURPOSE (chain);
2482 finish_var_decl (decl, expr);
2486 if (flag_typed_selectors)
2488 tree eltlist = NULL_TREE;
2489 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2490 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2491 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2492 expr = objc_build_constructor (objc_selector_template,
2493 nreverse (eltlist));
2496 initlist = tree_cons (NULL_TREE, expr, initlist);
2500 if (! flag_next_runtime)
2502 /* Cause the selector table (previously forward-declared)
2503 to be actually output. */
2504 initlist = tree_cons (NULL_TREE,
2505 flag_typed_selectors
2506 ? objc_build_constructor
2507 (objc_selector_template,
2508 tree_cons (NULL_TREE,
2509 build_int_cst (NULL_TREE, 0),
2510 tree_cons (NULL_TREE,
2511 build_int_cst (NULL_TREE, 0),
2513 : build_int_cst (NULL_TREE, 0), initlist);
2514 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2515 nreverse (initlist));
2516 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2521 get_proto_encoding (tree proto)
2526 if (! METHOD_ENCODING (proto))
2528 encoding = encode_method_prototype (proto);
2529 METHOD_ENCODING (proto) = encoding;
2532 encoding = METHOD_ENCODING (proto);
2534 return add_objc_string (encoding, meth_var_types);
2537 return build_int_cst (NULL_TREE, 0);
2540 /* sel_ref_chain is a list whose "value" fields will be instances of
2541 identifier_node that represent the selector. */
2544 build_typed_selector_reference (tree ident, tree prototype)
2546 tree *chain = &sel_ref_chain;
2552 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2553 goto return_at_index;
2556 chain = &TREE_CHAIN (*chain);
2559 *chain = tree_cons (prototype, ident, NULL_TREE);
2562 expr = build_unary_op (ADDR_EXPR,
2563 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2564 build_int_cst (NULL_TREE, index)),
2566 return convert (objc_selector_type, expr);
2570 build_selector_reference (tree ident)
2572 tree *chain = &sel_ref_chain;
2578 if (TREE_VALUE (*chain) == ident)
2579 return (flag_next_runtime
2580 ? TREE_PURPOSE (*chain)
2581 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2582 build_int_cst (NULL_TREE, index)));
2585 chain = &TREE_CHAIN (*chain);
2588 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2590 *chain = tree_cons (expr, ident, NULL_TREE);
2592 return (flag_next_runtime
2594 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2595 build_int_cst (NULL_TREE, index)));
2598 static GTY(()) int class_reference_idx;
2601 build_class_reference_decl (void)
2606 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2607 decl = start_var_decl (objc_class_type, buf);
2612 /* Create a class reference, but don't create a variable to reference
2616 add_class_reference (tree ident)
2620 if ((chain = cls_ref_chain))
2625 if (ident == TREE_VALUE (chain))
2629 chain = TREE_CHAIN (chain);
2633 /* Append to the end of the list */
2634 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2637 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2640 /* Get a class reference, creating it if necessary. Also create the
2641 reference variable. */
2644 objc_get_class_reference (tree ident)
2646 tree orig_ident = (DECL_P (ident)
2649 ? OBJC_TYPE_NAME (ident)
2651 bool local_scope = false;
2654 if (processing_template_decl)
2655 /* Must wait until template instantiation time. */
2656 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2659 if (TREE_CODE (ident) == TYPE_DECL)
2660 ident = (DECL_ORIGINAL_TYPE (ident)
2661 ? DECL_ORIGINAL_TYPE (ident)
2662 : TREE_TYPE (ident));
2665 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2666 && TYPE_CONTEXT (ident) != global_namespace)
2670 if (local_scope || !(ident = objc_is_class_name (ident)))
2672 error ("%qs is not an Objective-C class name or alias",
2673 IDENTIFIER_POINTER (orig_ident));
2674 return error_mark_node;
2677 if (flag_next_runtime && !flag_zero_link)
2682 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2683 if (TREE_VALUE (*chain) == ident)
2685 if (! TREE_PURPOSE (*chain))
2686 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2688 return TREE_PURPOSE (*chain);
2691 decl = build_class_reference_decl ();
2692 *chain = tree_cons (decl, ident, NULL_TREE);
2699 add_class_reference (ident);
2701 params = build_tree_list (NULL_TREE,
2702 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2703 IDENTIFIER_POINTER (ident)));
2705 assemble_external (objc_get_class_decl);
2706 return build_function_call (objc_get_class_decl, params);
2710 /* For each string section we have a chain which maps identifier nodes
2711 to decls for the strings. */
2714 add_objc_string (tree ident, enum string_section section)
2718 if (section == class_names)
2719 chain = &class_names_chain;
2720 else if (section == meth_var_names)
2721 chain = &meth_var_names_chain;
2722 else if (section == meth_var_types)
2723 chain = &meth_var_types_chain;
2729 if (TREE_VALUE (*chain) == ident)
2730 return convert (string_type_node,
2731 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2733 chain = &TREE_CHAIN (*chain);
2736 decl = build_objc_string_decl (section);
2738 *chain = tree_cons (decl, ident, NULL_TREE);
2740 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2743 static GTY(()) int class_names_idx;
2744 static GTY(()) int meth_var_names_idx;
2745 static GTY(()) int meth_var_types_idx;
2748 build_objc_string_decl (enum string_section section)
2753 if (section == class_names)
2754 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2755 else if (section == meth_var_names)
2756 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2757 else if (section == meth_var_types)
2758 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2760 ident = get_identifier (buf);
2762 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2763 DECL_EXTERNAL (decl) = 1;
2764 TREE_PUBLIC (decl) = 0;
2765 TREE_USED (decl) = 1;
2766 TREE_CONSTANT (decl) = 1;
2767 DECL_CONTEXT (decl) = 0;
2768 DECL_ARTIFICIAL (decl) = 1;
2770 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2773 make_decl_rtl (decl);
2774 pushdecl_top_level (decl);
2781 objc_declare_alias (tree alias_ident, tree class_ident)
2783 tree underlying_class;
2786 if (current_namespace != global_namespace) {
2787 error ("Objective-C declarations may only appear in global scope");
2789 #endif /* OBJCPLUS */
2791 if (!(underlying_class = objc_is_class_name (class_ident)))
2792 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2793 else if (objc_is_class_name (alias_ident))
2794 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2797 /* Implement @compatibility_alias as a typedef. */
2799 push_lang_context (lang_name_c); /* extern "C" */
2801 lang_hooks.decls.pushdecl (build_decl
2804 xref_tag (RECORD_TYPE, underlying_class)));
2806 pop_lang_context ();
2808 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2813 objc_declare_class (tree ident_list)
2817 if (current_namespace != global_namespace) {
2818 error ("Objective-C declarations may only appear in global scope");
2820 #endif /* OBJCPLUS */
2822 for (list = ident_list; list; list = TREE_CHAIN (list))
2824 tree ident = TREE_VALUE (list);
2826 if (! objc_is_class_name (ident))
2828 tree record = lookup_name (ident), type = record;
2832 if (TREE_CODE (record) == TYPE_DECL)
2833 type = DECL_ORIGINAL_TYPE (record);
2835 if (!TYPE_HAS_OBJC_INFO (type)
2836 || !TYPE_OBJC_INTERFACE (type))
2838 error ("%qs redeclared as different kind of symbol",
2839 IDENTIFIER_POINTER (ident));
2840 error ("%Jprevious declaration of '%D'",
2845 record = xref_tag (RECORD_TYPE, ident);
2846 INIT_TYPE_OBJC_INFO (record);
2847 TYPE_OBJC_INTERFACE (record) = ident;
2848 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2854 objc_is_class_name (tree ident)
2858 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2859 && identifier_global_value (ident))
2860 ident = identifier_global_value (ident);
2861 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2862 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2864 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2865 ident = OBJC_TYPE_NAME (ident);
2867 if (ident && TREE_CODE (ident) == TYPE_DECL)
2868 ident = DECL_NAME (ident);
2870 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2873 if (lookup_interface (ident))
2876 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2878 if (ident == TREE_VALUE (chain))
2882 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2884 if (ident == TREE_VALUE (chain))
2885 return TREE_PURPOSE (chain);
2891 /* Check whether TYPE is either 'id' or 'Class'. */
2894 objc_is_id (tree type)
2896 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2897 && identifier_global_value (type))
2898 type = identifier_global_value (type);
2900 if (type && TREE_CODE (type) == TYPE_DECL)
2901 type = TREE_TYPE (type);
2903 /* NB: This function may be called before the ObjC front-end has
2904 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2905 return (objc_object_type && type
2906 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2911 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2912 class instance. This is needed by other parts of the compiler to
2913 handle ObjC types gracefully. */
2916 objc_is_object_ptr (tree type)
2920 type = TYPE_MAIN_VARIANT (type);
2921 if (!POINTER_TYPE_P (type))
2924 ret = objc_is_id (type);
2926 ret = objc_is_class_name (TREE_TYPE (type));
2932 objc_is_gcable_type (tree type, int or_strong_p)
2938 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
2940 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
2942 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
2944 type = TREE_TYPE (type);
2945 if (TREE_CODE (type) != RECORD_TYPE)
2947 name = TYPE_NAME (type);
2948 return (objc_is_class_name (name) != NULL_TREE);
2952 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
2954 if (expr == oldexpr)
2957 switch (TREE_CODE (expr))
2960 return objc_build_component_ref
2961 (objc_substitute_decl (TREE_OPERAND (expr, 0),
2964 DECL_NAME (TREE_OPERAND (expr, 1)));
2966 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
2969 TREE_OPERAND (expr, 1));
2971 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
2980 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
2983 /* The LHS parameter contains the expression 'outervar->memberspec';
2984 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
2985 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
2988 = objc_substitute_decl
2989 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
2991 = (flag_objc_direct_dispatch
2992 ? objc_assign_ivar_fast_decl
2993 : objc_assign_ivar_decl);
2995 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
2997 func_params = tree_cons (NULL_TREE,
2998 convert (objc_object_type, rhs),
2999 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3000 tree_cons (NULL_TREE, offs,
3003 assemble_external (func);
3004 return build_function_call (func, func_params);
3008 objc_build_global_assignment (tree lhs, tree rhs)
3010 tree func_params = tree_cons (NULL_TREE,
3011 convert (objc_object_type, rhs),
3012 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3013 build_unary_op (ADDR_EXPR, lhs, 0)),
3016 assemble_external (objc_assign_global_decl);
3017 return build_function_call (objc_assign_global_decl, func_params);
3021 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3023 tree func_params = tree_cons (NULL_TREE,
3024 convert (objc_object_type, rhs),
3025 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3026 build_unary_op (ADDR_EXPR, lhs, 0)),
3029 assemble_external (objc_assign_strong_cast_decl);
3030 return build_function_call (objc_assign_strong_cast_decl, func_params);
3034 objc_is_gcable_p (tree expr)
3036 return (TREE_CODE (expr) == COMPONENT_REF
3037 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3038 : TREE_CODE (expr) == ARRAY_REF
3039 ? (objc_is_gcable_p (TREE_TYPE (expr))
3040 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3041 : TREE_CODE (expr) == ARRAY_TYPE
3042 ? objc_is_gcable_p (TREE_TYPE (expr))
3044 ? objc_is_gcable_type (expr, 1)
3045 : (objc_is_gcable_p (TREE_TYPE (expr))
3047 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3051 objc_is_ivar_reference_p (tree expr)
3053 return (TREE_CODE (expr) == ARRAY_REF
3054 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3055 : TREE_CODE (expr) == COMPONENT_REF
3056 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3061 objc_is_global_reference_p (tree expr)
3063 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3064 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3066 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3071 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3073 tree result = NULL_TREE, outer;
3074 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3076 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3077 will have been transformed to the form '*(type *)&expr'. */
3078 if (TREE_CODE (lhs) == INDIRECT_REF)
3080 outer = TREE_OPERAND (lhs, 0);
3082 while (!strong_cast_p
3083 && (TREE_CODE (outer) == CONVERT_EXPR
3084 || TREE_CODE (outer) == NOP_EXPR
3085 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3087 tree lhstype = TREE_TYPE (outer);
3089 /* Descend down the cast chain, and record the first objc_gc
3091 if (POINTER_TYPE_P (lhstype))
3094 = lookup_attribute ("objc_gc",
3095 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3101 outer = TREE_OPERAND (outer, 0);
3105 /* If we have a __strong cast, it trumps all else. */
3108 if (modifycode != NOP_EXPR)
3109 goto invalid_pointer_arithmetic;
3111 if (warn_assign_intercept)
3112 warning (0, "strong-cast assignment has been intercepted");
3114 result = objc_build_strong_cast_assignment (lhs, rhs);
3119 /* the lhs must be of a suitable type, regardless of its underlying
3121 if (!objc_is_gcable_p (lhs))
3127 && (TREE_CODE (outer) == COMPONENT_REF
3128 || TREE_CODE (outer) == ARRAY_REF))
3129 outer = TREE_OPERAND (outer, 0);
3131 if (TREE_CODE (outer) == INDIRECT_REF)
3133 outer = TREE_OPERAND (outer, 0);
3137 outer_gc_p = objc_is_gcable_p (outer);
3139 /* Handle ivar assignments. */
3140 if (objc_is_ivar_reference_p (lhs))
3142 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3143 doesn't cut it here), the best we can do here is suggest a cast. */
3144 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3146 /* We may still be able to use the global write barrier... */
3147 if (!indirect_p && objc_is_global_reference_p (outer))
3148 goto global_reference;
3151 if (modifycode == NOP_EXPR)
3153 if (warn_assign_intercept)
3154 warning (0, "strong-cast may possibly be needed");
3160 if (modifycode != NOP_EXPR)
3161 goto invalid_pointer_arithmetic;
3163 if (warn_assign_intercept)
3164 warning (0, "instance variable assignment has been intercepted");
3166 result = objc_build_ivar_assignment (outer, lhs, rhs);
3171 /* Likewise, intercept assignment to global/static variables if their type is
3173 if (objc_is_global_reference_p (outer))
3179 if (modifycode != NOP_EXPR)
3181 invalid_pointer_arithmetic:
3183 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3188 if (warn_assign_intercept)
3189 warning (0, "global/static variable assignment has been intercepted");
3191 result = objc_build_global_assignment (lhs, rhs);
3194 /* In all other cases, fall back to the normal mechanism. */
3199 struct interface_tuple GTY(())
3205 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3208 hash_interface (const void *p)
3210 const struct interface_tuple *d = p;
3211 return htab_hash_pointer (d->id);
3215 eq_interface (const void *p1, const void *p2)
3217 const struct interface_tuple *d = p1;
3222 lookup_interface (tree ident)
3225 if (ident && TREE_CODE (ident) == TYPE_DECL)
3226 ident = DECL_NAME (ident);
3229 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3233 struct interface_tuple **slot;
3238 slot = (struct interface_tuple **)
3239 htab_find_slot_with_hash (interface_htab, ident,
3240 htab_hash_pointer (ident),
3243 i = (*slot)->class_name;
3249 /* Implement @defs (<classname>) within struct bodies. */
3252 objc_get_class_ivars (tree class_name)
3254 tree interface = lookup_interface (class_name);
3257 return get_class_ivars (interface, true);
3259 error ("cannot find interface declaration for %qs",
3260 IDENTIFIER_POINTER (class_name));
3262 return error_mark_node;
3265 /* Used by: build_private_template, continue_class,
3266 and for @defs constructs. */
3269 get_class_ivars (tree interface, bool inherited)
3271 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3273 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3274 by the current class (i.e., they do not include super-class ivars).
3275 However, the CLASS_IVARS list will be side-effected by a call to
3276 finish_struct(), which will fill in field offsets. */
3277 if (!CLASS_IVARS (interface))
3278 CLASS_IVARS (interface) = ivar_chain;
3283 while (CLASS_SUPER_NAME (interface))
3285 /* Prepend super-class ivars. */
3286 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3287 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3295 objc_create_temporary_var (tree type)
3299 decl = build_decl (VAR_DECL, NULL_TREE, type);
3300 TREE_USED (decl) = 1;
3301 DECL_ARTIFICIAL (decl) = 1;
3302 DECL_IGNORED_P (decl) = 1;
3303 DECL_CONTEXT (decl) = current_function_decl;
3308 /* Exception handling constructs. We begin by having the parser do most
3309 of the work and passing us blocks. What we do next depends on whether
3310 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3311 We abstract all of this in a handful of appropriately named routines. */
3313 /* Stack of open try blocks. */
3315 struct objc_try_context
3317 struct objc_try_context *outer;
3319 /* Statements (or statement lists) as processed by the parser. */
3323 /* Some file position locations. */
3324 location_t try_locus;
3325 location_t end_try_locus;
3326 location_t end_catch_locus;
3327 location_t finally_locus;
3328 location_t end_finally_locus;
3330 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3331 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3334 /* The CATCH_EXPR of an open @catch clause. */
3337 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3343 static struct objc_try_context *cur_try_context;
3345 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3346 that represents TYPE. For Objective-C, this is just the class name. */
3347 /* ??? Isn't there a class object or some such? Is it easy to get? */
3351 objc_eh_runtime_type (tree type)
3353 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3357 /* Initialize exception handling. */
3360 objc_init_exceptions (void)
3362 static bool done = false;
3367 if (flag_objc_sjlj_exceptions)
3369 /* On Darwin, ObjC exceptions require a sufficiently recent
3370 version of the runtime, so the user must ask for them explicitly. */
3371 if (!flag_objc_exceptions)
3372 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3373 "exception syntax");
3378 c_eh_initialized_p = true;
3379 eh_personality_libfunc
3380 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3381 ? "__gnu_objc_personality_sj0"
3382 : "__gnu_objc_personality_v0");
3383 using_eh_for_cleanups ();
3384 lang_eh_runtime_type = objc_eh_runtime_type;
3389 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3390 we'll arrange for it to be initialized (and associated with a binding)
3394 objc_build_exc_ptr (void)
3396 if (flag_objc_sjlj_exceptions)
3398 tree var = cur_try_context->caught_decl;
3401 var = objc_create_temporary_var (objc_object_type);
3402 cur_try_context->caught_decl = var;
3407 return build (EXC_PTR_EXPR, objc_object_type);
3410 /* Build "objc_exception_try_exit(&_stack)". */
3413 next_sjlj_build_try_exit (void)
3416 t = build_fold_addr_expr (cur_try_context->stack_decl);
3417 t = tree_cons (NULL, t, NULL);
3418 t = build_function_call (objc_exception_try_exit_decl, t);
3423 objc_exception_try_enter (&_stack);
3424 if (_setjmp(&_stack.buf))
3428 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3429 empty, ready for the caller to fill them in. */
3432 next_sjlj_build_enter_and_setjmp (void)
3434 tree t, enter, sj, cond;
3436 t = build_fold_addr_expr (cur_try_context->stack_decl);
3437 t = tree_cons (NULL, t, NULL);
3438 enter = build_function_call (objc_exception_try_enter_decl, t);
3440 t = objc_build_component_ref (cur_try_context->stack_decl,
3441 get_identifier ("buf"));
3442 t = build_fold_addr_expr (t);
3444 /* Convert _setjmp argument to type that is expected. */
3445 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3446 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3448 t = convert (ptr_type_node, t);
3450 t = convert (ptr_type_node, t);
3452 t = tree_cons (NULL, t, NULL);
3453 sj = build_function_call (objc_setjmp_decl, t);
3455 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3456 cond = c_common_truthvalue_conversion (cond);
3458 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
3462 DECL = objc_exception_extract(&_stack);
3466 next_sjlj_build_exc_extract (tree decl)
3470 t = build_fold_addr_expr (cur_try_context->stack_decl);
3471 t = tree_cons (NULL, t, NULL);
3472 t = build_function_call (objc_exception_extract_decl, t);
3473 t = convert (TREE_TYPE (decl), t);
3474 t = build (MODIFY_EXPR, void_type_node, decl, t);
3480 if (objc_exception_match(obj_get_class(TYPE), _caught)
3487 objc_exception_try_exit(&_stack);
3489 from the sequence of CATCH_EXPRs in the current try context. */
3492 next_sjlj_build_catch_list (void)
3494 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3496 tree *last = &catch_seq;
3497 bool saw_id = false;
3499 for (; !tsi_end_p (i); tsi_next (&i))
3501 tree stmt = tsi_stmt (i);
3502 tree type = CATCH_TYPES (stmt);
3503 tree body = CATCH_BODY (stmt);
3515 if (type == error_mark_node)
3516 cond = error_mark_node;
3519 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3520 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3521 args = tree_cons (NULL, t, args);
3522 t = build_function_call (objc_exception_match_decl, args);
3523 cond = c_common_truthvalue_conversion (t);
3525 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3526 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3529 last = &COND_EXPR_ELSE (t);
3535 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3536 cur_try_context->caught_decl);
3537 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3538 append_to_statement_list (t, last);
3540 t = next_sjlj_build_try_exit ();
3541 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3542 append_to_statement_list (t, last);
3548 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3549 exception handling. We aim to build:
3552 struct _objc_exception_data _stack;
3553 id volatile _rethrow = 0;
3556 objc_exception_try_enter (&_stack);
3557 if (_setjmp(&_stack.buf))
3559 id _caught = objc_exception_extract(&_stack);
3560 objc_exception_try_enter (&_stack);
3561 if (_setjmp(&_stack.buf))
3562 _rethrow = objc_exception_extract(&_stack);
3572 objc_exception_try_exit(&_stack);
3575 objc_exception_throw(_rethrow);
3579 If CATCH-LIST is empty, we can omit all of the block containing
3580 "_caught" except for the setting of _rethrow. Note the use of
3581 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3582 but handles goto and other exits from the block. */
3585 next_sjlj_build_try_catch_finally (void)
3587 tree rethrow_decl, stack_decl, t;
3588 tree catch_seq, try_fin, bind;
3590 /* Create the declarations involved. */
3591 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3592 stack_decl = objc_create_temporary_var (t);
3593 cur_try_context->stack_decl = stack_decl;
3595 rethrow_decl = objc_create_temporary_var (objc_object_type);
3596 cur_try_context->rethrow_decl = rethrow_decl;
3597 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3598 TREE_CHAIN (rethrow_decl) = stack_decl;