1 /* GNU Runtime ABI version 8
2 Copyright (C) 2011-2013 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"
25 #include "stringpool.h"
28 #include "cp/cp-tree.h"
34 #include "langhooks.h"
35 #include "c-family/c-objc.h"
38 /* When building Objective-C++, we are not linking against the C front-end
39 and so need to replicate the C tree-construction functions in some way. */
41 #define OBJCP_REMAP_FUNCTIONS
42 #include "objcp-decl.h"
47 #include "tree-iterator.h"
49 #include "objc-runtime-hooks.h"
50 #include "objc-runtime-shared-support.h"
51 #include "objc-encoding.h"
53 /* GNU runtime private definitions. */
54 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
56 #define TAG_GETCLASS "objc_get_class"
57 #define TAG_GETMETACLASS "objc_get_meta_class"
59 #define TAG_MSGSEND "objc_msg_lookup"
60 #define TAG_MSGSENDSUPER "objc_msg_lookup_super"
62 /* GNU-specific tags. */
64 #define TAG_EXECCLASS "__objc_exec_class"
65 #define TAG_GNUINIT "__objc_gnu_init"
67 /* The version identifies which language generation and runtime
68 the module (file) was compiled for, and is recorded in the
70 #define OBJC_VERSION 8
72 #define PROTOCOL_VERSION 2
74 /* This macro provides a method of removing ambiguity between runtimes
75 when LTO is in use on targets supporting multiple runtimes.
77 For example, at present, any target that includes an implementation of
78 the NeXT runtime needs to place Objective-C meta-data into specific
79 named sections. This should _not_ be done for the GNU runtime, and the
80 following macro is used to attach Objective-C private attributes that may
81 be used to identify the runtime for which the meta-data are intended. */
83 #define OBJCMETA(DECL,VERS,KIND) \
85 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
87 static void gnu_runtime_01_initialize (void);
89 static void build_selector_template (void);
91 static tree
gnu_runtime_abi_01_super_superclassfield_id (void);
93 static tree
gnu_runtime_abi_01_class_decl (tree
);
94 static tree
gnu_runtime_abi_01_metaclass_decl (tree
);
95 static tree
gnu_runtime_abi_01_category_decl (tree
);
96 static tree
gnu_runtime_abi_01_protocol_decl (tree
);
97 static tree
gnu_runtime_abi_01_string_decl (tree
, const char *, string_section
);
99 static tree
gnu_runtime_abi_01_get_class_reference (tree
);
100 static tree
gnu_runtime_abi_01_build_typed_selector_reference (location_t
, tree
,
102 static tree
gnu_runtime_abi_01_get_protocol_reference (location_t
, tree
);
103 static tree
gnu_runtime_abi_01_build_ivar_ref (location_t
, tree
, tree
);
104 static tree
gnu_runtime_abi_01_get_class_super_ref (location_t
, struct imp_entry
*, bool);
105 static tree
gnu_runtime_abi_01_get_category_super_ref (location_t
, struct imp_entry
*, bool);
107 static tree
gnu_runtime_abi_01_receiver_is_class_object (tree
);
108 static void gnu_runtime_abi_01_get_arg_type_list_base (vec
<tree
, va_gc
> **,
110 static tree
gnu_runtime_abi_01_build_objc_method_call (location_t
, tree
, tree
,
111 tree
, tree
, tree
, int);
113 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
114 static tree
gnu_runtime_abi_01_build_const_string_constructor (location_t
, tree
,int);
116 static void objc_generate_v1_gnu_metadata (void);
118 static tree
objc_eh_runtime_type (tree type
);
119 static tree
objc_eh_personality (void);
120 static tree
objc_build_exc_ptr (struct objc_try_context
**);
121 static tree
build_throw_stmt (location_t
, tree
, bool);
122 static tree
begin_catch (struct objc_try_context
**, tree
, tree
, tree
, bool);
123 static void finish_catch (struct objc_try_context
**, tree
);
124 static tree
finish_try_stmt (struct objc_try_context
**);
127 objc_gnu_runtime_abi_01_init (objc_runtime_hooks
*rthooks
)
129 /* GNU runtime does not need the compiler to change code in order to do GC. */
132 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
136 /* Although I guess we could, we don't currently support SJLJ exceptions for the
138 if (flag_objc_sjlj_exceptions
)
140 inform (UNKNOWN_LOCATION
, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
141 flag_objc_sjlj_exceptions
= 0;
144 /* TODO: Complain if -fobjc-abi-version=N was used. */
146 /* TODO: Complain if -fobj-nilcheck was used. */
148 rthooks
->initialize
= gnu_runtime_01_initialize
;
149 rthooks
->default_constant_string_class_name
= DEF_CONSTANT_STRING_CLASS_NAME
;
150 rthooks
->tag_getclass
= TAG_GETCLASS
;
151 rthooks
->super_superclassfield_ident
= gnu_runtime_abi_01_super_superclassfield_id
;
153 rthooks
->class_decl
= gnu_runtime_abi_01_class_decl
;
154 rthooks
->metaclass_decl
= gnu_runtime_abi_01_metaclass_decl
;
155 rthooks
->category_decl
= gnu_runtime_abi_01_category_decl
;
156 rthooks
->protocol_decl
= gnu_runtime_abi_01_protocol_decl
;
157 rthooks
->string_decl
= gnu_runtime_abi_01_string_decl
;
159 rthooks
->get_class_reference
= gnu_runtime_abi_01_get_class_reference
;
160 rthooks
->build_selector_reference
= gnu_runtime_abi_01_build_typed_selector_reference
;
161 rthooks
->get_protocol_reference
= gnu_runtime_abi_01_get_protocol_reference
;
162 rthooks
->build_ivar_reference
= gnu_runtime_abi_01_build_ivar_ref
;
163 rthooks
->get_class_super_ref
= gnu_runtime_abi_01_get_class_super_ref
;
164 rthooks
->get_category_super_ref
= gnu_runtime_abi_01_get_category_super_ref
;
166 rthooks
->receiver_is_class_object
= gnu_runtime_abi_01_receiver_is_class_object
;
167 rthooks
->get_arg_type_list_base
= gnu_runtime_abi_01_get_arg_type_list_base
;
168 rthooks
->build_objc_method_call
= gnu_runtime_abi_01_build_objc_method_call
;
170 rthooks
->setup_const_string_class_decl
=
171 gnu_runtime_abi_01_setup_const_string_class_decl
;
172 rthooks
->build_const_string_constructor
=
173 gnu_runtime_abi_01_build_const_string_constructor
;
175 rthooks
->build_throw_stmt
= build_throw_stmt
;
176 rthooks
->build_exc_ptr
= objc_build_exc_ptr
;
177 rthooks
->begin_catch
= begin_catch
;
178 rthooks
->finish_catch
= finish_catch
;
179 rthooks
->finish_try_stmt
= finish_try_stmt
;
181 rthooks
->generate_metadata
= objc_generate_v1_gnu_metadata
;
185 static void build_selector_table_decl (void);
186 static void build_class_template (void);
187 static void build_category_template (void);
188 static void build_protocol_template (void);
190 static GTY(()) tree objc_meta
;
191 static GTY(()) tree meta_base
;
193 static void gnu_runtime_01_initialize (void)
195 tree type
, ftype
, IMP_type
;
197 /* We do not need to mark GNU ObjC metadata for different sections,
198 however, we do need to make sure that it is not mistaken for NeXT
200 objc_meta
= get_identifier ("OBJC1METG");
201 meta_base
= get_identifier ("NONE");
203 /* Declare type of selector-objects that represent an operation name. */
204 /* `const struct objc_selector *' */
205 type
= xref_tag (RECORD_TYPE
, get_identifier (TAG_SELECTOR
));
206 type
= build_qualified_type (type
, TYPE_QUAL_CONST
);
207 objc_selector_type
= build_pointer_type (type
);
209 /* typedef id (*IMP)(id, SEL, ...); */
210 ftype
= build_varargs_function_type_list (objc_object_type
,
215 IMP_type
= build_pointer_type (ftype
);
217 build_class_template ();
218 build_super_template ();
219 build_protocol_template ();
220 build_category_template ();
222 /* GNU runtime messenger entry points. */
223 /* TREE_NOTHROW is cleared for the message-sending functions,
224 because the function that gets called can throw in Obj-C++, or
225 could itself call something that can throw even in Obj-C. */
227 /* IMP objc_msg_lookup (id, SEL); */
228 type
= build_function_type_list (IMP_type
,
233 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
234 type
, 0, NOT_BUILT_IN
,
236 TREE_NOTHROW (umsg_decl
) = 0;
238 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
239 type
= build_function_type_list (IMP_type
,
244 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
245 type
, 0, NOT_BUILT_IN
,
247 TREE_NOTHROW (umsg_super_decl
) = 0;
249 /* The following GNU runtime entry point is called to initialize
252 __objc_exec_class (void *); */
253 type
= build_function_type_list (void_type_node
,
257 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
258 type
, 0, NOT_BUILT_IN
,
261 type
= build_function_type_list (objc_object_type
,
262 const_string_type_node
,
265 /* id objc_getClass (const char *); */
267 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
270 /* id objc_getMetaClass (const char *); */
271 objc_get_meta_class_decl
= add_builtin_function (TAG_GETMETACLASS
, type
,
272 0, NOT_BUILT_IN
, NULL
,
275 /* static SEL _OBJC_SELECTOR_TABLE[]; */
276 build_selector_table_decl ();
278 /* Stuff for properties.
279 The codegen relies on this being NULL for GNU. */
280 objc_copyStruct_decl
= NULL_TREE
;
282 /* This is the type of all of the following functions
283 bjc_getPropertyStruct() and objc_setPropertyStruct(). */
284 type
= build_function_type_list (void_type_node
,
292 /* Declare the following function:
294 objc_getPropertyStruct (void *destination, const void *source,
295 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
296 objc_getPropertyStruct_decl
= add_builtin_function ("objc_getPropertyStruct",
297 type
, 0, NOT_BUILT_IN
,
299 TREE_NOTHROW (objc_getPropertyStruct_decl
) = 0;
300 /* Declare the following function:
302 objc_setPropertyStruct (void *destination, const void *source,
303 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
304 objc_setPropertyStruct_decl
= add_builtin_function ("objc_setPropertyStruct",
305 type
, 0, NOT_BUILT_IN
,
307 TREE_NOTHROW (objc_setPropertyStruct_decl
) = 0;
309 using_eh_for_cleanups ();
310 lang_hooks
.eh_runtime_type
= objc_eh_runtime_type
;
311 lang_hooks
.eh_personality
= objc_eh_personality
;
314 /* --- templates --- */
315 /* struct _objc_selector {
321 build_selector_template (void)
323 tree decls
, *chain
= NULL
;
325 objc_selector_template
= objc_start_struct (get_identifier (UTAG_SELECTOR
));
328 decls
= add_field_decl (objc_selector_type
, "sel_id", &chain
);
330 /* char *sel_type; */
331 add_field_decl (string_type_node
, "sel_type", &chain
);
333 objc_finish_struct (objc_selector_template
, decls
);
336 /* struct _objc_class {
337 struct _objc_class *isa;
338 struct _objc_class *super_class;
343 struct _objc_ivar_list *ivars;
344 struct _objc_method_list *methods;
345 struct sarray *dtable;
346 struct _objc_class *subclass_list;
347 struct _objc_class *sibling_class;
348 struct _objc_protocol_list *protocols;
349 void *gc_object_type;
353 build_class_template (void)
355 tree ptype
, decls
, *chain
= NULL
;
357 objc_class_template
= objc_start_struct (get_identifier (UTAG_CLASS
));
359 /* struct _objc_class *isa; */
360 decls
= add_field_decl (build_pointer_type (objc_class_template
),
363 /* struct _objc_class *super_class; */
364 add_field_decl (build_pointer_type (objc_class_template
),
365 "super_class", &chain
);
368 add_field_decl (string_type_node
, "name", &chain
);
371 add_field_decl (long_integer_type_node
, "version", &chain
);
374 add_field_decl (long_integer_type_node
, "info", &chain
);
376 /* long instance_size; */
377 add_field_decl (long_integer_type_node
, "instance_size", &chain
);
379 /* struct _objc_ivar_list *ivars; */
380 add_field_decl (objc_ivar_list_ptr
,"ivars", &chain
);
382 /* struct _objc_method_list *methods; */
383 add_field_decl (objc_method_list_ptr
, "methods", &chain
);
385 /* struct sarray *dtable; */
386 ptype
= build_pointer_type(xref_tag (RECORD_TYPE
,
387 get_identifier ("sarray")));
388 add_field_decl (ptype
, "dtable", &chain
);
390 /* struct objc_class *subclass_list; */
391 ptype
= build_pointer_type (objc_class_template
);
392 add_field_decl (ptype
, "subclass_list", &chain
);
394 /* struct objc_class *sibling_class; */
395 ptype
= build_pointer_type (objc_class_template
);
396 add_field_decl (ptype
, "sibling_class", &chain
);
398 /* struct _objc_protocol **protocol_list; */
399 ptype
= build_pointer_type (build_pointer_type
400 (xref_tag (RECORD_TYPE
,
401 get_identifier (UTAG_PROTOCOL
))));
402 add_field_decl (ptype
, "protocol_list", &chain
);
404 /* void *gc_object_type; */
405 add_field_decl (build_pointer_type (void_type_node
),
406 "gc_object_type", &chain
);
408 objc_finish_struct (objc_class_template
, decls
);
411 /* struct _objc_category {
414 struct _objc_method_list *instance_methods;
415 struct _objc_method_list *class_methods;
416 struct _objc_protocol_list *protocols;
420 build_category_template (void)
422 tree ptype
, decls
, *chain
= NULL
;
424 objc_category_template
= objc_start_struct (get_identifier (UTAG_CATEGORY
));
426 /* char *category_name; */
427 decls
= add_field_decl (string_type_node
, "category_name", &chain
);
429 /* char *class_name; */
430 add_field_decl (string_type_node
, "class_name", &chain
);
432 /* struct _objc_method_list *instance_methods; */
433 add_field_decl (objc_method_list_ptr
, "instance_methods", &chain
);
435 /* struct _objc_method_list *class_methods; */
436 add_field_decl (objc_method_list_ptr
, "class_methods", &chain
);
438 /* struct _objc_protocol **protocol_list; */
439 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
440 add_field_decl (ptype
, "protocol_list", &chain
);
442 objc_finish_struct (objc_category_template
, decls
);
445 /* struct _objc_protocol {
446 struct _objc_class *isa;
448 struct _objc_protocol **protocol_list;
449 struct _objc__method_prototype_list *instance_methods;
450 struct _objc__method_prototype_list *class_methods;
454 build_protocol_template (void)
456 tree ptype
, decls
, *chain
= NULL
;
458 objc_protocol_template
= objc_start_struct (get_identifier (UTAG_PROTOCOL
));
460 /* struct _objc_class *isa; */
461 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
462 get_identifier (UTAG_CLASS
)));
463 decls
= add_field_decl (ptype
, "isa", &chain
);
465 /* char *protocol_name; */
466 add_field_decl (string_type_node
, "protocol_name", &chain
);
468 /* struct _objc_protocol **protocol_list; */
469 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
470 add_field_decl (ptype
, "protocol_list", &chain
);
472 /* struct _objc__method_prototype_list *instance_methods; */
473 add_field_decl (objc_method_proto_list_ptr
, "instance_methods", &chain
);
475 /* struct _objc__method_prototype_list *class_methods; */
476 add_field_decl (objc_method_proto_list_ptr
, "class_methods", &chain
);
478 objc_finish_struct (objc_protocol_template
, decls
);
481 /* --- names, decls + identifiers --- */
484 build_selector_table_decl (void)
488 build_selector_template ();
489 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
491 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
492 OBJCMETA (UOBJC_SELECTOR_TABLE_decl
, objc_meta
, meta_base
);
497 gnu_runtime_abi_01_super_superclassfield_id (void)
499 if (!super_superclassfield_id
)
500 super_superclassfield_id
= get_identifier ("super_class");
501 return super_superclassfield_id
;
506 gnu_runtime_abi_01_class_decl (tree klass
)
510 snprintf (buf
, BUFSIZE
, "_OBJC_Class_%s",
511 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
512 decl
= start_var_decl (objc_class_template
, buf
);
513 OBJCMETA (decl
, objc_meta
, meta_base
);
518 gnu_runtime_abi_01_metaclass_decl (tree klass
)
522 snprintf (buf
, BUFSIZE
, "_OBJC_MetaClass_%s",
523 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
524 decl
= start_var_decl (objc_class_template
, buf
);
525 OBJCMETA (decl
, objc_meta
, meta_base
);
530 gnu_runtime_abi_01_category_decl (tree klass
)
534 snprintf (buf
, BUFSIZE
, "_OBJC_Category_%s_on_%s",
535 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass
)),
536 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
537 decl
= start_var_decl (objc_category_template
, buf
);
538 OBJCMETA (decl
, objc_meta
, meta_base
);
543 gnu_runtime_abi_01_protocol_decl (tree p
)
548 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
549 snprintf (buf
, BUFSIZE
, "_OBJC_Protocol_%s",
550 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
551 decl
= start_var_decl (objc_protocol_template
, buf
);
552 OBJCMETA (decl
, objc_meta
, meta_base
);
557 gnu_runtime_abi_01_string_decl (tree type
, const char *name
,
558 string_section where ATTRIBUTE_UNUSED
)
560 tree decl
= start_var_decl (type
, name
);
561 OBJCMETA (decl
, objc_meta
, meta_base
);
568 gnu_runtime_abi_01_get_class_reference (tree ident
)
572 add_class_reference (ident
);
574 params
= build_tree_list (NULL_TREE
, my_build_string_pointer
575 (IDENTIFIER_LENGTH (ident
) + 1,
576 IDENTIFIER_POINTER (ident
)));
578 return build_function_call (input_location
, objc_get_class_decl
, params
);
581 /* Used by build_function_type_for_method. Append the types for
582 receiver & _cmd at the start of a method argument list to ARGTYPES.
583 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
584 trying to define a method or call one. SUPERFLAG says this is for a
585 send to super. METH may be NULL, in the case that there is no
589 gnu_runtime_abi_01_get_arg_type_list_base (vec
<tree
, va_gc
> **argtypes
,
590 tree meth
, int context
,
591 int superflag ATTRIBUTE_UNUSED
)
595 if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
596 receiver_type
= objc_instance_type
;
598 receiver_type
= objc_object_type
;
600 vec_safe_push (*argtypes
, receiver_type
);
601 /* Selector type - will eventually change to `int'. */
602 vec_safe_push (*argtypes
, objc_selector_type
);
605 /* Unused for GNU runtime. */
607 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED
)
612 /* sel_ref_chain is a list whose "value" fields will be instances of
613 identifier_node that represent the selector. LOC is the location of
617 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc
, tree ident
,
620 tree
*chain
= &sel_ref_chain
;
626 /* When we do a lookup for @selector () we have no idea of the
627 prototype - so match the first we find. */
628 if (TREE_VALUE (*chain
) == ident
629 && (!prototype
|| TREE_PURPOSE (*chain
) == prototype
))
630 goto return_at_index
;
633 chain
= &TREE_CHAIN (*chain
);
636 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
638 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
639 (b) provide better diagnostics for the first time an undefined
642 expr
= build_unary_op (loc
, ADDR_EXPR
,
643 build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
644 build_int_cst (NULL_TREE
, index
)),
646 return convert (objc_selector_type
, expr
);
649 /* Build a tree expression to send OBJECT the operation SELECTOR,
650 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
651 assuming the method has prototype METHOD_PROTOTYPE.
652 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
653 LOC is the location of the expression to build.
654 Use METHOD_PARAMS as list of args to pass to the method.
655 If SUPER_FLAG is nonzero, we look up the superclass's method. */
658 build_objc_method_call (location_t loc
, int super_flag
, tree method_prototype
,
659 tree lookup_object
, tree selector
,
662 tree sender
= (super_flag
? umsg_super_decl
663 : (flag_objc_direct_dispatch
? umsg_fast_decl
665 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
666 vec
<tree
, va_gc
> *parms
;
667 vec
<tree
, va_gc
> *tv
;
668 unsigned nparm
= (method_params
? list_length (method_params
) : 0);
670 /* If a prototype for the method to be called exists, then cast
671 the sender's return type and arguments to match that of the method.
672 Otherwise, leave sender as is. */
675 ? TREE_VALUE (TREE_TYPE (method_prototype
))
678 = build_function_type_for_method (ret_type
, method_prototype
,
679 METHOD_REF
, super_flag
);
683 if (method_prototype
&& METHOD_TYPE_ATTRIBUTES (method_prototype
))
684 ftype
= build_type_attribute_variant (ftype
,
685 METHOD_TYPE_ATTRIBUTES
688 sender_cast
= build_pointer_type (ftype
);
690 lookup_object
= build_c_cast (loc
, rcv_p
, lookup_object
);
692 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
693 lookup_object
= save_expr (lookup_object
);
695 /* Param list + 2 slots for object and selector. */
696 vec_alloc (parms
, nparm
+ 2);
699 /* First, call the lookup function to get a pointer to the method,
700 then cast the pointer, then call it with the method arguments. */
701 tv
->quick_push (lookup_object
);
702 tv
->quick_push (selector
);
703 method
= build_function_call_vec (loc
, sender
, tv
, NULL
);
706 /* Pass the appropriate object to the method. */
707 parms
->quick_push ((super_flag
? self_decl
: lookup_object
));
709 /* Pass the selector to the method. */
710 parms
->quick_push (selector
);
711 /* Now append the remainder of the parms. */
713 for (; method_params
; method_params
= TREE_CHAIN (method_params
))
714 parms
->quick_push (TREE_VALUE (method_params
));
716 /* Build an obj_type_ref, with the correct cast for the method call. */
717 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
718 t
= build_function_call_vec (loc
, t
, parms
, NULL
);
724 gnu_runtime_abi_01_build_objc_method_call (location_t loc
,
725 tree method_prototype
,
727 tree rtype ATTRIBUTE_UNUSED
,
730 int super ATTRIBUTE_UNUSED
)
733 gnu_runtime_abi_01_build_typed_selector_reference (loc
,
737 return build_objc_method_call (loc
, super
, method_prototype
, receiver
,
738 selector
, method_params
);
742 gnu_runtime_abi_01_get_protocol_reference (location_t loc
, tree p
)
744 tree expr
, protocol_struct_type
, *chain
;
745 if (!PROTOCOL_FORWARD_DECL (p
))
746 PROTOCOL_FORWARD_DECL (p
) = gnu_runtime_abi_01_protocol_decl (p
);
748 expr
= build_unary_op (loc
, ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
750 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
751 if we have it, rather than converting it here. */
752 expr
= convert (objc_protocol_type
, expr
);
754 /* The @protocol() expression is being compiled into a pointer to a
755 statically allocated instance of the Protocol class. To become
756 usable at runtime, the 'isa' pointer of the instance need to be
757 fixed up at runtime by the runtime library, to point to the
758 actual 'Protocol' class. */
760 /* For the GNU runtime, put the static Protocol instance in the list
761 of statically allocated instances, so that we make sure that its
762 'isa' pointer is fixed up at runtime by the GNU runtime library
763 to point to the Protocol class (at runtime, when loading the
764 module, the GNU runtime library loops on the statically allocated
765 instances (as found in the defs field in objc_symtab) and fixups
766 all the 'isa' pointers of those objects). */
768 /* This type is a struct containing the fields of a Protocol
769 object. (Cfr. objc_protocol_type instead is the type of a pointer
770 to such a struct). */
771 protocol_struct_type
= xref_tag (RECORD_TYPE
,
772 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
774 /* Look for the list of Protocol statically allocated instances
775 to fixup at runtime. Create a new list to hold Protocol
776 statically allocated instances, if the list is not found. At
777 present there is only another list, holding NSConstantString
778 static instances to be fixed up at runtime. */
780 for (chain
= &objc_static_instances
;
781 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
782 chain
= &TREE_CHAIN (*chain
));
786 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
787 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
791 /* Add this statically allocated instance to the Protocol list. */
792 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
793 PROTOCOL_FORWARD_DECL (p
),
794 TREE_PURPOSE (*chain
));
798 /* For ABI 8 an IVAR is just a fixed offset in the class struct. */
801 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED
,
804 return objc_build_component_ref (base
, id
);
807 /* We build super class references as we need them (but keep them once
808 built for the sake of efficiency). */
811 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED
,
812 struct imp_entry
*imp
, bool inst_meth
)
818 objc_build_component_ref (imp
->class_decl
,
819 get_identifier ("super_class"));
820 return ucls_super_ref
;
824 if (!uucls_super_ref
)
826 objc_build_component_ref (imp
->meta_decl
,
827 get_identifier ("super_class"));
828 return uucls_super_ref
;
833 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED
,
834 struct imp_entry
*imp
, bool inst_meth
)
836 tree super_name
= CLASS_SUPER_NAME (imp
->imp_template
);
839 add_class_reference (super_name
);
840 super_class
= (inst_meth
? objc_get_class_decl
: objc_get_meta_class_decl
);
841 super_name
= my_build_string_pointer (IDENTIFIER_LENGTH (super_name
) + 1,
842 IDENTIFIER_POINTER (super_name
));
843 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
844 return build_function_call (input_location
,
846 build_tree_list (NULL_TREE
, super_name
));
850 gnu_runtime_abi_01_setup_const_string_class_decl (void)
852 /* Do nothing, and create no error. */
856 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
858 static GTY(()) int num_static_inst
;
861 objc_add_static_instance (tree constructor
, tree class_decl
)
866 /* Find the list of static instances for the CLASS_DECL. Create one if
868 for (chain
= &objc_static_instances
;
869 *chain
&& TREE_VALUE (*chain
) != class_decl
;
870 chain
= &TREE_CHAIN (*chain
));
873 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
874 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
877 snprintf (buf
, BUFSIZE
, "_OBJC_INSTANCE_%d", num_static_inst
++);
878 decl
= build_decl (input_location
,
879 VAR_DECL
, get_identifier (buf
), class_decl
);
880 TREE_STATIC (decl
) = 1;
881 DECL_ARTIFICIAL (decl
) = 1;
882 TREE_USED (decl
) = 1;
883 DECL_INITIAL (decl
) = constructor
;
884 DECL_CONTEXT (decl
) = NULL
;
885 OBJCMETA (decl
, objc_meta
, meta_base
);
887 /* We may be writing something else just now.
888 Postpone till end of input. */
889 DECL_DEFER_OUTPUT (decl
) = 1;
890 pushdecl_top_level (decl
);
891 rest_of_decl_compilation (decl
, 1, 0);
893 /* Add the DECL to the head of this CLASS' list. */
894 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
900 gnu_runtime_abi_01_build_const_string_constructor (location_t loc
, tree string
,
903 tree constructor
, fields
;
904 vec
<constructor_elt
, va_gc
> *v
= NULL
;
906 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
907 fields
= TYPE_FIELDS (internal_const_str_type
);
908 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, 0));
910 fields
= DECL_CHAIN (fields
);
911 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_unary_op (loc
,
912 ADDR_EXPR
, string
, 1));
914 fields
= DECL_CHAIN (fields
);
915 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, length
));
916 constructor
= objc_build_constructor (internal_const_str_type
, v
);
918 constructor
= objc_add_static_instance (constructor
, constant_string_type
);
922 /* --- metadata - module initializer --- */
924 /* The GNU runtime requires us to provide a static initializer function
927 static void __objc_gnu_init (void) {
928 __objc_exec_class (&L_OBJC_MODULES);
933 build_module_initializer_routine (void)
938 push_lang_context (lang_name_c
); /* extern "C" */
941 objc_push_parm (build_decl (input_location
,
942 PARM_DECL
, NULL_TREE
, void_type_node
));
944 objc_start_function (get_identifier (TAG_GNUINIT
),
945 build_function_type_list (void_type_node
, NULL_TREE
),
946 NULL_TREE
, NULL_TREE
);
948 objc_start_function (get_identifier (TAG_GNUINIT
),
949 build_function_type_list (void_type_node
, NULL_TREE
),
950 NULL_TREE
, objc_get_parm_info (0, NULL_TREE
));
952 body
= c_begin_compound_stmt (true);
953 add_stmt (build_function_call
958 build_unary_op (input_location
, ADDR_EXPR
,
959 UOBJC_MODULES_decl
, 0))));
960 add_stmt (c_end_compound_stmt (input_location
, body
, true));
962 TREE_PUBLIC (current_function_decl
) = 0;
965 /* For Objective-C++, we will need to call __objc_gnu_init
966 from objc_generate_static_init_call() below. */
967 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
970 GNU_INIT_decl
= current_function_decl
;
979 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
980 to be called by the module initializer routine. */
983 objc_static_init_needed_p (void)
985 return (GNU_INIT_decl
!= NULL_TREE
);
988 /* Generate a call to the __objc_gnu_init initializer function. */
991 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
993 add_stmt (build_stmt (input_location
, EXPR_STMT
,
994 build_function_call (input_location
,
995 GNU_INIT_decl
, NULL_TREE
)));
999 #endif /* OBJCPLUS */
1001 /* --- Output GNU Meta-data --- */
1004 generate_classref_translation_entry (tree chain
)
1006 tree expr
, decl
, type
;
1008 decl
= TREE_PURPOSE (chain
);
1009 type
= TREE_TYPE (decl
);
1011 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
1012 expr
= convert (type
, expr
); /* cast! */
1014 /* This is a class reference. It is re-written by the runtime,
1015 but will be optimized away unless we force it. */
1016 DECL_PRESERVE_P (decl
) = 1;
1017 OBJCMETA (decl
, objc_meta
, meta_base
);
1018 finish_var_decl (decl
, expr
);
1024 handle_impent (struct imp_entry
*impent
)
1028 /* objc_implementation_context = impent->imp_context;
1029 implementation_template = impent->imp_template;*/
1031 switch (TREE_CODE (impent
->imp_context
))
1033 case CLASS_IMPLEMENTATION_TYPE
:
1035 const char *const class_name
=
1036 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
1038 string
= (char *) alloca (strlen (class_name
) + 30);
1040 sprintf (string
, "__objc_class_name_%s", class_name
);
1043 case CATEGORY_IMPLEMENTATION_TYPE
:
1045 const char *const class_name
=
1046 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
1047 const char *const class_super_name
=
1048 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
1050 string
= (char *) alloca (strlen (class_name
)
1051 + strlen (class_super_name
) + 30);
1053 /* Do the same for categories. Even though no references to
1054 these symbols are generated automatically by the compiler,
1055 it gives you a handle to pull them into an archive by
1057 sprintf (string
, "*__objc_category_name_%s_%s", class_name
, class_super_name
);
1067 init
= integer_zero_node
;
1068 decl
= build_decl (input_location
,
1069 VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
1070 TREE_PUBLIC (decl
) = 1;
1071 TREE_READONLY (decl
) = 1;
1072 TREE_USED (decl
) = 1;
1073 TREE_CONSTANT (decl
) = 1;
1074 DECL_CONTEXT (decl
) = NULL_TREE
;
1075 DECL_ARTIFICIAL (decl
) = 1;
1076 TREE_STATIC (decl
) = 1;
1077 DECL_INITIAL (decl
) = error_mark_node
; /* A real initializer is coming... */
1078 /* We must force the reference. */
1079 DECL_PRESERVE_P (decl
) = 1;
1081 finish_var_decl(decl
, init
) ;
1086 build_protocol_initializer (tree type
, tree protocol_name
, tree protocol_list
,
1087 tree inst_methods
, tree class_methods
)
1091 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1093 /* TODO: pass the loc in or find it from args. */
1094 loc
= input_location
;
1095 ttyp
= build_pointer_type (xref_tag (RECORD_TYPE
,
1096 get_identifier (UTAG_CLASS
)));
1097 /* Filling the "isa" in with a version allows the runtime system to
1099 expr
= build_int_cst (ttyp
, PROTOCOL_VERSION
);
1101 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1103 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_name
);
1104 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_list
);
1106 ttyp
= objc_method_proto_list_ptr
;
1108 expr
= convert (ttyp
, build_unary_op (loc
, ADDR_EXPR
, inst_methods
, 0));
1110 expr
= convert (ttyp
, null_pointer_node
);
1111 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1114 expr
= convert (ttyp
, build_unary_op (loc
, ADDR_EXPR
, class_methods
, 0));
1116 expr
= convert (ttyp
, null_pointer_node
);
1117 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1119 return objc_build_constructor (type
, inits
);
1123 generate_protocol_list (tree i_or_p
, tree klass_ctxt
)
1125 tree array_type
, ptype
, refs_decl
, lproto
, e
, plist
;
1126 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1130 switch (TREE_CODE (i_or_p
))
1132 case CLASS_INTERFACE_TYPE
:
1133 case CATEGORY_INTERFACE_TYPE
:
1134 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
1136 case PROTOCOL_INTERFACE_TYPE
:
1137 plist
= PROTOCOL_LIST (i_or_p
);
1144 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
1145 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
1146 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
1149 /* Build initializer. */
1150 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1151 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
1152 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
1154 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
1156 tree pval
= TREE_VALUE (lproto
);
1158 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
1159 && PROTOCOL_FORWARD_DECL (pval
))
1161 tree fwref
= PROTOCOL_FORWARD_DECL (pval
);
1162 location_t loc
= DECL_SOURCE_LOCATION (fwref
) ;
1163 e
= build_unary_op (loc
, ADDR_EXPR
, fwref
, 0);
1164 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
1168 /* static struct objc_protocol *refs[n]; */
1170 switch (TREE_CODE (i_or_p
))
1172 case PROTOCOL_INTERFACE_TYPE
:
1173 snprintf (buf
, BUFSIZE
, "_OBJC_ProtocolRefs_%s",
1174 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p
)));
1176 case CLASS_INTERFACE_TYPE
:
1177 snprintf (buf
, BUFSIZE
, "_OBJC_ClassProtocols_%s",
1178 IDENTIFIER_POINTER (CLASS_NAME (i_or_p
)));
1180 case CATEGORY_INTERFACE_TYPE
:
1181 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryProtocols_%s_%s",
1182 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt
)),
1183 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt
)));
1189 ptype
= build_pointer_type (objc_protocol_template
);
1190 array_type
= build_sized_array_type (ptype
, size
+ 3);
1191 refs_decl
= start_var_decl (array_type
, buf
);
1192 OBJCMETA (refs_decl
, objc_meta
, meta_base
);
1193 finish_var_decl (refs_decl
,
1194 objc_build_constructor (TREE_TYPE (refs_decl
), v
));
1200 generate_v1_meth_descriptor_table (tree chain
, tree protocol
, const char *prefix
)
1202 tree method_list_template
, initlist
, decl
;
1204 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1207 if (!chain
|| !prefix
)
1210 if (!objc_method_prototype_template
)
1211 objc_method_prototype_template
= build_method_prototype_template ();
1213 size
= list_length (chain
);
1214 method_list_template
=
1215 build_method_prototype_list_template (objc_method_prototype_template
,
1217 snprintf (buf
, BUFSIZE
, "%s_%s", prefix
,
1218 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol
)));
1220 decl
= start_var_decl (method_list_template
, buf
);
1222 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
1224 build_descriptor_table_initializer (objc_method_prototype_template
,
1226 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, initlist
);
1227 OBJCMETA (decl
, objc_meta
, meta_base
);
1228 finish_var_decl (decl
, objc_build_constructor (method_list_template
, v
));
1232 /* For each protocol which was referenced either from a @protocol()
1233 expression, or because a class/category implements it (then a
1234 pointer to the protocol is stored in the struct describing the
1235 class/category), we create a statically allocated instance of the
1236 Protocol class. The code is written in such a way as to generate
1237 as few Protocol objects as possible; we generate a unique Protocol
1238 instance for each protocol, and we don't generate a Protocol
1239 instance if the protocol is never referenced (either from a
1240 @protocol() or from a class/category implementation). These
1241 statically allocated objects can be referred to via the static
1242 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1244 The statically allocated Protocol objects that we generate here
1245 need to be fixed up at runtime in order to be used: the 'isa'
1246 pointer of the objects need to be set up to point to the 'Protocol'
1247 class, as known at runtime.
1249 The GNU runtime fixes up all protocols before user code from the module
1250 is executed; it requires pointers to those symbols
1251 to be put in the objc_symtab (which is then passed as argument to
1252 the function __objc_exec_class() which the compiler sets up to be
1253 executed automatically when the module is loaded); setup of those
1254 Protocol objects happen in two ways in the GNU runtime: all
1255 Protocol objects referred to by a class or category implementation
1256 are fixed up when the class/category is loaded; all Protocol
1257 objects referred to by a @protocol() expression are added by the
1258 compiler to the list of statically allocated instances to fixup
1259 (the same list holding the statically allocated constant string
1260 objects). Because, as explained above, the compiler generates as
1261 few Protocol objects as possible, some Protocol object might end up
1262 being referenced multiple times when compiled with the GNU runtime,
1263 and end up being fixed up multiple times at runtime initialization.
1264 But that doesn't hurt, it's just a little inefficient. */
1267 generate_protocols (void)
1271 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
1273 /* If a protocol was directly referenced, pull in indirect references. */
1274 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
1275 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
1276 generate_protocol_references (PROTOCOL_LIST (p
));
1278 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
1280 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
1281 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
1283 /* If protocol wasn't referenced, don't generate any code. */
1284 decl
= PROTOCOL_FORWARD_DECL (p
);
1289 /* Make sure we link in the Protocol class. */
1290 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
1294 if (! METHOD_ENCODING (nst_methods
))
1296 encoding
= encode_method_prototype (nst_methods
);
1297 METHOD_ENCODING (nst_methods
) = encoding
;
1299 nst_methods
= DECL_CHAIN (nst_methods
);
1302 UOBJC_INSTANCE_METHODS_decl
=
1303 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p
), p
,
1304 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1308 if (! METHOD_ENCODING (cls_methods
))
1310 encoding
= encode_method_prototype (cls_methods
);
1311 METHOD_ENCODING (cls_methods
) = encoding
;
1314 cls_methods
= DECL_CHAIN (cls_methods
);
1317 UOBJC_CLASS_METHODS_decl
=
1318 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p
), p
,
1319 "_OBJC_PROTOCOL_CLASS_METHODS");
1320 /* generate_method_descriptors (p);*/
1322 if (PROTOCOL_LIST (p
))
1323 refs_decl
= generate_protocol_list (p
, NULL_TREE
);
1327 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1328 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
1331 refs_expr
= convert (build_pointer_type (build_pointer_type
1332 (objc_protocol_template
)),
1333 build_unary_op (input_location
,
1334 ADDR_EXPR
, refs_decl
, 0));
1336 refs_expr
= build_int_cst (NULL_TREE
, 0);
1338 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1339 by generate_method_descriptors, which is called above. */
1340 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
1341 protocol_name_expr
, refs_expr
,
1342 UOBJC_INSTANCE_METHODS_decl
,
1343 UOBJC_CLASS_METHODS_decl
);
1344 finish_var_decl (decl
, initlist
);
1349 generate_dispatch_table (tree chain
, const char *name
)
1351 tree decl
, method_list_template
, initlist
;
1352 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1353 int size
= list_length (chain
);
1355 if (!objc_method_template
)
1356 objc_method_template
= build_method_template ();
1358 method_list_template
= build_method_list_template (objc_method_template
,
1360 initlist
= build_dispatch_table_initializer (objc_method_template
, chain
);
1362 decl
= start_var_decl (method_list_template
, name
);
1364 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1365 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1366 build_int_cst (integer_type_node
, size
));
1367 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, initlist
);
1369 OBJCMETA (decl
, objc_meta
, meta_base
);
1370 finish_var_decl (decl
,
1371 objc_build_constructor (TREE_TYPE (decl
), v
));
1376 /* Init a category. */
1378 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
1379 tree inst_methods
, tree class_methods
,
1384 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1386 /* TODO: pass the loc in or find it from args. */
1387 /* TODO: pass the loc in or find it from args. */
1388 loc
= UNKNOWN_LOCATION
;
1389 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, cat_name
);
1390 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, class_name
);
1392 ltyp
= objc_method_list_ptr
;
1394 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, inst_methods
, 0));
1396 expr
= convert (ltyp
, null_pointer_node
);
1397 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1400 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, class_methods
, 0));
1402 expr
= convert (ltyp
, null_pointer_node
);
1403 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1405 /* protocol_list = */
1406 ltyp
= build_pointer_type (build_pointer_type (objc_protocol_template
));
1408 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, protocol_list
, 0));
1410 expr
= convert (ltyp
, null_pointer_node
);
1411 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1413 return objc_build_constructor (type
, v
);
1416 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1419 generate_category (struct imp_entry
*impent
)
1421 tree initlist
, cat_name_expr
, class_name_expr
;
1422 tree protocol_decl
, category
, cat_decl
;
1423 tree inst_methods
= NULL_TREE
, class_methods
= NULL_TREE
;
1424 tree cat
= impent
->imp_context
;
1427 cat_decl
= impent
->class_decl
;
1429 add_class_reference (CLASS_NAME (cat
));
1430 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
1432 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
1434 category
= lookup_category (impent
->imp_template
, CLASS_SUPER_NAME (cat
));
1436 if (category
&& CLASS_PROTOCOL_LIST (category
))
1438 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
1439 protocol_decl
= generate_protocol_list (category
, cat
);
1444 if (CLASS_NST_METHODS (cat
))
1446 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryInstanceMethods_%s_%s",
1447 IDENTIFIER_POINTER (CLASS_NAME (cat
)),
1448 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat
)));
1449 inst_methods
= generate_dispatch_table (CLASS_NST_METHODS (cat
), buf
);
1452 if (CLASS_CLS_METHODS (cat
))
1454 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryClassMethods_%s_%s",
1455 IDENTIFIER_POINTER (CLASS_NAME (cat
)),
1456 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat
)));
1457 class_methods
= generate_dispatch_table (CLASS_CLS_METHODS (cat
), buf
);
1460 initlist
= build_category_initializer (TREE_TYPE (cat_decl
),
1461 cat_name_expr
, class_name_expr
,
1462 inst_methods
, class_methods
,
1464 /* Finish and initialize the forward decl. */
1465 finish_var_decl (cat_decl
, initlist
);
1466 impent
->class_decl
= cat_decl
;
1469 /* struct _objc_class {
1470 struct objc_class *isa;
1471 struct objc_class *super_class;
1476 struct objc_ivar_list *ivars;
1477 struct objc_method_list *methods;
1478 struct sarray *dtable;
1479 struct objc_class *subclass_list;
1480 struct objc_class *sibling_class;
1481 struct objc_protocol_list *protocols;
1482 void *gc_object_type;
1486 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
1487 tree name
, tree size
, int status
,
1488 tree dispatch_table
, tree ivar_list
,
1492 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1495 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, isa
);
1498 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, super
);
1501 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, default_conversion (name
));
1504 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1505 build_int_cst (long_integer_type_node
, 0));
1508 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1509 build_int_cst (long_integer_type_node
, status
));
1511 /* instance_size = */
1512 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1513 convert (long_integer_type_node
, size
));
1515 /* objc_ivar_list = */
1517 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1518 build_int_cst (objc_ivar_list_ptr
, 0));
1521 expr
= convert (objc_ivar_list_ptr
,
1522 build_unary_op (input_location
, ADDR_EXPR
,
1524 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1527 /* objc_method_list = */
1528 if (!dispatch_table
)
1529 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1530 convert (objc_method_list_ptr
, null_pointer_node
));
1533 expr
= convert (objc_method_list_ptr
,
1534 build_unary_op (input_location
, ADDR_EXPR
,
1535 dispatch_table
, 0));
1536 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1539 /* FIXME: Remove NeXT runtime code. */
1540 if (flag_next_runtime
)
1542 ltyp
= build_pointer_type (xref_tag (RECORD_TYPE
,
1543 get_identifier ("objc_cache")));
1544 /* method_cache = */
1545 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, convert (ltyp
, null_pointer_node
));
1550 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1552 /* subclass_list = */
1553 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1555 /* sibling_class = */
1556 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1559 /* protocol_list = */
1560 ltyp
= build_pointer_type (build_pointer_type (objc_protocol_template
));
1561 if (! protocol_list
)
1562 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (ltyp
, 0));
1565 expr
= convert (ltyp
,
1566 build_unary_op (input_location
, ADDR_EXPR
,
1568 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1571 /* FIXME: Remove NeXT runtime code. */
1572 if (flag_next_runtime
)
1574 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1576 /* gc_object_type = NULL */
1577 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1579 return objc_build_constructor (type
, v
);
1584 generate_ivars_list (tree chain
, const char *name
)
1586 tree initlist
, ivar_list_template
, decl
;
1588 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1593 if (!objc_ivar_template
)
1594 objc_ivar_template
= build_ivar_template ();
1596 size
= ivar_list_length (chain
);
1598 generating_instance_variables
= 1;
1599 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
1600 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
1601 generating_instance_variables
= 0;
1603 decl
= start_var_decl (ivar_list_template
, name
);
1605 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
1606 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, initlist
);
1608 OBJCMETA (decl
, objc_meta
, meta_base
);
1609 finish_var_decl (decl
,
1610 objc_build_constructor (TREE_TYPE (decl
), inits
));
1615 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1616 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1619 generate_class_structures (struct imp_entry
*impent
)
1621 tree name_expr
, super_expr
, root_expr
, class_decl
, meta_decl
;
1622 tree my_root_id
, my_super_id
;
1623 tree cast_type
, initlist
, protocol_decl
;
1624 tree inst_methods
= NULL_TREE
, class_methods
= NULL_TREE
;
1625 tree chain
, inst_ivars
= NULL_TREE
, class_ivars
= NULL_TREE
;
1630 /* objc_implementation_context = impent->imp_context;
1631 implementation_template = impent->imp_template;*/
1632 class_decl
= impent
->class_decl
;
1633 meta_decl
= impent
->meta_decl
;
1634 /* UOBJC_CLASS_decl = impent->class_decl;
1635 UOBJC_METACLASS_decl = impent->meta_decl;*/
1637 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1639 my_super_id
= CLASS_SUPER_NAME (impent
->imp_template
);
1642 add_class_reference (my_super_id
);
1644 /* Compute "my_root_id" - this is required for code generation.
1645 the "isa" for all meta class structures points to the root of
1646 the inheritance hierarchy (e.g. "__Object")... */
1647 my_root_id
= my_super_id
;
1650 tree my_root_int
= lookup_interface (my_root_id
);
1652 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
1653 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
1660 /* No super class. */
1661 my_root_id
= CLASS_NAME (impent
->imp_template
);
1663 cast_type
= build_pointer_type (objc_class_template
);
1664 name_expr
= add_objc_string (CLASS_NAME (impent
->imp_template
),
1667 /* Install class `isa' and `super' pointers at runtime. */
1669 super_expr
= add_objc_string (my_super_id
, class_names
);
1671 super_expr
= null_pointer_node
;
1673 super_expr
= build_c_cast (loc
, cast_type
, super_expr
);
1675 root_expr
= add_objc_string (my_root_id
, class_names
);
1676 root_expr
= build_c_cast (loc
, cast_type
, root_expr
);
1678 if (CLASS_PROTOCOL_LIST (impent
->imp_template
))
1680 generate_protocol_references (CLASS_PROTOCOL_LIST (impent
->imp_template
));
1681 protocol_decl
= generate_protocol_list (impent
->imp_template
,
1682 impent
->imp_context
);
1685 protocol_decl
= NULL_TREE
;
1687 if (CLASS_CLS_METHODS (impent
->imp_context
))
1689 snprintf (buf
, BUFSIZE
, "_OBJC_ClassMethods_%s",
1690 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1691 class_methods
= generate_dispatch_table (CLASS_CLS_METHODS (impent
->imp_context
),
1695 if (CLASS_SUPER_NAME (impent
->imp_template
) == NULL_TREE
1696 && (chain
= TYPE_FIELDS (objc_class_template
)))
1698 snprintf (buf
, BUFSIZE
, "_OBJC_ClassIvars_%s",
1699 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1700 class_ivars
= generate_ivars_list (chain
, buf
);
1703 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1706 build_shared_structure_initializer
1707 (TREE_TYPE (meta_decl
),
1708 root_expr
, super_expr
, name_expr
,
1709 convert (integer_type_node
,
1710 TYPE_SIZE_UNIT (objc_class_template
)),
1711 CLS_META
, class_methods
, class_ivars
,
1714 finish_var_decl (meta_decl
, initlist
);
1715 impent
->meta_decl
= meta_decl
;
1717 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1718 if (CLASS_NST_METHODS (impent
->imp_context
))
1720 snprintf (buf
, BUFSIZE
, "_OBJC_InstanceMethods_%s",
1721 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1722 inst_methods
= generate_dispatch_table (CLASS_NST_METHODS (impent
->imp_context
),
1726 if ((chain
= CLASS_IVARS (impent
->imp_template
)))
1728 snprintf (buf
, BUFSIZE
, "_OBJC_InstanceIvars_%s",
1729 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1730 inst_ivars
= generate_ivars_list (chain
, buf
);
1734 build_shared_structure_initializer
1735 (TREE_TYPE (class_decl
),
1736 build_unary_op (loc
, ADDR_EXPR
, meta_decl
, 0),
1737 super_expr
, name_expr
,
1738 convert (integer_type_node
,
1739 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1740 (impent
->imp_template
))),
1741 CLS_FACTORY
| cls_flags
, inst_methods
, inst_ivars
,
1744 finish_var_decl (class_decl
, initlist
);
1745 impent
->class_decl
= class_decl
;
1748 /* --- Output GNU Metadata --- */
1750 /* TODO: Make this into an array of refs. */
1752 handle_class_ref (tree chain
)
1754 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
1755 char *string
= (char *) alloca (strlen (name
) + 30);
1759 sprintf (string
, "__objc_class_name_%s", name
);
1761 /* Make a decl for this name, so we can use its address in a tree. */
1762 decl
= build_decl (input_location
,
1763 VAR_DECL
, get_identifier (string
), TREE_TYPE (integer_zero_node
));
1764 DECL_EXTERNAL (decl
) = 1;
1765 TREE_PUBLIC (decl
) = 1;
1766 DECL_CONTEXT (decl
) = NULL_TREE
;
1767 finish_var_decl (decl
, 0);
1769 /* Make a decl for the address. */
1770 sprintf (string
, "__objc_class_ref_%s", name
);
1771 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
1772 decl
= build_decl (input_location
,
1773 VAR_DECL
, get_identifier (string
), string_type_node
);
1774 TREE_STATIC (decl
) = 1;
1775 TREE_USED (decl
) = 1;
1776 DECL_READ_P (decl
) = 1;
1777 DECL_ARTIFICIAL (decl
) = 1;
1778 DECL_INITIAL (decl
) = error_mark_node
;
1780 /* We must force the reference. */
1781 DECL_PRESERVE_P (decl
) = 1;
1783 DECL_CONTEXT (decl
) = NULL_TREE
;
1784 finish_var_decl (decl
, exp
);
1788 get_proto_encoding (tree proto
)
1793 if (! METHOD_ENCODING (proto
))
1795 encoding
= encode_method_prototype (proto
);
1796 METHOD_ENCODING (proto
) = encoding
;
1799 encoding
= METHOD_ENCODING (proto
);
1801 return add_objc_string (encoding
, meth_var_types
);
1804 return build_int_cst (NULL_TREE
, 0);
1808 build_gnu_selector_translation_table (void)
1811 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1812 vec
<constructor_elt
, va_gc
> *v
;
1814 /* Cause the selector table (previously forward-declared)
1815 to be actually output. */
1817 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1822 /* TODO: improve on the location for the diagnostic. */
1823 location_t loc
= input_location
;
1824 diagnose_missing_method (TREE_VALUE (chain
), loc
);
1828 expr
= build_selector (TREE_VALUE (chain
));
1829 encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1830 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1831 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, encoding
);
1832 expr
= objc_build_constructor (objc_selector_template
, v
);
1834 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1835 } /* each element in the chain */
1837 /* List terminator. */
1839 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1840 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1841 expr
= objc_build_constructor (objc_selector_template
, v
);
1843 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1844 expr
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
1846 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, expr
);
1849 /* Output references to all statically allocated objects. Return the DECL
1850 for the array built. */
1853 generate_static_references (void)
1855 tree expr
= NULL_TREE
;
1856 tree class_name
, klass
, decl
;
1857 tree cl_chain
, in_chain
, type
1858 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
1859 int num_inst
, num_class
;
1861 vec
<constructor_elt
, va_gc
> *decls
= NULL
;
1863 /* FIXME: Remove NeXT runtime code. */
1864 if (flag_next_runtime
)
1867 for (cl_chain
= objc_static_instances
, num_class
= 0;
1868 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1870 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1872 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1873 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1875 snprintf (buf
, BUFSIZE
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1876 decl
= start_var_decl (type
, buf
);
1878 /* Output {class_name, ...}. */
1879 klass
= TREE_VALUE (cl_chain
);
1880 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (klass
), class_names
);
1881 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1882 build_unary_op (input_location
,
1883 ADDR_EXPR
, class_name
, 1));
1885 /* Output {..., instance, ...}. */
1886 for (in_chain
= TREE_PURPOSE (cl_chain
);
1887 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1889 expr
= build_unary_op (input_location
,
1890 ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1891 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1894 /* Output {..., NULL}. */
1895 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1897 expr
= objc_build_constructor (TREE_TYPE (decl
), v
);
1898 OBJCMETA (decl
, objc_meta
, meta_base
);
1899 finish_var_decl (decl
, expr
);
1900 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
,
1901 build_unary_op (input_location
,
1902 ADDR_EXPR
, decl
, 1));
1905 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1906 expr
= objc_build_constructor (type
, decls
);
1907 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
1908 OBJCMETA (static_instances_decl
, objc_meta
, meta_base
);
1909 finish_var_decl (static_instances_decl
, expr
);
1912 /* Create the initial value for the `defs' field of _objc_symtab.
1913 This is a CONSTRUCTOR. */
1916 init_def_list (tree type
)
1919 struct imp_entry
*impent
;
1921 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1924 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1926 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1928 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1929 expr
= build_unary_op (loc
,
1930 ADDR_EXPR
, impent
->class_decl
, 0);
1931 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1936 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1938 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1940 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1941 expr
= build_unary_op (loc
,
1942 ADDR_EXPR
, impent
->class_decl
, 0);
1943 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1947 loc
= UNKNOWN_LOCATION
;
1948 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1949 if (static_instances_decl
)
1950 expr
= build_unary_op (loc
, ADDR_EXPR
, static_instances_decl
, 0);
1952 expr
= integer_zero_node
;
1953 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1955 return objc_build_constructor (type
, v
);
1958 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1960 /* Predefine the following data type:
1968 void *defs[cls_def_cnt + cat_def_cnt];
1972 build_objc_symtab_template (void)
1974 tree fields
, array_type
, *chain
= NULL
;
1977 objc_symtab_template
= objc_start_struct (get_identifier (UTAG_SYMTAB
));
1979 /* long sel_ref_cnt; */
1980 fields
= add_field_decl (long_integer_type_node
, "sel_ref_cnt", &chain
);
1983 add_field_decl (build_pointer_type (objc_selector_type
), "refs", &chain
);
1985 /* short cls_def_cnt; */
1986 add_field_decl (short_integer_type_node
, "cls_def_cnt", &chain
);
1988 /* short cat_def_cnt; */
1989 add_field_decl (short_integer_type_node
, "cat_def_cnt", &chain
);
1991 /* Note that padding will be added here on LP64. */
1993 /* void *defs[imp_count + cat_count (+ 1)]; */
1994 /* NB: The index is one less than the size of the array. */
1995 index
= imp_count
+ cat_count
;
1996 array_type
= build_sized_array_type (ptr_type_node
, index
+ 1);
1997 add_field_decl (array_type
, "defs", &chain
);
1999 objc_finish_struct (objc_symtab_template
, fields
);
2001 /* Construct the initial value for all of _objc_symtab. */
2004 init_objc_symtab (tree type
)
2006 tree field
, expr
, ltyp
;
2008 vec
<constructor_elt
, va_gc
> *v
= NULL
;
2010 loc
= UNKNOWN_LOCATION
;
2012 /* sel_ref_cnt = { ..., 5, ... } */
2014 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2015 build_int_cst (long_integer_type_node
, 0));
2017 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2019 ltyp
= build_pointer_type (objc_selector_type
);
2021 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
,
2022 UOBJC_SELECTOR_TABLE_decl
, 1));
2024 expr
= convert (ltyp
, null_pointer_node
);
2025 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2027 /* cls_def_cnt = { ..., 5, ... } */
2029 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2030 build_int_cst (short_integer_type_node
, imp_count
));
2032 /* cat_def_cnt = { ..., 5, ... } */
2034 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2035 build_int_cst (short_integer_type_node
, cat_count
));
2037 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2039 field
= TYPE_FIELDS (type
);
2040 field
= DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field
))));
2042 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, init_def_list (TREE_TYPE (field
)));
2044 return objc_build_constructor (type
, v
);
2047 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2048 and initialized appropriately. */
2051 generate_objc_symtab_decl (void)
2053 build_objc_symtab_template ();
2054 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2055 OBJCMETA (UOBJC_SYMBOLS_decl
, objc_meta
, meta_base
);
2056 finish_var_decl (UOBJC_SYMBOLS_decl
,
2057 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2061 objc_generate_v1_gnu_metadata (void)
2063 struct imp_entry
*impent
;
2066 /* Process the static instances here because initialization of objc_symtab
2068 if (objc_static_instances
)
2069 generate_static_references ();
2071 objc_implementation_context
=
2072 implementation_template
=
2074 UOBJC_METACLASS_decl
= NULL_TREE
;
2076 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2078 /* If -gen-decls is present, Dump the @interface of each class.
2079 TODO: Dump the classes in the order they were found, rather than in
2080 reverse order as we are doing now. */
2081 if (flag_gen_declaration
)
2082 dump_interface (gen_declaration_file
, impent
->imp_context
);
2084 /* all of the following reference the string pool... */
2085 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2086 generate_class_structures (impent
);
2088 generate_category (impent
);
2091 /* If we are using an array of selectors, we must always
2092 finish up the array decl even if no selectors were used. */
2093 build_gnu_selector_translation_table ();
2096 generate_protocols ();
2098 /* Arrange for ObjC data structures to be initialized at run time. */
2099 /* FIXME: Have some more elegant way to determine if we need to
2100 generate objc_symtab_decl or not, instead of checking these
2102 if (imp_list
|| class_names_chain
2103 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
2104 || prop_names_attr_chain
)
2105 generate_objc_symtab_decl ();
2107 if (imp_list
|| class_names_chain
|| objc_static_instances
2108 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
2110 /* Make sure that the meta-data are identified as being
2112 build_module_descriptor (OBJC_VERSION
,
2113 build_tree_list (objc_meta
, meta_base
));
2114 build_module_initializer_routine ();
2117 /* Dump the class references. This forces the appropriate classes
2118 to be linked into the executable image, preserving unix archive
2119 semantics. This can be removed when we move to a more dynamically
2120 linked environment. */
2122 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2124 handle_class_ref (chain
);
2125 if (TREE_PURPOSE (chain
))
2126 generate_classref_translation_entry (chain
);
2129 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2130 handle_impent (impent
);
2132 generate_strings ();
2135 /* --- exceptions --- */
2137 static GTY(()) tree objc_eh_personality_decl
;
2140 objc_eh_runtime_type (tree type
)
2142 tree ident
, eh_id
, decl
, str
;
2144 if (type
== error_mark_node
2145 || errorcount
|| sorrycount
)
2147 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2148 to prevent an ICE. Note that we know that the compiler will
2149 terminate with an error and this 'ErrorMarkNode' class name will
2150 never be actually used. */
2151 ident
= get_identifier ("ErrorMarkNode");
2152 goto make_err_class
;
2155 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
2156 /* We don't want to identify 'id' for GNU. Instead, build a 0
2157 entry in the exceptions table. */
2158 return null_pointer_node
;
2160 if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
2163 /* This routine is also called for c++ catch clauses; in which case,
2164 we use the c++ typeinfo decl. */
2165 return build_eh_type_type (type
);
2167 error ("non-objective-c type '%T' cannot be caught", type
);
2168 ident
= get_identifier ("ErrorMarkNode");
2169 goto make_err_class
;
2173 ident
= OBJC_TYPE_NAME (TREE_TYPE (type
));
2176 /* If this class was already referenced, then it will be output during
2177 meta-data emission, so we don't need to do it here. */
2178 decl
= get_objc_string_decl (ident
, class_names
);
2179 eh_id
= add_objc_string (ident
, class_names
);
2182 /* Not found ... so we need to build it - from the freshly-entered id. */
2183 decl
= get_objc_string_decl (ident
, class_names
);
2184 str
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2185 IDENTIFIER_POINTER (ident
));
2186 /* We have to finalize this var here, because this might be called after
2187 all the other metadata strings have been emitted. */
2188 finish_var_decl (decl
, str
);
2194 objc_eh_personality (void)
2196 if (!objc_eh_personality_decl
)
2198 objc_eh_personality_decl
= build_personality_function ("gnu_objc");
2200 objc_eh_personality_decl
= build_personality_function ("gxx");
2202 return objc_eh_personality_decl
;
2205 /* -- interfaces --- */
2208 build_throw_stmt (location_t loc
, tree throw_expr
, bool rethrown ATTRIBUTE_UNUSED
)
2211 vec
<tree
, va_gc
> *parms
;
2212 vec_alloc (parms
, 1);
2213 /* A throw is just a call to the runtime throw function with the
2214 object as a parameter. */
2215 parms
->quick_push (throw_expr
);
2216 t
= build_function_call_vec (loc
, objc_exception_throw_decl
, parms
, NULL
);
2218 return add_stmt (t
);
2221 /* Build __builtin_eh_pointer. */
2224 objc_build_exc_ptr (struct objc_try_context
**x ATTRIBUTE_UNUSED
)
2227 t
= builtin_decl_explicit (BUILT_IN_EH_POINTER
);
2228 t
= build_call_expr (t
, 1, integer_zero_node
);
2229 return fold_convert (objc_object_type
, t
);
2233 begin_catch (struct objc_try_context
**cur_try_context
, tree type
,
2234 tree decl
, tree compound
, bool ellipsis ATTRIBUTE_UNUSED
)
2237 /* Record the data for the catch in the try context so that we can
2238 finalize it later. */
2240 t
= build_stmt (input_location
, CATCH_EXPR
, NULL
, compound
);
2242 t
= build_stmt (input_location
, CATCH_EXPR
, type
, compound
);
2243 (*cur_try_context
)->current_catch
= t
;
2245 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2246 t
= objc_build_exc_ptr (cur_try_context
);
2247 t
= convert (TREE_TYPE (decl
), t
);
2248 return build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
2252 finish_catch (struct objc_try_context
**cur_try_context
, tree current_catch
)
2254 append_to_statement_list (current_catch
, &((*cur_try_context
)->catch_list
));
2258 finish_try_stmt (struct objc_try_context
**cur_try_context
)
2260 struct objc_try_context
*c
= *cur_try_context
;
2261 tree stmt
= c
->try_body
;
2263 stmt
= build_stmt (c
->try_locus
, TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
2264 if (c
->finally_body
)
2265 stmt
= build_stmt (c
->try_locus
, TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
2269 #include "gt-objc-objc-gnu-runtime-abi-01.h"