1 /* GNU Runtime ABI version 8
2 Copyright (C) 2011-2020 Free Software Foundation, Inc.
3 Contributed by Iain Sandoe (split from objc-act.c)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
26 #include "stringpool.h"
30 #include "cp/cp-tree.h"
36 #include "langhooks.h"
37 #include "c-family/c-objc.h"
40 /* When building Objective-C++, we are not linking against the C front-end
41 and so need to replicate the C tree-construction functions in some way. */
43 #define OBJCP_REMAP_FUNCTIONS
44 #include "objcp-decl.h"
48 #include "tree-iterator.h"
50 #include "objc-runtime-hooks.h"
51 #include "objc-runtime-shared-support.h"
52 #include "objc-encoding.h"
54 /* GNU runtime private definitions. */
55 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
57 #define TAG_GETCLASS "objc_get_class"
58 #define TAG_GETMETACLASS "objc_get_meta_class"
60 #define TAG_MSGSEND "objc_msg_lookup"
61 #define TAG_MSGSENDSUPER "objc_msg_lookup_super"
63 /* GNU-specific tags. */
65 #define TAG_EXECCLASS "__objc_exec_class"
66 #define TAG_GNUINIT "__objc_gnu_init"
68 /* The version identifies which language generation and runtime
69 the module (file) was compiled for, and is recorded in the
71 #define OBJC_VERSION 8
73 #define PROTOCOL_VERSION 2
75 /* This macro provides a method of removing ambiguity between runtimes
76 when LTO is in use on targets supporting multiple runtimes.
78 For example, at present, any target that includes an implementation of
79 the NeXT runtime needs to place Objective-C meta-data into specific
80 named sections. This should _not_ be done for the GNU runtime, and the
81 following macro is used to attach Objective-C private attributes that may
82 be used to identify the runtime for which the meta-data are intended. */
84 #define OBJCMETA(DECL,VERS,KIND) \
86 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
88 static void gnu_runtime_01_initialize (void);
90 static void build_selector_template (void);
92 static tree
gnu_runtime_abi_01_super_superclassfield_id (void);
94 static tree
gnu_runtime_abi_01_class_decl (tree
);
95 static tree
gnu_runtime_abi_01_metaclass_decl (tree
);
96 static tree
gnu_runtime_abi_01_category_decl (tree
);
97 static tree
gnu_runtime_abi_01_protocol_decl (tree
);
98 static tree
gnu_runtime_abi_01_string_decl (tree
, const char *, string_section
);
100 static tree
gnu_runtime_abi_01_get_class_reference (tree
);
101 static tree
gnu_runtime_abi_01_build_typed_selector_reference (location_t
, tree
,
103 static tree
gnu_runtime_abi_01_get_protocol_reference (location_t
, tree
);
104 static tree
gnu_runtime_abi_01_build_ivar_ref (location_t
, tree
, tree
);
105 static tree
gnu_runtime_abi_01_get_class_super_ref (location_t
, struct imp_entry
*, bool);
106 static tree
gnu_runtime_abi_01_get_category_super_ref (location_t
, struct imp_entry
*, bool);
108 static tree
gnu_runtime_abi_01_receiver_is_class_object (tree
);
109 static void gnu_runtime_abi_01_get_arg_type_list_base (vec
<tree
, va_gc
> **,
111 static tree
gnu_runtime_abi_01_build_objc_method_call (location_t
, tree
, tree
,
112 tree
, tree
, tree
, int);
114 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
115 static tree
gnu_runtime_abi_01_build_const_string_constructor (location_t
, tree
,int);
117 static void objc_generate_v1_gnu_metadata (void);
119 static tree
objc_eh_runtime_type (tree type
);
120 static tree
objc_eh_personality (void);
121 static tree
objc_build_exc_ptr (struct objc_try_context
**);
122 static tree
build_throw_stmt (location_t
, tree
, bool);
123 static tree
begin_catch (struct objc_try_context
**, tree
, tree
, tree
, bool);
124 static void finish_catch (struct objc_try_context
**, tree
);
125 static tree
finish_try_stmt (struct objc_try_context
**);
128 objc_gnu_runtime_abi_01_init (objc_runtime_hooks
*rthooks
)
130 /* GNU runtime does not need the compiler to change code in order to do GC. */
133 warning_at (UNKNOWN_LOCATION
, 0,
134 "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
138 /* Although I guess we could, we don't currently support SJLJ exceptions for the
140 if (flag_objc_sjlj_exceptions
)
142 inform (UNKNOWN_LOCATION
, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
143 flag_objc_sjlj_exceptions
= 0;
146 /* TODO: Complain if -fobjc-abi-version=N was used. */
148 /* TODO: Complain if -fobj-nilcheck was used. */
150 rthooks
->initialize
= gnu_runtime_01_initialize
;
151 rthooks
->default_constant_string_class_name
= DEF_CONSTANT_STRING_CLASS_NAME
;
152 rthooks
->tag_getclass
= TAG_GETCLASS
;
153 rthooks
->super_superclassfield_ident
= gnu_runtime_abi_01_super_superclassfield_id
;
155 rthooks
->class_decl
= gnu_runtime_abi_01_class_decl
;
156 rthooks
->metaclass_decl
= gnu_runtime_abi_01_metaclass_decl
;
157 rthooks
->category_decl
= gnu_runtime_abi_01_category_decl
;
158 rthooks
->protocol_decl
= gnu_runtime_abi_01_protocol_decl
;
159 rthooks
->string_decl
= gnu_runtime_abi_01_string_decl
;
161 rthooks
->get_class_reference
= gnu_runtime_abi_01_get_class_reference
;
162 rthooks
->build_selector_reference
= gnu_runtime_abi_01_build_typed_selector_reference
;
163 rthooks
->get_protocol_reference
= gnu_runtime_abi_01_get_protocol_reference
;
164 rthooks
->build_ivar_reference
= gnu_runtime_abi_01_build_ivar_ref
;
165 rthooks
->get_class_super_ref
= gnu_runtime_abi_01_get_class_super_ref
;
166 rthooks
->get_category_super_ref
= gnu_runtime_abi_01_get_category_super_ref
;
168 rthooks
->receiver_is_class_object
= gnu_runtime_abi_01_receiver_is_class_object
;
169 rthooks
->get_arg_type_list_base
= gnu_runtime_abi_01_get_arg_type_list_base
;
170 rthooks
->build_objc_method_call
= gnu_runtime_abi_01_build_objc_method_call
;
172 rthooks
->setup_const_string_class_decl
=
173 gnu_runtime_abi_01_setup_const_string_class_decl
;
174 rthooks
->build_const_string_constructor
=
175 gnu_runtime_abi_01_build_const_string_constructor
;
177 rthooks
->build_throw_stmt
= build_throw_stmt
;
178 rthooks
->build_exc_ptr
= objc_build_exc_ptr
;
179 rthooks
->begin_catch
= begin_catch
;
180 rthooks
->finish_catch
= finish_catch
;
181 rthooks
->finish_try_stmt
= finish_try_stmt
;
183 rthooks
->generate_metadata
= objc_generate_v1_gnu_metadata
;
187 static void build_selector_table_decl (void);
188 static void build_class_template (void);
189 static void build_category_template (void);
190 static void build_protocol_template (void);
192 static GTY(()) tree objc_meta
;
193 static GTY(()) tree meta_base
;
195 static void gnu_runtime_01_initialize (void)
197 tree type
, ftype
, IMP_type
;
199 /* We do not need to mark GNU ObjC metadata for different sections,
200 however, we do need to make sure that it is not mistaken for NeXT
202 objc_meta
= get_identifier ("OBJC1METG");
203 meta_base
= get_identifier ("NONE");
205 /* Declare type of selector-objects that represent an operation name. */
206 /* `const struct objc_selector *' */
207 type
= xref_tag (RECORD_TYPE
, get_identifier (TAG_SELECTOR
));
208 type
= build_qualified_type (type
, TYPE_QUAL_CONST
);
209 objc_selector_type
= build_pointer_type (type
);
211 /* typedef id (*IMP)(id, SEL, ...); */
212 ftype
= build_varargs_function_type_list (objc_object_type
,
217 IMP_type
= build_pointer_type (ftype
);
219 build_class_template ();
220 build_super_template ();
221 build_protocol_template ();
222 build_category_template ();
224 /* GNU runtime messenger entry points. */
225 /* TREE_NOTHROW is cleared for the message-sending functions,
226 because the function that gets called can throw in Obj-C++, or
227 could itself call something that can throw even in Obj-C. */
229 /* IMP objc_msg_lookup (id, SEL); */
230 type
= build_function_type_list (IMP_type
,
235 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
236 type
, 0, NOT_BUILT_IN
,
238 TREE_NOTHROW (umsg_decl
) = 0;
240 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
241 type
= build_function_type_list (IMP_type
,
246 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
247 type
, 0, NOT_BUILT_IN
,
249 TREE_NOTHROW (umsg_super_decl
) = 0;
251 /* The following GNU runtime entry point is called to initialize
254 __objc_exec_class (void *); */
255 type
= build_function_type_list (void_type_node
,
259 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
260 type
, 0, NOT_BUILT_IN
,
263 type
= build_function_type_list (objc_object_type
,
264 const_string_type_node
,
267 /* id objc_getClass (const char *); */
269 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
272 /* id objc_getMetaClass (const char *); */
273 objc_get_meta_class_decl
= add_builtin_function (TAG_GETMETACLASS
, type
,
274 0, NOT_BUILT_IN
, NULL
,
277 /* static SEL _OBJC_SELECTOR_TABLE[]; */
278 build_selector_table_decl ();
280 /* Stuff for properties.
281 The codegen relies on this being NULL for GNU. */
282 objc_copyStruct_decl
= NULL_TREE
;
284 /* This is the type of all of the following functions
285 bjc_getPropertyStruct() and objc_setPropertyStruct(). */
286 type
= build_function_type_list (void_type_node
,
294 /* Declare the following function:
296 objc_getPropertyStruct (void *destination, const void *source,
297 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
298 objc_getPropertyStruct_decl
= add_builtin_function ("objc_getPropertyStruct",
299 type
, 0, NOT_BUILT_IN
,
301 TREE_NOTHROW (objc_getPropertyStruct_decl
) = 0;
302 /* Declare the following function:
304 objc_setPropertyStruct (void *destination, const void *source,
305 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
306 objc_setPropertyStruct_decl
= add_builtin_function ("objc_setPropertyStruct",
307 type
, 0, NOT_BUILT_IN
,
309 TREE_NOTHROW (objc_setPropertyStruct_decl
) = 0;
311 using_eh_for_cleanups ();
312 lang_hooks
.eh_runtime_type
= objc_eh_runtime_type
;
313 lang_hooks
.eh_personality
= objc_eh_personality
;
316 /* --- templates --- */
317 /* struct _objc_selector {
323 build_selector_template (void)
325 tree decls
, *chain
= NULL
;
327 objc_selector_template
= objc_start_struct (get_identifier (UTAG_SELECTOR
));
330 decls
= add_field_decl (objc_selector_type
, "sel_id", &chain
);
332 /* char *sel_type; */
333 add_field_decl (string_type_node
, "sel_type", &chain
);
335 objc_finish_struct (objc_selector_template
, decls
);
338 /* struct _objc_class {
339 struct _objc_class *isa;
340 struct _objc_class *super_class;
345 struct _objc_ivar_list *ivars;
346 struct _objc_method_list *methods;
347 struct sarray *dtable;
348 struct _objc_class *subclass_list;
349 struct _objc_class *sibling_class;
350 struct _objc_protocol_list *protocols;
351 void *gc_object_type;
355 build_class_template (void)
357 tree ptype
, decls
, *chain
= NULL
;
359 objc_class_template
= objc_start_struct (get_identifier (UTAG_CLASS
));
361 /* struct _objc_class *isa; */
362 decls
= add_field_decl (build_pointer_type (objc_class_template
),
365 /* struct _objc_class *super_class; */
366 add_field_decl (build_pointer_type (objc_class_template
),
367 "super_class", &chain
);
370 add_field_decl (string_type_node
, "name", &chain
);
373 add_field_decl (long_integer_type_node
, "version", &chain
);
376 add_field_decl (long_integer_type_node
, "info", &chain
);
378 /* long instance_size; */
379 add_field_decl (long_integer_type_node
, "instance_size", &chain
);
381 /* struct _objc_ivar_list *ivars; */
382 add_field_decl (objc_ivar_list_ptr
,"ivars", &chain
);
384 /* struct _objc_method_list *methods; */
385 add_field_decl (objc_method_list_ptr
, "methods", &chain
);
387 /* struct sarray *dtable; */
388 ptype
= build_pointer_type(xref_tag (RECORD_TYPE
,
389 get_identifier ("sarray")));
390 add_field_decl (ptype
, "dtable", &chain
);
392 /* struct objc_class *subclass_list; */
393 ptype
= build_pointer_type (objc_class_template
);
394 add_field_decl (ptype
, "subclass_list", &chain
);
396 /* struct objc_class *sibling_class; */
397 ptype
= build_pointer_type (objc_class_template
);
398 add_field_decl (ptype
, "sibling_class", &chain
);
400 /* struct _objc_protocol **protocol_list; */
401 ptype
= build_pointer_type (build_pointer_type
402 (xref_tag (RECORD_TYPE
,
403 get_identifier (UTAG_PROTOCOL
))));
404 add_field_decl (ptype
, "protocol_list", &chain
);
406 /* void *gc_object_type; */
407 add_field_decl (build_pointer_type (void_type_node
),
408 "gc_object_type", &chain
);
410 objc_finish_struct (objc_class_template
, decls
);
413 /* struct _objc_category {
416 struct _objc_method_list *instance_methods;
417 struct _objc_method_list *class_methods;
418 struct _objc_protocol_list *protocols;
422 build_category_template (void)
424 tree ptype
, decls
, *chain
= NULL
;
426 objc_category_template
= objc_start_struct (get_identifier (UTAG_CATEGORY
));
428 /* char *category_name; */
429 decls
= add_field_decl (string_type_node
, "category_name", &chain
);
431 /* char *class_name; */
432 add_field_decl (string_type_node
, "class_name", &chain
);
434 /* struct _objc_method_list *instance_methods; */
435 add_field_decl (objc_method_list_ptr
, "instance_methods", &chain
);
437 /* struct _objc_method_list *class_methods; */
438 add_field_decl (objc_method_list_ptr
, "class_methods", &chain
);
440 /* struct _objc_protocol **protocol_list; */
441 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
442 add_field_decl (ptype
, "protocol_list", &chain
);
444 objc_finish_struct (objc_category_template
, decls
);
447 /* struct _objc_protocol {
448 struct _objc_class *isa;
450 struct _objc_protocol **protocol_list;
451 struct _objc__method_prototype_list *instance_methods;
452 struct _objc__method_prototype_list *class_methods;
456 build_protocol_template (void)
458 tree ptype
, decls
, *chain
= NULL
;
460 objc_protocol_template
= objc_start_struct (get_identifier (UTAG_PROTOCOL
));
462 /* struct _objc_class *isa; */
463 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
464 get_identifier (UTAG_CLASS
)));
465 decls
= add_field_decl (ptype
, "isa", &chain
);
467 /* char *protocol_name; */
468 add_field_decl (string_type_node
, "protocol_name", &chain
);
470 /* struct _objc_protocol **protocol_list; */
471 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
472 add_field_decl (ptype
, "protocol_list", &chain
);
474 /* struct _objc__method_prototype_list *instance_methods; */
475 add_field_decl (objc_method_proto_list_ptr
, "instance_methods", &chain
);
477 /* struct _objc__method_prototype_list *class_methods; */
478 add_field_decl (objc_method_proto_list_ptr
, "class_methods", &chain
);
480 objc_finish_struct (objc_protocol_template
, decls
);
483 /* --- names, decls + identifiers --- */
486 build_selector_table_decl (void)
490 build_selector_template ();
491 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
493 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
494 /* Squash `defined but not used' warning check_global_declaration. */
495 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
496 OBJCMETA (UOBJC_SELECTOR_TABLE_decl
, objc_meta
, meta_base
);
501 gnu_runtime_abi_01_super_superclassfield_id (void)
503 if (!super_superclassfield_id
)
504 super_superclassfield_id
= get_identifier ("super_class");
505 return super_superclassfield_id
;
510 gnu_runtime_abi_01_class_decl (tree klass
)
514 snprintf (buf
, BUFSIZE
, "_OBJC_Class_%s",
515 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
516 decl
= start_var_decl (objc_class_template
, buf
);
517 OBJCMETA (decl
, objc_meta
, meta_base
);
522 gnu_runtime_abi_01_metaclass_decl (tree klass
)
526 snprintf (buf
, BUFSIZE
, "_OBJC_MetaClass_%s",
527 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
528 decl
= start_var_decl (objc_class_template
, buf
);
529 OBJCMETA (decl
, objc_meta
, meta_base
);
534 gnu_runtime_abi_01_category_decl (tree klass
)
538 snprintf (buf
, BUFSIZE
, "_OBJC_Category_%s_on_%s",
539 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass
)),
540 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
541 decl
= start_var_decl (objc_category_template
, buf
);
542 OBJCMETA (decl
, objc_meta
, meta_base
);
547 gnu_runtime_abi_01_protocol_decl (tree p
)
552 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
553 snprintf (buf
, BUFSIZE
, "_OBJC_Protocol_%s",
554 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
555 decl
= start_var_decl (objc_protocol_template
, buf
);
556 OBJCMETA (decl
, objc_meta
, meta_base
);
561 gnu_runtime_abi_01_string_decl (tree type
, const char *name
,
562 string_section where ATTRIBUTE_UNUSED
)
564 tree decl
= start_var_decl (type
, name
);
565 OBJCMETA (decl
, objc_meta
, meta_base
);
572 gnu_runtime_abi_01_get_class_reference (tree ident
)
576 add_class_reference (ident
);
578 params
= build_tree_list (NULL_TREE
, my_build_string_pointer
579 (IDENTIFIER_LENGTH (ident
) + 1,
580 IDENTIFIER_POINTER (ident
)));
582 return build_function_call (input_location
, objc_get_class_decl
, params
);
585 /* Used by build_function_type_for_method. Append the types for
586 receiver & _cmd at the start of a method argument list to ARGTYPES.
587 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
588 trying to define a method or call one. SUPERFLAG says this is for a
589 send to super. METH may be NULL, in the case that there is no
593 gnu_runtime_abi_01_get_arg_type_list_base (vec
<tree
, va_gc
> **argtypes
,
594 tree meth
, int context
,
595 int superflag ATTRIBUTE_UNUSED
)
599 if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
600 receiver_type
= objc_instance_type
;
602 receiver_type
= objc_object_type
;
604 vec_safe_push (*argtypes
, receiver_type
);
605 /* Selector type - will eventually change to `int'. */
606 vec_safe_push (*argtypes
, objc_selector_type
);
609 /* Unused for GNU runtime. */
611 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED
)
616 /* sel_ref_chain is a list whose "value" fields will be instances of
617 identifier_node that represent the selector. LOC is the location of
621 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc
, tree ident
,
624 tree
*chain
= &sel_ref_chain
;
630 /* When we do a lookup for @selector () we have no idea of the
631 prototype - so match the first we find. */
632 if (TREE_VALUE (*chain
) == ident
633 && (!prototype
|| TREE_PURPOSE (*chain
) == prototype
))
634 goto return_at_index
;
637 chain
= &TREE_CHAIN (*chain
);
640 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
642 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
643 (b) provide better diagnostics for the first time an undefined
646 expr
= build_unary_op (loc
, ADDR_EXPR
,
647 build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
648 build_int_cst (NULL_TREE
, index
)),
650 return convert (objc_selector_type
, expr
);
653 /* Build a tree expression to send OBJECT the operation SELECTOR,
654 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
655 assuming the method has prototype METHOD_PROTOTYPE.
656 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
657 LOC is the location of the expression to build.
658 Use METHOD_PARAMS as list of args to pass to the method.
659 If SUPER_FLAG is nonzero, we look up the superclass's method. */
662 build_objc_method_call (location_t loc
, int super_flag
, tree method_prototype
,
663 tree lookup_object
, tree selector
,
666 tree sender
= (super_flag
? umsg_super_decl
667 : (flag_objc_direct_dispatch
? umsg_fast_decl
669 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
670 vec
<tree
, va_gc
> *parms
;
671 vec
<tree
, va_gc
> *tv
;
672 unsigned nparm
= (method_params
? list_length (method_params
) : 0);
674 /* If a prototype for the method to be called exists, then cast
675 the sender's return type and arguments to match that of the method.
676 Otherwise, leave sender as is. */
679 ? TREE_VALUE (TREE_TYPE (method_prototype
))
682 = build_function_type_for_method (ret_type
, method_prototype
,
683 METHOD_REF
, super_flag
);
687 if (method_prototype
&& METHOD_TYPE_ATTRIBUTES (method_prototype
))
688 ftype
= build_type_attribute_variant (ftype
,
689 METHOD_TYPE_ATTRIBUTES
692 sender_cast
= build_pointer_type (ftype
);
694 lookup_object
= build_c_cast (loc
, rcv_p
, lookup_object
);
696 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
697 lookup_object
= save_expr (lookup_object
);
699 /* Param list + 2 slots for object and selector. */
700 vec_alloc (parms
, nparm
+ 2);
703 /* First, call the lookup function to get a pointer to the method,
704 then cast the pointer, then call it with the method arguments. */
705 tv
->quick_push (lookup_object
);
706 tv
->quick_push (selector
);
707 method
= build_function_call_vec (loc
, vNULL
, sender
, tv
, NULL
);
710 /* Pass the appropriate object to the method. */
711 parms
->quick_push ((super_flag
? self_decl
: lookup_object
));
713 /* Pass the selector to the method. */
714 parms
->quick_push (selector
);
715 /* Now append the remainder of the parms. */
717 for (; method_params
; method_params
= TREE_CHAIN (method_params
))
718 parms
->quick_push (TREE_VALUE (method_params
));
720 /* Build an obj_type_ref, with the correct cast for the method call. */
721 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
722 t
= build_function_call_vec (loc
, vNULL
, t
, parms
, NULL
);
728 gnu_runtime_abi_01_build_objc_method_call (location_t loc
,
729 tree method_prototype
,
731 tree rtype ATTRIBUTE_UNUSED
,
734 int super ATTRIBUTE_UNUSED
)
737 gnu_runtime_abi_01_build_typed_selector_reference (loc
,
741 return build_objc_method_call (loc
, super
, method_prototype
, receiver
,
742 selector
, method_params
);
746 gnu_runtime_abi_01_get_protocol_reference (location_t loc
, tree p
)
748 tree expr
, protocol_struct_type
, *chain
;
749 if (!PROTOCOL_FORWARD_DECL (p
))
750 PROTOCOL_FORWARD_DECL (p
) = gnu_runtime_abi_01_protocol_decl (p
);
752 expr
= build_unary_op (loc
, ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
754 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
755 if we have it, rather than converting it here. */
756 expr
= convert (objc_protocol_type
, expr
);
758 /* The @protocol() expression is being compiled into a pointer to a
759 statically allocated instance of the Protocol class. To become
760 usable at runtime, the 'isa' pointer of the instance need to be
761 fixed up at runtime by the runtime library, to point to the
762 actual 'Protocol' class. */
764 /* For the GNU runtime, put the static Protocol instance in the list
765 of statically allocated instances, so that we make sure that its
766 'isa' pointer is fixed up at runtime by the GNU runtime library
767 to point to the Protocol class (at runtime, when loading the
768 module, the GNU runtime library loops on the statically allocated
769 instances (as found in the defs field in objc_symtab) and fixups
770 all the 'isa' pointers of those objects). */
772 /* This type is a struct containing the fields of a Protocol
773 object. (Cfr. objc_protocol_type instead is the type of a pointer
774 to such a struct). */
775 protocol_struct_type
= xref_tag (RECORD_TYPE
,
776 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
778 /* Look for the list of Protocol statically allocated instances
779 to fixup at runtime. Create a new list to hold Protocol
780 statically allocated instances, if the list is not found. At
781 present there is only another list, holding NSConstantString
782 static instances to be fixed up at runtime. */
784 for (chain
= &objc_static_instances
;
785 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
786 chain
= &TREE_CHAIN (*chain
));
790 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
791 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
795 /* Add this statically allocated instance to the Protocol list. */
796 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
797 PROTOCOL_FORWARD_DECL (p
),
798 TREE_PURPOSE (*chain
));
802 /* For ABI 8 an IVAR is just a fixed offset in the class struct. */
805 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED
,
808 return objc_build_component_ref (base
, id
);
811 /* We build super class references as we need them (but keep them once
812 built for the sake of efficiency). */
815 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED
,
816 struct imp_entry
*imp
, bool inst_meth
)
822 objc_build_component_ref (imp
->class_decl
,
823 get_identifier ("super_class"));
824 return ucls_super_ref
;
828 if (!uucls_super_ref
)
830 objc_build_component_ref (imp
->meta_decl
,
831 get_identifier ("super_class"));
832 return uucls_super_ref
;
837 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED
,
838 struct imp_entry
*imp
, bool inst_meth
)
840 tree super_name
= CLASS_SUPER_NAME (imp
->imp_template
);
843 add_class_reference (super_name
);
844 super_class
= (inst_meth
? objc_get_class_decl
: objc_get_meta_class_decl
);
845 super_name
= my_build_string_pointer (IDENTIFIER_LENGTH (super_name
) + 1,
846 IDENTIFIER_POINTER (super_name
));
847 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
848 return build_function_call (input_location
,
850 build_tree_list (NULL_TREE
, super_name
));
854 gnu_runtime_abi_01_setup_const_string_class_decl (void)
856 /* Do nothing, and create no error. */
860 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
862 static GTY(()) int num_static_inst
;
865 objc_add_static_instance (tree constructor
, tree class_decl
)
870 /* Find the list of static instances for the CLASS_DECL. Create one if
872 for (chain
= &objc_static_instances
;
873 *chain
&& TREE_VALUE (*chain
) != class_decl
;
874 chain
= &TREE_CHAIN (*chain
));
877 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
878 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
881 snprintf (buf
, BUFSIZE
, "_OBJC_INSTANCE_%d", num_static_inst
++);
882 decl
= build_decl (input_location
,
883 VAR_DECL
, get_identifier (buf
), class_decl
);
884 TREE_STATIC (decl
) = 1;
885 DECL_ARTIFICIAL (decl
) = 1;
886 TREE_USED (decl
) = 1;
887 DECL_INITIAL (decl
) = constructor
;
888 DECL_CONTEXT (decl
) = NULL
;
889 OBJCMETA (decl
, objc_meta
, meta_base
);
891 /* We may be writing something else just now.
892 Postpone till end of input. */
893 DECL_DEFER_OUTPUT (decl
) = 1;
894 lang_hooks
.decls
.pushdecl (decl
);
895 rest_of_decl_compilation (decl
, 1, 0);
897 /* Add the DECL to the head of this CLASS' list. */
898 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
904 gnu_runtime_abi_01_build_const_string_constructor (location_t loc
, tree string
,
907 tree constructor
, fields
;
908 vec
<constructor_elt
, va_gc
> *v
= NULL
;
910 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
911 fields
= TYPE_FIELDS (internal_const_str_type
);
912 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, 0));
914 fields
= DECL_CHAIN (fields
);
915 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_unary_op (loc
,
916 ADDR_EXPR
, string
, 1));
918 fields
= DECL_CHAIN (fields
);
919 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, length
));
920 constructor
= objc_build_constructor (internal_const_str_type
, v
);
922 constructor
= objc_add_static_instance (constructor
, constant_string_type
);
926 /* --- metadata - module initializer --- */
928 /* The GNU runtime requires us to provide a static initializer function
931 static void __objc_gnu_init (void) {
932 __objc_exec_class (&L_OBJC_MODULES);
937 build_module_initializer_routine (void)
942 push_lang_context (lang_name_c
); /* extern "C" */
945 objc_push_parm (build_decl (input_location
,
946 PARM_DECL
, NULL_TREE
, void_type_node
));
948 objc_start_function (get_identifier (TAG_GNUINIT
),
949 build_function_type_list (void_type_node
, NULL_TREE
),
950 NULL_TREE
, NULL_TREE
);
952 objc_start_function (get_identifier (TAG_GNUINIT
),
953 build_function_type_list (void_type_node
, NULL_TREE
),
954 NULL_TREE
, objc_get_parm_info (0, NULL_TREE
));
956 body
= c_begin_compound_stmt (true);
957 add_stmt (build_function_call
962 build_unary_op (input_location
, ADDR_EXPR
,
963 UOBJC_MODULES_decl
, 0))));
964 add_stmt (c_end_compound_stmt (input_location
, body
, true));
966 TREE_PUBLIC (current_function_decl
) = 0;
969 /* For Objective-C++, we will need to call __objc_gnu_init
970 from objc_generate_static_init_call() below. */
971 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
974 GNU_INIT_decl
= current_function_decl
;
983 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
984 to be called by the module initializer routine. */
987 objc_static_init_needed_p (void)
989 return (GNU_INIT_decl
!= NULL_TREE
);
992 /* Generate a call to the __objc_gnu_init initializer function. */
995 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
997 add_stmt (build_stmt (input_location
, EXPR_STMT
,
998 build_function_call (input_location
,
999 GNU_INIT_decl
, NULL_TREE
)));
1003 #endif /* OBJCPLUS */
1005 /* --- Output GNU Meta-data --- */
1008 generate_classref_translation_entry (tree chain
)
1010 tree expr
, decl
, type
;
1012 decl
= TREE_PURPOSE (chain
);
1013 type
= TREE_TYPE (decl
);
1015 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
1016 expr
= convert (type
, expr
); /* cast! */
1018 /* This is a class reference. It is re-written by the runtime,
1019 but will be optimized away unless we force it. */
1020 DECL_PRESERVE_P (decl
) = 1;
1021 OBJCMETA (decl
, objc_meta
, meta_base
);
1022 finish_var_decl (decl
, expr
);
1028 handle_impent (struct imp_entry
*impent
)
1032 /* objc_implementation_context = impent->imp_context;
1033 implementation_template = impent->imp_template;*/
1035 switch (TREE_CODE (impent
->imp_context
))
1037 case CLASS_IMPLEMENTATION_TYPE
:
1039 const char *const class_name
=
1040 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
1042 string
= (char *) alloca (strlen (class_name
) + 30);
1044 sprintf (string
, "__objc_class_name_%s", class_name
);
1047 case CATEGORY_IMPLEMENTATION_TYPE
:
1049 const char *const class_name
=
1050 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
1051 const char *const class_super_name
=
1052 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
1054 string
= (char *) alloca (strlen (class_name
)
1055 + strlen (class_super_name
) + 30);
1057 /* Do the same for categories. Even though no references to
1058 these symbols are generated automatically by the compiler,
1059 it gives you a handle to pull them into an archive by
1061 sprintf (string
, "*__objc_category_name_%s_%s", class_name
, class_super_name
);
1071 init
= integer_zero_node
;
1072 decl
= build_decl (input_location
,
1073 VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
1074 TREE_PUBLIC (decl
) = 1;
1075 TREE_READONLY (decl
) = 1;
1076 TREE_USED (decl
) = 1;
1077 TREE_CONSTANT (decl
) = 1;
1078 DECL_CONTEXT (decl
) = NULL_TREE
;
1079 DECL_ARTIFICIAL (decl
) = 1;
1080 TREE_STATIC (decl
) = 1;
1081 DECL_INITIAL (decl
) = error_mark_node
; /* A real initializer is coming... */
1082 /* We must force the reference. */
1083 DECL_PRESERVE_P (decl
) = 1;
1085 finish_var_decl(decl
, init
) ;
1090 build_protocol_initializer (tree type
, tree protocol_name
, tree protocol_list
,
1091 tree inst_methods
, tree class_methods
)
1095 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1097 /* TODO: pass the loc in or find it from args. */
1098 loc
= input_location
;
1099 ttyp
= build_pointer_type (xref_tag (RECORD_TYPE
,
1100 get_identifier (UTAG_CLASS
)));
1101 /* Filling the "isa" in with a version allows the runtime system to
1103 expr
= build_int_cst (ttyp
, PROTOCOL_VERSION
);
1105 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1107 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_name
);
1108 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_list
);
1110 ttyp
= objc_method_proto_list_ptr
;
1112 expr
= convert (ttyp
, build_unary_op (loc
, ADDR_EXPR
, inst_methods
, 0));
1114 expr
= convert (ttyp
, null_pointer_node
);
1115 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1118 expr
= convert (ttyp
, build_unary_op (loc
, ADDR_EXPR
, class_methods
, 0));
1120 expr
= convert (ttyp
, null_pointer_node
);
1121 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1123 return objc_build_constructor (type
, inits
);
1127 generate_protocol_list (tree i_or_p
, tree klass_ctxt
)
1129 tree array_type
, ptype
, refs_decl
, lproto
, e
, plist
;
1130 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1134 switch (TREE_CODE (i_or_p
))
1136 case CLASS_INTERFACE_TYPE
:
1137 case CATEGORY_INTERFACE_TYPE
:
1138 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
1140 case PROTOCOL_INTERFACE_TYPE
:
1141 plist
= PROTOCOL_LIST (i_or_p
);
1148 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
1149 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
1150 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
1153 /* Build initializer. */
1154 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1155 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
1156 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
1158 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
1160 tree pval
= TREE_VALUE (lproto
);
1162 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
1163 && PROTOCOL_FORWARD_DECL (pval
))
1165 tree fwref
= PROTOCOL_FORWARD_DECL (pval
);
1166 location_t loc
= DECL_SOURCE_LOCATION (fwref
) ;
1167 e
= build_unary_op (loc
, ADDR_EXPR
, fwref
, 0);
1168 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
1172 /* static struct objc_protocol *refs[n]; */
1174 switch (TREE_CODE (i_or_p
))
1176 case PROTOCOL_INTERFACE_TYPE
:
1177 snprintf (buf
, BUFSIZE
, "_OBJC_ProtocolRefs_%s",
1178 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p
)));
1180 case CLASS_INTERFACE_TYPE
:
1181 snprintf (buf
, BUFSIZE
, "_OBJC_ClassProtocols_%s",
1182 IDENTIFIER_POINTER (CLASS_NAME (i_or_p
)));
1184 case CATEGORY_INTERFACE_TYPE
:
1185 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryProtocols_%s_%s",
1186 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt
)),
1187 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt
)));
1193 ptype
= build_pointer_type (objc_protocol_template
);
1194 array_type
= build_sized_array_type (ptype
, size
+ 3);
1195 refs_decl
= start_var_decl (array_type
, buf
);
1196 OBJCMETA (refs_decl
, objc_meta
, meta_base
);
1197 finish_var_decl (refs_decl
,
1198 objc_build_constructor (TREE_TYPE (refs_decl
), v
));
1204 generate_v1_meth_descriptor_table (tree chain
, tree protocol
, const char *prefix
)
1206 tree method_list_template
, initlist
, decl
;
1208 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1211 if (!chain
|| !prefix
)
1214 if (!objc_method_prototype_template
)
1215 objc_method_prototype_template
= build_method_prototype_template ();
1217 size
= list_length (chain
);
1218 method_list_template
=
1219 build_method_prototype_list_template (objc_method_prototype_template
,
1221 snprintf (buf
, BUFSIZE
, "%s_%s", prefix
,
1222 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol
)));
1224 decl
= start_var_decl (method_list_template
, buf
);
1226 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
1228 build_descriptor_table_initializer (objc_method_prototype_template
,
1230 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, initlist
);
1231 OBJCMETA (decl
, objc_meta
, meta_base
);
1232 finish_var_decl (decl
, objc_build_constructor (method_list_template
, v
));
1236 /* For each protocol which was referenced either from a @protocol()
1237 expression, or because a class/category implements it (then a
1238 pointer to the protocol is stored in the struct describing the
1239 class/category), we create a statically allocated instance of the
1240 Protocol class. The code is written in such a way as to generate
1241 as few Protocol objects as possible; we generate a unique Protocol
1242 instance for each protocol, and we don't generate a Protocol
1243 instance if the protocol is never referenced (either from a
1244 @protocol() or from a class/category implementation). These
1245 statically allocated objects can be referred to via the static
1246 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1248 The statically allocated Protocol objects that we generate here
1249 need to be fixed up at runtime in order to be used: the 'isa'
1250 pointer of the objects need to be set up to point to the 'Protocol'
1251 class, as known at runtime.
1253 The GNU runtime fixes up all protocols before user code from the module
1254 is executed; it requires pointers to those symbols
1255 to be put in the objc_symtab (which is then passed as argument to
1256 the function __objc_exec_class() which the compiler sets up to be
1257 executed automatically when the module is loaded); setup of those
1258 Protocol objects happen in two ways in the GNU runtime: all
1259 Protocol objects referred to by a class or category implementation
1260 are fixed up when the class/category is loaded; all Protocol
1261 objects referred to by a @protocol() expression are added by the
1262 compiler to the list of statically allocated instances to fixup
1263 (the same list holding the statically allocated constant string
1264 objects). Because, as explained above, the compiler generates as
1265 few Protocol objects as possible, some Protocol object might end up
1266 being referenced multiple times when compiled with the GNU runtime,
1267 and end up being fixed up multiple times at runtime initialization.
1268 But that doesn't hurt, it's just a little inefficient. */
1271 generate_protocols (void)
1275 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
1277 /* If a protocol was directly referenced, pull in indirect references. */
1278 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
1279 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
1280 generate_protocol_references (PROTOCOL_LIST (p
));
1282 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
1284 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
1285 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
1287 /* If protocol wasn't referenced, don't generate any code. */
1288 decl
= PROTOCOL_FORWARD_DECL (p
);
1293 /* Make sure we link in the Protocol class. */
1294 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
1298 if (! METHOD_ENCODING (nst_methods
))
1300 encoding
= encode_method_prototype (nst_methods
);
1301 METHOD_ENCODING (nst_methods
) = encoding
;
1303 nst_methods
= DECL_CHAIN (nst_methods
);
1306 UOBJC_INSTANCE_METHODS_decl
=
1307 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p
), p
,
1308 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1312 if (! METHOD_ENCODING (cls_methods
))
1314 encoding
= encode_method_prototype (cls_methods
);
1315 METHOD_ENCODING (cls_methods
) = encoding
;
1318 cls_methods
= DECL_CHAIN (cls_methods
);
1321 UOBJC_CLASS_METHODS_decl
=
1322 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p
), p
,
1323 "_OBJC_PROTOCOL_CLASS_METHODS");
1324 /* generate_method_descriptors (p);*/
1326 if (PROTOCOL_LIST (p
))
1327 refs_decl
= generate_protocol_list (p
, NULL_TREE
);
1331 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1332 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
1335 refs_expr
= convert (build_pointer_type (build_pointer_type
1336 (objc_protocol_template
)),
1337 build_unary_op (input_location
,
1338 ADDR_EXPR
, refs_decl
, 0));
1340 refs_expr
= build_int_cst (NULL_TREE
, 0);
1342 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1343 by generate_method_descriptors, which is called above. */
1344 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
1345 protocol_name_expr
, refs_expr
,
1346 UOBJC_INSTANCE_METHODS_decl
,
1347 UOBJC_CLASS_METHODS_decl
);
1348 finish_var_decl (decl
, initlist
);
1353 generate_dispatch_table (tree chain
, const char *name
)
1355 tree decl
, method_list_template
, initlist
;
1356 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1357 int size
= list_length (chain
);
1359 if (!objc_method_template
)
1360 objc_method_template
= build_method_template ();
1362 method_list_template
= build_method_list_template (objc_method_template
,
1364 initlist
= build_dispatch_table_initializer (objc_method_template
, chain
);
1366 decl
= start_var_decl (method_list_template
, name
);
1368 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1369 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1370 build_int_cst (integer_type_node
, size
));
1371 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, initlist
);
1373 OBJCMETA (decl
, objc_meta
, meta_base
);
1374 finish_var_decl (decl
,
1375 objc_build_constructor (TREE_TYPE (decl
), v
));
1380 /* Init a category. */
1382 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
1383 tree inst_methods
, tree class_methods
,
1388 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1390 /* TODO: pass the loc in or find it from args. */
1391 /* TODO: pass the loc in or find it from args. */
1392 loc
= UNKNOWN_LOCATION
;
1393 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, cat_name
);
1394 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, class_name
);
1396 ltyp
= objc_method_list_ptr
;
1398 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, inst_methods
, 0));
1400 expr
= convert (ltyp
, null_pointer_node
);
1401 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1404 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, class_methods
, 0));
1406 expr
= convert (ltyp
, null_pointer_node
);
1407 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1409 /* protocol_list = */
1410 ltyp
= build_pointer_type (build_pointer_type (objc_protocol_template
));
1412 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, protocol_list
, 0));
1414 expr
= convert (ltyp
, null_pointer_node
);
1415 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1417 return objc_build_constructor (type
, v
);
1420 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1423 generate_category (struct imp_entry
*impent
)
1425 tree initlist
, cat_name_expr
, class_name_expr
;
1426 tree protocol_decl
, category
, cat_decl
;
1427 tree inst_methods
= NULL_TREE
, class_methods
= NULL_TREE
;
1428 tree cat
= impent
->imp_context
;
1431 cat_decl
= impent
->class_decl
;
1433 add_class_reference (CLASS_NAME (cat
));
1434 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
1436 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
1438 category
= lookup_category (impent
->imp_template
, CLASS_SUPER_NAME (cat
));
1440 if (category
&& CLASS_PROTOCOL_LIST (category
))
1442 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
1443 protocol_decl
= generate_protocol_list (category
, cat
);
1448 if (CLASS_NST_METHODS (cat
))
1450 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryInstanceMethods_%s_%s",
1451 IDENTIFIER_POINTER (CLASS_NAME (cat
)),
1452 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat
)));
1453 inst_methods
= generate_dispatch_table (CLASS_NST_METHODS (cat
), buf
);
1456 if (CLASS_CLS_METHODS (cat
))
1458 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryClassMethods_%s_%s",
1459 IDENTIFIER_POINTER (CLASS_NAME (cat
)),
1460 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat
)));
1461 class_methods
= generate_dispatch_table (CLASS_CLS_METHODS (cat
), buf
);
1464 initlist
= build_category_initializer (TREE_TYPE (cat_decl
),
1465 cat_name_expr
, class_name_expr
,
1466 inst_methods
, class_methods
,
1468 /* Finish and initialize the forward decl. */
1469 finish_var_decl (cat_decl
, initlist
);
1470 impent
->class_decl
= cat_decl
;
1473 /* struct _objc_class {
1474 struct objc_class *isa;
1475 struct objc_class *super_class;
1480 struct objc_ivar_list *ivars;
1481 struct objc_method_list *methods;
1482 struct sarray *dtable;
1483 struct objc_class *subclass_list;
1484 struct objc_class *sibling_class;
1485 struct objc_protocol_list *protocols;
1486 void *gc_object_type;
1490 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
1491 tree name
, tree size
, int status
,
1492 tree dispatch_table
, tree ivar_list
,
1496 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1499 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, isa
);
1502 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, super
);
1505 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, default_conversion (name
));
1508 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1509 build_int_cst (long_integer_type_node
, 0));
1512 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1513 build_int_cst (long_integer_type_node
, status
));
1515 /* instance_size = */
1516 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1517 convert (long_integer_type_node
, size
));
1519 /* objc_ivar_list = */
1521 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1522 build_int_cst (objc_ivar_list_ptr
, 0));
1525 expr
= convert (objc_ivar_list_ptr
,
1526 build_unary_op (input_location
, ADDR_EXPR
,
1528 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1531 /* objc_method_list = */
1532 if (!dispatch_table
)
1533 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1534 convert (objc_method_list_ptr
, null_pointer_node
));
1537 expr
= convert (objc_method_list_ptr
,
1538 build_unary_op (input_location
, ADDR_EXPR
,
1539 dispatch_table
, 0));
1540 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1543 /* FIXME: Remove NeXT runtime code. */
1544 if (flag_next_runtime
)
1546 ltyp
= build_pointer_type (xref_tag (RECORD_TYPE
,
1547 get_identifier ("objc_cache")));
1548 /* method_cache = */
1549 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, convert (ltyp
, null_pointer_node
));
1554 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1556 /* subclass_list = */
1557 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1559 /* sibling_class = */
1560 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1563 /* protocol_list = */
1564 ltyp
= build_pointer_type (build_pointer_type (objc_protocol_template
));
1565 if (! protocol_list
)
1566 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (ltyp
, 0));
1569 expr
= convert (ltyp
,
1570 build_unary_op (input_location
, ADDR_EXPR
,
1572 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1575 /* FIXME: Remove NeXT runtime code. */
1576 if (flag_next_runtime
)
1578 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1580 /* gc_object_type = NULL */
1581 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1583 return objc_build_constructor (type
, v
);
1588 generate_ivars_list (tree chain
, const char *name
)
1590 tree initlist
, ivar_list_template
, decl
;
1592 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1597 if (!objc_ivar_template
)
1598 objc_ivar_template
= build_ivar_template ();
1600 size
= ivar_list_length (chain
);
1602 generating_instance_variables
= 1;
1603 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
1604 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
1605 generating_instance_variables
= 0;
1607 decl
= start_var_decl (ivar_list_template
, name
);
1609 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
1610 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, initlist
);
1612 OBJCMETA (decl
, objc_meta
, meta_base
);
1613 finish_var_decl (decl
,
1614 objc_build_constructor (TREE_TYPE (decl
), inits
));
1619 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1620 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1623 generate_class_structures (struct imp_entry
*impent
)
1625 tree name_expr
, super_expr
, root_expr
, class_decl
, meta_decl
;
1626 tree my_root_id
, my_super_id
;
1627 tree cast_type
, initlist
, protocol_decl
;
1628 tree inst_methods
= NULL_TREE
, class_methods
= NULL_TREE
;
1629 tree chain
, inst_ivars
= NULL_TREE
, class_ivars
= NULL_TREE
;
1634 /* objc_implementation_context = impent->imp_context;
1635 implementation_template = impent->imp_template;*/
1636 class_decl
= impent
->class_decl
;
1637 meta_decl
= impent
->meta_decl
;
1638 /* UOBJC_CLASS_decl = impent->class_decl;
1639 UOBJC_METACLASS_decl = impent->meta_decl;*/
1641 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1643 my_super_id
= CLASS_SUPER_NAME (impent
->imp_template
);
1646 add_class_reference (my_super_id
);
1648 /* Compute "my_root_id" - this is required for code generation.
1649 the "isa" for all meta class structures points to the root of
1650 the inheritance hierarchy (e.g. "__Object")... */
1651 my_root_id
= my_super_id
;
1654 tree my_root_int
= lookup_interface (my_root_id
);
1656 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
1657 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
1664 /* No super class. */
1665 my_root_id
= CLASS_NAME (impent
->imp_template
);
1667 cast_type
= build_pointer_type (objc_class_template
);
1668 name_expr
= add_objc_string (CLASS_NAME (impent
->imp_template
),
1671 /* Install class `isa' and `super' pointers at runtime. */
1673 super_expr
= add_objc_string (my_super_id
, class_names
);
1675 super_expr
= null_pointer_node
;
1677 super_expr
= build_c_cast (loc
, cast_type
, super_expr
);
1679 root_expr
= add_objc_string (my_root_id
, class_names
);
1680 root_expr
= build_c_cast (loc
, cast_type
, root_expr
);
1682 if (CLASS_PROTOCOL_LIST (impent
->imp_template
))
1684 generate_protocol_references (CLASS_PROTOCOL_LIST (impent
->imp_template
));
1685 protocol_decl
= generate_protocol_list (impent
->imp_template
,
1686 impent
->imp_context
);
1689 protocol_decl
= NULL_TREE
;
1691 if (CLASS_CLS_METHODS (impent
->imp_context
))
1693 snprintf (buf
, BUFSIZE
, "_OBJC_ClassMethods_%s",
1694 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1695 class_methods
= generate_dispatch_table (CLASS_CLS_METHODS (impent
->imp_context
),
1699 if (CLASS_SUPER_NAME (impent
->imp_template
) == NULL_TREE
1700 && (chain
= TYPE_FIELDS (objc_class_template
)))
1702 snprintf (buf
, BUFSIZE
, "_OBJC_ClassIvars_%s",
1703 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1704 class_ivars
= generate_ivars_list (chain
, buf
);
1707 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1710 build_shared_structure_initializer
1711 (TREE_TYPE (meta_decl
),
1712 root_expr
, super_expr
, name_expr
,
1713 convert (integer_type_node
,
1714 TYPE_SIZE_UNIT (objc_class_template
)),
1715 CLS_META
, class_methods
, class_ivars
,
1718 finish_var_decl (meta_decl
, initlist
);
1719 impent
->meta_decl
= meta_decl
;
1721 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1722 if (CLASS_NST_METHODS (impent
->imp_context
))
1724 snprintf (buf
, BUFSIZE
, "_OBJC_InstanceMethods_%s",
1725 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1726 inst_methods
= generate_dispatch_table (CLASS_NST_METHODS (impent
->imp_context
),
1730 if ((chain
= CLASS_IVARS (impent
->imp_template
)))
1732 snprintf (buf
, BUFSIZE
, "_OBJC_InstanceIvars_%s",
1733 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1734 inst_ivars
= generate_ivars_list (chain
, buf
);
1738 build_shared_structure_initializer
1739 (TREE_TYPE (class_decl
),
1740 build_unary_op (loc
, ADDR_EXPR
, meta_decl
, 0),
1741 super_expr
, name_expr
,
1742 convert (integer_type_node
,
1743 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1744 (impent
->imp_template
))),
1745 CLS_FACTORY
| cls_flags
, inst_methods
, inst_ivars
,
1748 finish_var_decl (class_decl
, initlist
);
1749 impent
->class_decl
= class_decl
;
1752 /* --- Output GNU Metadata --- */
1754 /* TODO: Make this into an array of refs. */
1756 handle_class_ref (tree chain
)
1758 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
1759 char *string
= (char *) alloca (strlen (name
) + 30);
1763 sprintf (string
, "__objc_class_name_%s", name
);
1765 /* Make a decl for this name, so we can use its address in a tree. */
1766 decl
= build_decl (input_location
,
1767 VAR_DECL
, get_identifier (string
), TREE_TYPE (integer_zero_node
));
1768 DECL_EXTERNAL (decl
) = 1;
1769 TREE_PUBLIC (decl
) = 1;
1770 DECL_CONTEXT (decl
) = NULL_TREE
;
1771 finish_var_decl (decl
, 0);
1773 /* Make a decl for the address. */
1774 sprintf (string
, "__objc_class_ref_%s", name
);
1775 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
1776 decl
= build_decl (input_location
,
1777 VAR_DECL
, get_identifier (string
), string_type_node
);
1778 TREE_STATIC (decl
) = 1;
1779 TREE_USED (decl
) = 1;
1780 DECL_READ_P (decl
) = 1;
1781 DECL_ARTIFICIAL (decl
) = 1;
1782 DECL_INITIAL (decl
) = error_mark_node
;
1784 /* We must force the reference. */
1785 DECL_PRESERVE_P (decl
) = 1;
1787 DECL_CONTEXT (decl
) = NULL_TREE
;
1788 finish_var_decl (decl
, exp
);
1792 get_proto_encoding (tree proto
)
1797 if (! METHOD_ENCODING (proto
))
1799 encoding
= encode_method_prototype (proto
);
1800 METHOD_ENCODING (proto
) = encoding
;
1803 encoding
= METHOD_ENCODING (proto
);
1805 return add_objc_string (encoding
, meth_var_types
);
1808 return build_int_cst (NULL_TREE
, 0);
1812 build_gnu_selector_translation_table (void)
1815 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1816 vec
<constructor_elt
, va_gc
> *v
;
1818 /* Cause the selector table (previously forward-declared)
1819 to be actually output. */
1821 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1826 /* TODO: improve on the location for the diagnostic. */
1827 location_t loc
= input_location
;
1828 diagnose_missing_method (TREE_VALUE (chain
), loc
);
1832 expr
= build_selector (TREE_VALUE (chain
));
1833 encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1834 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1835 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, encoding
);
1836 expr
= objc_build_constructor (objc_selector_template
, v
);
1838 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1839 } /* each element in the chain */
1841 /* List terminator. */
1843 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1844 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1845 expr
= objc_build_constructor (objc_selector_template
, v
);
1847 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1848 expr
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
1850 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, expr
);
1853 /* Output references to all statically allocated objects. Return the DECL
1854 for the array built. */
1857 generate_static_references (void)
1859 tree expr
= NULL_TREE
;
1860 tree class_name
, klass
, decl
;
1861 tree cl_chain
, in_chain
, type
1862 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
1863 int num_inst
, num_class
;
1865 vec
<constructor_elt
, va_gc
> *decls
= NULL
;
1867 /* FIXME: Remove NeXT runtime code. */
1868 if (flag_next_runtime
)
1871 for (cl_chain
= objc_static_instances
, num_class
= 0;
1872 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1874 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1876 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1877 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1879 snprintf (buf
, BUFSIZE
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1880 decl
= start_var_decl (type
, buf
);
1882 /* Output {class_name, ...}. */
1883 klass
= TREE_VALUE (cl_chain
);
1884 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (klass
), class_names
);
1885 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1886 build_unary_op (input_location
,
1887 ADDR_EXPR
, class_name
, 1));
1889 /* Output {..., instance, ...}. */
1890 for (in_chain
= TREE_PURPOSE (cl_chain
);
1891 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1893 expr
= build_unary_op (input_location
,
1894 ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1895 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1898 /* Output {..., NULL}. */
1899 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1901 expr
= objc_build_constructor (TREE_TYPE (decl
), v
);
1902 OBJCMETA (decl
, objc_meta
, meta_base
);
1903 finish_var_decl (decl
, expr
);
1904 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
,
1905 build_unary_op (input_location
,
1906 ADDR_EXPR
, decl
, 1));
1909 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1910 expr
= objc_build_constructor (type
, decls
);
1911 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
1912 OBJCMETA (static_instances_decl
, objc_meta
, meta_base
);
1913 finish_var_decl (static_instances_decl
, expr
);
1916 /* Create the initial value for the `defs' field of _objc_symtab.
1917 This is a CONSTRUCTOR. */
1920 init_def_list (tree type
)
1923 struct imp_entry
*impent
;
1925 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1928 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1930 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1932 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1933 expr
= build_unary_op (loc
,
1934 ADDR_EXPR
, impent
->class_decl
, 0);
1935 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1940 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1942 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1944 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1945 expr
= build_unary_op (loc
,
1946 ADDR_EXPR
, impent
->class_decl
, 0);
1947 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1951 loc
= UNKNOWN_LOCATION
;
1952 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1953 if (static_instances_decl
)
1954 expr
= build_unary_op (loc
, ADDR_EXPR
, static_instances_decl
, 0);
1956 expr
= integer_zero_node
;
1957 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1959 return objc_build_constructor (type
, v
);
1962 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1964 /* Predefine the following data type:
1972 void *defs[cls_def_cnt + cat_def_cnt];
1976 build_objc_symtab_template (void)
1978 tree fields
, array_type
, *chain
= NULL
;
1981 objc_symtab_template
= objc_start_struct (get_identifier (UTAG_SYMTAB
));
1983 /* long sel_ref_cnt; */
1984 fields
= add_field_decl (long_integer_type_node
, "sel_ref_cnt", &chain
);
1987 add_field_decl (build_pointer_type (objc_selector_type
), "refs", &chain
);
1989 /* short cls_def_cnt; */
1990 add_field_decl (short_integer_type_node
, "cls_def_cnt", &chain
);
1992 /* short cat_def_cnt; */
1993 add_field_decl (short_integer_type_node
, "cat_def_cnt", &chain
);
1995 /* Note that padding will be added here on LP64. */
1997 /* void *defs[imp_count + cat_count (+ 1)]; */
1998 /* NB: The index is one less than the size of the array. */
1999 index
= imp_count
+ cat_count
;
2000 array_type
= build_sized_array_type (ptr_type_node
, index
+ 1);
2001 add_field_decl (array_type
, "defs", &chain
);
2003 objc_finish_struct (objc_symtab_template
, fields
);
2005 /* Construct the initial value for all of _objc_symtab. */
2008 init_objc_symtab (tree type
)
2010 tree field
, expr
, ltyp
;
2012 vec
<constructor_elt
, va_gc
> *v
= NULL
;
2014 loc
= UNKNOWN_LOCATION
;
2016 /* sel_ref_cnt = { ..., 5, ... } */
2018 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2019 build_int_cst (long_integer_type_node
, 0));
2021 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2023 ltyp
= build_pointer_type (objc_selector_type
);
2025 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
,
2026 UOBJC_SELECTOR_TABLE_decl
, 1));
2028 expr
= convert (ltyp
, null_pointer_node
);
2029 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2031 /* cls_def_cnt = { ..., 5, ... } */
2033 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2034 build_int_cst (short_integer_type_node
, imp_count
));
2036 /* cat_def_cnt = { ..., 5, ... } */
2038 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2039 build_int_cst (short_integer_type_node
, cat_count
));
2041 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2043 field
= TYPE_FIELDS (type
);
2044 field
= DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field
))));
2046 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, init_def_list (TREE_TYPE (field
)));
2048 return objc_build_constructor (type
, v
);
2051 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2052 and initialized appropriately. */
2055 generate_objc_symtab_decl (void)
2057 build_objc_symtab_template ();
2058 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2059 OBJCMETA (UOBJC_SYMBOLS_decl
, objc_meta
, meta_base
);
2060 finish_var_decl (UOBJC_SYMBOLS_decl
,
2061 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2065 objc_generate_v1_gnu_metadata (void)
2067 struct imp_entry
*impent
;
2070 /* Process the static instances here because initialization of objc_symtab
2072 if (objc_static_instances
)
2073 generate_static_references ();
2075 objc_implementation_context
=
2076 implementation_template
=
2078 UOBJC_METACLASS_decl
= NULL_TREE
;
2080 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2082 /* If -gen-decls is present, Dump the @interface of each class.
2083 TODO: Dump the classes in the order they were found, rather than in
2084 reverse order as we are doing now. */
2085 if (flag_gen_declaration
)
2086 dump_interface (gen_declaration_file
, impent
->imp_context
);
2088 /* all of the following reference the string pool... */
2089 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2090 generate_class_structures (impent
);
2092 generate_category (impent
);
2095 /* If we are using an array of selectors, we must always
2096 finish up the array decl even if no selectors were used. */
2097 build_gnu_selector_translation_table ();
2100 generate_protocols ();
2102 /* Arrange for ObjC data structures to be initialized at run time. */
2103 /* FIXME: Have some more elegant way to determine if we need to
2104 generate objc_symtab_decl or not, instead of checking these
2106 if (imp_list
|| class_names_chain
2107 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
2108 || prop_names_attr_chain
)
2109 generate_objc_symtab_decl ();
2111 if (imp_list
|| class_names_chain
|| objc_static_instances
2112 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
2114 /* Make sure that the meta-data are identified as being
2116 build_module_descriptor (OBJC_VERSION
,
2117 build_tree_list (objc_meta
, meta_base
));
2118 build_module_initializer_routine ();
2121 /* Dump the class references. This forces the appropriate classes
2122 to be linked into the executable image, preserving unix archive
2123 semantics. This can be removed when we move to a more dynamically
2124 linked environment. */
2126 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2128 handle_class_ref (chain
);
2129 if (TREE_PURPOSE (chain
))
2130 generate_classref_translation_entry (chain
);
2133 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2134 handle_impent (impent
);
2136 generate_strings ();
2139 /* --- exceptions --- */
2141 static GTY(()) tree objc_eh_personality_decl
;
2144 objc_eh_runtime_type (tree type
)
2146 tree ident
, eh_id
, decl
, str
;
2148 if (type
== error_mark_node
2149 || errorcount
|| sorrycount
)
2151 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2152 to prevent an ICE. Note that we know that the compiler will
2153 terminate with an error and this 'ErrorMarkNode' class name will
2154 never be actually used. */
2155 ident
= get_identifier ("ErrorMarkNode");
2156 goto make_err_class
;
2159 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
2160 /* We don't want to identify 'id' for GNU. Instead, build a 0
2161 entry in the exceptions table. */
2162 return null_pointer_node
;
2164 if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
2167 /* This routine is also called for c++ catch clauses; in which case,
2168 we use the c++ typeinfo decl. */
2169 return build_eh_type_type (type
);
2171 error ("non-objective-c type %qT cannot be caught", type
);
2172 ident
= get_identifier ("ErrorMarkNode");
2173 goto make_err_class
;
2177 ident
= OBJC_TYPE_NAME (TREE_TYPE (type
));
2180 /* If this class was already referenced, then it will be output during
2181 meta-data emission, so we don't need to do it here. */
2182 decl
= get_objc_string_decl (ident
, class_names
);
2183 eh_id
= add_objc_string (ident
, class_names
);
2186 /* Not found ... so we need to build it - from the freshly-entered id. */
2187 decl
= get_objc_string_decl (ident
, class_names
);
2188 str
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2189 IDENTIFIER_POINTER (ident
));
2190 /* We have to finalize this var here, because this might be called after
2191 all the other metadata strings have been emitted. */
2192 finish_var_decl (decl
, str
);
2198 objc_eh_personality (void)
2200 if (!objc_eh_personality_decl
)
2202 objc_eh_personality_decl
= build_personality_function ("gnu_objc");
2204 objc_eh_personality_decl
= build_personality_function ("gxx");
2206 return objc_eh_personality_decl
;
2209 /* -- interfaces --- */
2212 build_throw_stmt (location_t loc
, tree throw_expr
, bool rethrown ATTRIBUTE_UNUSED
)
2215 vec
<tree
, va_gc
> *parms
;
2216 vec_alloc (parms
, 1);
2217 /* A throw is just a call to the runtime throw function with the
2218 object as a parameter. */
2219 parms
->quick_push (throw_expr
);
2220 t
= build_function_call_vec (loc
, vNULL
, objc_exception_throw_decl
, parms
,
2223 return add_stmt (t
);
2226 /* Build __builtin_eh_pointer. */
2229 objc_build_exc_ptr (struct objc_try_context
**x ATTRIBUTE_UNUSED
)
2232 t
= builtin_decl_explicit (BUILT_IN_EH_POINTER
);
2233 t
= build_call_expr (t
, 1, integer_zero_node
);
2234 return fold_convert (objc_object_type
, t
);
2238 begin_catch (struct objc_try_context
**cur_try_context
, tree type
,
2239 tree decl
, tree compound
, bool ellipsis ATTRIBUTE_UNUSED
)
2242 /* Record the data for the catch in the try context so that we can
2243 finalize it later. */
2245 t
= build_stmt (input_location
, CATCH_EXPR
, NULL
, compound
);
2247 t
= build_stmt (input_location
, CATCH_EXPR
, type
, compound
);
2248 (*cur_try_context
)->current_catch
= t
;
2250 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2251 t
= objc_build_exc_ptr (cur_try_context
);
2252 t
= convert (TREE_TYPE (decl
), t
);
2253 return build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
2257 finish_catch (struct objc_try_context
**cur_try_context
, tree current_catch
)
2259 append_to_statement_list (current_catch
, &((*cur_try_context
)->catch_list
));
2263 finish_try_stmt (struct objc_try_context
**cur_try_context
)
2265 struct objc_try_context
*c
= *cur_try_context
;
2266 tree stmt
= c
->try_body
;
2268 stmt
= build_stmt (c
->try_locus
, TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
2269 if (c
->finally_body
)
2270 stmt
= build_stmt (c
->try_locus
, TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
2274 #include "gt-objc-objc-gnu-runtime-abi-01.h"