1 /* Next Runtime (ABI-2) private.
2 Copyright (C) 2011-2019 Free Software Foundation, Inc.
4 Contributed by Iain Sandoe and based, in part, on an implementation in
5 'branches/apple/trunk' contributed by Apple Computer Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* The NeXT ABI2 is used for m64 implementations on Darwin/OSX machines.
25 This version is intended to match (logically) the output of Apple's
30 #include "coretypes.h"
32 #include "stringpool.h"
36 #include "cp/cp-tree.h"
41 #include "langhooks.h"
42 #include "c-family/c-objc.h"
45 /* When building Objective-C++, we are not linking against the C front-end
46 and so need to replicate the C tree-construction functions in some way. */
48 #define OBJCP_REMAP_FUNCTIONS
49 #include "objcp-decl.h"
53 #include "tree-iterator.h"
55 #include "objc-runtime-hooks.h"
56 #include "objc-runtime-shared-support.h"
57 #include "objc-encoding.h"
59 /* ABI 2 Private definitions. */
60 #define DEF_CONSTANT_STRING_CLASS_NAME "NSConstantString"
62 #define TAG_GETCLASS "objc_getClass"
63 #define TAG_GETMETACLASS "objc_getMetaClass"
65 #define TAG_MSGSEND "objc_msgSend"
66 #define TAG_MSGSENDSUPER "objc_msgSendSuper"
67 #define TAG_MSGSEND_STRET "objc_msgSend_stret"
68 #define TAG_MSGSENDSUPER_STRET "objc_msgSendSuper_stret"
70 #define TAG_NEXT_EHVTABLE_NAME "objc_ehtype_vtable"
71 #define TAG_V2_EH_TYPE "objc_ehtype_t"
73 #define UTAG_V2_CLASS "_class_t"
74 #define UTAG_V2_CLASS_RO "_class_ro_t"
75 #define UTAG_V2_PROTOCOL "_protocol_t"
76 #define UTAG_V2_PROTOCOL_LIST "_protocol_list_t"
78 #define UTAG_V2_EH_TYPE "_objc_ehtype_t"
80 #define OBJC2_CLS_HAS_CXX_STRUCTORS 0x0004L
82 enum objc_v2_tree_index
90 OCTI_V2_IVAR_LIST_TEMPL,
91 OCTI_V2_MESSAGE_REF_TEMPL,
92 OCTI_V2_SUPER_MESSAGE_REF_TEMPL,
94 OCTI_V2_MESSAGE_SELECTOR_TYPE,
95 OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE,
97 OCTI_V2_SUPER_IMP_TYPE,
102 OCTI_V2_PROPERTY_TEMPL,
105 OCTI_V2_UMSG_FIXUP_DECL,
106 OCTI_V2_UMSG_STRET_FIXUP_DECL,
107 OCTI_V2_UMSG_ID_FIXUP_DECL,
108 OCTI_V2_UMSG_ID_STRET_FIXUP_DECL,
109 OCTI_V2_UMSG_SUPER2_FIXUP_DECL,
110 OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL,
112 /* Exceptions - related. */
113 OCTI_V2_BEGIN_CATCH_DECL,
114 OCTI_V2_END_CATCH_DECL,
115 OCTI_V2_RETHROW_DECL,
120 #define objc_v2_class_template objc_v2_global_trees[OCTI_V2_CLS_TEMPL]
121 #define objc_v2_class_ro_template \
122 objc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL]
123 #define objc_v2_category_template \
124 objc_v2_global_trees[OCTI_V2_CAT_TEMPL]
125 #define objc_v2_protocol_template \
126 objc_v2_global_trees[OCTI_V2_PROTO_TEMPL]
128 /* struct message_ref_t */
129 #define objc_v2_message_ref_template \
130 objc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL]
132 #define objc_v2_ivar_list_ptr objc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL]
134 /* struct super_message_ref_t */
135 #define objc_v2_super_message_ref_template \
136 objc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL]
138 /* struct message_ref_t* */
139 #define objc_v2_selector_type objc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE]
140 /* struct super_super_message_ref_t */
141 #define objc_v2_super_selector_type \
142 objc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE]
143 #define objc_v2_imp_type objc_v2_global_trees[OCTI_V2_IMP_TYPE]
144 #define objc_v2_super_imp_type objc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE]
146 #define UOBJC_V2_CACHE_decl objc_v2_global_trees[OCTI_V2_CACHE_DECL]
147 #define UOBJC_V2_VTABLE_decl objc_v2_global_trees[OCTI_V2_VTABLE_DECL]
149 #define objc_v2_ivar_template objc_v2_global_trees[OCTI_V2_IVAR_TEMPL]
150 #define objc_v2_property_template \
151 objc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL]
155 /* objc_msgSend_fixup_rtp */
156 #define umsg_fixup_decl objc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL]
157 /* objc_msgSend_stret_fixup_rtp */
158 #define umsg_stret_fixup_decl objc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL]
159 /* objc_msgSendId_fixup_rtp */
160 #define umsg_id_fixup_decl objc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL]
161 /* objc_msgSendId_stret_fixup_rtp */
162 #define umsg_id_stret_fixup_decl \
163 objc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL]
164 /* objc_msgSendSuper2_fixup_rtp */
165 #define umsg_id_super2_fixup_decl \
166 objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL]
167 /* objc_msgSendSuper2_stret_fixup_rtp */
168 #define umsg_id_super2_stret_fixup_decl \
169 objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL]
171 #define objc2_begin_catch_decl objc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL]
172 #define objc2_end_catch_decl objc_v2_global_trees[OCTI_V2_END_CATCH_DECL]
173 #define objc_rethrow_exception_decl \
174 objc_v2_global_trees[OCTI_V2_RETHROW_DECL]
176 /* rt_trees identifiers - shared between NeXT implementations. These allow
177 the FE to tag meta-data in a manner that survives LTO and can be used when
178 the runtime requires that certain meta-data items appear in particular
181 #include "objc-next-metadata-tags.h"
182 extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX];
184 /* The OCTI_V2_... enumeration itself is in above. */
185 static GTY(()) tree objc_v2_global_trees[OCTI_V2_MAX];
187 static void next_runtime_02_initialize (void);
189 static void build_v2_message_ref_templates (void);
190 static void build_v2_class_templates (void);
191 static void build_v2_super_template (void);
192 static void build_v2_category_template (void);
193 static void build_v2_protocol_template (void);
195 static tree next_runtime_abi_02_super_superclassfield_id (void);
197 static tree next_runtime_abi_02_class_decl (tree);
198 static tree next_runtime_abi_02_metaclass_decl (tree);
199 static tree next_runtime_abi_02_category_decl (tree);
200 static tree next_runtime_abi_02_protocol_decl (tree);
201 static tree next_runtime_abi_02_string_decl (tree, const char *, string_section);
203 static tree next_runtime_abi_02_get_class_reference (tree);
204 static tree next_runtime_abi_02_build_selector_reference (location_t, tree, tree);
205 static tree next_runtime_abi_02_get_protocol_reference (location_t, tree);
206 static tree next_runtime_abi_02_build_ivar_ref (location_t, tree, tree);
207 static tree next_runtime_abi_02_get_class_super_ref (location_t, struct imp_entry *, bool);
208 static tree next_runtime_abi_02_get_category_super_ref (location_t, struct imp_entry *, bool);
210 static tree next_runtime_abi_02_receiver_is_class_object (tree);
211 static void next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **,
213 static tree next_runtime_abi_02_build_objc_method_call (location_t, tree, tree,
214 tree, tree, tree, int);
215 static bool next_runtime_abi_02_setup_const_string_class_decl (void);
216 static tree next_runtime_abi_02_build_const_string_constructor (location_t, tree, int);
218 static tree create_extern_decl (tree, const char *);
220 static void objc_generate_v2_next_metadata (void);
221 static bool objc2_objc_exception_attr (tree);
223 /* void build_v2_protocol_reference (tree);*/
224 static void build_v2_ehtype_template (void);
225 static void build_v2_eh_catch_objects (void);
226 static tree next_runtime_02_eh_type (tree);
227 static tree objc_eh_personality (void);
228 static tree build_throw_stmt (location_t, tree, bool);
229 static tree objc_build_exc_ptr (struct objc_try_context **);
230 static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool);
231 static void finish_catch (struct objc_try_context **, tree);
232 static tree finish_try_stmt (struct objc_try_context **);
234 /* TODO: Use an objc-map. */
235 static GTY ((length ("SIZEHASHTABLE"))) hash *extern_names;
238 objc_next_runtime_abi_02_init (objc_runtime_hooks *rthooks)
240 extern_names = ggc_cleared_vec_alloc<hash> (SIZEHASHTABLE);
242 if (flag_objc_exceptions && flag_objc_sjlj_exceptions)
244 inform (UNKNOWN_LOCATION,
245 "%<-fobjc-sjlj-exceptions%> is ignored for "
246 "%<-fnext-runtime%> when %<-fobjc-abi-version%> "
248 flag_objc_sjlj_exceptions = 0;
251 rthooks->initialize = next_runtime_02_initialize;
252 rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
253 rthooks->tag_getclass = TAG_GETCLASS;
254 rthooks->super_superclassfield_ident = next_runtime_abi_02_super_superclassfield_id;
256 rthooks->class_decl = next_runtime_abi_02_class_decl;
257 rthooks->metaclass_decl = next_runtime_abi_02_metaclass_decl;
258 rthooks->category_decl = next_runtime_abi_02_category_decl;
259 rthooks->protocol_decl = next_runtime_abi_02_protocol_decl;
260 rthooks->string_decl = next_runtime_abi_02_string_decl;
262 rthooks->get_class_reference = next_runtime_abi_02_get_class_reference;
263 rthooks->build_selector_reference = next_runtime_abi_02_build_selector_reference;
264 rthooks->get_protocol_reference = next_runtime_abi_02_get_protocol_reference;
265 rthooks->build_ivar_reference = next_runtime_abi_02_build_ivar_ref;
266 rthooks->get_class_super_ref = next_runtime_abi_02_get_class_super_ref;
267 rthooks->get_category_super_ref = next_runtime_abi_02_get_category_super_ref;
269 rthooks->receiver_is_class_object = next_runtime_abi_02_receiver_is_class_object;
270 rthooks->get_arg_type_list_base = next_runtime_abi_02_get_arg_type_list_base;
271 rthooks->build_objc_method_call = next_runtime_abi_02_build_objc_method_call;
273 rthooks->setup_const_string_class_decl =
274 next_runtime_abi_02_setup_const_string_class_decl;
275 rthooks->build_const_string_constructor =
276 next_runtime_abi_02_build_const_string_constructor;
278 rthooks->build_throw_stmt = build_throw_stmt;
279 rthooks->build_exc_ptr = objc_build_exc_ptr;
280 rthooks->begin_catch = begin_catch;
281 rthooks->finish_catch = finish_catch;
282 rthooks->finish_try_stmt = finish_try_stmt;
284 rthooks->generate_metadata = objc_generate_v2_next_metadata;
288 /* We need a way to convey what kind of meta-data are represented by a given
289 variable, since each type is expected (by the runtime) to be found in a
290 specific named section. The solution must be usable with LTO.
292 The scheme used for NeXT ABI 0/1 (partial matching of variable names) is not
293 satisfactory when LTO is used with ABI-2. We now tag ObjC meta-data with
294 identification attributes in the front end. The back-end may choose to act
295 on these as it requires. */
298 next_runtime_abi_02_init_metadata_attributes (void)
301 objc_meta = get_identifier ("OBJC2META");
304 meta_base = get_identifier ("V2_BASE");
306 meta_class = get_identifier ("G2_CLAS");
307 meta_metaclass = get_identifier ("G2_META");
309 meta_protocol = meta_base;
312 meta_clai_vars = meta_base;
318 meta_proto_cls_meth =
319 meta_proto_nst_meth = meta_base;
322 meta_catg_prot = meta_base;
324 meta_sel_refs = get_identifier ("V2_SRFS");
329 meta_prop_name_attr = get_identifier ("V2_STRG");
331 meta_mref = get_identifier ("V2_MREF");
332 meta_class_ref = get_identifier ("V2_CLRF");
333 meta_superclass_ref = get_identifier ("V2_SURF");
335 meta_label_classlist = get_identifier ("V2_CLAB");
336 meta_label_nonlazy_classlist = get_identifier ("V2_NLCL");
337 meta_label_categorylist = get_identifier ("V2_CALA");
338 meta_label_nonlazy_categorylist = get_identifier ("V2_NLCA");
340 meta_label_protocollist = get_identifier ("V2_PLST");
341 meta_proto_ref = get_identifier ("V2_PRFS");
343 meta_info = get_identifier ("V2_INFO");
345 meta_ehtype = get_identifier ("V2_EHTY");
347 meta_const_str = get_identifier ("V2_CSTR");
350 static void next_runtime_02_initialize (void)
354 /* For all NeXT objc ABIs -fobjc-call-cxx-cdtors is on by
356 if (!global_options_set.x_flag_objc_call_cxx_cdtors)
357 global_options.x_flag_objc_call_cxx_cdtors = 1;
360 /* Set up attributes to be attached to the meta-data so that they
361 will be placed in the correct sections. */
362 next_runtime_abi_02_init_metadata_attributes ();
364 /* `struct objc_selector *' */
365 objc_selector_type = build_pointer_type (xref_tag (RECORD_TYPE,
366 get_identifier (TAG_SELECTOR)));
368 /* IMP : id (*) (id, _message_ref_t*, ...)
369 SUPER_IMP : id (*) ( super_t*, _super_message_ref_t*, ...)
370 objc_v2_selector_type. */
371 build_v2_message_ref_templates ();
373 objc_v2_ivar_list_ptr =
374 build_pointer_type (xref_tag (RECORD_TYPE,
375 get_identifier ("_ivar_list_t")));
378 build_pointer_type (xref_tag (RECORD_TYPE,
379 get_identifier ("_prop_list_t")));
381 build_v2_class_templates ();
382 build_v2_super_template ();
383 build_v2_protocol_template ();
384 build_v2_category_template ();
386 /* id objc_msgSend_fixup_rtp (id, struct message_ref_t*, ...); */
387 type = build_varargs_function_type_list (objc_object_type,
389 objc_v2_selector_type,
391 umsg_fixup_decl = add_builtin_function ("objc_msgSend_fixup",
392 type, 0, NOT_BUILT_IN,
394 TREE_NOTHROW (umsg_fixup_decl) = 0;
396 /* id objc_msgSend_stret_fixup_rtp (id, struct message_ref_t*, ...); */
397 umsg_stret_fixup_decl = add_builtin_function ("objc_msgSend_stret_fixup",
398 type, 0, NOT_BUILT_IN,
400 TREE_NOTHROW (umsg_stret_fixup_decl) = 0;
402 /* id objc_msgSendId_fixup_rtp (id, struct message_ref_t*, ...); */
403 umsg_id_fixup_decl = add_builtin_function ("objc_msgSendId_fixup",
404 type, 0, NOT_BUILT_IN,
406 TREE_NOTHROW (umsg_id_fixup_decl) = 0;
408 /* id objc_msgSendId_stret_fixup_rtp
409 (id, struct message_ref_t*, ...); */
410 umsg_id_stret_fixup_decl = add_builtin_function ("objc_msgSendId_stret_fixup",
411 type, 0, NOT_BUILT_IN,
413 TREE_NOTHROW (umsg_id_stret_fixup_decl) = 0;
415 /* id objc_msgSendSuper2_fixup_rtp
416 (struct objc_super *, struct message_ref_t*, ...); */
417 type = build_varargs_function_type_list (objc_object_type,
419 objc_v2_super_selector_type,
421 umsg_id_super2_fixup_decl = add_builtin_function ("objc_msgSendSuper2_fixup",
422 type, 0, NOT_BUILT_IN,
424 TREE_NOTHROW (umsg_id_super2_fixup_decl) = 0;
426 /* id objc_msgSendSuper2_stret_fixup_rtp
427 (struct objc_super *, struct message_ref_t*, ...); */
428 umsg_id_super2_stret_fixup_decl =
429 add_builtin_function ("objc_msgSendSuper2_stret_fixup",
430 type, 0, NOT_BUILT_IN,
432 TREE_NOTHROW (umsg_id_super2_stret_fixup_decl) = 0;
434 /* Present in the library, but unused by the FE. */
435 /* Protocol *objc_getProtocol (const char *)
436 type = build_function_type_list (objc_protocol_type,
437 const_string_type_node,
439 objc_v2_getprotocol_decl = add_builtin_function ("objc_getProtocol",
440 type, 0, NOT_BUILT_IN,
442 TREE_NOTHROW (objc_v2_getprotocol_decl) = 0;*/
444 UOBJC_V2_CACHE_decl = create_extern_decl (ptr_type_node,
445 "_objc_empty_cache");
447 UOBJC_V2_VTABLE_decl = create_extern_decl (objc_v2_imp_type,
448 "_objc_empty_vtable");
450 /* id objc_getClass (const char *); */
451 type = build_function_type_list (objc_object_type,
452 const_string_type_node,
454 objc_get_class_decl = add_builtin_function (TAG_GETCLASS,
455 type, 0, NOT_BUILT_IN,
458 /* id objc_getMetaClass (const char *); */
459 objc_get_meta_class_decl = add_builtin_function (TAG_GETMETACLASS,
460 type, 0, NOT_BUILT_IN,
463 /* This is the type of all of the following functions
464 objc_copyStruct(). */
465 type = build_function_type_list (void_type_node,
472 /* Declare the following function:
474 objc_copyStruct (void *destination, const void *source,
475 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
476 objc_copyStruct_decl = add_builtin_function ("objc_copyStruct",
477 type, 0, NOT_BUILT_IN,
479 TREE_NOTHROW (objc_copyStruct_decl) = 0;
480 objc_getPropertyStruct_decl = NULL_TREE;
481 objc_setPropertyStruct_decl = NULL_TREE;
483 gcc_assert (!flag_objc_sjlj_exceptions);
485 /* Although we warn that fobjc-exceptions is required for exceptions
486 code, we carry on and create it anyway. */
488 /* This can be required, even when exceptions code is not present,
489 when an __attribute__((objc_exception)) is applied to a
491 build_v2_ehtype_template ();
493 /* void * objc_begin_catch (void *) */
494 type = build_function_type_list (ptr_type_node,
495 ptr_type_node, NULL_TREE);
497 objc2_begin_catch_decl = add_builtin_function ("objc_begin_catch",
498 type, 0, NOT_BUILT_IN,
500 TREE_NOTHROW (objc2_begin_catch_decl) = 0;
502 /* void objc_end_catch () */
503 type = build_function_type_list (void_type_node, NULL_TREE);
504 objc2_end_catch_decl = add_builtin_function ("objc_end_catch",
505 type, 0, NOT_BUILT_IN,
507 TREE_NOTHROW (objc2_end_catch_decl) = 0;
509 /* void objc_exception_rethrow (void) */
510 objc_rethrow_exception_decl =
511 add_builtin_function ("objc_exception_rethrow",
512 type, 0, NOT_BUILT_IN,
514 TREE_NOTHROW (objc_rethrow_exception_decl) = 0;
515 using_eh_for_cleanups ();
516 lang_hooks.eh_runtime_type = next_runtime_02_eh_type;
517 lang_hooks.eh_personality = objc_eh_personality;
520 /* NOTE --- templates --- */
522 /* Set 'objc_v2_message_ref_template' to the data type node for
523 'struct _message_ref_t'. This needs to be done just once per
524 compilation. Also Set 'objc_v2_super_message_ref_template' to data
525 type node for 'struct _super_message_ref_t'. */
527 /* struct _message_ref_t
532 where IMP is: id (*) (id, _message_ref_t*, ...)
535 /* struct _super_message_ref_t
540 where SUPER_IMP is: id (*) ( super_t*, _super_message_ref_t*, ...)
544 build_v2_message_ref_templates (void)
546 tree ptr_message_ref_t;
547 tree decls, *chain = NULL;
549 /* struct _message_ref_t {...} */
550 objc_v2_message_ref_template =
551 objc_start_struct (get_identifier ("_message_ref_t"));
555 build_pointer_type (xref_tag (RECORD_TYPE,
556 get_identifier ("_message_ref_t")));
559 build_pointer_type (build_function_type_list
565 decls = add_field_decl (objc_v2_imp_type, "messenger", &chain);
568 add_field_decl (objc_selector_type, "name", &chain);
570 objc_finish_struct (objc_v2_message_ref_template, decls);
572 objc_v2_selector_type = build_pointer_type (objc_v2_message_ref_template);
575 /* struct _super_message_ref_t {...} */
576 objc_v2_super_message_ref_template =
577 objc_start_struct (get_identifier ("_super_message_ref_t"));
579 /* SUPER_IMP messenger; */
580 ptr_message_ref_t = build_pointer_type
581 (xref_tag (RECORD_TYPE,
582 get_identifier ("_super_message_ref_t")));
584 objc_v2_super_imp_type =
585 build_pointer_type (build_function_type_list
591 add_field_decl (objc_v2_super_imp_type, "messenger", &chain);
594 add_field_decl (objc_selector_type, "name", &chain);
596 objc_finish_struct (objc_v2_super_message_ref_template, decls);
597 objc_v2_super_selector_type =
598 build_pointer_type (objc_v2_super_message_ref_template);
601 /* Build following types which represent each class implementation.
605 uint32_t const flags;
606 uint32_t const instanceStart;
607 uint32_t const instanceSize;
609 uint32_t const reserved;
611 const uint8_t * const ivarLayout;
612 const char *const name;
613 const struct method_list_t * const baseMethods;
614 const struct objc_protocol_list *const baseProtocols;
615 const struct ivar_list_t *const ivars;
616 const uint8_t * const weakIvarLayout;
617 const struct _prop_list_t * const properties;
623 struct class_t *superclass;
627 ...When this is active - it will point to a rw version, but
628 when we build the meta-data we point it to the ro...
629 struct class_ro_t *data;
635 build_v2_class_templates (void)
638 tree decls, *chain = NULL;
640 /* struct class_ro_t {...} */
641 objc_v2_class_ro_template =
642 objc_start_struct (get_identifier (UTAG_V2_CLASS_RO));
644 /* uint32_t const flags; */
645 decls = add_field_decl (integer_type_node, "flags", &chain);
647 /* uint32_t const instanceStart; */
648 add_field_decl (integer_type_node, "instanceStart", &chain);
650 /* uint32_t const instanceSize; */
651 add_field_decl (integer_type_node, "instanceSize", &chain);
653 /* This ABI is currently only used on m64 NeXT. We always
654 explicitly declare the alignment padding. */
655 /* uint32_t const reserved; */
656 add_field_decl (integer_type_node, "reserved", &chain);
658 /* const uint8_t * const ivarLayout; */
659 cnst_strg_type = build_pointer_type (unsigned_char_type_node);
660 add_field_decl (cnst_strg_type, "ivarLayout", &chain);
662 /* const char *const name; */
663 add_field_decl (string_type_node, "name", &chain);
665 /* const struct method_list_t * const baseMethods; */
666 add_field_decl (objc_method_list_ptr, "baseMethods", &chain);
668 /* const struct objc_protocol_list *const baseProtocols; */
669 add_field_decl (build_pointer_type
670 (xref_tag (RECORD_TYPE,
671 get_identifier (UTAG_V2_PROTOCOL_LIST))),
672 "baseProtocols", &chain);
674 /* const struct ivar_list_t *const ivars; */
675 add_field_decl (objc_v2_ivar_list_ptr, "ivars", &chain);
677 /* const uint8_t * const weakIvarLayout; */
678 add_field_decl (cnst_strg_type, "weakIvarLayout", &chain);
680 /* struct _prop_list_t * baseProperties; */
681 add_field_decl (objc_prop_list_ptr, "baseProperties", &chain);
683 objc_finish_struct (objc_v2_class_ro_template, decls);
686 /* struct class_t {...} */
687 objc_v2_class_template =
688 objc_start_struct (get_identifier (UTAG_V2_CLASS));
690 /* struct class_t *isa; */
691 decls = add_field_decl (build_pointer_type (objc_v2_class_template),
694 /* struct class_t * const superclass; */
695 add_field_decl (build_pointer_type (objc_v2_class_template),
696 "superclass", &chain);
699 add_field_decl (build_pointer_type (void_type_node), "cache", &chain);
702 add_field_decl (build_pointer_type (objc_v2_imp_type), "vtable", &chain);
704 /* struct class_ro_t *ro; */
705 add_field_decl (build_pointer_type (objc_v2_class_ro_template), "ro", &chain);
707 objc_finish_struct (objc_v2_class_template, decls);
710 /* struct _objc_super
712 struct _objc_object *self;
716 build_v2_super_template (void)
718 tree decls, *chain = NULL;
720 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
722 /* struct _objc_object *self; */
723 decls = add_field_decl (objc_object_type, "self", &chain);
726 add_field_decl (objc_class_type, "cls", &chain);
728 objc_finish_struct (objc_super_template, decls);
734 const char * const protocol_name;
735 const struct protocol_list_t * const protocol_list;
736 const struct method_list_t * const instance_methods;
737 const struct method_list_t * const class_methods;
738 const struct method_list_t * optionalInstanceMethods;
739 const struct method_list_t * optionalClassMethod
740 const struct _prop_list_t * const properties;
742 const uint32_t flags;
746 build_v2_protocol_template (void)
748 tree decls, *chain = NULL;
750 objc_v2_protocol_template =
751 objc_start_struct (get_identifier (UTAG_V2_PROTOCOL));
754 decls = add_field_decl (objc_object_type, "isa", &chain);
756 /* char *protocol_name; */
757 add_field_decl (string_type_node, "protocol_name", &chain);
759 /* const struct protocol_list_t * const protocol_list; */
760 add_field_decl (build_pointer_type (objc_v2_protocol_template),
761 "protocol_list", &chain);
763 /* const struct method_list_t * const instance_methods; */
764 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
766 /* const struct method_list_t * const class_methods; */
767 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
769 /* const struct method_list_t * optionalInstanceMethods; */
770 add_field_decl (objc_method_proto_list_ptr, "optionalInstanceMethods", &chain);
772 /* const struct method_list_t * optionalClassMethods; */
773 add_field_decl (objc_method_proto_list_ptr, "optionalClassMethods", &chain);
775 /* struct _prop_list_t * properties; */
776 add_field_decl (objc_prop_list_ptr, "properties", &chain);
778 /* const uint32_t size; */
779 add_field_decl (integer_type_node, "size", &chain);
781 /* const uint32_t flags; */
782 add_field_decl (integer_type_node, "flags", &chain);
784 objc_finish_struct (objc_v2_protocol_template, decls);
787 /* Build type for a category:
790 const char * const name;
791 struct class_t *const cls;
792 const struct method_list_t * const instance_methods;
793 const struct method_list_t * const class_methods;
794 const struct protocol_list_t * const protocols;
795 const struct _prop_list_t * const properties;
800 build_v2_category_template (void)
802 tree decls, *chain = NULL;
804 objc_v2_category_template =
805 objc_start_struct (get_identifier ("_category_t"));
808 decls = add_field_decl (string_type_node, "name", &chain);
810 /* struct class_t *const cls; */
811 add_field_decl (build_pointer_type (objc_v2_class_template), "cls", &chain);
813 /* struct method_list_t *instance_methods; */
814 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
816 /* struct method_list_t *class_methods; */
817 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
819 /* struct protocol_list_t *protocol_list; */
820 add_field_decl (build_pointer_type (objc_v2_protocol_template),
821 "protocol_list", &chain );
823 /* struct _prop_list_t * properties; */
824 add_field_decl (objc_prop_list_ptr, "properties", &chain);
826 objc_finish_struct (objc_v2_category_template, decls);
829 /* NOTE --- Decls, Identifiers, Names etc. --- */
831 /* This routine is given a name and returns a matching extern variable
835 hash_name_lookup (hash *hashlist, tree name)
839 target = hashlist[IDENTIFIER_HASH_VALUE (name) % SIZEHASHTABLE];
843 if (name == DECL_NAME (target->key))
846 target = target->next;
851 /* This routine is given an extern variable and enters it in its hash
852 table. Note that hashing is done on its inner IDENTIFIER_NODE
856 hash_name_enter (hash *hashlist, tree id)
859 int slot = IDENTIFIER_HASH_VALUE (DECL_NAME (id)) % SIZEHASHTABLE;
861 obj = ggc_alloc<hashed_entry> ();
863 obj->next = hashlist[slot];
866 hashlist[slot] = obj; /* append to front */
869 /* Create a declaration "extern <type> <name>;"
870 The var will need to be finalized (e.g. by calling finish_var_decl()). */
873 create_extern_decl (tree type, const char *name)
875 tree id = get_identifier (name);
876 tree var = hash_name_lookup (extern_names, id);
880 var = start_var_decl (type, name);
881 TREE_STATIC (var) = 0;
882 DECL_EXTERNAL (var) = 1;
883 TREE_PUBLIC (var) = 1;
884 hash_name_enter (extern_names, var);
888 /* Create a globally visible definition for variable NAME of a given TYPE. The
889 finish_var_decl() routine will need to be called on it afterwards. */
892 create_global_decl (tree type, const char *name)
894 tree id = get_identifier (name);
895 tree var = hash_name_lookup (extern_names, id);
898 DECL_EXTERNAL (var) = 0;
899 TREE_STATIC (var) = 1;
903 var = start_var_decl (type, name);
904 hash_name_enter (extern_names, var);
906 TREE_PUBLIC (var) = 1;
910 /* Create a symbol with __attribute__ ((visibility ("hidden")))
911 attribute (private extern). */
914 create_hidden_decl (tree type, const char *name)
916 tree decl = create_global_decl (type, name);
917 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
918 DECL_VISIBILITY_SPECIFIED (decl) = 1;
922 /* Irritatingly, we have a different superclass field name for ABI=2. */
923 /* PS/TODO: The field name does not matter, it is only used internally
924 by the compiler. We can rename it to whatever we want. ;-) */
927 next_runtime_abi_02_super_superclassfield_id (void)
929 /* TODO: Simplify. Just always return get_identifier ("cls"), or at
930 most look it once at startup then always return it. */
931 if (!super_superclassfield_id)
932 super_superclassfield_id = get_identifier ("cls");
933 return super_superclassfield_id;
937 next_runtime_abi_02_class_decl (tree klass)
941 snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s",
942 IDENTIFIER_POINTER (CLASS_NAME (klass)));
943 /* ObjC2 classes are extern visible. */
944 decl = create_global_decl (objc_v2_class_template, buf);
945 OBJCMETA (decl, objc_meta, meta_class);
950 next_runtime_abi_02_metaclass_decl (tree klass)
954 snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s",
955 IDENTIFIER_POINTER (CLASS_NAME (klass)));
956 /* ObjC2 classes are extern visible. */
957 decl = create_global_decl (objc_v2_class_template, buf);
958 OBJCMETA (decl, objc_meta, meta_metaclass);
963 next_runtime_abi_02_category_decl (tree klass)
967 snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
968 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)),
969 IDENTIFIER_POINTER (CLASS_NAME (klass)));
970 decl = start_var_decl (objc_v2_category_template, buf);
971 OBJCMETA (decl, objc_meta, meta_category);
976 next_runtime_abi_02_protocol_decl (tree p)
981 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
982 snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
983 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
984 decl = start_var_decl (objc_v2_protocol_template, buf);
985 OBJCMETA (decl, objc_meta, meta_protocol);
990 next_runtime_abi_02_string_decl (tree type, const char *name, string_section where)
992 tree var = start_var_decl (type, name);
996 OBJCMETA (var, objc_meta, meta_class_name);
999 OBJCMETA (var, objc_meta, meta_meth_name);
1001 case meth_var_types:
1002 OBJCMETA (var, objc_meta, meta_meth_type);
1004 case prop_names_attr:
1005 OBJCMETA (var, objc_meta, meta_prop_name_attr);
1008 OBJCMETA (var, objc_meta, meta_base);
1014 /* NOTE --- entry --- */
1016 struct GTY(()) ident_data_tuple {
1021 /* This routine creates a file scope static variable of type 'Class'
1022 to hold the address of a class. */
1025 build_v2_class_reference_decl (tree ident)
1030 snprintf (buf, BUFSIZE, "_OBJC_ClassRef_%s", IDENTIFIER_POINTER (ident));
1031 decl = start_var_decl (objc_class_type, buf);
1032 OBJCMETA (decl, objc_meta, meta_class_ref);
1036 /* This routine builds a class refs entry for each class name used.
1037 Initially, a (static-ref, IDENT) tuple is added to the list. The
1038 ident is replaced with address of the class metadata (of type
1039 'Class') in the output routine. */
1041 static GTY (()) vec<ident_data_tuple, va_gc> *classrefs;
1044 objc_v2_get_class_reference (tree ident)
1051 ident_data_tuple *ref;
1052 FOR_EACH_VEC_ELT (*classrefs, count, ref)
1054 if (ref->ident == ident)
1057 ref->data = build_v2_class_reference_decl (ident);
1063 /* Somewhat arbitrary initial provision. */
1064 vec_alloc (classrefs, 16);
1066 /* We come here if we don't find the entry - or if the table was yet
1068 decl = build_v2_class_reference_decl (ident);
1071 vec_safe_push (classrefs, e);
1076 next_runtime_abi_02_get_class_reference (tree ident)
1078 if (!flag_zero_link)
1079 return objc_v2_get_class_reference (ident);
1082 /* We fall back to using objc_getClass (). */
1083 vec<tree, va_gc> *v;
1086 /* ??? add_class_reference (ident); - is pointless, since the
1087 system lib does not export the equivalent symbols. Maybe we
1088 need to build a class ref anyway. */
1089 t = my_build_string_pointer (IDENTIFIER_LENGTH (ident) + 1,
1090 IDENTIFIER_POINTER (ident));
1092 t = build_function_call_vec (input_location, vNULL, objc_get_class_decl,
1099 /* Used by build_function_type_for_method. Append the types for
1100 receiver & _cmd at the start of a method argument list to ARGTYPES.
1101 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
1102 trying to define a method or call one. SUPERFLAG says this is for a
1103 send to super. METH may be NULL, in the case that there is no
1107 next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
1108 tree meth, int context,
1114 receiver_type = objc_super_type;
1115 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
1116 receiver_type = objc_instance_type;
1118 receiver_type = objc_object_type;
1120 vec_safe_push (*argtypes, receiver_type);
1121 /* Selector type - will eventually change to `int'. */
1122 vec_safe_push (*argtypes,
1123 superflag ? objc_v2_super_selector_type
1124 : objc_v2_selector_type);
1127 /* TODO: Merge this with the message refs. */
1129 build_selector_reference_decl (tree ident)
1132 char *t, buf[BUFSIZE];
1134 snprintf (buf, BUFSIZE, "_OBJC_SelRef_%s", IDENTIFIER_POINTER (ident));
1139 *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */
1142 decl = start_var_decl (objc_selector_type, buf);
1143 OBJCMETA (decl, objc_meta, meta_sel_refs);
1148 next_runtime_abi_02_build_selector_reference (location_t loc ATTRIBUTE_UNUSED,
1150 tree proto ATTRIBUTE_UNUSED)
1152 tree *chain = &sel_ref_chain;
1157 if (TREE_VALUE (*chain) == ident)
1158 return TREE_PURPOSE (*chain);
1160 chain = &TREE_CHAIN (*chain);
1163 expr = build_selector_reference_decl (ident);
1164 *chain = tree_cons (expr, ident, NULL_TREE);
1169 /* Declare a variable of type 'struct message_ref_t'. */
1170 /* This will be finished in build_v2_message_ref_translation_table ().
1171 We take an idea from LLVM in making the names a bit more connected
1172 and thus the asm more readable. */
1175 build_v2_message_reference_decl (tree sel_name, tree message_func_ident)
1178 char buf[BUFSIZE], *t;
1181 /* Skip past the objc_msgSend it's the same for all... */
1182 if (IDENTIFIER_POINTER (message_func_ident)[offset] == '_')
1185 snprintf (buf, BUFSIZE, "_OBJC_MsgRef_%s_%s",
1186 &(IDENTIFIER_POINTER (message_func_ident)[offset]),
1187 IDENTIFIER_POINTER (sel_name));
1192 *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */
1195 decl = start_var_decl (objc_v2_message_ref_template, buf);
1196 OBJCMETA (decl, objc_meta, meta_mref);
1200 struct GTY(()) msgref_entry {
1206 static GTY (()) vec<msgref_entry, va_gc> *msgrefs;
1208 /* Build the list of (objc_msgSend_fixup_xxx, selector name), used
1209 later on to initialize the table of 'struct message_ref_t'
1213 build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl)
1221 FOR_EACH_VEC_ELT (*msgrefs, count, ref)
1222 if (ref->func == message_func_decl && ref->selname == sel_name)
1223 return ref->refdecl;
1226 /* Somewhat arbitrary initial provision. */
1227 vec_alloc (msgrefs, 32);
1229 /* We come here if we don't find a match or at the start. */
1230 decl = build_v2_message_reference_decl (sel_name,
1231 DECL_NAME (message_func_decl));
1232 e.func = message_func_decl;
1233 e.selname = sel_name;
1235 vec_safe_push (msgrefs, e);
1240 build_v2_protocollist_ref_decl (tree protocol)
1243 tree protocol_ident = PROTOCOL_NAME (protocol);
1246 snprintf (buf, BUFSIZE, "_OBJC_ProtocolRef_%s",
1247 IDENTIFIER_POINTER (protocol_ident));
1248 /* TODO: other compiler versions make these hidden & weak. */
1249 decl = create_global_decl (objc_protocol_type, buf);
1250 /* Let optimizer know that this decl is not removable. */
1251 DECL_PRESERVE_P (decl) = 1;
1252 OBJCMETA (decl, objc_meta, meta_proto_ref);
1256 struct GTY(()) prot_list_entry {
1260 static GTY (()) vec<prot_list_entry, va_gc> *protrefs;
1263 objc_v2_get_protocol_reference (tree ident)
1270 prot_list_entry *ref;
1271 FOR_EACH_VEC_ELT (*protrefs, count, ref)
1273 if (ref->id == ident)
1276 ref->refdecl = build_v2_protocollist_ref_decl (ident);
1277 return ref->refdecl;
1282 /* Somewhat arbitrary initial provision. */
1283 vec_alloc (protrefs, 32);
1285 /* We come here if we don't find the entry - or if the table was yet
1287 decl = build_v2_protocollist_ref_decl (ident);
1290 vec_safe_push (protrefs, e);
1295 next_runtime_abi_02_get_protocol_reference (location_t loc ATTRIBUTE_UNUSED,
1298 if (!PROTOCOL_FORWARD_DECL (p))
1299 PROTOCOL_FORWARD_DECL (p) = next_runtime_abi_02_protocol_decl (p);
1301 return objc_v2_get_protocol_reference (p);
1304 /* This routine returns the ivar declaration, if component is a valid
1305 ivar field; NULL_TREE otherwise. On finding an ivar, it also
1306 returns the class name in CLASS. */
1309 objc_is_ivar (tree expr, tree component, tree *klass)
1311 tree field = NULL_TREE;
1312 tree basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
1314 if (TREE_CODE (basetype) == RECORD_TYPE
1315 && TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
1317 *klass = lookup_interface (OBJC_TYPE_NAME (basetype));
1322 tree ivar_chain = CLASS_RAW_IVARS (*klass);
1325 field = is_ivar (ivar_chain, component);
1326 if (field != NULL_TREE)
1329 *klass = lookup_interface (CLASS_SUPER_NAME (*klass));
1338 create_ivar_offset_name (char *buf, tree class_name, tree field_decl)
1340 tree fname = DECL_NAME (field_decl);
1342 sprintf (buf, "OBJC_IVAR_$_%s.%s", IDENTIFIER_POINTER (class_name),
1343 IDENTIFIER_POINTER (fname));
1347 /* This routine generates new abi's ivar reference tree. It amounts
1348 to generating *(TYPE*)((char*)pObj + OFFSET_IVAR) when we normally
1349 generate pObj->IVAR. OFFSET_IVAR is an 'extern' variable holding
1350 the offset for 'IVAR' field. TYPE is type of IVAR field. */
1353 objc_v2_build_ivar_ref (tree datum, tree component)
1355 tree field, ref, class_name, offset, ftype, expr;
1356 char var_offset_name[512];
1358 field = objc_is_ivar (datum, component, &class_name);
1362 /* This routine only handles non-bitfield fields */
1363 /* DECL_INITIAL macro is set to width of bitfield and can be relied
1364 on to check for bitfield ivars. Note that I cannot rely on
1365 DECL_BIT_FIELD macro because it is only set when the whole struct
1366 is seen (at finish_struct) and not when the ivar chain is
1368 if (DECL_INITIAL (field))
1371 create_ivar_offset_name (var_offset_name, CLASS_NAME (class_name), field);
1373 offset = create_extern_decl (TREE_TYPE (size_zero_node), var_offset_name);
1375 ftype = TREE_TYPE (field);
1378 expr = build_c_cast (input_location,
1379 string_type_node, build_fold_addr_expr (datum));
1381 /* (char*)datum + offset */
1382 expr = fold_build_pointer_plus_loc (input_location, expr, offset);
1384 /* (ftype*)((char*)datum + offset) */
1385 expr = build_c_cast (input_location, build_pointer_type (ftype), expr);
1387 /* Finally: *(ftype*)((char*)datum + offset) */
1388 ref = build_indirect_ref (input_location, expr, RO_UNARY_STAR);
1390 /* We must set type of the resulting expression to be the same as
1391 the field type. This is because, build_indirect_ref (...)
1392 rebuilds the type which may result in lost information; as in the
1393 case of protocol-qualified types (id <protocol> ). */
1394 TREE_TYPE (ref) = ftype;
1396 if (TREE_READONLY (datum) || TREE_READONLY (field))
1397 TREE_READONLY (ref) = 1;
1399 if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field))
1400 TREE_THIS_VOLATILE (ref) = 1;
1402 if (TREE_DEPRECATED (field))
1403 warn_deprecated_use (field, NULL_TREE);
1408 /* IVAR refs are made via an externally referenceable offset and built
1409 on the fly. That is, unless they refer to (private) fields in the
1412 next_runtime_abi_02_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
1416 if ((ivar = objc_v2_build_ivar_ref (base, id)))
1418 return objc_build_component_ref (base, id);
1421 /* [super ...] references are listed here (and built into a table at
1422 meta -data emit time). */
1424 build_v2_superclass_ref_decl (tree ident, bool inst)
1429 snprintf (buf, BUFSIZE, "_OBJC_%sSuperRef_%s", (inst?"":"Meta"),
1430 IDENTIFIER_POINTER (ident));
1431 decl = start_var_decl (objc_class_type, buf);
1432 OBJCMETA (decl, objc_meta, meta_superclass_ref);
1436 static GTY (()) vec<ident_data_tuple, va_gc> *class_super_refs;
1437 static GTY (()) vec<ident_data_tuple, va_gc> *metaclass_super_refs;
1440 next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
1441 struct imp_entry *imp, bool inst_meth)
1445 tree id = CLASS_NAME (imp->imp_context);
1446 vec<ident_data_tuple, va_gc> *list = inst_meth ? class_super_refs
1447 : metaclass_super_refs;
1452 ident_data_tuple *ref;
1453 FOR_EACH_VEC_ELT (*list, count, ref)
1455 if (ref->ident == id)
1458 ref->data = build_v2_superclass_ref_decl (id, inst_meth);
1465 /* Somewhat arbitrary initial provision. */
1468 vec_alloc (class_super_refs, 16);
1469 list = class_super_refs;
1473 vec_alloc (metaclass_super_refs, 16);
1474 list = metaclass_super_refs;
1477 /* We come here if we don't find the entry - or if the table was yet
1479 decl = build_v2_superclass_ref_decl (id, inst_meth);
1482 vec_safe_push (list, e);
1487 next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
1488 struct imp_entry *imp, bool inst_meth)
1490 /* ??? is this OK when zero-link = true? */
1491 tree super_name = CLASS_SUPER_NAME (imp->imp_template);
1494 if (!flag_zero_link)
1496 super_class = objc_get_class_reference (CLASS_NAME (imp->imp_template));
1500 /* If we are in a class method, we must retrieve the
1501 _metaclass_ for the current class, pointed at by the
1502 class's "isa" pointer. The following assumes that "isa" is
1503 the first ivar in a class (which it must be). */
1505 build_indirect_ref (input_location,
1506 build_c_cast (input_location,
1507 build_pointer_type (objc_class_type),
1512 /* ??? Do we need to add the class ref anway for zero-link? */
1513 /* else do it the slow way. */
1514 super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
1515 super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
1516 IDENTIFIER_POINTER (super_name));
1517 /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
1518 return build_function_call (input_location,
1520 build_tree_list (NULL_TREE, super_name));
1524 next_runtime_abi_02_receiver_is_class_object (tree receiver)
1526 if (TREE_CODE (receiver) == VAR_DECL
1527 && IS_CLASS (TREE_TYPE (receiver))
1528 && vec_safe_length (classrefs))
1531 ident_data_tuple *ref;
1532 /* The receiver is a variable created by build_class_reference_decl. */
1533 FOR_EACH_VEC_ELT (*classrefs, count, ref)
1534 if (ref->data == receiver)
1540 /* Assign all arguments in VALUES which have side-effect to a temporary
1541 and replaced that argument in VALUES list with the temporary. The
1542 arguments will be passed to a function with FNTYPE. */
1545 objc_copy_to_temp_side_effect_params (tree fntype, tree values)
1548 function_args_iterator iter;
1550 /* Skip over receiver and the &_msf_ref types. */
1551 function_args_iter_init (&iter, fntype);
1552 function_args_iter_next (&iter);
1553 function_args_iter_next (&iter);
1555 for (valtail = values; valtail;
1556 valtail = TREE_CHAIN (valtail), function_args_iter_next (&iter))
1558 tree value = TREE_VALUE (valtail);
1559 tree type = function_args_iter_cond (&iter);
1560 if (type == NULL_TREE)
1562 if (!TREE_SIDE_EFFECTS (value))
1564 /* To prevent re-evaluation. */
1565 value = save_expr (value);
1567 TREE_VALUE (valtail) = value;
1572 /* Build the new abi's messaging library call. It looks like:
1573 (*_msg.messenger) (receiver, &_msg, ...) */
1576 build_v2_build_objc_method_call (int super_flag, tree method_prototype,
1577 tree lookup_object, tree selector,
1582 tree sender, rcv_p, t;
1585 ? TREE_VALUE (TREE_TYPE (method_prototype))
1586 : objc_object_type);
1587 tree ftype = build_function_type_for_method (ret_type, method_prototype,
1588 METHOD_REF, super_flag);
1591 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
1592 ftype = build_type_attribute_variant (
1593 ftype, METHOD_TYPE_ATTRIBUTES (method_prototype));
1595 sender_cast = build_pointer_type (ftype);
1598 method_params = objc_copy_to_temp_side_effect_params (ftype,
1601 /* Get &message_ref_t.messenger. */
1602 sender = build_c_cast (input_location,
1603 build_pointer_type (super_flag
1604 ? objc_v2_super_imp_type
1605 : objc_v2_imp_type),
1608 sender = build_indirect_ref (input_location, sender, RO_UNARY_STAR);
1610 rcv_p = (super_flag ? objc_super_type : objc_object_type);
1612 lookup_object = build_c_cast (input_location, rcv_p, lookup_object);
1614 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
1615 lookup_object = save_expr (lookup_object);
1617 method_params = tree_cons (NULL_TREE, lookup_object,
1618 tree_cons (NULL_TREE, selector,
1620 t = build3 (OBJ_TYPE_REF, sender_cast, sender, lookup_object, size_zero_node);
1621 ret_val = build_function_call (input_location, t, method_params);
1624 /* receiver != nil ? ret_val : 0 */
1628 if (TREE_CODE (ret_type) == RECORD_TYPE
1629 || TREE_CODE (ret_type) == UNION_TYPE)
1631 vec<constructor_elt, va_gc> *rtt = NULL;
1632 /* ??? CHECKME. hmmm..... think we need something more
1634 CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE);
1635 ftree = objc_build_constructor (ret_type, rtt);
1638 ftree = fold_convert (ret_type, integer_zero_node);
1640 ifexp = build_binary_op (input_location, NE_EXPR,
1642 fold_convert (rcv_p, integer_zero_node), 1);
1645 ret_val = build_conditional_expr (input_location,
1646 ifexp, ret_val, ftree,
1647 tf_warning_or_error);
1650 ret_val = build_conditional_expr (input_location,
1652 ret_val, NULL_TREE, input_location,
1653 ftree, NULL_TREE, input_location);
1660 next_runtime_abi_02_build_objc_method_call (location_t loc,
1661 tree method_prototype,
1668 tree ret_type, selector;
1669 tree message_func_decl;
1670 bool check_for_nil = flag_objc_nilcheck;
1672 ret_type = method_prototype
1673 ? TREE_VALUE (TREE_TYPE (method_prototype))
1676 /* Do we need to check for nil receivers ? */
1677 /* For now, message sent to classes need no nil check. In the
1678 future, class declaration marked as weak_import must be nil
1681 || (TREE_CODE (receiver) == VAR_DECL
1682 && TREE_TYPE (receiver) == objc_class_type))
1683 check_for_nil = false;
1685 if (!targetm.calls.struct_value_rtx (0, 0)
1686 && (TREE_CODE (ret_type) == RECORD_TYPE
1687 || TREE_CODE (ret_type) == UNION_TYPE)
1688 && targetm.calls.return_in_memory (ret_type, 0))
1691 message_func_decl = umsg_id_super2_stret_fixup_decl;
1693 message_func_decl = objc_is_id (rtype)
1694 ? umsg_id_stret_fixup_decl
1695 : umsg_stret_fixup_decl;
1700 message_func_decl = umsg_id_super2_fixup_decl;
1702 message_func_decl = objc_is_id (rtype)
1703 ? umsg_id_fixup_decl
1707 selector = build_v2_selector_messenger_reference (sel_name,
1710 /* selector = &_msg; */
1711 selector = build_unary_op (loc, ADDR_EXPR, selector, 0);
1713 selector = build_c_cast (loc, (super ? objc_v2_super_selector_type
1714 : objc_v2_selector_type),
1717 /* (*_msg.messenger) (receiver, &_msg, ...); */
1718 return build_v2_build_objc_method_call (super, method_prototype,
1720 method_params, check_for_nil);
1723 /* NOTE --- Constant String Class Stuff --- */
1726 next_runtime_abi_02_setup_const_string_class_decl (void)
1728 if (!constant_string_global_id)
1730 /* Hopefully, this should not represent a serious limitation. */
1732 snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s", constant_string_class_name);
1733 constant_string_global_id = get_identifier (buf);
1736 string_class_decl = lookup_name (constant_string_global_id);
1738 /* In OBJC2 abi, constant string class reference refers to class
1739 name for NSConstantString class. This declaration may not be
1740 available yet (in fact it is not in most cases). So, declare an
1741 extern OBJC_CLASS_$_NSConstantString in its place. */
1742 if (!string_class_decl)
1744 create_extern_decl (objc_v2_class_template,
1745 IDENTIFIER_POINTER (constant_string_global_id));
1747 return (string_class_decl != NULL_TREE);
1751 next_runtime_abi_02_build_const_string_constructor (location_t loc, tree string,
1754 tree constructor, fields, var;
1755 vec<constructor_elt, va_gc> *v = NULL;
1757 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1758 fields = TYPE_FIELDS (internal_const_str_type);
1759 CONSTRUCTOR_APPEND_ELT (v, fields,
1760 build_unary_op (loc, ADDR_EXPR, string_class_decl, 0));
1762 fields = DECL_CHAIN (fields);
1763 CONSTRUCTOR_APPEND_ELT (v, fields,
1764 build_unary_op (loc, ADDR_EXPR, string, 1));
1766 /* ??? check if this should be long. */
1767 fields = DECL_CHAIN (fields);
1768 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
1769 constructor = objc_build_constructor (internal_const_str_type, v);
1771 var = build_decl (input_location, CONST_DECL, NULL, TREE_TYPE (constructor));
1772 DECL_INITIAL (var) = constructor;
1773 TREE_STATIC (var) = 1;
1774 DECL_CONTEXT (var) = NULL;
1775 OBJCMETA (var, objc_meta, meta_const_str);
1779 /* NOTE --- NeXT V2 Metadata templates --- */
1781 /* This routine builds the following type:
1784 const char * const name; // property name
1785 const char * const attributes; // comma-delimited, encoded,
1786 // property attributes
1791 build_v2_property_template (void)
1794 tree decls, *chain = NULL;
1796 prop_record = objc_start_struct (get_identifier ("_prop_t"));
1797 /* const char * name */
1798 decls = add_field_decl (string_type_node, "name", &chain);
1800 /* const char * attribute */
1801 add_field_decl (string_type_node, "attribute", &chain);
1803 objc_finish_struct (prop_record, decls);
1809 unsigned long int *offset;
1818 build_v2_ivar_t_template (void)
1820 tree objc_ivar_id, objc_ivar_record;
1821 tree decls, *chain = NULL;
1823 objc_ivar_id = get_identifier ("_ivar_t");
1824 objc_ivar_record = objc_start_struct (objc_ivar_id);
1826 /* unsigned long int *offset; */
1827 decls = add_field_decl (build_pointer_type
1828 (TREE_TYPE (size_zero_node)), "offset", &chain);
1831 add_field_decl (string_type_node, "name", &chain);
1834 add_field_decl (string_type_node, "type", &chain);
1836 /* uint32_t alignment; */
1837 add_field_decl (integer_type_node, "alignment", &chain);
1839 /* uint32_t size; */
1840 add_field_decl (integer_type_node, "size", &chain);
1842 objc_finish_struct (objc_ivar_record, decls);
1843 return objc_ivar_record;
1847 build_metadata_templates (void)
1850 if (!objc_method_template)
1851 objc_method_template = build_method_template ();
1853 if (!objc_v2_property_template)
1854 objc_v2_property_template = build_v2_property_template ();
1856 if (!objc_v2_ivar_template)
1857 objc_v2_ivar_template = build_v2_ivar_t_template ();
1861 /* NOTE --- Output NeXT V2 Metadata --- */
1863 /* Routine builds name of Interface's main meta-data of type class_t. */
1866 objc_build_internal_classname (tree ident, bool metaclass)
1868 static char string[512];
1869 snprintf (string, 512, "%s_%s", metaclass ? "OBJC_METACLASS_$"
1871 IDENTIFIER_POINTER (ident));
1875 /* Build the name for object of type struct class_ro_t */
1878 newabi_append_ro (const char *name)
1882 static char string[BUFSIZE];
1883 dollar = strchr (name, '$');
1884 gcc_assert (dollar);
1887 strncpy (p, name, (int)(dollar - name));
1888 p += (int)(dollar - name);
1889 sprintf (p, "RO_%s", dollar);
1893 /* Build the struct message_ref_t msg =
1894 {objc_msgSend_fixup_xxx, @selector(func)}
1898 void build_v2_message_ref_translation_table (void)
1903 if (!vec_safe_length (msgrefs))
1906 FOR_EACH_VEC_ELT (*msgrefs, count, ref)
1908 vec<constructor_elt, va_gc> *initializer;
1909 tree expr, constructor;
1910 tree struct_type = TREE_TYPE (ref->refdecl);
1911 location_t loc = DECL_SOURCE_LOCATION (ref->refdecl);
1914 /* First 'IMP messenger' field... */
1915 expr = build_unary_op (loc, ADDR_EXPR, ref->func, 0);
1916 expr = convert (objc_v2_imp_type, expr);
1917 CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr);
1919 /* ... then 'SEL name' field. */
1920 expr = build_selector (ref->selname);
1921 CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr);
1922 constructor = objc_build_constructor (struct_type, initializer);
1923 finish_var_decl (ref->refdecl, constructor);
1927 /* Build decl = initializer; for each externally visible class
1931 build_v2_classrefs_table (void)
1934 ident_data_tuple *ref;
1936 if (!vec_safe_length (classrefs))
1939 FOR_EACH_VEC_ELT (*classrefs, count, ref)
1941 tree expr = ref->ident;
1942 tree decl = ref->data;
1943 /* Interface with no implementation and yet one of its messages
1944 has been used. Need to generate a full address-of tree for it
1946 if (TREE_CODE (expr) == IDENTIFIER_NODE)
1948 const char *name = objc_build_internal_classname (expr, false);
1949 expr = create_extern_decl (objc_v2_class_template, name);
1950 expr = convert (objc_class_type, build_fold_addr_expr (expr));
1952 /* The runtime wants this, even if it appears unused, so we must force the
1954 DECL_PRESERVE_P (decl) = 1; */
1955 finish_var_decl (decl, expr);
1959 /* Build decl = initializer; for each externally visible super class
1963 build_v2_super_classrefs_table (bool metaclass)
1966 ident_data_tuple *ref;
1967 vec<ident_data_tuple, va_gc> *list = metaclass ? metaclass_super_refs
1970 if (!vec_safe_length (list))
1973 FOR_EACH_VEC_ELT (*list, count, ref)
1975 tree expr = ref->ident;
1976 tree decl = ref->data;
1977 /* Interface with no implementation and yet one of its messages
1978 has been used. Need to generate a full address-of tree for it
1980 if (TREE_CODE (expr) == IDENTIFIER_NODE)
1982 const char * name = objc_build_internal_classname (expr, metaclass);
1983 expr = create_extern_decl (objc_v2_class_template, name);
1984 expr = convert (objc_class_type, build_fold_addr_expr (expr));
1986 finish_var_decl (decl, expr);
1990 /* Add the global class meta-data declaration to the list which later
1991 on ends up in the __class_list section. */
1993 static GTY(()) vec<tree, va_gc> *class_list;
1996 objc_v2_add_to_class_list (tree global_class_decl)
1998 vec_safe_push (class_list, global_class_decl);
2001 static GTY(()) vec<tree, va_gc> *nonlazy_class_list;
2003 /* Add the global class meta-data declaration to the list which later
2004 on ends up in the __nonlazy_class section. */
2007 objc_v2_add_to_nonlazy_class_list (tree global_class_decl)
2009 vec_safe_push (nonlazy_class_list, global_class_decl);
2012 static GTY(()) vec<tree, va_gc> *category_list;
2014 /* Add the category meta-data declaration to the list which later on
2015 ends up in the __nonlazy_category section. */
2018 objc_v2_add_to_category_list (tree decl)
2020 vec_safe_push (category_list, decl);
2023 static GTY(()) vec<tree, va_gc> *nonlazy_category_list;
2025 /* Add the category meta-data declaration to the list which later on
2026 ends up in the __category_list section. */
2029 objc_v2_add_to_nonlazy_category_list (tree decl)
2031 vec_safe_push (nonlazy_category_list, decl);
2035 has_load_impl (tree clsmeth)
2039 tree id = METHOD_SEL_NAME (clsmeth);
2040 if (IDENTIFIER_LENGTH (id) == 4
2041 && strncmp (IDENTIFIER_POINTER (id), "load", 4) == 0)
2043 clsmeth = DECL_CHAIN (clsmeth);
2049 /* Build a __{class,category}_list section table containing address of
2050 all @implemented {class,category} meta-data. */
2053 build_v2_address_table (vec<tree, va_gc> *src, const char *nam, tree attr)
2056 tree type, decl, expr;
2057 vec<constructor_elt, va_gc> *initlist = NULL;
2059 if (!vec_safe_length (src))
2062 FOR_EACH_VEC_ELT (*src, count, decl)
2065 tree purpose = build_int_cst (NULL_TREE, count);
2067 tree purpose = NULL_TREE;
2069 expr = convert (objc_class_type, build_fold_addr_expr (decl));
2070 CONSTRUCTOR_APPEND_ELT (initlist, purpose, expr);
2072 gcc_assert (count > 0);
2073 type = build_array_type (objc_class_type,
2074 build_index_type (build_int_cst (NULL_TREE, count - 1)));
2075 decl = start_var_decl (type, nam);
2076 /* The runtime wants this, even if it appears unused, so we must
2077 force the output. */
2078 DECL_PRESERVE_P (decl) = 1;
2079 expr = objc_build_constructor (type, initlist);
2080 OBJCMETA (decl, objc_meta, attr);
2081 finish_var_decl (decl, expr);
2084 /* Build decl = initializer; for each protocol referenced in
2085 @protocol(MyProt) expression. Refs as built in the entry section
2089 build_v2_protocol_list_translation_table (void)
2092 prot_list_entry *ref;
2097 FOR_EACH_VEC_ELT (*protrefs, count, ref)
2101 gcc_assert (TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE);
2102 snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
2103 IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id)));
2104 expr = start_var_decl (objc_v2_protocol_template, buf);
2105 expr = convert (objc_protocol_type, build_fold_addr_expr (expr));
2106 finish_var_decl (ref->refdecl, expr);
2108 /* TODO: Maybe we could explicitly delete the vec. now? */
2111 static GTY (()) vec<prot_list_entry, va_gc> *protlist;
2113 /* Add the local protocol meta-data declaration to the list which
2114 later on ends up in the __protocol_list section. */
2117 objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl)
2121 /* Arbitrary init count. */
2122 vec_alloc (protlist, 32);
2123 e.id = protocol_interface_decl;
2124 e.refdecl = protocol_decl;
2125 vec_safe_push (protlist, e);
2128 /* Build the __protocol_list section table containing address of all
2129 generate protocol_t meta-data. */
2132 build_v2_protocol_list_address_table (void)
2135 prot_list_entry *ref;
2136 if (!vec_safe_length (protlist))
2139 FOR_EACH_VEC_ELT (*protlist, count, ref)
2143 gcc_assert (ref->id && TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE);
2144 snprintf (buf, BUFSIZE, "_OBJC_LabelProtocol_%s",
2145 IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id)));
2146 decl = create_global_decl (objc_protocol_type, buf);
2147 expr = convert (objc_protocol_type, build_fold_addr_expr (ref->refdecl));
2148 OBJCMETA (decl, objc_meta, meta_label_protocollist);
2149 finish_var_decl (decl, expr);
2152 /* TODO: delete the vec. */
2153 /* TODO: upgrade to the clang/llvm hidden version. */
2156 /* This routine declares a variable to hold meta data for 'struct
2157 protocol_list_t'. */
2160 generate_v2_protocol_list (tree i_or_p, tree klass_ctxt)
2162 tree refs_decl, lproto, e, plist, ptempl_p_t;
2164 vec<constructor_elt, va_gc> *initlist = NULL;
2167 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
2168 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
2169 plist = CLASS_PROTOCOL_LIST (i_or_p);
2170 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
2171 plist = PROTOCOL_LIST (i_or_p);
2176 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2177 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
2178 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
2181 /* Build initializer. */
2183 ptempl_p_t = build_pointer_type (objc_v2_protocol_template);
2184 e = build_int_cst (ptempl_p_t, size);
2185 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, e);
2187 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
2189 tree pval = TREE_VALUE (lproto);
2191 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
2192 && PROTOCOL_FORWARD_DECL (pval))
2194 tree fwref = PROTOCOL_FORWARD_DECL (pval);
2195 location_t loc = DECL_SOURCE_LOCATION (fwref) ;
2196 e = build_unary_op (loc, ADDR_EXPR, fwref, 0);
2197 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, e);
2201 /* static struct protocol_list_t *list[size]; */
2203 switch (TREE_CODE (i_or_p))
2205 case PROTOCOL_INTERFACE_TYPE:
2206 snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
2207 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
2209 case CLASS_INTERFACE_TYPE:
2210 snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
2211 IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
2213 case CATEGORY_INTERFACE_TYPE:
2214 snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
2215 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)),
2216 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt)));
2222 refs_decl = start_var_decl (build_sized_array_type (ptempl_p_t, size+1),
2224 /* ObjC2 puts all these in the base section. */
2225 OBJCMETA (refs_decl, objc_meta, meta_base);
2226 DECL_PRESERVE_P (refs_decl) = 1;
2227 finish_var_decl (refs_decl,
2228 objc_build_constructor (TREE_TYPE (refs_decl),initlist));
2232 /* This routine builds one 'struct method_t' initializer list. Note
2233 that the old ABI is supposed to build 'struct objc_method' which
2234 has 3 fields, but it does not build the initialization expression
2235 for 'method_imp' which for protocols is NULL any way. To be
2236 consistent with declaration of 'struct method_t', in the new ABI we
2237 set the method_t.imp to NULL. */
2240 build_v2_descriptor_table_initializer (tree type, tree entries)
2242 vec<constructor_elt, va_gc> *initlist = NULL;
2245 vec<constructor_elt, va_gc> *eltlist = NULL;
2246 CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,
2247 build_selector (METHOD_SEL_NAME (entries)));
2248 CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,
2249 add_objc_string (METHOD_ENCODING (entries),
2251 CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE, null_pointer_node);
2253 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
2254 objc_build_constructor (type, eltlist));
2255 entries = TREE_CHAIN (entries);
2259 return objc_build_constructor (build_array_type (type, 0), initlist);
2262 /* struct method_list_t
2265 uint32_t method_count;
2266 struct objc_method method_list[method_count];
2270 build_v2_method_list_template (tree list_type, int size)
2272 tree method_list_t_record;
2273 tree array_type, decls, *chain = NULL;
2275 method_list_t_record = objc_start_struct (NULL_TREE);
2277 /* uint32_t const entsize; */
2278 decls = add_field_decl (integer_type_node, "entsize", &chain);
2280 /* int method_count; */
2281 add_field_decl (integer_type_node, "method_count", &chain);
2283 /* struct objc_method method_list[]; */
2284 array_type = build_sized_array_type (list_type, size);
2285 add_field_decl (array_type, "method_list", &chain);
2287 objc_finish_struct (method_list_t_record, decls);
2288 return method_list_t_record;
2291 /* Note, as above that we are building to the objc_method_template
2292 which has the *imp field. ABI0/1 build with
2293 objc_method_prototype_template which is missing this field. */
2295 generate_v2_meth_descriptor_table (tree chain, tree protocol,
2296 const char *prefix, tree attr)
2298 tree method_list_template, initlist, decl, methods;
2300 vec<constructor_elt, va_gc> *v = NULL;
2303 if (!chain || !prefix)
2310 if (! METHOD_ENCODING (methods))
2311 METHOD_ENCODING (methods) = encode_method_prototype (methods);
2312 methods = TREE_CHAIN (methods);
2317 method_list_template = build_v2_method_list_template (objc_method_template,
2319 snprintf (buf, BUFSIZE, "%s_%s", prefix,
2320 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
2322 decl = start_var_decl (method_list_template, buf);
2324 entsize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template));
2325 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, entsize));
2326 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
2328 build_v2_descriptor_table_initializer (objc_method_template,
2330 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
2331 /* Get into the right section. */
2332 OBJCMETA (decl, objc_meta, attr);
2333 finish_var_decl (decl, objc_build_constructor (method_list_template, v));
2337 /* This routine builds the initializer list to initialize the 'struct
2338 _prop_t prop_list[]' field of 'struct _prop_list_t' meta-data. */
2341 build_v2_property_table_initializer (tree type, tree context)
2344 vec<constructor_elt, va_gc> *inits = NULL;
2345 if (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE)
2346 x = CLASS_PROPERTY_DECL (context);
2348 x = IMPL_PROPERTY_DECL (context);
2350 for (; x; x = TREE_CHAIN (x))
2352 vec<constructor_elt, va_gc> *elemlist = NULL;
2353 /* NOTE! sections where property name/attribute go MUST change
2355 tree attribute, name_ident = PROPERTY_NAME (x);
2357 CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE,
2358 add_objc_string (name_ident, prop_names_attr));
2360 attribute = objc_v2_encode_prop_attr (x);
2361 CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE,
2362 add_objc_string (attribute, prop_names_attr));
2364 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
2365 objc_build_constructor (type, elemlist));
2368 return objc_build_constructor (build_array_type (type, 0),inits);
2371 /* This routine builds the following type:
2374 uint32_t entsize; // sizeof (struct _prop_t)
2375 uint32_t prop_count;
2376 struct _prop_t prop_list [prop_count];
2381 build_v2_property_list_template (tree list_type, int size)
2383 tree property_list_t_record;
2384 tree array_type, decls, *chain = NULL;
2387 property_list_t_record = objc_start_struct (NULL_TREE);
2389 /* uint32_t const entsize; */
2390 decls = add_field_decl (integer_type_node, "entsize", &chain);
2392 /* int prop_count; */
2393 add_field_decl (integer_type_node, "prop_count", &chain);
2395 /* struct _prop_t prop_list[]; */
2396 array_type = build_sized_array_type (list_type, size);
2397 add_field_decl (array_type, "prop_list", &chain);
2399 objc_finish_struct (property_list_t_record, decls);
2400 return property_list_t_record;
2403 /* Top-level routine to generate property tables for each
2407 generate_v2_property_table (tree context, tree klass_ctxt)
2409 tree x, decl, initlist, property_list_template;
2410 bool is_proto = false;
2411 vec<constructor_elt, va_gc> *inits = NULL;
2412 int init_val, size = 0;
2417 gcc_assert (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE);
2418 x = CLASS_PROPERTY_DECL (context);
2422 x = IMPL_PROPERTY_DECL (klass_ctxt);
2424 for (; x; x = TREE_CHAIN (x))
2430 property_list_template =
2431 build_v2_property_list_template (objc_v2_property_template,
2434 initlist = build_v2_property_table_initializer (objc_v2_property_template,
2438 init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_property_template));
2440 snprintf (buf, BUFSIZE, "_OBJC_ProtocolPropList_%s",
2441 IDENTIFIER_POINTER (PROTOCOL_NAME (context)));
2443 snprintf (buf, BUFSIZE, "_OBJC_ClassPropList_%s",
2444 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)));
2446 decl = start_var_decl (property_list_template, buf);
2448 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
2449 build_int_cst (NULL_TREE, init_val));
2450 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
2451 build_int_cst (NULL_TREE, size));
2452 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
2454 OBJCMETA (decl, objc_meta, meta_base);
2455 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits));
2460 build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
2461 tree inst_methods, tree class_methods,
2462 tree opt_ins_meth, tree opt_cls_meth,
2467 vec<constructor_elt, va_gc> *inits = NULL;
2469 /* TODO: find a better representation of location from the inputs. */
2470 loc = UNKNOWN_LOCATION;
2472 /* This is NULL for the new ABI. */
2473 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
2474 convert (objc_object_type, null_pointer_node));
2476 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
2477 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
2479 ttyp = objc_method_proto_list_ptr;
2481 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
2483 expr = convert (ttyp, null_pointer_node);
2484 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2487 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
2489 expr = convert (ttyp, null_pointer_node);
2490 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2493 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, opt_ins_meth, 0));
2495 expr = convert (ttyp, null_pointer_node);
2496 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2499 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, opt_cls_meth, 0));
2501 expr = convert (ttyp, null_pointer_node);
2502 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2504 ttyp = objc_prop_list_ptr;
2506 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, property_list, 0));
2508 expr = convert (ttyp, null_pointer_node);
2509 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2511 /* const uint32_t size; = sizeof(struct protocol_t) */
2512 expr = build_int_cst (integer_type_node,
2513 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_protocol_template)));
2514 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2515 /* const uint32_t flags; = 0 */
2516 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, integer_zero_node);
2518 return objc_build_constructor (type, inits);
2521 /* Main routine to build all meta data for all protocols used in a
2522 translation unit. */
2525 generate_v2_protocols (void)
2530 if (!protocol_chain)
2533 /* If a protocol was directly referenced, pull in indirect
2535 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2536 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
2537 generate_protocol_references (PROTOCOL_LIST (p));
2539 for (p = protocol_chain; p; p = TREE_CHAIN (p))
2542 tree inst_meth, class_meth, opt_inst_meth, opt_class_meth, props;
2543 tree decl, initlist, protocol_name_expr, refs_decl, refs_expr;
2545 /* If protocol wasn't referenced, don't generate any code. */
2546 decl = PROTOCOL_FORWARD_DECL (p);
2551 loc = DECL_SOURCE_LOCATION (decl);
2555 generate_v2_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
2556 "_OBJC_ProtocolInstanceMethods",
2557 meta_proto_nst_meth);
2560 generate_v2_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
2561 "_OBJC_ProtocolClassMethods",
2562 meta_proto_cls_meth);
2565 generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p), p,
2566 "_OBJC_OptProtocolInstMethods",
2567 meta_proto_nst_meth);
2570 generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p), p,
2571 "_OBJC_OptProtocolClassMethods",
2572 meta_proto_cls_meth);
2574 if (PROTOCOL_LIST (p))
2575 refs_decl = generate_v2_protocol_list (p, NULL_TREE);
2579 /* static struct objc_protocol _OBJC_Protocol_<mumble>; */
2580 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
2583 refs_expr = convert (build_pointer_type (objc_v2_protocol_template),
2584 build_unary_op (loc, ADDR_EXPR, refs_decl, 0));
2586 refs_expr = build_int_cst (NULL_TREE, 0);
2588 props = generate_v2_property_table (p, NULL_TREE);
2590 initlist = build_v2_protocol_initializer (TREE_TYPE (decl),
2591 protocol_name_expr, refs_expr,
2592 inst_meth, class_meth,
2593 opt_inst_meth, opt_class_meth,
2595 finish_var_decl (decl, initlist);
2596 objc_add_to_protocol_list (p, decl);
2601 /* Make sure we get the Protocol class linked in - reference
2603 p = objc_v2_get_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
2604 /* ... but since we don't specifically use the reference... we
2605 need to force it. */
2606 DECL_PRESERVE_P (p) = 1;
2611 generate_v2_dispatch_table (tree chain, const char *name, tree attr)
2613 tree decl, method_list_template, initlist;
2614 vec<constructor_elt, va_gc> *v = NULL;
2617 if (!chain || !name || !(size = list_length (chain)))
2620 method_list_template
2621 = build_v2_method_list_template (objc_method_template, size);
2623 = build_dispatch_table_initializer (objc_method_template, chain);
2625 decl = start_var_decl (method_list_template, name);
2627 init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template));
2628 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2629 build_int_cst (integer_type_node, init_val));
2630 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2631 build_int_cst (integer_type_node, size));
2632 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
2634 OBJCMETA (decl, objc_meta, attr);
2635 finish_var_decl (decl,
2636 objc_build_constructor (TREE_TYPE (decl), v));
2640 /* Init a category. */
2642 build_v2_category_initializer (tree type, tree cat_name, tree class_name,
2643 tree inst_methods, tree class_methods,
2644 tree protocol_list, tree property_list,
2648 vec<constructor_elt, va_gc> *v = NULL;
2650 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
2651 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
2653 ltyp = objc_method_list_ptr;
2655 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
2657 expr = convert (ltyp, null_pointer_node);
2658 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2661 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
2663 expr = convert (ltyp, null_pointer_node);
2664 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2666 /* protocol_list = */
2667 ltyp = build_pointer_type (objc_v2_protocol_template);
2669 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0));
2671 expr = convert (ltyp, null_pointer_node);
2672 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2674 ltyp = objc_prop_list_ptr;
2676 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0));
2678 expr = convert (ltyp, null_pointer_node);
2679 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2681 return objc_build_constructor (type, v);
2684 /* static struct category_t _OBJC_CATEGORY_$_<name> = { ... }; */
2687 generate_v2_category (struct imp_entry *impent)
2689 tree initlist, cat_name_expr, class_name_expr;
2690 tree protocol_decl, category, props, t;
2691 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
2692 tree cat = impent->imp_context;
2693 tree cat_decl = impent->class_decl;
2697 loc = DECL_SOURCE_LOCATION (cat_decl);
2699 /* ??? not sure this is really necessary, the following references should
2700 force appropriate linkage linkage...
2701 -- but ... ensure a reference to the class... */
2702 t = objc_v2_get_class_reference (CLASS_NAME (cat));
2703 /* ... which we ignore so force it out.. */
2704 DECL_PRESERVE_P (t) = 1;
2706 snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (cat)));
2707 class_name_expr = create_extern_decl (objc_v2_class_template, buf);
2708 class_name_expr = build_fold_addr_expr (class_name_expr);
2710 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
2711 category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat));
2713 if (category && CLASS_PROTOCOL_LIST (category))
2715 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
2716 protocol_decl = generate_v2_protocol_list (category, cat);
2719 protocol_decl = NULL_TREE;
2721 /* decl = update_var_decl(impent->class_decl); */
2723 props = generate_v2_property_table (NULL_TREE, cat);
2725 if (CLASS_NST_METHODS (cat))
2727 snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s",
2728 IDENTIFIER_POINTER (CLASS_NAME (cat)),
2729 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
2730 inst_methods = generate_v2_dispatch_table (CLASS_NST_METHODS (cat), buf,
2734 if (CLASS_CLS_METHODS (cat))
2736 snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s",
2737 IDENTIFIER_POINTER (CLASS_NAME (cat)),
2738 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
2739 class_methods = generate_v2_dispatch_table (CLASS_CLS_METHODS (cat), buf,
2743 initlist = build_v2_category_initializer (TREE_TYPE (cat_decl),
2744 cat_name_expr, class_name_expr,
2745 inst_methods, class_methods,
2746 protocol_decl, props, loc);
2748 finish_var_decl (cat_decl, initlist);
2749 impent->class_decl = cat_decl;
2751 /* Add to list of pointers in __category_list section. */
2752 objc_v2_add_to_category_list (cat_decl);
2753 if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)))
2754 objc_v2_add_to_nonlazy_category_list (cat_decl);
2757 /* This routine declares a variable to hold the offset for ivar
2758 FIELD_DECL. Variable name is .objc_ivar.ClassName.IvarName. */
2760 struct GTY(()) ivarref_entry
2766 static GTY (()) vec<ivarref_entry, va_gc> *ivar_offset_refs;
2769 ivar_offset_ref (tree class_name, tree field_decl)
2771 tree decl, field_decl_id;
2776 create_ivar_offset_name (buf, class_name, field_decl);
2777 field_decl_id = get_identifier (buf);
2779 if (ivar_offset_refs)
2783 FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)
2784 if (DECL_NAME (ref->decl) == field_decl_id)
2788 /* Somewhat arbitrary initial provision. */
2789 vec_alloc (ivar_offset_refs, 32);
2791 /* We come here if we don't find a match or at the start. */
2792 global_var = (TREE_PUBLIC (field_decl) || TREE_PROTECTED (field_decl));
2794 decl = create_global_decl (TREE_TYPE (size_zero_node), buf);
2796 decl = create_hidden_decl (TREE_TYPE (size_zero_node), buf);
2798 /* Make sure it ends up in an ObjC section. */
2799 OBJCMETA (decl, objc_meta, meta_base);
2802 e.offset = byte_position (field_decl);
2803 vec_safe_push (ivar_offset_refs, e);
2807 /* This routine builds initializer-list needed to initialize 'struct
2808 ivar_t list[count] of 'struct ivar_list_t' meta data. TYPE is
2809 'struct ivar_t' and FIELD_DECL is list of ivars for the target
2813 build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl)
2815 vec<constructor_elt, va_gc> *inits = NULL;
2819 vec<constructor_elt, va_gc> *ivar = NULL;
2823 /* Unnamed bitfields are ignored. */
2824 if (!DECL_NAME (field_decl))
2826 field_decl = DECL_CHAIN (field_decl);
2831 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
2832 build_unary_op (input_location,
2834 ivar_offset_ref (class_name,
2838 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
2839 add_objc_string (DECL_NAME (field_decl),
2843 id = add_objc_string (encode_field_decl (field_decl),
2845 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
2847 /* Set alignment. */
2848 val = DECL_ALIGN_UNIT (field_decl);
2849 val = exact_log2 (val);
2850 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
2851 build_int_cst (integer_type_node, val));
2854 val = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl));
2855 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
2856 build_int_cst (integer_type_node, val));
2858 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
2859 objc_build_constructor (type, ivar));
2862 field_decl = DECL_CHAIN (field_decl);
2863 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
2867 return objc_build_constructor (build_array_type (type, 0), inits);
2875 struct iver_t list[count];
2880 build_v2_ivar_list_t_template (tree list_type, int size)
2882 tree objc_ivar_list_record;
2883 tree decls, *chain = NULL;
2886 objc_ivar_list_record = objc_start_struct (NULL_TREE);
2888 /* uint32 entsize; */
2889 decls = add_field_decl (integer_type_node, "entsize", &chain);
2892 add_field_decl (integer_type_node, "count", &chain);
2894 /* struct objc_ivar ivar_list[]; */
2895 add_field_decl (build_sized_array_type (list_type, size),
2898 objc_finish_struct (objc_ivar_list_record, decls);
2899 return objc_ivar_list_record;
2902 /* This routine declares a static variable of type 'struct
2903 ivar_list_t' and initializes it. chain is the source of the data,
2904 name is the name for the var. attr is the meta-data section tag
2905 attribute. templ is the implementation template for the class. */
2908 generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ)
2910 tree decl, initlist, ivar_list_template;
2911 vec<constructor_elt, va_gc> *inits = NULL;
2912 int size, ivar_t_size;
2914 if (!chain || !name || !(size = ivar_list_length (chain)))
2917 generating_instance_variables = 1;
2918 ivar_list_template = build_v2_ivar_list_t_template (objc_v2_ivar_template,
2921 initlist = build_v2_ivar_list_initializer (CLASS_NAME (templ),
2922 objc_v2_ivar_template, chain);
2923 ivar_t_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_ivar_template));
2925 decl = start_var_decl (ivar_list_template, name);
2926 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
2927 build_int_cst (integer_type_node, ivar_t_size));
2928 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
2929 build_int_cst (integer_type_node, size));
2930 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
2931 OBJCMETA (decl, objc_meta, attr);
2932 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits));
2933 generating_instance_variables = 0;
2937 /* Routine to build initializer list to initialize objects of type
2941 build_v2_class_t_initializer (tree type, tree isa, tree superclass,
2942 tree ro, tree cache, tree vtable)
2944 vec<constructor_elt, va_gc> *initlist = NULL;
2947 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, isa);
2950 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, superclass);
2954 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cache);
2956 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, null_pointer_node);
2960 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, vtable);
2962 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, null_pointer_node);
2965 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, ro);
2967 return objc_build_constructor (type, initlist);
2970 /* Routine to build object of struct class_ro_t { ... }; */
2973 build_v2_class_ro_t_initializer (tree type, tree name,
2974 unsigned int flags, unsigned int instanceStart,
2975 unsigned int instanceSize,
2977 tree baseMethods, tree baseProtocols,
2978 tree ivars, tree property_list)
2980 tree expr, unsigned_char_star, ltyp;
2982 vec<constructor_elt, va_gc> *initlist = NULL;
2984 /* TODO: fish out the real location from somewhere. */
2985 loc = UNKNOWN_LOCATION;
2988 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
2989 build_int_cst (integer_type_node, flags));
2992 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
2993 build_int_cst (integer_type_node, instanceStart));
2996 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
2997 build_int_cst (integer_type_node, instanceSize));
2999 /* This ABI is currently only used on m64 NeXT. We always
3000 explicitly declare the alignment padding. */
3001 /* reserved, pads alignment. */
3002 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
3003 build_int_cst (integer_type_node, 0));
3006 unsigned_char_star = build_pointer_type (unsigned_char_type_node);
3010 expr = convert (unsigned_char_star, null_pointer_node);
3011 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr);
3014 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, default_conversion (name));
3017 ltyp = objc_method_list_ptr;
3019 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseMethods, 0));
3021 expr = convert (ltyp, null_pointer_node);
3022 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr);
3025 ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
3026 get_identifier (UTAG_V2_PROTOCOL_LIST)));
3028 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseProtocols, 0));
3030 expr = convert (ltyp, null_pointer_node);
3031 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr);
3034 ltyp = objc_v2_ivar_list_ptr;
3036 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivars, 0));
3038 expr = convert (ltyp, null_pointer_node);
3039 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr);
3041 /* TODO: We don't yet have the weak/strong stuff... */
3042 /* weakIvarLayout */
3043 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,
3044 convert (unsigned_char_star, null_pointer_node));
3047 ltyp = objc_prop_list_ptr;
3049 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0));
3051 expr = convert (ltyp, null_pointer_node);
3052 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr);
3053 return objc_build_constructor (type, initlist);
3056 static GTY (()) vec<ident_data_tuple, va_gc> *ehtype_list;
3058 /* Record a name as needing a catcher. */
3060 objc_v2_add_to_ehtype_list (tree name)
3066 ident_data_tuple *ref;
3068 FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
3069 if (ref->ident == name)
3070 return; /* Already entered. */
3073 /* Arbitrary initial count. */
3074 vec_alloc (ehtype_list, 8);
3076 /* Not found, or new list. */
3079 vec_safe_push (ehtype_list, e);
3083 generate_v2_class_structs (struct imp_entry *impent)
3085 tree decl, name_expr, initlist, protocol_decl, metaclass_decl, class_decl;
3086 tree field, firstIvar, chain;
3087 tree class_superclass_expr, metaclass_superclass_expr, props;
3088 /* TODO: figure out how to compute this. */
3089 tree ivarLayout = NULL_TREE;
3090 tree my_super_id = NULL_TREE, root_expr = NULL_TREE;
3091 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
3092 tree inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
3095 unsigned int instanceStart, instanceSize;
3096 unsigned int flags = 0x01; /* RO_META */
3097 int cls_flags = impent->has_cxx_cdtors ? OBJC2_CLS_HAS_CXX_STRUCTORS
3100 class_decl = impent->class_decl;
3101 metaclass_decl = impent->meta_decl;
3102 loc = DECL_SOURCE_LOCATION (class_decl);
3104 DECL_EXTERNAL (class_decl) = DECL_EXTERNAL (metaclass_decl) = 0;
3105 TREE_PUBLIC (class_decl) = TREE_PUBLIC (metaclass_decl) = 1;
3107 gcc_assert (!CP_DECL_CONTEXT (class_decl) || CP_DECL_CONTEXT (class_decl) == global_namespace);
3108 gcc_assert (!CP_DECL_CONTEXT (metaclass_decl) || CP_DECL_CONTEXT (metaclass_decl) == global_namespace);
3111 /* Generation of data for meta class. */
3112 my_super_id = CLASS_SUPER_NAME (impent->imp_template);
3115 /* Compute reference to root's name. For a meta class, "isa" is
3116 a reference to the root class name. */
3117 tree my_root_id = my_super_id;
3118 tree my_root_int, interface;
3121 my_root_int = lookup_interface (my_root_id);
3123 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
3124 my_root_id = CLASS_SUPER_NAME (my_root_int);
3130 /* {extern} struct class_t OBJC_METACLASS_$_<my_root_int>
3131 create extern if not already declared. */
3132 snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s",
3133 IDENTIFIER_POINTER (CLASS_NAME (my_root_int)));
3134 root_expr = create_extern_decl (objc_v2_class_template, buf);
3135 root_expr = build_fold_addr_expr (root_expr);
3137 /* Install class `isa' and `super' pointers at runtime. */
3138 interface = lookup_interface (my_super_id);
3139 gcc_assert (interface);
3140 /* Similarly, for OBJC_CLASS_$_<interface>... */
3141 snprintf (buf, BUFSIZE, "OBJC_CLASS_$_%s",
3142 IDENTIFIER_POINTER (CLASS_NAME (interface)));
3143 class_superclass_expr = create_extern_decl (objc_v2_class_template, buf);
3144 class_superclass_expr = build_fold_addr_expr (class_superclass_expr);
3145 /* ... and for OBJC_METACLASS_$_<interface>. */
3146 snprintf (buf, BUFSIZE, "OBJC_METACLASS_$_%s",
3147 IDENTIFIER_POINTER (CLASS_NAME (interface)));
3148 metaclass_superclass_expr = create_extern_decl (objc_v2_class_template, buf);
3149 metaclass_superclass_expr = build_fold_addr_expr (metaclass_superclass_expr);
3154 root_expr = build_unary_op (loc, ADDR_EXPR, metaclass_decl, 0);
3155 metaclass_superclass_expr = build_unary_op (loc, ADDR_EXPR, class_decl, 0);
3156 class_superclass_expr = build_int_cst (NULL_TREE, 0);
3157 flags |= 0x02; /* RO_ROOT: it is also a root meta class. */
3160 if (CLASS_PROTOCOL_LIST (impent->imp_template))
3162 generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
3163 protocol_decl = generate_v2_protocol_list (impent->imp_template,
3164 impent->imp_context);
3169 name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
3172 if (CLASS_CLS_METHODS (impent->imp_context))
3174 snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
3175 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
3177 generate_v2_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
3178 buf, meta_clac_meth);
3181 instanceStart = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template));
3183 /* Currently there are no class ivars and generation of class
3184 variables for the root of the inheritance has been removed. It
3185 causes multiple defines if there are two root classes in the
3186 link, because each will define its own identically-named offset
3189 class_ivars = NULL_TREE;
3190 /* TODO: Add total size of class variables when implemented. */
3191 instanceSize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template));
3193 /* So now build the META CLASS structs. */
3194 /* static struct class_ro_t _OBJC_METACLASS_Foo = { ... }; */
3196 decl = start_var_decl (objc_v2_class_ro_template,
3197 newabi_append_ro (IDENTIFIER_POINTER
3198 (DECL_NAME (metaclass_decl))));
3200 /* TODO: ivarLayout needs t be built. */
3202 build_v2_class_ro_t_initializer (TREE_TYPE (decl), name_expr,
3203 (flags | cls_flags), instanceStart,
3204 instanceSize, ivarLayout,
3205 class_methods, protocol_decl,
3206 class_ivars, NULL_TREE);
3207 /* The ROs sit in the default const section. */
3208 OBJCMETA (decl, objc_meta, meta_base);
3209 finish_var_decl (decl, initlist);
3211 /* static struct class_t _OBJC_METACLASS_Foo = { ... }; */
3213 build_v2_class_t_initializer (TREE_TYPE (metaclass_decl),
3215 metaclass_superclass_expr,
3216 build_fold_addr_expr (decl),
3217 build_fold_addr_expr (UOBJC_V2_CACHE_decl),
3218 build_fold_addr_expr (UOBJC_V2_VTABLE_decl));
3219 /* The class section attributes are set when they are created. */
3220 finish_var_decl (metaclass_decl, initlist);
3221 impent->meta_decl = metaclass_decl;
3223 /* So now build the CLASS structs. */
3225 flags = 0x0; /* ... */
3227 flags |= 0x02; /* RO_ROOT: this is a root class */
3229 if (DECL_VISIBILITY (class_decl) == VISIBILITY_HIDDEN)
3230 flags |= 0x10; /* RO_HIDDEN, OBJC2_CLS_HIDDEN; */
3232 if (objc2_objc_exception_attr (impent->imp_template))
3233 flags |= 0x20; /* RO_EXCEPTION */
3235 if (CLASS_NST_METHODS (impent->imp_context))
3237 snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
3238 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
3240 generate_v2_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
3241 buf, meta_clai_meth);
3244 /* Sort out the ivars before we try to compute the class sizes. */
3245 if ((chain = CLASS_IVARS (impent->imp_template)))
3247 snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
3248 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
3249 inst_ivars = generate_v2_ivars_list (chain, buf, meta_clai_vars,
3250 impent->imp_template);
3253 /* Compute instanceStart. */
3254 gcc_assert (CLASS_STATIC_TEMPLATE (impent->imp_template));
3255 field = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (impent->imp_template));
3256 if (my_super_id && field && TREE_CHAIN (field))
3257 field = TREE_CHAIN (field);
3261 while (firstIvar && TREE_CODE (firstIvar) != FIELD_DECL)
3262 firstIvar = TREE_CHAIN (firstIvar);
3264 gcc_assert (inst_ivars? (firstIvar != NULL_TREE): true);
3266 /* Compute instanceSize. */
3267 while (field && TREE_CHAIN (field)
3268 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
3269 field = TREE_CHAIN (field);
3271 if (field && TREE_CODE (field) == FIELD_DECL)
3272 instanceSize = int_byte_position (field) * BITS_PER_UNIT
3273 + tree_to_shwi (DECL_SIZE (field));
3276 instanceSize /= BITS_PER_UNIT;
3278 props = generate_v2_property_table (NULL_TREE, impent->imp_context);
3280 /* If the class has no ivars, instanceStart should be set to the
3281 superclass's instanceSize. */
3283 (inst_ivars != NULL_TREE) ? (unsigned) int_byte_position (firstIvar)
3286 /* static struct class_ro_t _OBJC_CLASS_Foo = { ... }; */
3287 decl = start_var_decl (objc_v2_class_ro_template,
3288 newabi_append_ro (IDENTIFIER_POINTER
3289 (DECL_NAME (class_decl))));
3292 build_v2_class_ro_t_initializer (TREE_TYPE (decl), name_expr,
3293 (flags | cls_flags), instanceStart,
3294 instanceSize, ivarLayout,
3295 inst_methods, protocol_decl,
3297 /* The ROs sit in the default const section. */
3298 OBJCMETA (decl, objc_meta, meta_base);
3299 finish_var_decl (decl, initlist);
3301 /* static struct class_t _OBJC_CLASS_Foo = { ... }; */
3302 initlist = build_v2_class_t_initializer (TREE_TYPE (class_decl),
3303 build_fold_addr_expr (metaclass_decl),
3304 class_superclass_expr,
3305 build_fold_addr_expr (decl),
3306 build_fold_addr_expr (UOBJC_V2_CACHE_decl),
3307 build_fold_addr_expr (UOBJC_V2_VTABLE_decl));
3309 /* The class section attributes are set when they are created. */
3310 finish_var_decl (class_decl, initlist);
3311 impent->class_decl = class_decl;
3313 objc_v2_add_to_class_list (class_decl);
3314 if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)))
3315 objc_v2_add_to_nonlazy_class_list (class_decl);
3317 if (flags & 0x20) /* RO_EXCEPTION */
3318 objc_v2_add_to_ehtype_list (CLASS_NAME (impent->imp_template));
3321 /* This routine outputs the (ivar_reference_offset, offset)
3325 build_v2_ivar_offset_ref_table (void)
3330 if (!vec_safe_length (ivar_offset_refs))
3333 FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)
3334 finish_var_decl (ref->decl, ref->offset);
3338 objc_generate_v2_next_metadata (void)
3340 struct imp_entry *impent;
3342 /* FIXME: Make sure that we generate no metadata if there is nothing
3345 gcc_assert (!objc_static_instances); /* Not for NeXT */
3347 build_metadata_templates ();
3349 for (impent = imp_list; impent; impent = impent->next)
3351 /* If -gen-decls is present, Dump the @interface of each class.
3352 TODO: Dump the classes in the order they were found, rather
3353 than in reverse order as we are doing now. */
3354 if (flag_gen_declaration)
3355 dump_interface (gen_declaration_file, impent->imp_context);
3357 /* all of the following reference the string pool... */
3358 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
3359 generate_v2_class_structs (impent);
3361 generate_v2_category (impent);
3364 build_next_selector_translation_table ();
3365 build_v2_message_ref_translation_table ();
3367 /* This will add "Protocol" to the class refs. */
3368 generate_v2_protocols ();
3370 build_v2_classrefs_table ();
3371 build_v2_super_classrefs_table (/*metaclass= */false);
3372 build_v2_super_classrefs_table (/*metaclass= */true);
3374 build_v2_ivar_offset_ref_table ();
3376 build_v2_protocol_list_translation_table ();
3377 build_v2_protocol_list_address_table ();
3379 build_v2_address_table (class_list, "_OBJC_ClassList$",
3380 meta_label_classlist);
3381 build_v2_address_table (category_list, "_OBJC_CategoryList$",
3382 meta_label_categorylist);
3383 build_v2_address_table (nonlazy_class_list, "_OBJC_NonLazyClassList$",
3384 meta_label_nonlazy_classlist);
3385 build_v2_address_table (nonlazy_category_list, "_OBJC_NonLazyCategoryList$",
3386 meta_label_nonlazy_categorylist);
3388 /* Generate catch objects for eh, if any are needed. */
3389 build_v2_eh_catch_objects ();
3391 /* Emit the string table last. */
3392 generate_strings ();
3395 /* NOTE --- Output NeXT V2 Exceptions --- */
3397 static GTY(()) tree objc_v2_ehtype_template;
3398 static GTY(()) tree next_v2_ehvtable_decl;
3399 static GTY(()) tree next_v2_EHTYPE_id_decl;
3402 build_v2_ehtype_template (void)
3404 tree decls, *chain = NULL;
3405 objc_v2_ehtype_template = objc_start_struct (get_identifier (UTAG_V2_EH_TYPE));
3407 /* void *_objc_ehtype_vtable; */
3408 decls = add_field_decl (ptr_type_node, "_objc_ehtype_vtable_ptr", &chain);
3410 /* const char *className; */
3411 add_field_decl (string_type_node, "className", &chain);
3413 /* struct class_t *const cls; */
3414 add_field_decl (build_pointer_type (objc_v2_class_template), "cls", &chain);
3416 objc_finish_struct (objc_v2_ehtype_template, decls);
3419 /* Template for the Objective-C family typeinfo type for ABI=2. This
3420 starts off the same as the gxx/cxx eh typeinfo.
3422 struct _objc_ehtype_t
3424 void *_objc_ehtype_vtable_ptr; - as per c++
3425 const char *className; - as per c++
3426 struct class_t *const cls;
3430 /* This routine builds initializer list for object of type struct _objc_ehtype_t.
3434 objc2_build_ehtype_initializer (tree name, tree cls)
3436 vec<constructor_elt, va_gc> *initlist = NULL;
3439 /* This is done the same way as c++, missing the two first entries
3440 in the parent vtable. NOTE: there is a fix-me in the Apple/NeXT
3441 runtime source about this so, perhaps, this will change at some
3443 /* _objc_ehtype_vtable + 2*sizeof(void*) */
3444 if (!next_v2_ehvtable_decl)
3446 next_v2_ehvtable_decl =
3447 start_var_decl (ptr_type_node, TAG_NEXT_EHVTABLE_NAME);
3448 TREE_STATIC (next_v2_ehvtable_decl) = 0;
3449 DECL_EXTERNAL (next_v2_ehvtable_decl) = 1;
3450 TREE_PUBLIC (next_v2_ehvtable_decl) = 1;
3452 addr = build_fold_addr_expr_with_type (next_v2_ehvtable_decl, ptr_type_node);
3453 offs = size_int (2 * int_cst_value (TYPE_SIZE_UNIT (ptr_type_node)));
3454 addr = fold_build_pointer_plus (addr, offs);
3456 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, addr);
3459 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, name);
3462 CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cls);
3464 return objc_build_constructor (objc_v2_ehtype_template, initlist);
3468 build_ehtype (tree name, const char *eh_name, bool weak)
3470 tree name_expr, class_name_expr, ehtype_decl, inits;
3472 name_expr = add_objc_string (name, class_names);
3473 /* Extern ref. for the class. ??? Maybe we can look this up
3476 create_extern_decl (objc_v2_class_template,
3477 objc_build_internal_classname (name, false));
3478 class_name_expr = build_fold_addr_expr (class_name_expr);
3479 ehtype_decl = create_global_decl (objc_v2_ehtype_template, eh_name);
3481 DECL_WEAK (ehtype_decl) = 1;
3482 inits = objc2_build_ehtype_initializer (name_expr, class_name_expr);
3483 OBJCMETA (ehtype_decl, objc_meta, meta_ehtype);
3484 finish_var_decl (ehtype_decl, inits);
3488 /* This routine returns TRUE if CLS or any of its super classes has
3489 __attribute__ ((objc_exception)). */
3492 objc2_objc_exception_attr (tree cls)
3496 if (CLASS_HAS_EXCEPTION_ATTR (cls))
3498 cls = lookup_interface (CLASS_SUPER_NAME (cls));
3505 is_implemented (tree name)
3507 struct imp_entry *t;
3508 for (t = imp_list; t; t = t->next)
3509 if (TREE_CODE (t->imp_context) == CLASS_IMPLEMENTATION_TYPE
3510 && CLASS_NAME (t->imp_template) == name)
3516 /* We will build catch objects:
3517 for any type implemented here.
3518 for any type used in a catch that has no exception attribute. */
3519 static void build_v2_eh_catch_objects (void)
3522 ident_data_tuple *ref;
3524 if (!vec_safe_length (ehtype_list))
3527 FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
3530 bool impl = is_implemented (ref->ident);
3531 bool excpt = objc2_objc_exception_attr (lookup_interface (ref->ident));
3532 snprintf (buf, BUFSIZE, "OBJC_EHTYPE_$_%s", IDENTIFIER_POINTER (ref->ident));
3534 /* The User says this class has a catcher already. */
3535 ref->data = create_extern_decl (objc_v2_ehtype_template, buf);
3537 /* Create a catcher, weak if it wasn't marked. */
3538 ref->data = build_ehtype (ref->ident, buf, !excpt);
3543 lookup_ehtype_ref (tree id)
3546 ident_data_tuple *ref;
3548 if (!vec_safe_length (ehtype_list))
3551 FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
3552 if (ref->ident == id)
3557 /* This hook, called via lang_eh_runtime_type, generates a runtime
3558 object which is either the address of the 'OBJC_EHTYPE_$_class'
3559 object or address of external OBJC_EHTYPE_id object. */
3561 next_runtime_02_eh_type (tree type)
3565 if (type == error_mark_node
3566 /*|| errorcount || sorrycount*/)
3569 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3571 if (!next_v2_EHTYPE_id_decl)
3573 /* This is provided by the Apple/NeXT libobjc.dylib so we
3574 need only to reference it. */
3575 next_v2_EHTYPE_id_decl =
3576 start_var_decl (objc_v2_ehtype_template, "OBJC_EHTYPE_id");
3577 DECL_EXTERNAL (next_v2_EHTYPE_id_decl) = 1;
3578 TREE_PUBLIC (next_v2_EHTYPE_id_decl) = 1;
3579 TREE_STATIC (next_v2_EHTYPE_id_decl) = 0;
3581 return build_fold_addr_expr (next_v2_EHTYPE_id_decl);
3584 if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3587 /* This routine is also called for c++'s catch clause; in which
3588 case, we use c++'s typeinfo decl. */
3589 return build_eh_type_type (type);
3591 error ("non-objective-c type %qT cannot be caught", type);
3596 t = OBJC_TYPE_NAME (TREE_TYPE (type));
3598 /* We have to build a reference to the OBJC_EHTYPE_<Class>. */
3599 t = lookup_ehtype_ref (t);
3603 return build_fold_addr_expr (t);
3606 return error_mark_node;
3609 static GTY(()) tree objc_eh_personality_decl;
3612 objc_eh_personality (void)
3614 if (!objc_eh_personality_decl)
3615 objc_eh_personality_decl = build_personality_function ("objc");
3616 return objc_eh_personality_decl;
3619 /* NOTE --- interfaces --- */
3622 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown)
3626 /* We have a separate re-throw entry. */
3627 t = build_function_call_vec (loc, vNULL, objc_rethrow_exception_decl,
3631 /* Throw like the others... */
3632 vec<tree, va_gc> *parms;
3633 vec_alloc (parms, 1);
3634 parms->quick_push (throw_expr);
3635 t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl,
3639 return add_stmt (t);
3642 /* Build __builtin_eh_pointer. */
3645 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
3648 t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
3649 t = build_call_expr (t, 1, integer_zero_node);
3650 return fold_convert (objc_object_type, t);
3653 static tree begin_catch (struct objc_try_context **cur_try_context, tree type,
3654 tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
3658 /* Record the data for the catch in the try context so that we can
3659 finalize it later. Ellipsis is signalled by a NULL entry. */
3661 t = build_stmt (input_location, CATCH_EXPR, NULL_TREE, compound);
3663 t = build_stmt (input_location, CATCH_EXPR, type, compound);
3664 (*cur_try_context)->current_catch = t;
3666 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3667 t = objc_build_exc_ptr (cur_try_context);
3668 t = convert (TREE_TYPE (decl), t);
3669 /* FIXME: location. */
3670 if (type && type != error_mark_node)
3672 t = build1(NOP_EXPR, ptr_type_node, t);
3673 t = build_function_call (input_location, objc2_begin_catch_decl,
3674 tree_cons (NULL_TREE, t, NULL_TREE));
3676 /* We might want to build a catch object for this (if it's not
3678 if (POINTER_TYPE_P (type)
3679 && !objc_is_object_id (TREE_TYPE (type))
3680 && TYPED_OBJECT (TREE_TYPE (type)))
3681 objc_v2_add_to_ehtype_list (OBJC_TYPE_NAME (TREE_TYPE (type)));
3683 return build2 (MODIFY_EXPR, void_type_node, decl, t);
3686 /* try { catch-body } finally { objc_end_catch (); } */
3688 finish_catch (struct objc_try_context **cur_try_context, tree curr_catch)
3690 struct objc_try_context *ct;
3691 tree try_exp, func, *l, t ;
3692 location_t loc = (*cur_try_context)->try_locus;
3694 if (!curr_catch || curr_catch == error_mark_node)
3697 t = CATCH_BODY (curr_catch);
3698 if (TREE_CODE (t) == BIND_EXPR)
3700 /* Usual case of @catch (objc-expr). */
3701 objc_begin_try_stmt (loc, BIND_EXPR_BODY (t));
3702 BIND_EXPR_BODY (t) = NULL_TREE;
3703 l = &BIND_EXPR_BODY (t);
3707 /* NULL entry, meaning @catch (...). */
3708 objc_begin_try_stmt (loc, t);
3709 CATCH_BODY (curr_catch) = NULL_TREE;
3710 l = &CATCH_BODY (curr_catch);
3713 /* Pick up the new context we made in begin_try above... */
3714 ct = *cur_try_context;
3715 func = build_function_call_vec (loc, vNULL, objc2_end_catch_decl, NULL,
3717 append_to_statement_list (func, &ct->finally_body);
3718 try_exp = build_stmt (loc, TRY_FINALLY_EXPR, ct->try_body, ct->finally_body);
3719 *cur_try_context = ct->outer;
3721 append_to_statement_list (try_exp, l);
3722 append_to_statement_list (curr_catch, &((*cur_try_context)->catch_list));
3726 finish_try_stmt (struct objc_try_context **cur_try_context)
3728 struct objc_try_context *c = *cur_try_context;
3729 tree stmt = c->try_body;
3731 stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
3732 if (c->finally_body)
3733 stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
3737 #include "gt-objc-objc-next-runtime-abi-02.h"