1 /* GNU Runtime ABI version 8
2 Copyright (C) 2011-2015 Free Software Foundation, Inc.
3 Contributed by Iain Sandoe (split from objc-act.c)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
27 #include "double-int.h"
35 #include "fold-const.h"
36 #include "stringpool.h"
39 #include "cp/cp-tree.h"
45 #include "langhooks.h"
46 #include "c-family/c-objc.h"
49 /* When building Objective-C++, we are not linking against the C front-end
50 and so need to replicate the C tree-construction functions in some way. */
52 #define OBJCP_REMAP_FUNCTIONS
53 #include "objcp-decl.h"
58 #include "tree-iterator.h"
60 #include "objc-runtime-hooks.h"
61 #include "objc-runtime-shared-support.h"
62 #include "objc-encoding.h"
64 /* GNU runtime private definitions. */
65 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
67 #define TAG_GETCLASS "objc_get_class"
68 #define TAG_GETMETACLASS "objc_get_meta_class"
70 #define TAG_MSGSEND "objc_msg_lookup"
71 #define TAG_MSGSENDSUPER "objc_msg_lookup_super"
73 /* GNU-specific tags. */
75 #define TAG_EXECCLASS "__objc_exec_class"
76 #define TAG_GNUINIT "__objc_gnu_init"
78 /* The version identifies which language generation and runtime
79 the module (file) was compiled for, and is recorded in the
81 #define OBJC_VERSION 8
83 #define PROTOCOL_VERSION 2
85 /* This macro provides a method of removing ambiguity between runtimes
86 when LTO is in use on targets supporting multiple runtimes.
88 For example, at present, any target that includes an implementation of
89 the NeXT runtime needs to place Objective-C meta-data into specific
90 named sections. This should _not_ be done for the GNU runtime, and the
91 following macro is used to attach Objective-C private attributes that may
92 be used to identify the runtime for which the meta-data are intended. */
94 #define OBJCMETA(DECL,VERS,KIND) \
96 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
98 static void gnu_runtime_01_initialize (void);
100 static void build_selector_template (void);
102 static tree gnu_runtime_abi_01_super_superclassfield_id (void);
104 static tree gnu_runtime_abi_01_class_decl (tree);
105 static tree gnu_runtime_abi_01_metaclass_decl (tree);
106 static tree gnu_runtime_abi_01_category_decl (tree);
107 static tree gnu_runtime_abi_01_protocol_decl (tree);
108 static tree gnu_runtime_abi_01_string_decl (tree, const char *, string_section);
110 static tree gnu_runtime_abi_01_get_class_reference (tree);
111 static tree gnu_runtime_abi_01_build_typed_selector_reference (location_t, tree,
113 static tree gnu_runtime_abi_01_get_protocol_reference (location_t, tree);
114 static tree gnu_runtime_abi_01_build_ivar_ref (location_t, tree, tree);
115 static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool);
116 static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
118 static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
119 static void gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **,
121 static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
122 tree, tree, tree, int);
124 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
125 static tree gnu_runtime_abi_01_build_const_string_constructor (location_t, tree,int);
127 static void objc_generate_v1_gnu_metadata (void);
129 static tree objc_eh_runtime_type (tree type);
130 static tree objc_eh_personality (void);
131 static tree objc_build_exc_ptr (struct objc_try_context **);
132 static tree build_throw_stmt (location_t, tree, bool);
133 static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool);
134 static void finish_catch (struct objc_try_context **, tree);
135 static tree finish_try_stmt (struct objc_try_context **);
138 objc_gnu_runtime_abi_01_init (objc_runtime_hooks *rthooks)
140 /* GNU runtime does not need the compiler to change code in order to do GC. */
143 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
147 /* Although I guess we could, we don't currently support SJLJ exceptions for the
149 if (flag_objc_sjlj_exceptions)
151 inform (UNKNOWN_LOCATION, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
152 flag_objc_sjlj_exceptions = 0;
155 /* TODO: Complain if -fobjc-abi-version=N was used. */
157 /* TODO: Complain if -fobj-nilcheck was used. */
159 rthooks->initialize = gnu_runtime_01_initialize;
160 rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
161 rthooks->tag_getclass = TAG_GETCLASS;
162 rthooks->super_superclassfield_ident = gnu_runtime_abi_01_super_superclassfield_id;
164 rthooks->class_decl = gnu_runtime_abi_01_class_decl;
165 rthooks->metaclass_decl = gnu_runtime_abi_01_metaclass_decl;
166 rthooks->category_decl = gnu_runtime_abi_01_category_decl;
167 rthooks->protocol_decl = gnu_runtime_abi_01_protocol_decl;
168 rthooks->string_decl = gnu_runtime_abi_01_string_decl;
170 rthooks->get_class_reference = gnu_runtime_abi_01_get_class_reference;
171 rthooks->build_selector_reference = gnu_runtime_abi_01_build_typed_selector_reference;
172 rthooks->get_protocol_reference = gnu_runtime_abi_01_get_protocol_reference;
173 rthooks->build_ivar_reference = gnu_runtime_abi_01_build_ivar_ref;
174 rthooks->get_class_super_ref = gnu_runtime_abi_01_get_class_super_ref;
175 rthooks->get_category_super_ref = gnu_runtime_abi_01_get_category_super_ref;
177 rthooks->receiver_is_class_object = gnu_runtime_abi_01_receiver_is_class_object;
178 rthooks->get_arg_type_list_base = gnu_runtime_abi_01_get_arg_type_list_base;
179 rthooks->build_objc_method_call = gnu_runtime_abi_01_build_objc_method_call;
181 rthooks->setup_const_string_class_decl =
182 gnu_runtime_abi_01_setup_const_string_class_decl;
183 rthooks->build_const_string_constructor =
184 gnu_runtime_abi_01_build_const_string_constructor;
186 rthooks->build_throw_stmt = build_throw_stmt;
187 rthooks->build_exc_ptr = objc_build_exc_ptr;
188 rthooks->begin_catch = begin_catch;
189 rthooks->finish_catch = finish_catch;
190 rthooks->finish_try_stmt = finish_try_stmt;
192 rthooks->generate_metadata = objc_generate_v1_gnu_metadata;
196 static void build_selector_table_decl (void);
197 static void build_class_template (void);
198 static void build_category_template (void);
199 static void build_protocol_template (void);
201 static GTY(()) tree objc_meta;
202 static GTY(()) tree meta_base;
204 static void gnu_runtime_01_initialize (void)
206 tree type, ftype, IMP_type;
208 /* We do not need to mark GNU ObjC metadata for different sections,
209 however, we do need to make sure that it is not mistaken for NeXT
211 objc_meta = get_identifier ("OBJC1METG");
212 meta_base = get_identifier ("NONE");
214 /* Declare type of selector-objects that represent an operation name. */
215 /* `const struct objc_selector *' */
216 type = xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR));
217 type = build_qualified_type (type, TYPE_QUAL_CONST);
218 objc_selector_type = build_pointer_type (type);
220 /* typedef id (*IMP)(id, SEL, ...); */
221 ftype = build_varargs_function_type_list (objc_object_type,
226 IMP_type = build_pointer_type (ftype);
228 build_class_template ();
229 build_super_template ();
230 build_protocol_template ();
231 build_category_template ();
233 /* GNU runtime messenger entry points. */
234 /* TREE_NOTHROW is cleared for the message-sending functions,
235 because the function that gets called can throw in Obj-C++, or
236 could itself call something that can throw even in Obj-C. */
238 /* IMP objc_msg_lookup (id, SEL); */
239 type = build_function_type_list (IMP_type,
244 umsg_decl = add_builtin_function (TAG_MSGSEND,
245 type, 0, NOT_BUILT_IN,
247 TREE_NOTHROW (umsg_decl) = 0;
249 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
250 type = build_function_type_list (IMP_type,
255 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
256 type, 0, NOT_BUILT_IN,
258 TREE_NOTHROW (umsg_super_decl) = 0;
260 /* The following GNU runtime entry point is called to initialize
263 __objc_exec_class (void *); */
264 type = build_function_type_list (void_type_node,
268 execclass_decl = add_builtin_function (TAG_EXECCLASS,
269 type, 0, NOT_BUILT_IN,
272 type = build_function_type_list (objc_object_type,
273 const_string_type_node,
276 /* id objc_getClass (const char *); */
278 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
281 /* id objc_getMetaClass (const char *); */
282 objc_get_meta_class_decl = add_builtin_function (TAG_GETMETACLASS, type,
283 0, NOT_BUILT_IN, NULL,
286 /* static SEL _OBJC_SELECTOR_TABLE[]; */
287 build_selector_table_decl ();
289 /* Stuff for properties.
290 The codegen relies on this being NULL for GNU. */
291 objc_copyStruct_decl = NULL_TREE;
293 /* This is the type of all of the following functions
294 bjc_getPropertyStruct() and objc_setPropertyStruct(). */
295 type = build_function_type_list (void_type_node,
303 /* Declare the following function:
305 objc_getPropertyStruct (void *destination, const void *source,
306 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
307 objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
308 type, 0, NOT_BUILT_IN,
310 TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
311 /* Declare the following function:
313 objc_setPropertyStruct (void *destination, const void *source,
314 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
315 objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
316 type, 0, NOT_BUILT_IN,
318 TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
320 using_eh_for_cleanups ();
321 lang_hooks.eh_runtime_type = objc_eh_runtime_type;
322 lang_hooks.eh_personality = objc_eh_personality;
325 /* --- templates --- */
326 /* struct _objc_selector {
332 build_selector_template (void)
334 tree decls, *chain = NULL;
336 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
339 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
341 /* char *sel_type; */
342 add_field_decl (string_type_node, "sel_type", &chain);
344 objc_finish_struct (objc_selector_template, decls);
347 /* struct _objc_class {
348 struct _objc_class *isa;
349 struct _objc_class *super_class;
354 struct _objc_ivar_list *ivars;
355 struct _objc_method_list *methods;
356 struct sarray *dtable;
357 struct _objc_class *subclass_list;
358 struct _objc_class *sibling_class;
359 struct _objc_protocol_list *protocols;
360 void *gc_object_type;
364 build_class_template (void)
366 tree ptype, decls, *chain = NULL;
368 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
370 /* struct _objc_class *isa; */
371 decls = add_field_decl (build_pointer_type (objc_class_template),
374 /* struct _objc_class *super_class; */
375 add_field_decl (build_pointer_type (objc_class_template),
376 "super_class", &chain);
379 add_field_decl (string_type_node, "name", &chain);
382 add_field_decl (long_integer_type_node, "version", &chain);
385 add_field_decl (long_integer_type_node, "info", &chain);
387 /* long instance_size; */
388 add_field_decl (long_integer_type_node, "instance_size", &chain);
390 /* struct _objc_ivar_list *ivars; */
391 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
393 /* struct _objc_method_list *methods; */
394 add_field_decl (objc_method_list_ptr, "methods", &chain);
396 /* struct sarray *dtable; */
397 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
398 get_identifier ("sarray")));
399 add_field_decl (ptype, "dtable", &chain);
401 /* struct objc_class *subclass_list; */
402 ptype = build_pointer_type (objc_class_template);
403 add_field_decl (ptype, "subclass_list", &chain);
405 /* struct objc_class *sibling_class; */
406 ptype = build_pointer_type (objc_class_template);
407 add_field_decl (ptype, "sibling_class", &chain);
409 /* struct _objc_protocol **protocol_list; */
410 ptype = build_pointer_type (build_pointer_type
411 (xref_tag (RECORD_TYPE,
412 get_identifier (UTAG_PROTOCOL))));
413 add_field_decl (ptype, "protocol_list", &chain);
415 /* void *gc_object_type; */
416 add_field_decl (build_pointer_type (void_type_node),
417 "gc_object_type", &chain);
419 objc_finish_struct (objc_class_template, decls);
422 /* struct _objc_category {
425 struct _objc_method_list *instance_methods;
426 struct _objc_method_list *class_methods;
427 struct _objc_protocol_list *protocols;
431 build_category_template (void)
433 tree ptype, decls, *chain = NULL;
435 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
437 /* char *category_name; */
438 decls = add_field_decl (string_type_node, "category_name", &chain);
440 /* char *class_name; */
441 add_field_decl (string_type_node, "class_name", &chain);
443 /* struct _objc_method_list *instance_methods; */
444 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
446 /* struct _objc_method_list *class_methods; */
447 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
449 /* struct _objc_protocol **protocol_list; */
450 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
451 add_field_decl (ptype, "protocol_list", &chain);
453 objc_finish_struct (objc_category_template, decls);
456 /* struct _objc_protocol {
457 struct _objc_class *isa;
459 struct _objc_protocol **protocol_list;
460 struct _objc__method_prototype_list *instance_methods;
461 struct _objc__method_prototype_list *class_methods;
465 build_protocol_template (void)
467 tree ptype, decls, *chain = NULL;
469 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
471 /* struct _objc_class *isa; */
472 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
473 get_identifier (UTAG_CLASS)));
474 decls = add_field_decl (ptype, "isa", &chain);
476 /* char *protocol_name; */
477 add_field_decl (string_type_node, "protocol_name", &chain);
479 /* struct _objc_protocol **protocol_list; */
480 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
481 add_field_decl (ptype, "protocol_list", &chain);
483 /* struct _objc__method_prototype_list *instance_methods; */
484 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
486 /* struct _objc__method_prototype_list *class_methods; */
487 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
489 objc_finish_struct (objc_protocol_template, decls);
492 /* --- names, decls + identifiers --- */
495 build_selector_table_decl (void)
499 build_selector_template ();
500 temp = build_array_type (objc_selector_template, NULL_TREE);
502 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
503 OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base);
508 gnu_runtime_abi_01_super_superclassfield_id (void)
510 if (!super_superclassfield_id)
511 super_superclassfield_id = get_identifier ("super_class");
512 return super_superclassfield_id;
517 gnu_runtime_abi_01_class_decl (tree klass)
521 snprintf (buf, BUFSIZE, "_OBJC_Class_%s",
522 IDENTIFIER_POINTER (CLASS_NAME (klass)));
523 decl = start_var_decl (objc_class_template, buf);
524 OBJCMETA (decl, objc_meta, meta_base);
529 gnu_runtime_abi_01_metaclass_decl (tree klass)
533 snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s",
534 IDENTIFIER_POINTER (CLASS_NAME (klass)));
535 decl = start_var_decl (objc_class_template, buf);
536 OBJCMETA (decl, objc_meta, meta_base);
541 gnu_runtime_abi_01_category_decl (tree klass)
545 snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
546 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)),
547 IDENTIFIER_POINTER (CLASS_NAME (klass)));
548 decl = start_var_decl (objc_category_template, buf);
549 OBJCMETA (decl, objc_meta, meta_base);
554 gnu_runtime_abi_01_protocol_decl (tree p)
559 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
560 snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
561 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
562 decl = start_var_decl (objc_protocol_template, buf);
563 OBJCMETA (decl, objc_meta, meta_base);
568 gnu_runtime_abi_01_string_decl (tree type, const char *name,
569 string_section where ATTRIBUTE_UNUSED)
571 tree decl = start_var_decl (type, name);
572 OBJCMETA (decl, objc_meta, meta_base);
579 gnu_runtime_abi_01_get_class_reference (tree ident)
583 add_class_reference (ident);
585 params = build_tree_list (NULL_TREE, my_build_string_pointer
586 (IDENTIFIER_LENGTH (ident) + 1,
587 IDENTIFIER_POINTER (ident)));
589 return build_function_call (input_location, objc_get_class_decl, params);
592 /* Used by build_function_type_for_method. Append the types for
593 receiver & _cmd at the start of a method argument list to ARGTYPES.
594 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
595 trying to define a method or call one. SUPERFLAG says this is for a
596 send to super. METH may be NULL, in the case that there is no
600 gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
601 tree meth, int context,
602 int superflag ATTRIBUTE_UNUSED)
606 if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
607 receiver_type = objc_instance_type;
609 receiver_type = objc_object_type;
611 vec_safe_push (*argtypes, receiver_type);
612 /* Selector type - will eventually change to `int'. */
613 vec_safe_push (*argtypes, objc_selector_type);
616 /* Unused for GNU runtime. */
618 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED)
623 /* sel_ref_chain is a list whose "value" fields will be instances of
624 identifier_node that represent the selector. LOC is the location of
628 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc, tree ident,
631 tree *chain = &sel_ref_chain;
637 /* When we do a lookup for @selector () we have no idea of the
638 prototype - so match the first we find. */
639 if (TREE_VALUE (*chain) == ident
640 && (!prototype || TREE_PURPOSE (*chain) == prototype))
641 goto return_at_index;
644 chain = &TREE_CHAIN (*chain);
647 *chain = tree_cons (prototype, ident, NULL_TREE);
649 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
650 (b) provide better diagnostics for the first time an undefined
653 expr = build_unary_op (loc, ADDR_EXPR,
654 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
655 build_int_cst (NULL_TREE, index)),
657 return convert (objc_selector_type, expr);
660 /* Build a tree expression to send OBJECT the operation SELECTOR,
661 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
662 assuming the method has prototype METHOD_PROTOTYPE.
663 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
664 LOC is the location of the expression to build.
665 Use METHOD_PARAMS as list of args to pass to the method.
666 If SUPER_FLAG is nonzero, we look up the superclass's method. */
669 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
670 tree lookup_object, tree selector,
673 tree sender = (super_flag ? umsg_super_decl
674 : (flag_objc_direct_dispatch ? umsg_fast_decl
676 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
677 vec<tree, va_gc> *parms;
678 vec<tree, va_gc> *tv;
679 unsigned nparm = (method_params ? list_length (method_params) : 0);
681 /* If a prototype for the method to be called exists, then cast
682 the sender's return type and arguments to match that of the method.
683 Otherwise, leave sender as is. */
686 ? TREE_VALUE (TREE_TYPE (method_prototype))
689 = build_function_type_for_method (ret_type, method_prototype,
690 METHOD_REF, super_flag);
694 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
695 ftype = build_type_attribute_variant (ftype,
696 METHOD_TYPE_ATTRIBUTES
699 sender_cast = build_pointer_type (ftype);
701 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
703 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
704 lookup_object = save_expr (lookup_object);
706 /* Param list + 2 slots for object and selector. */
707 vec_alloc (parms, nparm + 2);
710 /* First, call the lookup function to get a pointer to the method,
711 then cast the pointer, then call it with the method arguments. */
712 tv->quick_push (lookup_object);
713 tv->quick_push (selector);
714 method = build_function_call_vec (loc, vNULL, sender, tv, NULL);
717 /* Pass the appropriate object to the method. */
718 parms->quick_push ((super_flag ? self_decl : lookup_object));
720 /* Pass the selector to the method. */
721 parms->quick_push (selector);
722 /* Now append the remainder of the parms. */
724 for (; method_params; method_params = TREE_CHAIN (method_params))
725 parms->quick_push (TREE_VALUE (method_params));
727 /* Build an obj_type_ref, with the correct cast for the method call. */
728 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
729 t = build_function_call_vec (loc, vNULL, t, parms, NULL);
735 gnu_runtime_abi_01_build_objc_method_call (location_t loc,
736 tree method_prototype,
738 tree rtype ATTRIBUTE_UNUSED,
741 int super ATTRIBUTE_UNUSED)
744 gnu_runtime_abi_01_build_typed_selector_reference (loc,
748 return build_objc_method_call (loc, super, method_prototype, receiver,
749 selector, method_params);
753 gnu_runtime_abi_01_get_protocol_reference (location_t loc, tree p)
755 tree expr, protocol_struct_type, *chain;
756 if (!PROTOCOL_FORWARD_DECL (p))
757 PROTOCOL_FORWARD_DECL (p) = gnu_runtime_abi_01_protocol_decl (p);
759 expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
761 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
762 if we have it, rather than converting it here. */
763 expr = convert (objc_protocol_type, expr);
765 /* The @protocol() expression is being compiled into a pointer to a
766 statically allocated instance of the Protocol class. To become
767 usable at runtime, the 'isa' pointer of the instance need to be
768 fixed up at runtime by the runtime library, to point to the
769 actual 'Protocol' class. */
771 /* For the GNU runtime, put the static Protocol instance in the list
772 of statically allocated instances, so that we make sure that its
773 'isa' pointer is fixed up at runtime by the GNU runtime library
774 to point to the Protocol class (at runtime, when loading the
775 module, the GNU runtime library loops on the statically allocated
776 instances (as found in the defs field in objc_symtab) and fixups
777 all the 'isa' pointers of those objects). */
779 /* This type is a struct containing the fields of a Protocol
780 object. (Cfr. objc_protocol_type instead is the type of a pointer
781 to such a struct). */
782 protocol_struct_type = xref_tag (RECORD_TYPE,
783 get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
785 /* Look for the list of Protocol statically allocated instances
786 to fixup at runtime. Create a new list to hold Protocol
787 statically allocated instances, if the list is not found. At
788 present there is only another list, holding NSConstantString
789 static instances to be fixed up at runtime. */
791 for (chain = &objc_static_instances;
792 *chain && TREE_VALUE (*chain) != protocol_struct_type;
793 chain = &TREE_CHAIN (*chain));
797 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
798 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
802 /* Add this statically allocated instance to the Protocol list. */
803 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
804 PROTOCOL_FORWARD_DECL (p),
805 TREE_PURPOSE (*chain));
809 /* For ABI 8 an IVAR is just a fixed offset in the class struct. */
812 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
815 return objc_build_component_ref (base, id);
818 /* We build super class references as we need them (but keep them once
819 built for the sake of efficiency). */
822 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
823 struct imp_entry *imp, bool inst_meth)
829 objc_build_component_ref (imp->class_decl,
830 get_identifier ("super_class"));
831 return ucls_super_ref;
835 if (!uucls_super_ref)
837 objc_build_component_ref (imp->meta_decl,
838 get_identifier ("super_class"));
839 return uucls_super_ref;
844 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
845 struct imp_entry *imp, bool inst_meth)
847 tree super_name = CLASS_SUPER_NAME (imp->imp_template);
850 add_class_reference (super_name);
851 super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
852 super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
853 IDENTIFIER_POINTER (super_name));
854 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
855 return build_function_call (input_location,
857 build_tree_list (NULL_TREE, super_name));
861 gnu_runtime_abi_01_setup_const_string_class_decl (void)
863 /* Do nothing, and create no error. */
867 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
869 static GTY(()) int num_static_inst;
872 objc_add_static_instance (tree constructor, tree class_decl)
877 /* Find the list of static instances for the CLASS_DECL. Create one if
879 for (chain = &objc_static_instances;
880 *chain && TREE_VALUE (*chain) != class_decl;
881 chain = &TREE_CHAIN (*chain));
884 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
885 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
888 snprintf (buf, BUFSIZE, "_OBJC_INSTANCE_%d", num_static_inst++);
889 decl = build_decl (input_location,
890 VAR_DECL, get_identifier (buf), class_decl);
891 TREE_STATIC (decl) = 1;
892 DECL_ARTIFICIAL (decl) = 1;
893 TREE_USED (decl) = 1;
894 DECL_INITIAL (decl) = constructor;
895 DECL_CONTEXT (decl) = NULL;
896 OBJCMETA (decl, objc_meta, meta_base);
898 /* We may be writing something else just now.
899 Postpone till end of input. */
900 DECL_DEFER_OUTPUT (decl) = 1;
901 pushdecl_top_level (decl);
902 rest_of_decl_compilation (decl, 1, 0);
904 /* Add the DECL to the head of this CLASS' list. */
905 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
911 gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string,
914 tree constructor, fields;
915 vec<constructor_elt, va_gc> *v = NULL;
917 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
918 fields = TYPE_FIELDS (internal_const_str_type);
919 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0));
921 fields = DECL_CHAIN (fields);
922 CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc,
923 ADDR_EXPR, string, 1));
925 fields = DECL_CHAIN (fields);
926 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
927 constructor = objc_build_constructor (internal_const_str_type, v);
929 constructor = objc_add_static_instance (constructor, constant_string_type);
933 /* --- metadata - module initializer --- */
935 /* The GNU runtime requires us to provide a static initializer function
938 static void __objc_gnu_init (void) {
939 __objc_exec_class (&L_OBJC_MODULES);
944 build_module_initializer_routine (void)
949 push_lang_context (lang_name_c); /* extern "C" */
952 objc_push_parm (build_decl (input_location,
953 PARM_DECL, NULL_TREE, void_type_node));
955 objc_start_function (get_identifier (TAG_GNUINIT),
956 build_function_type_list (void_type_node, NULL_TREE),
957 NULL_TREE, NULL_TREE);
959 objc_start_function (get_identifier (TAG_GNUINIT),
960 build_function_type_list (void_type_node, NULL_TREE),
961 NULL_TREE, objc_get_parm_info (0, NULL_TREE));
963 body = c_begin_compound_stmt (true);
964 add_stmt (build_function_call
969 build_unary_op (input_location, ADDR_EXPR,
970 UOBJC_MODULES_decl, 0))));
971 add_stmt (c_end_compound_stmt (input_location, body, true));
973 TREE_PUBLIC (current_function_decl) = 0;
976 /* For Objective-C++, we will need to call __objc_gnu_init
977 from objc_generate_static_init_call() below. */
978 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
981 GNU_INIT_decl = current_function_decl;
990 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
991 to be called by the module initializer routine. */
994 objc_static_init_needed_p (void)
996 return (GNU_INIT_decl != NULL_TREE);
999 /* Generate a call to the __objc_gnu_init initializer function. */
1002 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
1004 add_stmt (build_stmt (input_location, EXPR_STMT,
1005 build_function_call (input_location,
1006 GNU_INIT_decl, NULL_TREE)));
1010 #endif /* OBJCPLUS */
1012 /* --- Output GNU Meta-data --- */
1015 generate_classref_translation_entry (tree chain)
1017 tree expr, decl, type;
1019 decl = TREE_PURPOSE (chain);
1020 type = TREE_TYPE (decl);
1022 expr = add_objc_string (TREE_VALUE (chain), class_names);
1023 expr = convert (type, expr); /* cast! */
1025 /* This is a class reference. It is re-written by the runtime,
1026 but will be optimized away unless we force it. */
1027 DECL_PRESERVE_P (decl) = 1;
1028 OBJCMETA (decl, objc_meta, meta_base);
1029 finish_var_decl (decl, expr);
1035 handle_impent (struct imp_entry *impent)
1039 /* objc_implementation_context = impent->imp_context;
1040 implementation_template = impent->imp_template;*/
1042 switch (TREE_CODE (impent->imp_context))
1044 case CLASS_IMPLEMENTATION_TYPE:
1046 const char *const class_name =
1047 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1049 string = (char *) alloca (strlen (class_name) + 30);
1051 sprintf (string, "__objc_class_name_%s", class_name);
1054 case CATEGORY_IMPLEMENTATION_TYPE:
1056 const char *const class_name =
1057 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1058 const char *const class_super_name =
1059 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
1061 string = (char *) alloca (strlen (class_name)
1062 + strlen (class_super_name) + 30);
1064 /* Do the same for categories. Even though no references to
1065 these symbols are generated automatically by the compiler,
1066 it gives you a handle to pull them into an archive by
1068 sprintf (string, "*__objc_category_name_%s_%s", class_name, class_super_name);
1078 init = integer_zero_node;
1079 decl = build_decl (input_location,
1080 VAR_DECL, get_identifier (string), TREE_TYPE (init));
1081 TREE_PUBLIC (decl) = 1;
1082 TREE_READONLY (decl) = 1;
1083 TREE_USED (decl) = 1;
1084 TREE_CONSTANT (decl) = 1;
1085 DECL_CONTEXT (decl) = NULL_TREE;
1086 DECL_ARTIFICIAL (decl) = 1;
1087 TREE_STATIC (decl) = 1;
1088 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
1089 /* We must force the reference. */
1090 DECL_PRESERVE_P (decl) = 1;
1092 finish_var_decl(decl, init) ;
1097 build_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
1098 tree inst_methods, tree class_methods)
1102 vec<constructor_elt, va_gc> *inits = NULL;
1104 /* TODO: pass the loc in or find it from args. */
1105 loc = input_location;
1106 ttyp = build_pointer_type (xref_tag (RECORD_TYPE,
1107 get_identifier (UTAG_CLASS)));
1108 /* Filling the "isa" in with a version allows the runtime system to
1110 expr = build_int_cst (ttyp, PROTOCOL_VERSION);
1112 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1114 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
1115 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
1117 ttyp = objc_method_proto_list_ptr;
1119 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1121 expr = convert (ttyp, null_pointer_node);
1122 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1125 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1127 expr = convert (ttyp, null_pointer_node);
1128 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1130 return objc_build_constructor (type, inits);
1134 generate_protocol_list (tree i_or_p, tree klass_ctxt)
1136 tree array_type, ptype, refs_decl, lproto, e, plist;
1137 vec<constructor_elt, va_gc> *v = NULL;
1141 switch (TREE_CODE (i_or_p))
1143 case CLASS_INTERFACE_TYPE:
1144 case CATEGORY_INTERFACE_TYPE:
1145 plist = CLASS_PROTOCOL_LIST (i_or_p);
1147 case PROTOCOL_INTERFACE_TYPE:
1148 plist = PROTOCOL_LIST (i_or_p);
1155 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1156 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
1157 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
1160 /* Build initializer. */
1161 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1162 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
1163 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1165 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1167 tree pval = TREE_VALUE (lproto);
1169 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
1170 && PROTOCOL_FORWARD_DECL (pval))
1172 tree fwref = PROTOCOL_FORWARD_DECL (pval);
1173 location_t loc = DECL_SOURCE_LOCATION (fwref) ;
1174 e = build_unary_op (loc, ADDR_EXPR, fwref, 0);
1175 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1179 /* static struct objc_protocol *refs[n]; */
1181 switch (TREE_CODE (i_or_p))
1183 case PROTOCOL_INTERFACE_TYPE:
1184 snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
1185 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
1187 case CLASS_INTERFACE_TYPE:
1188 snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
1189 IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
1191 case CATEGORY_INTERFACE_TYPE:
1192 snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
1193 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)),
1194 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt)));
1200 ptype = build_pointer_type (objc_protocol_template);
1201 array_type = build_sized_array_type (ptype, size + 3);
1202 refs_decl = start_var_decl (array_type, buf);
1203 OBJCMETA (refs_decl, objc_meta, meta_base);
1204 finish_var_decl (refs_decl,
1205 objc_build_constructor (TREE_TYPE (refs_decl), v));
1211 generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix)
1213 tree method_list_template, initlist, decl;
1215 vec<constructor_elt, va_gc> *v = NULL;
1218 if (!chain || !prefix)
1221 if (!objc_method_prototype_template)
1222 objc_method_prototype_template = build_method_prototype_template ();
1224 size = list_length (chain);
1225 method_list_template =
1226 build_method_prototype_list_template (objc_method_prototype_template,
1228 snprintf (buf, BUFSIZE, "%s_%s", prefix,
1229 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
1231 decl = start_var_decl (method_list_template, buf);
1233 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
1235 build_descriptor_table_initializer (objc_method_prototype_template,
1237 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1238 OBJCMETA (decl, objc_meta, meta_base);
1239 finish_var_decl (decl, objc_build_constructor (method_list_template, v));
1243 /* For each protocol which was referenced either from a @protocol()
1244 expression, or because a class/category implements it (then a
1245 pointer to the protocol is stored in the struct describing the
1246 class/category), we create a statically allocated instance of the
1247 Protocol class. The code is written in such a way as to generate
1248 as few Protocol objects as possible; we generate a unique Protocol
1249 instance for each protocol, and we don't generate a Protocol
1250 instance if the protocol is never referenced (either from a
1251 @protocol() or from a class/category implementation). These
1252 statically allocated objects can be referred to via the static
1253 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1255 The statically allocated Protocol objects that we generate here
1256 need to be fixed up at runtime in order to be used: the 'isa'
1257 pointer of the objects need to be set up to point to the 'Protocol'
1258 class, as known at runtime.
1260 The GNU runtime fixes up all protocols before user code from the module
1261 is executed; it requires pointers to those symbols
1262 to be put in the objc_symtab (which is then passed as argument to
1263 the function __objc_exec_class() which the compiler sets up to be
1264 executed automatically when the module is loaded); setup of those
1265 Protocol objects happen in two ways in the GNU runtime: all
1266 Protocol objects referred to by a class or category implementation
1267 are fixed up when the class/category is loaded; all Protocol
1268 objects referred to by a @protocol() expression are added by the
1269 compiler to the list of statically allocated instances to fixup
1270 (the same list holding the statically allocated constant string
1271 objects). Because, as explained above, the compiler generates as
1272 few Protocol objects as possible, some Protocol object might end up
1273 being referenced multiple times when compiled with the GNU runtime,
1274 and end up being fixed up multiple times at runtime initialization.
1275 But that doesn't hurt, it's just a little inefficient. */
1278 generate_protocols (void)
1282 tree initlist, protocol_name_expr, refs_decl, refs_expr;
1284 /* If a protocol was directly referenced, pull in indirect references. */
1285 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1286 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
1287 generate_protocol_references (PROTOCOL_LIST (p));
1289 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1291 tree nst_methods = PROTOCOL_NST_METHODS (p);
1292 tree cls_methods = PROTOCOL_CLS_METHODS (p);
1294 /* If protocol wasn't referenced, don't generate any code. */
1295 decl = PROTOCOL_FORWARD_DECL (p);
1300 /* Make sure we link in the Protocol class. */
1301 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
1305 if (! METHOD_ENCODING (nst_methods))
1307 encoding = encode_method_prototype (nst_methods);
1308 METHOD_ENCODING (nst_methods) = encoding;
1310 nst_methods = DECL_CHAIN (nst_methods);
1313 UOBJC_INSTANCE_METHODS_decl =
1314 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
1315 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1319 if (! METHOD_ENCODING (cls_methods))
1321 encoding = encode_method_prototype (cls_methods);
1322 METHOD_ENCODING (cls_methods) = encoding;
1325 cls_methods = DECL_CHAIN (cls_methods);
1328 UOBJC_CLASS_METHODS_decl =
1329 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
1330 "_OBJC_PROTOCOL_CLASS_METHODS");
1331 /* generate_method_descriptors (p);*/
1333 if (PROTOCOL_LIST (p))
1334 refs_decl = generate_protocol_list (p, NULL_TREE);
1338 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1339 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
1342 refs_expr = convert (build_pointer_type (build_pointer_type
1343 (objc_protocol_template)),
1344 build_unary_op (input_location,
1345 ADDR_EXPR, refs_decl, 0));
1347 refs_expr = build_int_cst (NULL_TREE, 0);
1349 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1350 by generate_method_descriptors, which is called above. */
1351 initlist = build_protocol_initializer (TREE_TYPE (decl),
1352 protocol_name_expr, refs_expr,
1353 UOBJC_INSTANCE_METHODS_decl,
1354 UOBJC_CLASS_METHODS_decl);
1355 finish_var_decl (decl, initlist);
1360 generate_dispatch_table (tree chain, const char *name)
1362 tree decl, method_list_template, initlist;
1363 vec<constructor_elt, va_gc> *v = NULL;
1364 int size = list_length (chain);
1366 if (!objc_method_template)
1367 objc_method_template = build_method_template ();
1369 method_list_template = build_method_list_template (objc_method_template,
1371 initlist = build_dispatch_table_initializer (objc_method_template, chain);
1373 decl = start_var_decl (method_list_template, name);
1375 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1376 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1377 build_int_cst (integer_type_node, size));
1378 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1380 OBJCMETA (decl, objc_meta, meta_base);
1381 finish_var_decl (decl,
1382 objc_build_constructor (TREE_TYPE (decl), v));
1387 /* Init a category. */
1389 build_category_initializer (tree type, tree cat_name, tree class_name,
1390 tree inst_methods, tree class_methods,
1395 vec<constructor_elt, va_gc> *v = NULL;
1397 /* TODO: pass the loc in or find it from args. */
1398 /* TODO: pass the loc in or find it from args. */
1399 loc = UNKNOWN_LOCATION;
1400 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
1401 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
1403 ltyp = objc_method_list_ptr;
1405 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1407 expr = convert (ltyp, null_pointer_node);
1408 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1411 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1413 expr = convert (ltyp, null_pointer_node);
1414 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1416 /* protocol_list = */
1417 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1419 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0));
1421 expr = convert (ltyp, null_pointer_node);
1422 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1424 return objc_build_constructor (type, v);
1427 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1430 generate_category (struct imp_entry *impent)
1432 tree initlist, cat_name_expr, class_name_expr;
1433 tree protocol_decl, category, cat_decl;
1434 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1435 tree cat = impent->imp_context;
1438 cat_decl = impent->class_decl;
1440 add_class_reference (CLASS_NAME (cat));
1441 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
1443 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
1445 category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat));
1447 if (category && CLASS_PROTOCOL_LIST (category))
1449 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
1450 protocol_decl = generate_protocol_list (category, cat);
1455 if (CLASS_NST_METHODS (cat))
1457 snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s",
1458 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1459 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1460 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf);
1463 if (CLASS_CLS_METHODS (cat))
1465 snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s",
1466 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1467 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1468 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf);
1471 initlist = build_category_initializer (TREE_TYPE (cat_decl),
1472 cat_name_expr, class_name_expr,
1473 inst_methods, class_methods,
1475 /* Finish and initialize the forward decl. */
1476 finish_var_decl (cat_decl, initlist);
1477 impent->class_decl = cat_decl;
1480 /* struct _objc_class {
1481 struct objc_class *isa;
1482 struct objc_class *super_class;
1487 struct objc_ivar_list *ivars;
1488 struct objc_method_list *methods;
1489 struct sarray *dtable;
1490 struct objc_class *subclass_list;
1491 struct objc_class *sibling_class;
1492 struct objc_protocol_list *protocols;
1493 void *gc_object_type;
1497 build_shared_structure_initializer (tree type, tree isa, tree super,
1498 tree name, tree size, int status,
1499 tree dispatch_table, tree ivar_list,
1503 vec<constructor_elt, va_gc> *v = NULL;
1506 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
1509 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
1512 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
1515 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1516 build_int_cst (long_integer_type_node, 0));
1519 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1520 build_int_cst (long_integer_type_node, status));
1522 /* instance_size = */
1523 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1524 convert (long_integer_type_node, size));
1526 /* objc_ivar_list = */
1528 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1529 build_int_cst (objc_ivar_list_ptr, 0));
1532 expr = convert (objc_ivar_list_ptr,
1533 build_unary_op (input_location, ADDR_EXPR,
1535 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1538 /* objc_method_list = */
1539 if (!dispatch_table)
1540 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1541 convert (objc_method_list_ptr, null_pointer_node));
1544 expr = convert (objc_method_list_ptr,
1545 build_unary_op (input_location, ADDR_EXPR,
1546 dispatch_table, 0));
1547 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1550 /* FIXME: Remove NeXT runtime code. */
1551 if (flag_next_runtime)
1553 ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
1554 get_identifier ("objc_cache")));
1555 /* method_cache = */
1556 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
1561 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1563 /* subclass_list = */
1564 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1566 /* sibling_class = */
1567 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1570 /* protocol_list = */
1571 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1572 if (! protocol_list)
1573 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0));
1576 expr = convert (ltyp,
1577 build_unary_op (input_location, ADDR_EXPR,
1579 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1582 /* FIXME: Remove NeXT runtime code. */
1583 if (flag_next_runtime)
1585 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1587 /* gc_object_type = NULL */
1588 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1590 return objc_build_constructor (type, v);
1595 generate_ivars_list (tree chain, const char *name)
1597 tree initlist, ivar_list_template, decl;
1599 vec<constructor_elt, va_gc> *inits = NULL;
1604 if (!objc_ivar_template)
1605 objc_ivar_template = build_ivar_template ();
1607 size = ivar_list_length (chain);
1609 generating_instance_variables = 1;
1610 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1611 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
1612 generating_instance_variables = 0;
1614 decl = start_var_decl (ivar_list_template, name);
1616 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
1617 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
1619 OBJCMETA (decl, objc_meta, meta_base);
1620 finish_var_decl (decl,
1621 objc_build_constructor (TREE_TYPE (decl), inits));
1626 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1627 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1630 generate_class_structures (struct imp_entry *impent)
1632 tree name_expr, super_expr, root_expr, class_decl, meta_decl;
1633 tree my_root_id, my_super_id;
1634 tree cast_type, initlist, protocol_decl;
1635 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1636 tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
1641 /* objc_implementation_context = impent->imp_context;
1642 implementation_template = impent->imp_template;*/
1643 class_decl = impent->class_decl;
1644 meta_decl = impent->meta_decl;
1645 /* UOBJC_CLASS_decl = impent->class_decl;
1646 UOBJC_METACLASS_decl = impent->meta_decl;*/
1648 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1650 my_super_id = CLASS_SUPER_NAME (impent->imp_template);
1653 add_class_reference (my_super_id);
1655 /* Compute "my_root_id" - this is required for code generation.
1656 the "isa" for all meta class structures points to the root of
1657 the inheritance hierarchy (e.g. "__Object")... */
1658 my_root_id = my_super_id;
1661 tree my_root_int = lookup_interface (my_root_id);
1663 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
1664 my_root_id = CLASS_SUPER_NAME (my_root_int);
1671 /* No super class. */
1672 my_root_id = CLASS_NAME (impent->imp_template);
1674 cast_type = build_pointer_type (objc_class_template);
1675 name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
1678 /* Install class `isa' and `super' pointers at runtime. */
1680 super_expr = add_objc_string (my_super_id, class_names);
1682 super_expr = null_pointer_node;
1684 super_expr = build_c_cast (loc, cast_type, super_expr);
1686 root_expr = add_objc_string (my_root_id, class_names);
1687 root_expr = build_c_cast (loc, cast_type, root_expr);
1689 if (CLASS_PROTOCOL_LIST (impent->imp_template))
1691 generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
1692 protocol_decl = generate_protocol_list (impent->imp_template,
1693 impent->imp_context);
1696 protocol_decl = NULL_TREE;
1698 if (CLASS_CLS_METHODS (impent->imp_context))
1700 snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
1701 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1702 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
1706 if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE
1707 && (chain = TYPE_FIELDS (objc_class_template)))
1709 snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s",
1710 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1711 class_ivars = generate_ivars_list (chain, buf);
1714 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1717 build_shared_structure_initializer
1718 (TREE_TYPE (meta_decl),
1719 root_expr, super_expr, name_expr,
1720 convert (integer_type_node,
1721 TYPE_SIZE_UNIT (objc_class_template)),
1722 CLS_META, class_methods, class_ivars,
1725 finish_var_decl (meta_decl, initlist);
1726 impent->meta_decl = meta_decl;
1728 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1729 if (CLASS_NST_METHODS (impent->imp_context))
1731 snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
1732 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1733 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
1737 if ((chain = CLASS_IVARS (impent->imp_template)))
1739 snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
1740 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1741 inst_ivars = generate_ivars_list (chain, buf);
1745 build_shared_structure_initializer
1746 (TREE_TYPE (class_decl),
1747 build_unary_op (loc, ADDR_EXPR, meta_decl, 0),
1748 super_expr, name_expr,
1749 convert (integer_type_node,
1750 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1751 (impent->imp_template))),
1752 CLS_FACTORY | cls_flags, inst_methods, inst_ivars,
1755 finish_var_decl (class_decl, initlist);
1756 impent->class_decl = class_decl;
1759 /* --- Output GNU Metadata --- */
1761 /* TODO: Make this into an array of refs. */
1763 handle_class_ref (tree chain)
1765 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
1766 char *string = (char *) alloca (strlen (name) + 30);
1770 sprintf (string, "__objc_class_name_%s", name);
1772 /* Make a decl for this name, so we can use its address in a tree. */
1773 decl = build_decl (input_location,
1774 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
1775 DECL_EXTERNAL (decl) = 1;
1776 TREE_PUBLIC (decl) = 1;
1777 DECL_CONTEXT (decl) = NULL_TREE;
1778 finish_var_decl (decl, 0);
1780 /* Make a decl for the address. */
1781 sprintf (string, "__objc_class_ref_%s", name);
1782 exp = build1 (ADDR_EXPR, string_type_node, decl);
1783 decl = build_decl (input_location,
1784 VAR_DECL, get_identifier (string), string_type_node);
1785 TREE_STATIC (decl) = 1;
1786 TREE_USED (decl) = 1;
1787 DECL_READ_P (decl) = 1;
1788 DECL_ARTIFICIAL (decl) = 1;
1789 DECL_INITIAL (decl) = error_mark_node;
1791 /* We must force the reference. */
1792 DECL_PRESERVE_P (decl) = 1;
1794 DECL_CONTEXT (decl) = NULL_TREE;
1795 finish_var_decl (decl, exp);
1799 get_proto_encoding (tree proto)
1804 if (! METHOD_ENCODING (proto))
1806 encoding = encode_method_prototype (proto);
1807 METHOD_ENCODING (proto) = encoding;
1810 encoding = METHOD_ENCODING (proto);
1812 return add_objc_string (encoding, meth_var_types);
1815 return build_int_cst (NULL_TREE, 0);
1819 build_gnu_selector_translation_table (void)
1822 vec<constructor_elt, va_gc> *inits = NULL;
1823 vec<constructor_elt, va_gc> *v ;
1825 /* Cause the selector table (previously forward-declared)
1826 to be actually output. */
1828 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1833 /* TODO: improve on the location for the diagnostic. */
1834 location_t loc = input_location;
1835 diagnose_missing_method (TREE_VALUE (chain), loc);
1839 expr = build_selector (TREE_VALUE (chain));
1840 encoding = get_proto_encoding (TREE_PURPOSE (chain));
1841 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1842 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
1843 expr = objc_build_constructor (objc_selector_template, v);
1845 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1846 } /* each element in the chain */
1848 /* List terminator. */
1850 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1851 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1852 expr = objc_build_constructor (objc_selector_template, v);
1854 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1855 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1857 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
1860 /* Output references to all statically allocated objects. Return the DECL
1861 for the array built. */
1864 generate_static_references (void)
1866 tree expr = NULL_TREE;
1867 tree class_name, klass, decl;
1868 tree cl_chain, in_chain, type
1869 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
1870 int num_inst, num_class;
1872 vec<constructor_elt, va_gc> *decls = NULL;
1874 /* FIXME: Remove NeXT runtime code. */
1875 if (flag_next_runtime)
1878 for (cl_chain = objc_static_instances, num_class = 0;
1879 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1881 vec<constructor_elt, va_gc> *v = NULL;
1883 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1884 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1886 snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class);
1887 decl = start_var_decl (type, buf);
1889 /* Output {class_name, ...}. */
1890 klass = TREE_VALUE (cl_chain);
1891 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
1892 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1893 build_unary_op (input_location,
1894 ADDR_EXPR, class_name, 1));
1896 /* Output {..., instance, ...}. */
1897 for (in_chain = TREE_PURPOSE (cl_chain);
1898 in_chain; in_chain = TREE_CHAIN (in_chain))
1900 expr = build_unary_op (input_location,
1901 ADDR_EXPR, TREE_VALUE (in_chain), 1);
1902 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1905 /* Output {..., NULL}. */
1906 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1908 expr = objc_build_constructor (TREE_TYPE (decl), v);
1909 OBJCMETA (decl, objc_meta, meta_base);
1910 finish_var_decl (decl, expr);
1911 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
1912 build_unary_op (input_location,
1913 ADDR_EXPR, decl, 1));
1916 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
1917 expr = objc_build_constructor (type, decls);
1918 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
1919 OBJCMETA (static_instances_decl, objc_meta, meta_base);
1920 finish_var_decl (static_instances_decl, expr);
1923 /* Create the initial value for the `defs' field of _objc_symtab.
1924 This is a CONSTRUCTOR. */
1927 init_def_list (tree type)
1930 struct imp_entry *impent;
1932 vec<constructor_elt, va_gc> *v = NULL;
1935 for (impent = imp_list; impent; impent = impent->next)
1937 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1939 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1940 expr = build_unary_op (loc,
1941 ADDR_EXPR, impent->class_decl, 0);
1942 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1947 for (impent = imp_list; impent; impent = impent->next)
1949 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1951 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1952 expr = build_unary_op (loc,
1953 ADDR_EXPR, impent->class_decl, 0);
1954 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1958 loc = UNKNOWN_LOCATION;
1959 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1960 if (static_instances_decl)
1961 expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0);
1963 expr = integer_zero_node;
1964 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1966 return objc_build_constructor (type, v);
1969 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1971 /* Predefine the following data type:
1979 void *defs[cls_def_cnt + cat_def_cnt];
1983 build_objc_symtab_template (void)
1985 tree fields, array_type, *chain = NULL;
1988 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
1990 /* long sel_ref_cnt; */
1991 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
1994 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
1996 /* short cls_def_cnt; */
1997 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
1999 /* short cat_def_cnt; */
2000 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
2002 /* Note that padding will be added here on LP64. */
2004 /* void *defs[imp_count + cat_count (+ 1)]; */
2005 /* NB: The index is one less than the size of the array. */
2006 index = imp_count + cat_count;
2007 array_type = build_sized_array_type (ptr_type_node, index + 1);
2008 add_field_decl (array_type, "defs", &chain);
2010 objc_finish_struct (objc_symtab_template, fields);
2012 /* Construct the initial value for all of _objc_symtab. */
2015 init_objc_symtab (tree type)
2017 tree field, expr, ltyp;
2019 vec<constructor_elt, va_gc> *v = NULL;
2021 loc = UNKNOWN_LOCATION;
2023 /* sel_ref_cnt = { ..., 5, ... } */
2025 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2026 build_int_cst (long_integer_type_node, 0));
2028 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2030 ltyp = build_pointer_type (objc_selector_type);
2032 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,
2033 UOBJC_SELECTOR_TABLE_decl, 1));
2035 expr = convert (ltyp, null_pointer_node);
2036 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2038 /* cls_def_cnt = { ..., 5, ... } */
2040 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2041 build_int_cst (short_integer_type_node, imp_count));
2043 /* cat_def_cnt = { ..., 5, ... } */
2045 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2046 build_int_cst (short_integer_type_node, cat_count));
2048 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2050 field = TYPE_FIELDS (type);
2051 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2053 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2055 return objc_build_constructor (type, v);
2058 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2059 and initialized appropriately. */
2062 generate_objc_symtab_decl (void)
2064 build_objc_symtab_template ();
2065 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2066 OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base);
2067 finish_var_decl (UOBJC_SYMBOLS_decl,
2068 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2072 objc_generate_v1_gnu_metadata (void)
2074 struct imp_entry *impent;
2077 /* Process the static instances here because initialization of objc_symtab
2079 if (objc_static_instances)
2080 generate_static_references ();
2082 objc_implementation_context =
2083 implementation_template =
2085 UOBJC_METACLASS_decl = NULL_TREE;
2087 for (impent = imp_list; impent; impent = impent->next)
2089 /* If -gen-decls is present, Dump the @interface of each class.
2090 TODO: Dump the classes in the order they were found, rather than in
2091 reverse order as we are doing now. */
2092 if (flag_gen_declaration)
2093 dump_interface (gen_declaration_file, impent->imp_context);
2095 /* all of the following reference the string pool... */
2096 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2097 generate_class_structures (impent);
2099 generate_category (impent);
2102 /* If we are using an array of selectors, we must always
2103 finish up the array decl even if no selectors were used. */
2104 build_gnu_selector_translation_table ();
2107 generate_protocols ();
2109 /* Arrange for ObjC data structures to be initialized at run time. */
2110 /* FIXME: Have some more elegant way to determine if we need to
2111 generate objc_symtab_decl or not, instead of checking these
2113 if (imp_list || class_names_chain
2114 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain
2115 || prop_names_attr_chain)
2116 generate_objc_symtab_decl ();
2118 if (imp_list || class_names_chain || objc_static_instances
2119 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
2121 /* Make sure that the meta-data are identified as being
2123 build_module_descriptor (OBJC_VERSION,
2124 build_tree_list (objc_meta, meta_base));
2125 build_module_initializer_routine ();
2128 /* Dump the class references. This forces the appropriate classes
2129 to be linked into the executable image, preserving unix archive
2130 semantics. This can be removed when we move to a more dynamically
2131 linked environment. */
2133 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
2135 handle_class_ref (chain);
2136 if (TREE_PURPOSE (chain))
2137 generate_classref_translation_entry (chain);
2140 for (impent = imp_list; impent; impent = impent->next)
2141 handle_impent (impent);
2143 generate_strings ();
2146 /* --- exceptions --- */
2148 static GTY(()) tree objc_eh_personality_decl;
2151 objc_eh_runtime_type (tree type)
2153 tree ident, eh_id, decl, str;
2155 if (type == error_mark_node
2156 || errorcount || sorrycount)
2158 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2159 to prevent an ICE. Note that we know that the compiler will
2160 terminate with an error and this 'ErrorMarkNode' class name will
2161 never be actually used. */
2162 ident = get_identifier ("ErrorMarkNode");
2163 goto make_err_class;
2166 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
2167 /* We don't want to identify 'id' for GNU. Instead, build a 0
2168 entry in the exceptions table. */
2169 return null_pointer_node;
2171 if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
2174 /* This routine is also called for c++ catch clauses; in which case,
2175 we use the c++ typeinfo decl. */
2176 return build_eh_type_type (type);
2178 error ("non-objective-c type '%T' cannot be caught", type);
2179 ident = get_identifier ("ErrorMarkNode");
2180 goto make_err_class;
2184 ident = OBJC_TYPE_NAME (TREE_TYPE (type));
2187 /* If this class was already referenced, then it will be output during
2188 meta-data emission, so we don't need to do it here. */
2189 decl = get_objc_string_decl (ident, class_names);
2190 eh_id = add_objc_string (ident, class_names);
2193 /* Not found ... so we need to build it - from the freshly-entered id. */
2194 decl = get_objc_string_decl (ident, class_names);
2195 str = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2196 IDENTIFIER_POINTER (ident));
2197 /* We have to finalize this var here, because this might be called after
2198 all the other metadata strings have been emitted. */
2199 finish_var_decl (decl, str);
2205 objc_eh_personality (void)
2207 if (!objc_eh_personality_decl)
2209 objc_eh_personality_decl = build_personality_function ("gnu_objc");
2211 objc_eh_personality_decl = build_personality_function ("gxx");
2213 return objc_eh_personality_decl;
2216 /* -- interfaces --- */
2219 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
2222 vec<tree, va_gc> *parms;
2223 vec_alloc (parms, 1);
2224 /* A throw is just a call to the runtime throw function with the
2225 object as a parameter. */
2226 parms->quick_push (throw_expr);
2227 t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl, parms,
2230 return add_stmt (t);
2233 /* Build __builtin_eh_pointer. */
2236 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
2239 t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
2240 t = build_call_expr (t, 1, integer_zero_node);
2241 return fold_convert (objc_object_type, t);
2245 begin_catch (struct objc_try_context **cur_try_context, tree type,
2246 tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
2249 /* Record the data for the catch in the try context so that we can
2250 finalize it later. */
2252 t = build_stmt (input_location, CATCH_EXPR, NULL, compound);
2254 t = build_stmt (input_location, CATCH_EXPR, type, compound);
2255 (*cur_try_context)->current_catch = t;
2257 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2258 t = objc_build_exc_ptr (cur_try_context);
2259 t = convert (TREE_TYPE (decl), t);
2260 return build2 (MODIFY_EXPR, void_type_node, decl, t);
2264 finish_catch (struct objc_try_context **cur_try_context, tree current_catch)
2266 append_to_statement_list (current_catch, &((*cur_try_context)->catch_list));
2270 finish_try_stmt (struct objc_try_context **cur_try_context)
2272 struct objc_try_context *c = *cur_try_context;
2273 tree stmt = c->try_body;
2275 stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
2276 if (c->finally_body)
2277 stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
2281 #include "gt-objc-objc-gnu-runtime-abi-01.h"