1 /* GNU Runtime ABI version 8
2 Copyright (C) 2011-2015 Free Software Foundation, Inc.
3 Contributed by Iain Sandoe (split from objc-act.c)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "fold-const.h"
29 #include "stringpool.h"
32 #include "cp/cp-tree.h"
38 #include "langhooks.h"
39 #include "c-family/c-objc.h"
42 /* When building Objective-C++, we are not linking against the C front-end
43 and so need to replicate the C tree-construction functions in some way. */
45 #define OBJCP_REMAP_FUNCTIONS
46 #include "objcp-decl.h"
50 #include "tree-iterator.h"
52 #include "objc-runtime-hooks.h"
53 #include "objc-runtime-shared-support.h"
54 #include "objc-encoding.h"
56 /* GNU runtime private definitions. */
57 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
59 #define TAG_GETCLASS "objc_get_class"
60 #define TAG_GETMETACLASS "objc_get_meta_class"
62 #define TAG_MSGSEND "objc_msg_lookup"
63 #define TAG_MSGSENDSUPER "objc_msg_lookup_super"
65 /* GNU-specific tags. */
67 #define TAG_EXECCLASS "__objc_exec_class"
68 #define TAG_GNUINIT "__objc_gnu_init"
70 /* The version identifies which language generation and runtime
71 the module (file) was compiled for, and is recorded in the
73 #define OBJC_VERSION 8
75 #define PROTOCOL_VERSION 2
77 /* This macro provides a method of removing ambiguity between runtimes
78 when LTO is in use on targets supporting multiple runtimes.
80 For example, at present, any target that includes an implementation of
81 the NeXT runtime needs to place Objective-C meta-data into specific
82 named sections. This should _not_ be done for the GNU runtime, and the
83 following macro is used to attach Objective-C private attributes that may
84 be used to identify the runtime for which the meta-data are intended. */
86 #define OBJCMETA(DECL,VERS,KIND) \
88 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
90 static void gnu_runtime_01_initialize (void);
92 static void build_selector_template (void);
94 static tree
gnu_runtime_abi_01_super_superclassfield_id (void);
96 static tree
gnu_runtime_abi_01_class_decl (tree
);
97 static tree
gnu_runtime_abi_01_metaclass_decl (tree
);
98 static tree
gnu_runtime_abi_01_category_decl (tree
);
99 static tree
gnu_runtime_abi_01_protocol_decl (tree
);
100 static tree
gnu_runtime_abi_01_string_decl (tree
, const char *, string_section
);
102 static tree
gnu_runtime_abi_01_get_class_reference (tree
);
103 static tree
gnu_runtime_abi_01_build_typed_selector_reference (location_t
, tree
,
105 static tree
gnu_runtime_abi_01_get_protocol_reference (location_t
, tree
);
106 static tree
gnu_runtime_abi_01_build_ivar_ref (location_t
, tree
, tree
);
107 static tree
gnu_runtime_abi_01_get_class_super_ref (location_t
, struct imp_entry
*, bool);
108 static tree
gnu_runtime_abi_01_get_category_super_ref (location_t
, struct imp_entry
*, bool);
110 static tree
gnu_runtime_abi_01_receiver_is_class_object (tree
);
111 static void gnu_runtime_abi_01_get_arg_type_list_base (vec
<tree
, va_gc
> **,
113 static tree
gnu_runtime_abi_01_build_objc_method_call (location_t
, tree
, tree
,
114 tree
, tree
, tree
, int);
116 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
117 static tree
gnu_runtime_abi_01_build_const_string_constructor (location_t
, tree
,int);
119 static void objc_generate_v1_gnu_metadata (void);
121 static tree
objc_eh_runtime_type (tree type
);
122 static tree
objc_eh_personality (void);
123 static tree
objc_build_exc_ptr (struct objc_try_context
**);
124 static tree
build_throw_stmt (location_t
, tree
, bool);
125 static tree
begin_catch (struct objc_try_context
**, tree
, tree
, tree
, bool);
126 static void finish_catch (struct objc_try_context
**, tree
);
127 static tree
finish_try_stmt (struct objc_try_context
**);
130 objc_gnu_runtime_abi_01_init (objc_runtime_hooks
*rthooks
)
132 /* GNU runtime does not need the compiler to change code in order to do GC. */
135 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
139 /* Although I guess we could, we don't currently support SJLJ exceptions for the
141 if (flag_objc_sjlj_exceptions
)
143 inform (UNKNOWN_LOCATION
, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
144 flag_objc_sjlj_exceptions
= 0;
147 /* TODO: Complain if -fobjc-abi-version=N was used. */
149 /* TODO: Complain if -fobj-nilcheck was used. */
151 rthooks
->initialize
= gnu_runtime_01_initialize
;
152 rthooks
->default_constant_string_class_name
= DEF_CONSTANT_STRING_CLASS_NAME
;
153 rthooks
->tag_getclass
= TAG_GETCLASS
;
154 rthooks
->super_superclassfield_ident
= gnu_runtime_abi_01_super_superclassfield_id
;
156 rthooks
->class_decl
= gnu_runtime_abi_01_class_decl
;
157 rthooks
->metaclass_decl
= gnu_runtime_abi_01_metaclass_decl
;
158 rthooks
->category_decl
= gnu_runtime_abi_01_category_decl
;
159 rthooks
->protocol_decl
= gnu_runtime_abi_01_protocol_decl
;
160 rthooks
->string_decl
= gnu_runtime_abi_01_string_decl
;
162 rthooks
->get_class_reference
= gnu_runtime_abi_01_get_class_reference
;
163 rthooks
->build_selector_reference
= gnu_runtime_abi_01_build_typed_selector_reference
;
164 rthooks
->get_protocol_reference
= gnu_runtime_abi_01_get_protocol_reference
;
165 rthooks
->build_ivar_reference
= gnu_runtime_abi_01_build_ivar_ref
;
166 rthooks
->get_class_super_ref
= gnu_runtime_abi_01_get_class_super_ref
;
167 rthooks
->get_category_super_ref
= gnu_runtime_abi_01_get_category_super_ref
;
169 rthooks
->receiver_is_class_object
= gnu_runtime_abi_01_receiver_is_class_object
;
170 rthooks
->get_arg_type_list_base
= gnu_runtime_abi_01_get_arg_type_list_base
;
171 rthooks
->build_objc_method_call
= gnu_runtime_abi_01_build_objc_method_call
;
173 rthooks
->setup_const_string_class_decl
=
174 gnu_runtime_abi_01_setup_const_string_class_decl
;
175 rthooks
->build_const_string_constructor
=
176 gnu_runtime_abi_01_build_const_string_constructor
;
178 rthooks
->build_throw_stmt
= build_throw_stmt
;
179 rthooks
->build_exc_ptr
= objc_build_exc_ptr
;
180 rthooks
->begin_catch
= begin_catch
;
181 rthooks
->finish_catch
= finish_catch
;
182 rthooks
->finish_try_stmt
= finish_try_stmt
;
184 rthooks
->generate_metadata
= objc_generate_v1_gnu_metadata
;
188 static void build_selector_table_decl (void);
189 static void build_class_template (void);
190 static void build_category_template (void);
191 static void build_protocol_template (void);
193 static GTY(()) tree objc_meta
;
194 static GTY(()) tree meta_base
;
196 static void gnu_runtime_01_initialize (void)
198 tree type
, ftype
, IMP_type
;
200 /* We do not need to mark GNU ObjC metadata for different sections,
201 however, we do need to make sure that it is not mistaken for NeXT
203 objc_meta
= get_identifier ("OBJC1METG");
204 meta_base
= get_identifier ("NONE");
206 /* Declare type of selector-objects that represent an operation name. */
207 /* `const struct objc_selector *' */
208 type
= xref_tag (RECORD_TYPE
, get_identifier (TAG_SELECTOR
));
209 type
= build_qualified_type (type
, TYPE_QUAL_CONST
);
210 objc_selector_type
= build_pointer_type (type
);
212 /* typedef id (*IMP)(id, SEL, ...); */
213 ftype
= build_varargs_function_type_list (objc_object_type
,
218 IMP_type
= build_pointer_type (ftype
);
220 build_class_template ();
221 build_super_template ();
222 build_protocol_template ();
223 build_category_template ();
225 /* GNU runtime messenger entry points. */
226 /* TREE_NOTHROW is cleared for the message-sending functions,
227 because the function that gets called can throw in Obj-C++, or
228 could itself call something that can throw even in Obj-C. */
230 /* IMP objc_msg_lookup (id, SEL); */
231 type
= build_function_type_list (IMP_type
,
236 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
237 type
, 0, NOT_BUILT_IN
,
239 TREE_NOTHROW (umsg_decl
) = 0;
241 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
242 type
= build_function_type_list (IMP_type
,
247 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
248 type
, 0, NOT_BUILT_IN
,
250 TREE_NOTHROW (umsg_super_decl
) = 0;
252 /* The following GNU runtime entry point is called to initialize
255 __objc_exec_class (void *); */
256 type
= build_function_type_list (void_type_node
,
260 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
261 type
, 0, NOT_BUILT_IN
,
264 type
= build_function_type_list (objc_object_type
,
265 const_string_type_node
,
268 /* id objc_getClass (const char *); */
270 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
273 /* id objc_getMetaClass (const char *); */
274 objc_get_meta_class_decl
= add_builtin_function (TAG_GETMETACLASS
, type
,
275 0, NOT_BUILT_IN
, NULL
,
278 /* static SEL _OBJC_SELECTOR_TABLE[]; */
279 build_selector_table_decl ();
281 /* Stuff for properties.
282 The codegen relies on this being NULL for GNU. */
283 objc_copyStruct_decl
= NULL_TREE
;
285 /* This is the type of all of the following functions
286 bjc_getPropertyStruct() and objc_setPropertyStruct(). */
287 type
= build_function_type_list (void_type_node
,
295 /* Declare the following function:
297 objc_getPropertyStruct (void *destination, const void *source,
298 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
299 objc_getPropertyStruct_decl
= add_builtin_function ("objc_getPropertyStruct",
300 type
, 0, NOT_BUILT_IN
,
302 TREE_NOTHROW (objc_getPropertyStruct_decl
) = 0;
303 /* Declare the following function:
305 objc_setPropertyStruct (void *destination, const void *source,
306 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
307 objc_setPropertyStruct_decl
= add_builtin_function ("objc_setPropertyStruct",
308 type
, 0, NOT_BUILT_IN
,
310 TREE_NOTHROW (objc_setPropertyStruct_decl
) = 0;
312 using_eh_for_cleanups ();
313 lang_hooks
.eh_runtime_type
= objc_eh_runtime_type
;
314 lang_hooks
.eh_personality
= objc_eh_personality
;
317 /* --- templates --- */
318 /* struct _objc_selector {
324 build_selector_template (void)
326 tree decls
, *chain
= NULL
;
328 objc_selector_template
= objc_start_struct (get_identifier (UTAG_SELECTOR
));
331 decls
= add_field_decl (objc_selector_type
, "sel_id", &chain
);
333 /* char *sel_type; */
334 add_field_decl (string_type_node
, "sel_type", &chain
);
336 objc_finish_struct (objc_selector_template
, decls
);
339 /* struct _objc_class {
340 struct _objc_class *isa;
341 struct _objc_class *super_class;
346 struct _objc_ivar_list *ivars;
347 struct _objc_method_list *methods;
348 struct sarray *dtable;
349 struct _objc_class *subclass_list;
350 struct _objc_class *sibling_class;
351 struct _objc_protocol_list *protocols;
352 void *gc_object_type;
356 build_class_template (void)
358 tree ptype
, decls
, *chain
= NULL
;
360 objc_class_template
= objc_start_struct (get_identifier (UTAG_CLASS
));
362 /* struct _objc_class *isa; */
363 decls
= add_field_decl (build_pointer_type (objc_class_template
),
366 /* struct _objc_class *super_class; */
367 add_field_decl (build_pointer_type (objc_class_template
),
368 "super_class", &chain
);
371 add_field_decl (string_type_node
, "name", &chain
);
374 add_field_decl (long_integer_type_node
, "version", &chain
);
377 add_field_decl (long_integer_type_node
, "info", &chain
);
379 /* long instance_size; */
380 add_field_decl (long_integer_type_node
, "instance_size", &chain
);
382 /* struct _objc_ivar_list *ivars; */
383 add_field_decl (objc_ivar_list_ptr
,"ivars", &chain
);
385 /* struct _objc_method_list *methods; */
386 add_field_decl (objc_method_list_ptr
, "methods", &chain
);
388 /* struct sarray *dtable; */
389 ptype
= build_pointer_type(xref_tag (RECORD_TYPE
,
390 get_identifier ("sarray")));
391 add_field_decl (ptype
, "dtable", &chain
);
393 /* struct objc_class *subclass_list; */
394 ptype
= build_pointer_type (objc_class_template
);
395 add_field_decl (ptype
, "subclass_list", &chain
);
397 /* struct objc_class *sibling_class; */
398 ptype
= build_pointer_type (objc_class_template
);
399 add_field_decl (ptype
, "sibling_class", &chain
);
401 /* struct _objc_protocol **protocol_list; */
402 ptype
= build_pointer_type (build_pointer_type
403 (xref_tag (RECORD_TYPE
,
404 get_identifier (UTAG_PROTOCOL
))));
405 add_field_decl (ptype
, "protocol_list", &chain
);
407 /* void *gc_object_type; */
408 add_field_decl (build_pointer_type (void_type_node
),
409 "gc_object_type", &chain
);
411 objc_finish_struct (objc_class_template
, decls
);
414 /* struct _objc_category {
417 struct _objc_method_list *instance_methods;
418 struct _objc_method_list *class_methods;
419 struct _objc_protocol_list *protocols;
423 build_category_template (void)
425 tree ptype
, decls
, *chain
= NULL
;
427 objc_category_template
= objc_start_struct (get_identifier (UTAG_CATEGORY
));
429 /* char *category_name; */
430 decls
= add_field_decl (string_type_node
, "category_name", &chain
);
432 /* char *class_name; */
433 add_field_decl (string_type_node
, "class_name", &chain
);
435 /* struct _objc_method_list *instance_methods; */
436 add_field_decl (objc_method_list_ptr
, "instance_methods", &chain
);
438 /* struct _objc_method_list *class_methods; */
439 add_field_decl (objc_method_list_ptr
, "class_methods", &chain
);
441 /* struct _objc_protocol **protocol_list; */
442 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
443 add_field_decl (ptype
, "protocol_list", &chain
);
445 objc_finish_struct (objc_category_template
, decls
);
448 /* struct _objc_protocol {
449 struct _objc_class *isa;
451 struct _objc_protocol **protocol_list;
452 struct _objc__method_prototype_list *instance_methods;
453 struct _objc__method_prototype_list *class_methods;
457 build_protocol_template (void)
459 tree ptype
, decls
, *chain
= NULL
;
461 objc_protocol_template
= objc_start_struct (get_identifier (UTAG_PROTOCOL
));
463 /* struct _objc_class *isa; */
464 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
465 get_identifier (UTAG_CLASS
)));
466 decls
= add_field_decl (ptype
, "isa", &chain
);
468 /* char *protocol_name; */
469 add_field_decl (string_type_node
, "protocol_name", &chain
);
471 /* struct _objc_protocol **protocol_list; */
472 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
473 add_field_decl (ptype
, "protocol_list", &chain
);
475 /* struct _objc__method_prototype_list *instance_methods; */
476 add_field_decl (objc_method_proto_list_ptr
, "instance_methods", &chain
);
478 /* struct _objc__method_prototype_list *class_methods; */
479 add_field_decl (objc_method_proto_list_ptr
, "class_methods", &chain
);
481 objc_finish_struct (objc_protocol_template
, decls
);
484 /* --- names, decls + identifiers --- */
487 build_selector_table_decl (void)
491 build_selector_template ();
492 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
494 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
495 /* Squash `defined but not used' warning check_global_declaration. */
496 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
497 OBJCMETA (UOBJC_SELECTOR_TABLE_decl
, objc_meta
, meta_base
);
502 gnu_runtime_abi_01_super_superclassfield_id (void)
504 if (!super_superclassfield_id
)
505 super_superclassfield_id
= get_identifier ("super_class");
506 return super_superclassfield_id
;
511 gnu_runtime_abi_01_class_decl (tree klass
)
515 snprintf (buf
, BUFSIZE
, "_OBJC_Class_%s",
516 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
517 decl
= start_var_decl (objc_class_template
, buf
);
518 OBJCMETA (decl
, objc_meta
, meta_base
);
523 gnu_runtime_abi_01_metaclass_decl (tree klass
)
527 snprintf (buf
, BUFSIZE
, "_OBJC_MetaClass_%s",
528 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
529 decl
= start_var_decl (objc_class_template
, buf
);
530 OBJCMETA (decl
, objc_meta
, meta_base
);
535 gnu_runtime_abi_01_category_decl (tree klass
)
539 snprintf (buf
, BUFSIZE
, "_OBJC_Category_%s_on_%s",
540 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass
)),
541 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
542 decl
= start_var_decl (objc_category_template
, buf
);
543 OBJCMETA (decl
, objc_meta
, meta_base
);
548 gnu_runtime_abi_01_protocol_decl (tree p
)
553 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
554 snprintf (buf
, BUFSIZE
, "_OBJC_Protocol_%s",
555 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
556 decl
= start_var_decl (objc_protocol_template
, buf
);
557 OBJCMETA (decl
, objc_meta
, meta_base
);
562 gnu_runtime_abi_01_string_decl (tree type
, const char *name
,
563 string_section where ATTRIBUTE_UNUSED
)
565 tree decl
= start_var_decl (type
, name
);
566 OBJCMETA (decl
, objc_meta
, meta_base
);
573 gnu_runtime_abi_01_get_class_reference (tree ident
)
577 add_class_reference (ident
);
579 params
= build_tree_list (NULL_TREE
, my_build_string_pointer
580 (IDENTIFIER_LENGTH (ident
) + 1,
581 IDENTIFIER_POINTER (ident
)));
583 return build_function_call (input_location
, objc_get_class_decl
, params
);
586 /* Used by build_function_type_for_method. Append the types for
587 receiver & _cmd at the start of a method argument list to ARGTYPES.
588 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
589 trying to define a method or call one. SUPERFLAG says this is for a
590 send to super. METH may be NULL, in the case that there is no
594 gnu_runtime_abi_01_get_arg_type_list_base (vec
<tree
, va_gc
> **argtypes
,
595 tree meth
, int context
,
596 int superflag ATTRIBUTE_UNUSED
)
600 if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
601 receiver_type
= objc_instance_type
;
603 receiver_type
= objc_object_type
;
605 vec_safe_push (*argtypes
, receiver_type
);
606 /* Selector type - will eventually change to `int'. */
607 vec_safe_push (*argtypes
, objc_selector_type
);
610 /* Unused for GNU runtime. */
612 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED
)
617 /* sel_ref_chain is a list whose "value" fields will be instances of
618 identifier_node that represent the selector. LOC is the location of
622 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc
, tree ident
,
625 tree
*chain
= &sel_ref_chain
;
631 /* When we do a lookup for @selector () we have no idea of the
632 prototype - so match the first we find. */
633 if (TREE_VALUE (*chain
) == ident
634 && (!prototype
|| TREE_PURPOSE (*chain
) == prototype
))
635 goto return_at_index
;
638 chain
= &TREE_CHAIN (*chain
);
641 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
643 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
644 (b) provide better diagnostics for the first time an undefined
647 expr
= build_unary_op (loc
, ADDR_EXPR
,
648 build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
649 build_int_cst (NULL_TREE
, index
)),
651 return convert (objc_selector_type
, expr
);
654 /* Build a tree expression to send OBJECT the operation SELECTOR,
655 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
656 assuming the method has prototype METHOD_PROTOTYPE.
657 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
658 LOC is the location of the expression to build.
659 Use METHOD_PARAMS as list of args to pass to the method.
660 If SUPER_FLAG is nonzero, we look up the superclass's method. */
663 build_objc_method_call (location_t loc
, int super_flag
, tree method_prototype
,
664 tree lookup_object
, tree selector
,
667 tree sender
= (super_flag
? umsg_super_decl
668 : (flag_objc_direct_dispatch
? umsg_fast_decl
670 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
671 vec
<tree
, va_gc
> *parms
;
672 vec
<tree
, va_gc
> *tv
;
673 unsigned nparm
= (method_params
? list_length (method_params
) : 0);
675 /* If a prototype for the method to be called exists, then cast
676 the sender's return type and arguments to match that of the method.
677 Otherwise, leave sender as is. */
680 ? TREE_VALUE (TREE_TYPE (method_prototype
))
683 = build_function_type_for_method (ret_type
, method_prototype
,
684 METHOD_REF
, super_flag
);
688 if (method_prototype
&& METHOD_TYPE_ATTRIBUTES (method_prototype
))
689 ftype
= build_type_attribute_variant (ftype
,
690 METHOD_TYPE_ATTRIBUTES
693 sender_cast
= build_pointer_type (ftype
);
695 lookup_object
= build_c_cast (loc
, rcv_p
, lookup_object
);
697 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
698 lookup_object
= save_expr (lookup_object
);
700 /* Param list + 2 slots for object and selector. */
701 vec_alloc (parms
, nparm
+ 2);
704 /* First, call the lookup function to get a pointer to the method,
705 then cast the pointer, then call it with the method arguments. */
706 tv
->quick_push (lookup_object
);
707 tv
->quick_push (selector
);
708 method
= build_function_call_vec (loc
, vNULL
, sender
, tv
, NULL
);
711 /* Pass the appropriate object to the method. */
712 parms
->quick_push ((super_flag
? self_decl
: lookup_object
));
714 /* Pass the selector to the method. */
715 parms
->quick_push (selector
);
716 /* Now append the remainder of the parms. */
718 for (; method_params
; method_params
= TREE_CHAIN (method_params
))
719 parms
->quick_push (TREE_VALUE (method_params
));
721 /* Build an obj_type_ref, with the correct cast for the method call. */
722 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
723 t
= build_function_call_vec (loc
, vNULL
, t
, parms
, NULL
);
729 gnu_runtime_abi_01_build_objc_method_call (location_t loc
,
730 tree method_prototype
,
732 tree rtype ATTRIBUTE_UNUSED
,
735 int super ATTRIBUTE_UNUSED
)
738 gnu_runtime_abi_01_build_typed_selector_reference (loc
,
742 return build_objc_method_call (loc
, super
, method_prototype
, receiver
,
743 selector
, method_params
);
747 gnu_runtime_abi_01_get_protocol_reference (location_t loc
, tree p
)
749 tree expr
, protocol_struct_type
, *chain
;
750 if (!PROTOCOL_FORWARD_DECL (p
))
751 PROTOCOL_FORWARD_DECL (p
) = gnu_runtime_abi_01_protocol_decl (p
);
753 expr
= build_unary_op (loc
, ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
755 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
756 if we have it, rather than converting it here. */
757 expr
= convert (objc_protocol_type
, expr
);
759 /* The @protocol() expression is being compiled into a pointer to a
760 statically allocated instance of the Protocol class. To become
761 usable at runtime, the 'isa' pointer of the instance need to be
762 fixed up at runtime by the runtime library, to point to the
763 actual 'Protocol' class. */
765 /* For the GNU runtime, put the static Protocol instance in the list
766 of statically allocated instances, so that we make sure that its
767 'isa' pointer is fixed up at runtime by the GNU runtime library
768 to point to the Protocol class (at runtime, when loading the
769 module, the GNU runtime library loops on the statically allocated
770 instances (as found in the defs field in objc_symtab) and fixups
771 all the 'isa' pointers of those objects). */
773 /* This type is a struct containing the fields of a Protocol
774 object. (Cfr. objc_protocol_type instead is the type of a pointer
775 to such a struct). */
776 protocol_struct_type
= xref_tag (RECORD_TYPE
,
777 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
779 /* Look for the list of Protocol statically allocated instances
780 to fixup at runtime. Create a new list to hold Protocol
781 statically allocated instances, if the list is not found. At
782 present there is only another list, holding NSConstantString
783 static instances to be fixed up at runtime. */
785 for (chain
= &objc_static_instances
;
786 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
787 chain
= &TREE_CHAIN (*chain
));
791 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
792 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
796 /* Add this statically allocated instance to the Protocol list. */
797 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
798 PROTOCOL_FORWARD_DECL (p
),
799 TREE_PURPOSE (*chain
));
803 /* For ABI 8 an IVAR is just a fixed offset in the class struct. */
806 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED
,
809 return objc_build_component_ref (base
, id
);
812 /* We build super class references as we need them (but keep them once
813 built for the sake of efficiency). */
816 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED
,
817 struct imp_entry
*imp
, bool inst_meth
)
823 objc_build_component_ref (imp
->class_decl
,
824 get_identifier ("super_class"));
825 return ucls_super_ref
;
829 if (!uucls_super_ref
)
831 objc_build_component_ref (imp
->meta_decl
,
832 get_identifier ("super_class"));
833 return uucls_super_ref
;
838 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED
,
839 struct imp_entry
*imp
, bool inst_meth
)
841 tree super_name
= CLASS_SUPER_NAME (imp
->imp_template
);
844 add_class_reference (super_name
);
845 super_class
= (inst_meth
? objc_get_class_decl
: objc_get_meta_class_decl
);
846 super_name
= my_build_string_pointer (IDENTIFIER_LENGTH (super_name
) + 1,
847 IDENTIFIER_POINTER (super_name
));
848 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
849 return build_function_call (input_location
,
851 build_tree_list (NULL_TREE
, super_name
));
855 gnu_runtime_abi_01_setup_const_string_class_decl (void)
857 /* Do nothing, and create no error. */
861 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
863 static GTY(()) int num_static_inst
;
866 objc_add_static_instance (tree constructor
, tree class_decl
)
871 /* Find the list of static instances for the CLASS_DECL. Create one if
873 for (chain
= &objc_static_instances
;
874 *chain
&& TREE_VALUE (*chain
) != class_decl
;
875 chain
= &TREE_CHAIN (*chain
));
878 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
879 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
882 snprintf (buf
, BUFSIZE
, "_OBJC_INSTANCE_%d", num_static_inst
++);
883 decl
= build_decl (input_location
,
884 VAR_DECL
, get_identifier (buf
), class_decl
);
885 TREE_STATIC (decl
) = 1;
886 DECL_ARTIFICIAL (decl
) = 1;
887 TREE_USED (decl
) = 1;
888 DECL_INITIAL (decl
) = constructor
;
889 DECL_CONTEXT (decl
) = NULL
;
890 OBJCMETA (decl
, objc_meta
, meta_base
);
892 /* We may be writing something else just now.
893 Postpone till end of input. */
894 DECL_DEFER_OUTPUT (decl
) = 1;
895 pushdecl_top_level (decl
);
896 rest_of_decl_compilation (decl
, 1, 0);
898 /* Add the DECL to the head of this CLASS' list. */
899 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
905 gnu_runtime_abi_01_build_const_string_constructor (location_t loc
, tree string
,
908 tree constructor
, fields
;
909 vec
<constructor_elt
, va_gc
> *v
= NULL
;
911 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
912 fields
= TYPE_FIELDS (internal_const_str_type
);
913 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, 0));
915 fields
= DECL_CHAIN (fields
);
916 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_unary_op (loc
,
917 ADDR_EXPR
, string
, 1));
919 fields
= DECL_CHAIN (fields
);
920 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, length
));
921 constructor
= objc_build_constructor (internal_const_str_type
, v
);
923 constructor
= objc_add_static_instance (constructor
, constant_string_type
);
927 /* --- metadata - module initializer --- */
929 /* The GNU runtime requires us to provide a static initializer function
932 static void __objc_gnu_init (void) {
933 __objc_exec_class (&L_OBJC_MODULES);
938 build_module_initializer_routine (void)
943 push_lang_context (lang_name_c
); /* extern "C" */
946 objc_push_parm (build_decl (input_location
,
947 PARM_DECL
, NULL_TREE
, void_type_node
));
949 objc_start_function (get_identifier (TAG_GNUINIT
),
950 build_function_type_list (void_type_node
, NULL_TREE
),
951 NULL_TREE
, NULL_TREE
);
953 objc_start_function (get_identifier (TAG_GNUINIT
),
954 build_function_type_list (void_type_node
, NULL_TREE
),
955 NULL_TREE
, objc_get_parm_info (0, NULL_TREE
));
957 body
= c_begin_compound_stmt (true);
958 add_stmt (build_function_call
963 build_unary_op (input_location
, ADDR_EXPR
,
964 UOBJC_MODULES_decl
, 0))));
965 add_stmt (c_end_compound_stmt (input_location
, body
, true));
967 TREE_PUBLIC (current_function_decl
) = 0;
970 /* For Objective-C++, we will need to call __objc_gnu_init
971 from objc_generate_static_init_call() below. */
972 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
975 GNU_INIT_decl
= current_function_decl
;
984 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
985 to be called by the module initializer routine. */
988 objc_static_init_needed_p (void)
990 return (GNU_INIT_decl
!= NULL_TREE
);
993 /* Generate a call to the __objc_gnu_init initializer function. */
996 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
998 add_stmt (build_stmt (input_location
, EXPR_STMT
,
999 build_function_call (input_location
,
1000 GNU_INIT_decl
, NULL_TREE
)));
1004 #endif /* OBJCPLUS */
1006 /* --- Output GNU Meta-data --- */
1009 generate_classref_translation_entry (tree chain
)
1011 tree expr
, decl
, type
;
1013 decl
= TREE_PURPOSE (chain
);
1014 type
= TREE_TYPE (decl
);
1016 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
1017 expr
= convert (type
, expr
); /* cast! */
1019 /* This is a class reference. It is re-written by the runtime,
1020 but will be optimized away unless we force it. */
1021 DECL_PRESERVE_P (decl
) = 1;
1022 OBJCMETA (decl
, objc_meta
, meta_base
);
1023 finish_var_decl (decl
, expr
);
1029 handle_impent (struct imp_entry
*impent
)
1033 /* objc_implementation_context = impent->imp_context;
1034 implementation_template = impent->imp_template;*/
1036 switch (TREE_CODE (impent
->imp_context
))
1038 case CLASS_IMPLEMENTATION_TYPE
:
1040 const char *const class_name
=
1041 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
1043 string
= (char *) alloca (strlen (class_name
) + 30);
1045 sprintf (string
, "__objc_class_name_%s", class_name
);
1048 case CATEGORY_IMPLEMENTATION_TYPE
:
1050 const char *const class_name
=
1051 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
1052 const char *const class_super_name
=
1053 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
1055 string
= (char *) alloca (strlen (class_name
)
1056 + strlen (class_super_name
) + 30);
1058 /* Do the same for categories. Even though no references to
1059 these symbols are generated automatically by the compiler,
1060 it gives you a handle to pull them into an archive by
1062 sprintf (string
, "*__objc_category_name_%s_%s", class_name
, class_super_name
);
1072 init
= integer_zero_node
;
1073 decl
= build_decl (input_location
,
1074 VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
1075 TREE_PUBLIC (decl
) = 1;
1076 TREE_READONLY (decl
) = 1;
1077 TREE_USED (decl
) = 1;
1078 TREE_CONSTANT (decl
) = 1;
1079 DECL_CONTEXT (decl
) = NULL_TREE
;
1080 DECL_ARTIFICIAL (decl
) = 1;
1081 TREE_STATIC (decl
) = 1;
1082 DECL_INITIAL (decl
) = error_mark_node
; /* A real initializer is coming... */
1083 /* We must force the reference. */
1084 DECL_PRESERVE_P (decl
) = 1;
1086 finish_var_decl(decl
, init
) ;
1091 build_protocol_initializer (tree type
, tree protocol_name
, tree protocol_list
,
1092 tree inst_methods
, tree class_methods
)
1096 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1098 /* TODO: pass the loc in or find it from args. */
1099 loc
= input_location
;
1100 ttyp
= build_pointer_type (xref_tag (RECORD_TYPE
,
1101 get_identifier (UTAG_CLASS
)));
1102 /* Filling the "isa" in with a version allows the runtime system to
1104 expr
= build_int_cst (ttyp
, PROTOCOL_VERSION
);
1106 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1108 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_name
);
1109 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_list
);
1111 ttyp
= objc_method_proto_list_ptr
;
1113 expr
= convert (ttyp
, build_unary_op (loc
, ADDR_EXPR
, inst_methods
, 0));
1115 expr
= convert (ttyp
, null_pointer_node
);
1116 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1119 expr
= convert (ttyp
, build_unary_op (loc
, ADDR_EXPR
, class_methods
, 0));
1121 expr
= convert (ttyp
, null_pointer_node
);
1122 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1124 return objc_build_constructor (type
, inits
);
1128 generate_protocol_list (tree i_or_p
, tree klass_ctxt
)
1130 tree array_type
, ptype
, refs_decl
, lproto
, e
, plist
;
1131 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1135 switch (TREE_CODE (i_or_p
))
1137 case CLASS_INTERFACE_TYPE
:
1138 case CATEGORY_INTERFACE_TYPE
:
1139 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
1141 case PROTOCOL_INTERFACE_TYPE
:
1142 plist
= PROTOCOL_LIST (i_or_p
);
1149 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
1150 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
1151 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
1154 /* Build initializer. */
1155 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1156 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
1157 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
1159 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
1161 tree pval
= TREE_VALUE (lproto
);
1163 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
1164 && PROTOCOL_FORWARD_DECL (pval
))
1166 tree fwref
= PROTOCOL_FORWARD_DECL (pval
);
1167 location_t loc
= DECL_SOURCE_LOCATION (fwref
) ;
1168 e
= build_unary_op (loc
, ADDR_EXPR
, fwref
, 0);
1169 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
1173 /* static struct objc_protocol *refs[n]; */
1175 switch (TREE_CODE (i_or_p
))
1177 case PROTOCOL_INTERFACE_TYPE
:
1178 snprintf (buf
, BUFSIZE
, "_OBJC_ProtocolRefs_%s",
1179 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p
)));
1181 case CLASS_INTERFACE_TYPE
:
1182 snprintf (buf
, BUFSIZE
, "_OBJC_ClassProtocols_%s",
1183 IDENTIFIER_POINTER (CLASS_NAME (i_or_p
)));
1185 case CATEGORY_INTERFACE_TYPE
:
1186 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryProtocols_%s_%s",
1187 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt
)),
1188 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt
)));
1194 ptype
= build_pointer_type (objc_protocol_template
);
1195 array_type
= build_sized_array_type (ptype
, size
+ 3);
1196 refs_decl
= start_var_decl (array_type
, buf
);
1197 OBJCMETA (refs_decl
, objc_meta
, meta_base
);
1198 finish_var_decl (refs_decl
,
1199 objc_build_constructor (TREE_TYPE (refs_decl
), v
));
1205 generate_v1_meth_descriptor_table (tree chain
, tree protocol
, const char *prefix
)
1207 tree method_list_template
, initlist
, decl
;
1209 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1212 if (!chain
|| !prefix
)
1215 if (!objc_method_prototype_template
)
1216 objc_method_prototype_template
= build_method_prototype_template ();
1218 size
= list_length (chain
);
1219 method_list_template
=
1220 build_method_prototype_list_template (objc_method_prototype_template
,
1222 snprintf (buf
, BUFSIZE
, "%s_%s", prefix
,
1223 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol
)));
1225 decl
= start_var_decl (method_list_template
, buf
);
1227 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
1229 build_descriptor_table_initializer (objc_method_prototype_template
,
1231 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, initlist
);
1232 OBJCMETA (decl
, objc_meta
, meta_base
);
1233 finish_var_decl (decl
, objc_build_constructor (method_list_template
, v
));
1237 /* For each protocol which was referenced either from a @protocol()
1238 expression, or because a class/category implements it (then a
1239 pointer to the protocol is stored in the struct describing the
1240 class/category), we create a statically allocated instance of the
1241 Protocol class. The code is written in such a way as to generate
1242 as few Protocol objects as possible; we generate a unique Protocol
1243 instance for each protocol, and we don't generate a Protocol
1244 instance if the protocol is never referenced (either from a
1245 @protocol() or from a class/category implementation). These
1246 statically allocated objects can be referred to via the static
1247 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1249 The statically allocated Protocol objects that we generate here
1250 need to be fixed up at runtime in order to be used: the 'isa'
1251 pointer of the objects need to be set up to point to the 'Protocol'
1252 class, as known at runtime.
1254 The GNU runtime fixes up all protocols before user code from the module
1255 is executed; it requires pointers to those symbols
1256 to be put in the objc_symtab (which is then passed as argument to
1257 the function __objc_exec_class() which the compiler sets up to be
1258 executed automatically when the module is loaded); setup of those
1259 Protocol objects happen in two ways in the GNU runtime: all
1260 Protocol objects referred to by a class or category implementation
1261 are fixed up when the class/category is loaded; all Protocol
1262 objects referred to by a @protocol() expression are added by the
1263 compiler to the list of statically allocated instances to fixup
1264 (the same list holding the statically allocated constant string
1265 objects). Because, as explained above, the compiler generates as
1266 few Protocol objects as possible, some Protocol object might end up
1267 being referenced multiple times when compiled with the GNU runtime,
1268 and end up being fixed up multiple times at runtime initialization.
1269 But that doesn't hurt, it's just a little inefficient. */
1272 generate_protocols (void)
1276 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
1278 /* If a protocol was directly referenced, pull in indirect references. */
1279 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
1280 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
1281 generate_protocol_references (PROTOCOL_LIST (p
));
1283 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
1285 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
1286 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
1288 /* If protocol wasn't referenced, don't generate any code. */
1289 decl
= PROTOCOL_FORWARD_DECL (p
);
1294 /* Make sure we link in the Protocol class. */
1295 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
1299 if (! METHOD_ENCODING (nst_methods
))
1301 encoding
= encode_method_prototype (nst_methods
);
1302 METHOD_ENCODING (nst_methods
) = encoding
;
1304 nst_methods
= DECL_CHAIN (nst_methods
);
1307 UOBJC_INSTANCE_METHODS_decl
=
1308 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p
), p
,
1309 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1313 if (! METHOD_ENCODING (cls_methods
))
1315 encoding
= encode_method_prototype (cls_methods
);
1316 METHOD_ENCODING (cls_methods
) = encoding
;
1319 cls_methods
= DECL_CHAIN (cls_methods
);
1322 UOBJC_CLASS_METHODS_decl
=
1323 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p
), p
,
1324 "_OBJC_PROTOCOL_CLASS_METHODS");
1325 /* generate_method_descriptors (p);*/
1327 if (PROTOCOL_LIST (p
))
1328 refs_decl
= generate_protocol_list (p
, NULL_TREE
);
1332 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1333 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
1336 refs_expr
= convert (build_pointer_type (build_pointer_type
1337 (objc_protocol_template
)),
1338 build_unary_op (input_location
,
1339 ADDR_EXPR
, refs_decl
, 0));
1341 refs_expr
= build_int_cst (NULL_TREE
, 0);
1343 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1344 by generate_method_descriptors, which is called above. */
1345 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
1346 protocol_name_expr
, refs_expr
,
1347 UOBJC_INSTANCE_METHODS_decl
,
1348 UOBJC_CLASS_METHODS_decl
);
1349 finish_var_decl (decl
, initlist
);
1354 generate_dispatch_table (tree chain
, const char *name
)
1356 tree decl
, method_list_template
, initlist
;
1357 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1358 int size
= list_length (chain
);
1360 if (!objc_method_template
)
1361 objc_method_template
= build_method_template ();
1363 method_list_template
= build_method_list_template (objc_method_template
,
1365 initlist
= build_dispatch_table_initializer (objc_method_template
, chain
);
1367 decl
= start_var_decl (method_list_template
, name
);
1369 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1370 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1371 build_int_cst (integer_type_node
, size
));
1372 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, initlist
);
1374 OBJCMETA (decl
, objc_meta
, meta_base
);
1375 finish_var_decl (decl
,
1376 objc_build_constructor (TREE_TYPE (decl
), v
));
1381 /* Init a category. */
1383 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
1384 tree inst_methods
, tree class_methods
,
1389 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1391 /* TODO: pass the loc in or find it from args. */
1392 /* TODO: pass the loc in or find it from args. */
1393 loc
= UNKNOWN_LOCATION
;
1394 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, cat_name
);
1395 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, class_name
);
1397 ltyp
= objc_method_list_ptr
;
1399 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, inst_methods
, 0));
1401 expr
= convert (ltyp
, null_pointer_node
);
1402 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1405 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, class_methods
, 0));
1407 expr
= convert (ltyp
, null_pointer_node
);
1408 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1410 /* protocol_list = */
1411 ltyp
= build_pointer_type (build_pointer_type (objc_protocol_template
));
1413 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, protocol_list
, 0));
1415 expr
= convert (ltyp
, null_pointer_node
);
1416 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1418 return objc_build_constructor (type
, v
);
1421 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1424 generate_category (struct imp_entry
*impent
)
1426 tree initlist
, cat_name_expr
, class_name_expr
;
1427 tree protocol_decl
, category
, cat_decl
;
1428 tree inst_methods
= NULL_TREE
, class_methods
= NULL_TREE
;
1429 tree cat
= impent
->imp_context
;
1432 cat_decl
= impent
->class_decl
;
1434 add_class_reference (CLASS_NAME (cat
));
1435 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
1437 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
1439 category
= lookup_category (impent
->imp_template
, CLASS_SUPER_NAME (cat
));
1441 if (category
&& CLASS_PROTOCOL_LIST (category
))
1443 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
1444 protocol_decl
= generate_protocol_list (category
, cat
);
1449 if (CLASS_NST_METHODS (cat
))
1451 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryInstanceMethods_%s_%s",
1452 IDENTIFIER_POINTER (CLASS_NAME (cat
)),
1453 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat
)));
1454 inst_methods
= generate_dispatch_table (CLASS_NST_METHODS (cat
), buf
);
1457 if (CLASS_CLS_METHODS (cat
))
1459 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryClassMethods_%s_%s",
1460 IDENTIFIER_POINTER (CLASS_NAME (cat
)),
1461 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat
)));
1462 class_methods
= generate_dispatch_table (CLASS_CLS_METHODS (cat
), buf
);
1465 initlist
= build_category_initializer (TREE_TYPE (cat_decl
),
1466 cat_name_expr
, class_name_expr
,
1467 inst_methods
, class_methods
,
1469 /* Finish and initialize the forward decl. */
1470 finish_var_decl (cat_decl
, initlist
);
1471 impent
->class_decl
= cat_decl
;
1474 /* struct _objc_class {
1475 struct objc_class *isa;
1476 struct objc_class *super_class;
1481 struct objc_ivar_list *ivars;
1482 struct objc_method_list *methods;
1483 struct sarray *dtable;
1484 struct objc_class *subclass_list;
1485 struct objc_class *sibling_class;
1486 struct objc_protocol_list *protocols;
1487 void *gc_object_type;
1491 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
1492 tree name
, tree size
, int status
,
1493 tree dispatch_table
, tree ivar_list
,
1497 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1500 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, isa
);
1503 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, super
);
1506 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, default_conversion (name
));
1509 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1510 build_int_cst (long_integer_type_node
, 0));
1513 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1514 build_int_cst (long_integer_type_node
, status
));
1516 /* instance_size = */
1517 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1518 convert (long_integer_type_node
, size
));
1520 /* objc_ivar_list = */
1522 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1523 build_int_cst (objc_ivar_list_ptr
, 0));
1526 expr
= convert (objc_ivar_list_ptr
,
1527 build_unary_op (input_location
, ADDR_EXPR
,
1529 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1532 /* objc_method_list = */
1533 if (!dispatch_table
)
1534 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1535 convert (objc_method_list_ptr
, null_pointer_node
));
1538 expr
= convert (objc_method_list_ptr
,
1539 build_unary_op (input_location
, ADDR_EXPR
,
1540 dispatch_table
, 0));
1541 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1544 /* FIXME: Remove NeXT runtime code. */
1545 if (flag_next_runtime
)
1547 ltyp
= build_pointer_type (xref_tag (RECORD_TYPE
,
1548 get_identifier ("objc_cache")));
1549 /* method_cache = */
1550 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, convert (ltyp
, null_pointer_node
));
1555 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1557 /* subclass_list = */
1558 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1560 /* sibling_class = */
1561 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1564 /* protocol_list = */
1565 ltyp
= build_pointer_type (build_pointer_type (objc_protocol_template
));
1566 if (! protocol_list
)
1567 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (ltyp
, 0));
1570 expr
= convert (ltyp
,
1571 build_unary_op (input_location
, ADDR_EXPR
,
1573 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1576 /* FIXME: Remove NeXT runtime code. */
1577 if (flag_next_runtime
)
1579 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1581 /* gc_object_type = NULL */
1582 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1584 return objc_build_constructor (type
, v
);
1589 generate_ivars_list (tree chain
, const char *name
)
1591 tree initlist
, ivar_list_template
, decl
;
1593 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1598 if (!objc_ivar_template
)
1599 objc_ivar_template
= build_ivar_template ();
1601 size
= ivar_list_length (chain
);
1603 generating_instance_variables
= 1;
1604 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
1605 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
1606 generating_instance_variables
= 0;
1608 decl
= start_var_decl (ivar_list_template
, name
);
1610 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
1611 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, initlist
);
1613 OBJCMETA (decl
, objc_meta
, meta_base
);
1614 finish_var_decl (decl
,
1615 objc_build_constructor (TREE_TYPE (decl
), inits
));
1620 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1621 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1624 generate_class_structures (struct imp_entry
*impent
)
1626 tree name_expr
, super_expr
, root_expr
, class_decl
, meta_decl
;
1627 tree my_root_id
, my_super_id
;
1628 tree cast_type
, initlist
, protocol_decl
;
1629 tree inst_methods
= NULL_TREE
, class_methods
= NULL_TREE
;
1630 tree chain
, inst_ivars
= NULL_TREE
, class_ivars
= NULL_TREE
;
1635 /* objc_implementation_context = impent->imp_context;
1636 implementation_template = impent->imp_template;*/
1637 class_decl
= impent
->class_decl
;
1638 meta_decl
= impent
->meta_decl
;
1639 /* UOBJC_CLASS_decl = impent->class_decl;
1640 UOBJC_METACLASS_decl = impent->meta_decl;*/
1642 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1644 my_super_id
= CLASS_SUPER_NAME (impent
->imp_template
);
1647 add_class_reference (my_super_id
);
1649 /* Compute "my_root_id" - this is required for code generation.
1650 the "isa" for all meta class structures points to the root of
1651 the inheritance hierarchy (e.g. "__Object")... */
1652 my_root_id
= my_super_id
;
1655 tree my_root_int
= lookup_interface (my_root_id
);
1657 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
1658 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
1665 /* No super class. */
1666 my_root_id
= CLASS_NAME (impent
->imp_template
);
1668 cast_type
= build_pointer_type (objc_class_template
);
1669 name_expr
= add_objc_string (CLASS_NAME (impent
->imp_template
),
1672 /* Install class `isa' and `super' pointers at runtime. */
1674 super_expr
= add_objc_string (my_super_id
, class_names
);
1676 super_expr
= null_pointer_node
;
1678 super_expr
= build_c_cast (loc
, cast_type
, super_expr
);
1680 root_expr
= add_objc_string (my_root_id
, class_names
);
1681 root_expr
= build_c_cast (loc
, cast_type
, root_expr
);
1683 if (CLASS_PROTOCOL_LIST (impent
->imp_template
))
1685 generate_protocol_references (CLASS_PROTOCOL_LIST (impent
->imp_template
));
1686 protocol_decl
= generate_protocol_list (impent
->imp_template
,
1687 impent
->imp_context
);
1690 protocol_decl
= NULL_TREE
;
1692 if (CLASS_CLS_METHODS (impent
->imp_context
))
1694 snprintf (buf
, BUFSIZE
, "_OBJC_ClassMethods_%s",
1695 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1696 class_methods
= generate_dispatch_table (CLASS_CLS_METHODS (impent
->imp_context
),
1700 if (CLASS_SUPER_NAME (impent
->imp_template
) == NULL_TREE
1701 && (chain
= TYPE_FIELDS (objc_class_template
)))
1703 snprintf (buf
, BUFSIZE
, "_OBJC_ClassIvars_%s",
1704 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1705 class_ivars
= generate_ivars_list (chain
, buf
);
1708 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1711 build_shared_structure_initializer
1712 (TREE_TYPE (meta_decl
),
1713 root_expr
, super_expr
, name_expr
,
1714 convert (integer_type_node
,
1715 TYPE_SIZE_UNIT (objc_class_template
)),
1716 CLS_META
, class_methods
, class_ivars
,
1719 finish_var_decl (meta_decl
, initlist
);
1720 impent
->meta_decl
= meta_decl
;
1722 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1723 if (CLASS_NST_METHODS (impent
->imp_context
))
1725 snprintf (buf
, BUFSIZE
, "_OBJC_InstanceMethods_%s",
1726 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1727 inst_methods
= generate_dispatch_table (CLASS_NST_METHODS (impent
->imp_context
),
1731 if ((chain
= CLASS_IVARS (impent
->imp_template
)))
1733 snprintf (buf
, BUFSIZE
, "_OBJC_InstanceIvars_%s",
1734 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1735 inst_ivars
= generate_ivars_list (chain
, buf
);
1739 build_shared_structure_initializer
1740 (TREE_TYPE (class_decl
),
1741 build_unary_op (loc
, ADDR_EXPR
, meta_decl
, 0),
1742 super_expr
, name_expr
,
1743 convert (integer_type_node
,
1744 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1745 (impent
->imp_template
))),
1746 CLS_FACTORY
| cls_flags
, inst_methods
, inst_ivars
,
1749 finish_var_decl (class_decl
, initlist
);
1750 impent
->class_decl
= class_decl
;
1753 /* --- Output GNU Metadata --- */
1755 /* TODO: Make this into an array of refs. */
1757 handle_class_ref (tree chain
)
1759 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
1760 char *string
= (char *) alloca (strlen (name
) + 30);
1764 sprintf (string
, "__objc_class_name_%s", name
);
1766 /* Make a decl for this name, so we can use its address in a tree. */
1767 decl
= build_decl (input_location
,
1768 VAR_DECL
, get_identifier (string
), TREE_TYPE (integer_zero_node
));
1769 DECL_EXTERNAL (decl
) = 1;
1770 TREE_PUBLIC (decl
) = 1;
1771 DECL_CONTEXT (decl
) = NULL_TREE
;
1772 finish_var_decl (decl
, 0);
1774 /* Make a decl for the address. */
1775 sprintf (string
, "__objc_class_ref_%s", name
);
1776 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
1777 decl
= build_decl (input_location
,
1778 VAR_DECL
, get_identifier (string
), string_type_node
);
1779 TREE_STATIC (decl
) = 1;
1780 TREE_USED (decl
) = 1;
1781 DECL_READ_P (decl
) = 1;
1782 DECL_ARTIFICIAL (decl
) = 1;
1783 DECL_INITIAL (decl
) = error_mark_node
;
1785 /* We must force the reference. */
1786 DECL_PRESERVE_P (decl
) = 1;
1788 DECL_CONTEXT (decl
) = NULL_TREE
;
1789 finish_var_decl (decl
, exp
);
1793 get_proto_encoding (tree proto
)
1798 if (! METHOD_ENCODING (proto
))
1800 encoding
= encode_method_prototype (proto
);
1801 METHOD_ENCODING (proto
) = encoding
;
1804 encoding
= METHOD_ENCODING (proto
);
1806 return add_objc_string (encoding
, meth_var_types
);
1809 return build_int_cst (NULL_TREE
, 0);
1813 build_gnu_selector_translation_table (void)
1816 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1817 vec
<constructor_elt
, va_gc
> *v
;
1819 /* Cause the selector table (previously forward-declared)
1820 to be actually output. */
1822 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1827 /* TODO: improve on the location for the diagnostic. */
1828 location_t loc
= input_location
;
1829 diagnose_missing_method (TREE_VALUE (chain
), loc
);
1833 expr
= build_selector (TREE_VALUE (chain
));
1834 encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1835 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1836 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, encoding
);
1837 expr
= objc_build_constructor (objc_selector_template
, v
);
1839 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1840 } /* each element in the chain */
1842 /* List terminator. */
1844 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1845 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1846 expr
= objc_build_constructor (objc_selector_template
, v
);
1848 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1849 expr
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
1851 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, expr
);
1854 /* Output references to all statically allocated objects. Return the DECL
1855 for the array built. */
1858 generate_static_references (void)
1860 tree expr
= NULL_TREE
;
1861 tree class_name
, klass
, decl
;
1862 tree cl_chain
, in_chain
, type
1863 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
1864 int num_inst
, num_class
;
1866 vec
<constructor_elt
, va_gc
> *decls
= NULL
;
1868 /* FIXME: Remove NeXT runtime code. */
1869 if (flag_next_runtime
)
1872 for (cl_chain
= objc_static_instances
, num_class
= 0;
1873 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1875 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1877 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1878 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1880 snprintf (buf
, BUFSIZE
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1881 decl
= start_var_decl (type
, buf
);
1883 /* Output {class_name, ...}. */
1884 klass
= TREE_VALUE (cl_chain
);
1885 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (klass
), class_names
);
1886 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1887 build_unary_op (input_location
,
1888 ADDR_EXPR
, class_name
, 1));
1890 /* Output {..., instance, ...}. */
1891 for (in_chain
= TREE_PURPOSE (cl_chain
);
1892 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1894 expr
= build_unary_op (input_location
,
1895 ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1896 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1899 /* Output {..., NULL}. */
1900 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1902 expr
= objc_build_constructor (TREE_TYPE (decl
), v
);
1903 OBJCMETA (decl
, objc_meta
, meta_base
);
1904 finish_var_decl (decl
, expr
);
1905 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
,
1906 build_unary_op (input_location
,
1907 ADDR_EXPR
, decl
, 1));
1910 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1911 expr
= objc_build_constructor (type
, decls
);
1912 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
1913 OBJCMETA (static_instances_decl
, objc_meta
, meta_base
);
1914 finish_var_decl (static_instances_decl
, expr
);
1917 /* Create the initial value for the `defs' field of _objc_symtab.
1918 This is a CONSTRUCTOR. */
1921 init_def_list (tree type
)
1924 struct imp_entry
*impent
;
1926 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1929 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1931 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1933 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1934 expr
= build_unary_op (loc
,
1935 ADDR_EXPR
, impent
->class_decl
, 0);
1936 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1941 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1943 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1945 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1946 expr
= build_unary_op (loc
,
1947 ADDR_EXPR
, impent
->class_decl
, 0);
1948 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1952 loc
= UNKNOWN_LOCATION
;
1953 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1954 if (static_instances_decl
)
1955 expr
= build_unary_op (loc
, ADDR_EXPR
, static_instances_decl
, 0);
1957 expr
= integer_zero_node
;
1958 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1960 return objc_build_constructor (type
, v
);
1963 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1965 /* Predefine the following data type:
1973 void *defs[cls_def_cnt + cat_def_cnt];
1977 build_objc_symtab_template (void)
1979 tree fields
, array_type
, *chain
= NULL
;
1982 objc_symtab_template
= objc_start_struct (get_identifier (UTAG_SYMTAB
));
1984 /* long sel_ref_cnt; */
1985 fields
= add_field_decl (long_integer_type_node
, "sel_ref_cnt", &chain
);
1988 add_field_decl (build_pointer_type (objc_selector_type
), "refs", &chain
);
1990 /* short cls_def_cnt; */
1991 add_field_decl (short_integer_type_node
, "cls_def_cnt", &chain
);
1993 /* short cat_def_cnt; */
1994 add_field_decl (short_integer_type_node
, "cat_def_cnt", &chain
);
1996 /* Note that padding will be added here on LP64. */
1998 /* void *defs[imp_count + cat_count (+ 1)]; */
1999 /* NB: The index is one less than the size of the array. */
2000 index
= imp_count
+ cat_count
;
2001 array_type
= build_sized_array_type (ptr_type_node
, index
+ 1);
2002 add_field_decl (array_type
, "defs", &chain
);
2004 objc_finish_struct (objc_symtab_template
, fields
);
2006 /* Construct the initial value for all of _objc_symtab. */
2009 init_objc_symtab (tree type
)
2011 tree field
, expr
, ltyp
;
2013 vec
<constructor_elt
, va_gc
> *v
= NULL
;
2015 loc
= UNKNOWN_LOCATION
;
2017 /* sel_ref_cnt = { ..., 5, ... } */
2019 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2020 build_int_cst (long_integer_type_node
, 0));
2022 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2024 ltyp
= build_pointer_type (objc_selector_type
);
2026 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
,
2027 UOBJC_SELECTOR_TABLE_decl
, 1));
2029 expr
= convert (ltyp
, null_pointer_node
);
2030 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2032 /* cls_def_cnt = { ..., 5, ... } */
2034 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2035 build_int_cst (short_integer_type_node
, imp_count
));
2037 /* cat_def_cnt = { ..., 5, ... } */
2039 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2040 build_int_cst (short_integer_type_node
, cat_count
));
2042 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2044 field
= TYPE_FIELDS (type
);
2045 field
= DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field
))));
2047 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, init_def_list (TREE_TYPE (field
)));
2049 return objc_build_constructor (type
, v
);
2052 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2053 and initialized appropriately. */
2056 generate_objc_symtab_decl (void)
2058 build_objc_symtab_template ();
2059 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2060 OBJCMETA (UOBJC_SYMBOLS_decl
, objc_meta
, meta_base
);
2061 finish_var_decl (UOBJC_SYMBOLS_decl
,
2062 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2066 objc_generate_v1_gnu_metadata (void)
2068 struct imp_entry
*impent
;
2071 /* Process the static instances here because initialization of objc_symtab
2073 if (objc_static_instances
)
2074 generate_static_references ();
2076 objc_implementation_context
=
2077 implementation_template
=
2079 UOBJC_METACLASS_decl
= NULL_TREE
;
2081 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2083 /* If -gen-decls is present, Dump the @interface of each class.
2084 TODO: Dump the classes in the order they were found, rather than in
2085 reverse order as we are doing now. */
2086 if (flag_gen_declaration
)
2087 dump_interface (gen_declaration_file
, impent
->imp_context
);
2089 /* all of the following reference the string pool... */
2090 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2091 generate_class_structures (impent
);
2093 generate_category (impent
);
2096 /* If we are using an array of selectors, we must always
2097 finish up the array decl even if no selectors were used. */
2098 build_gnu_selector_translation_table ();
2101 generate_protocols ();
2103 /* Arrange for ObjC data structures to be initialized at run time. */
2104 /* FIXME: Have some more elegant way to determine if we need to
2105 generate objc_symtab_decl or not, instead of checking these
2107 if (imp_list
|| class_names_chain
2108 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
2109 || prop_names_attr_chain
)
2110 generate_objc_symtab_decl ();
2112 if (imp_list
|| class_names_chain
|| objc_static_instances
2113 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
2115 /* Make sure that the meta-data are identified as being
2117 build_module_descriptor (OBJC_VERSION
,
2118 build_tree_list (objc_meta
, meta_base
));
2119 build_module_initializer_routine ();
2122 /* Dump the class references. This forces the appropriate classes
2123 to be linked into the executable image, preserving unix archive
2124 semantics. This can be removed when we move to a more dynamically
2125 linked environment. */
2127 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2129 handle_class_ref (chain
);
2130 if (TREE_PURPOSE (chain
))
2131 generate_classref_translation_entry (chain
);
2134 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2135 handle_impent (impent
);
2137 generate_strings ();
2140 /* --- exceptions --- */
2142 static GTY(()) tree objc_eh_personality_decl
;
2145 objc_eh_runtime_type (tree type
)
2147 tree ident
, eh_id
, decl
, str
;
2149 if (type
== error_mark_node
2150 || errorcount
|| sorrycount
)
2152 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2153 to prevent an ICE. Note that we know that the compiler will
2154 terminate with an error and this 'ErrorMarkNode' class name will
2155 never be actually used. */
2156 ident
= get_identifier ("ErrorMarkNode");
2157 goto make_err_class
;
2160 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
2161 /* We don't want to identify 'id' for GNU. Instead, build a 0
2162 entry in the exceptions table. */
2163 return null_pointer_node
;
2165 if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
2168 /* This routine is also called for c++ catch clauses; in which case,
2169 we use the c++ typeinfo decl. */
2170 return build_eh_type_type (type
);
2172 error ("non-objective-c type '%T' cannot be caught", type
);
2173 ident
= get_identifier ("ErrorMarkNode");
2174 goto make_err_class
;
2178 ident
= OBJC_TYPE_NAME (TREE_TYPE (type
));
2181 /* If this class was already referenced, then it will be output during
2182 meta-data emission, so we don't need to do it here. */
2183 decl
= get_objc_string_decl (ident
, class_names
);
2184 eh_id
= add_objc_string (ident
, class_names
);
2187 /* Not found ... so we need to build it - from the freshly-entered id. */
2188 decl
= get_objc_string_decl (ident
, class_names
);
2189 str
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2190 IDENTIFIER_POINTER (ident
));
2191 /* We have to finalize this var here, because this might be called after
2192 all the other metadata strings have been emitted. */
2193 finish_var_decl (decl
, str
);
2199 objc_eh_personality (void)
2201 if (!objc_eh_personality_decl
)
2203 objc_eh_personality_decl
= build_personality_function ("gnu_objc");
2205 objc_eh_personality_decl
= build_personality_function ("gxx");
2207 return objc_eh_personality_decl
;
2210 /* -- interfaces --- */
2213 build_throw_stmt (location_t loc
, tree throw_expr
, bool rethrown ATTRIBUTE_UNUSED
)
2216 vec
<tree
, va_gc
> *parms
;
2217 vec_alloc (parms
, 1);
2218 /* A throw is just a call to the runtime throw function with the
2219 object as a parameter. */
2220 parms
->quick_push (throw_expr
);
2221 t
= build_function_call_vec (loc
, vNULL
, objc_exception_throw_decl
, parms
,
2224 return add_stmt (t
);
2227 /* Build __builtin_eh_pointer. */
2230 objc_build_exc_ptr (struct objc_try_context
**x ATTRIBUTE_UNUSED
)
2233 t
= builtin_decl_explicit (BUILT_IN_EH_POINTER
);
2234 t
= build_call_expr (t
, 1, integer_zero_node
);
2235 return fold_convert (objc_object_type
, t
);
2239 begin_catch (struct objc_try_context
**cur_try_context
, tree type
,
2240 tree decl
, tree compound
, bool ellipsis ATTRIBUTE_UNUSED
)
2243 /* Record the data for the catch in the try context so that we can
2244 finalize it later. */
2246 t
= build_stmt (input_location
, CATCH_EXPR
, NULL
, compound
);
2248 t
= build_stmt (input_location
, CATCH_EXPR
, type
, compound
);
2249 (*cur_try_context
)->current_catch
= t
;
2251 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2252 t
= objc_build_exc_ptr (cur_try_context
);
2253 t
= convert (TREE_TYPE (decl
), t
);
2254 return build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
2258 finish_catch (struct objc_try_context
**cur_try_context
, tree current_catch
)
2260 append_to_statement_list (current_catch
, &((*cur_try_context
)->catch_list
));
2264 finish_try_stmt (struct objc_try_context
**cur_try_context
)
2266 struct objc_try_context
*c
= *cur_try_context
;
2267 tree stmt
= c
->try_body
;
2269 stmt
= build_stmt (c
->try_locus
, TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
2270 if (c
->finally_body
)
2271 stmt
= build_stmt (c
->try_locus
, TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
2275 #include "gt-objc-objc-gnu-runtime-abi-01.h"