1 /* GNU Runtime ABI version 8
2 Copyright (C) 2011-2017 Free Software Foundation, Inc.
3 Contributed by Iain Sandoe (split from objc-act.c)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
26 #include "stringpool.h"
30 #include "cp/cp-tree.h"
36 #include "langhooks.h"
37 #include "c-family/c-objc.h"
40 /* When building Objective-C++, we are not linking against the C front-end
41 and so need to replicate the C tree-construction functions in some way. */
43 #define OBJCP_REMAP_FUNCTIONS
44 #include "objcp-decl.h"
48 #include "tree-iterator.h"
50 #include "objc-runtime-hooks.h"
51 #include "objc-runtime-shared-support.h"
52 #include "objc-encoding.h"
54 /* GNU runtime private definitions. */
55 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
57 #define TAG_GETCLASS "objc_get_class"
58 #define TAG_GETMETACLASS "objc_get_meta_class"
60 #define TAG_MSGSEND "objc_msg_lookup"
61 #define TAG_MSGSENDSUPER "objc_msg_lookup_super"
63 /* GNU-specific tags. */
65 #define TAG_EXECCLASS "__objc_exec_class"
66 #define TAG_GNUINIT "__objc_gnu_init"
68 /* The version identifies which language generation and runtime
69 the module (file) was compiled for, and is recorded in the
71 #define OBJC_VERSION 8
73 #define PROTOCOL_VERSION 2
75 /* This macro provides a method of removing ambiguity between runtimes
76 when LTO is in use on targets supporting multiple runtimes.
78 For example, at present, any target that includes an implementation of
79 the NeXT runtime needs to place Objective-C meta-data into specific
80 named sections. This should _not_ be done for the GNU runtime, and the
81 following macro is used to attach Objective-C private attributes that may
82 be used to identify the runtime for which the meta-data are intended. */
84 #define OBJCMETA(DECL,VERS,KIND) \
86 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
88 static void gnu_runtime_01_initialize (void);
90 static void build_selector_template (void);
92 static tree
gnu_runtime_abi_01_super_superclassfield_id (void);
94 static tree
gnu_runtime_abi_01_class_decl (tree
);
95 static tree
gnu_runtime_abi_01_metaclass_decl (tree
);
96 static tree
gnu_runtime_abi_01_category_decl (tree
);
97 static tree
gnu_runtime_abi_01_protocol_decl (tree
);
98 static tree
gnu_runtime_abi_01_string_decl (tree
, const char *, string_section
);
100 static tree
gnu_runtime_abi_01_get_class_reference (tree
);
101 static tree
gnu_runtime_abi_01_build_typed_selector_reference (location_t
, tree
,
103 static tree
gnu_runtime_abi_01_get_protocol_reference (location_t
, tree
);
104 static tree
gnu_runtime_abi_01_build_ivar_ref (location_t
, tree
, tree
);
105 static tree
gnu_runtime_abi_01_get_class_super_ref (location_t
, struct imp_entry
*, bool);
106 static tree
gnu_runtime_abi_01_get_category_super_ref (location_t
, struct imp_entry
*, bool);
108 static tree
gnu_runtime_abi_01_receiver_is_class_object (tree
);
109 static void gnu_runtime_abi_01_get_arg_type_list_base (vec
<tree
, va_gc
> **,
111 static tree
gnu_runtime_abi_01_build_objc_method_call (location_t
, tree
, tree
,
112 tree
, tree
, tree
, int);
114 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
115 static tree
gnu_runtime_abi_01_build_const_string_constructor (location_t
, tree
,int);
117 static void objc_generate_v1_gnu_metadata (void);
119 static tree
objc_eh_runtime_type (tree type
);
120 static tree
objc_eh_personality (void);
121 static tree
objc_build_exc_ptr (struct objc_try_context
**);
122 static tree
build_throw_stmt (location_t
, tree
, bool);
123 static tree
begin_catch (struct objc_try_context
**, tree
, tree
, tree
, bool);
124 static void finish_catch (struct objc_try_context
**, tree
);
125 static tree
finish_try_stmt (struct objc_try_context
**);
128 objc_gnu_runtime_abi_01_init (objc_runtime_hooks
*rthooks
)
130 /* GNU runtime does not need the compiler to change code in order to do GC. */
133 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
137 /* Although I guess we could, we don't currently support SJLJ exceptions for the
139 if (flag_objc_sjlj_exceptions
)
141 inform (UNKNOWN_LOCATION
, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
142 flag_objc_sjlj_exceptions
= 0;
145 /* TODO: Complain if -fobjc-abi-version=N was used. */
147 /* TODO: Complain if -fobj-nilcheck was used. */
149 rthooks
->initialize
= gnu_runtime_01_initialize
;
150 rthooks
->default_constant_string_class_name
= DEF_CONSTANT_STRING_CLASS_NAME
;
151 rthooks
->tag_getclass
= TAG_GETCLASS
;
152 rthooks
->super_superclassfield_ident
= gnu_runtime_abi_01_super_superclassfield_id
;
154 rthooks
->class_decl
= gnu_runtime_abi_01_class_decl
;
155 rthooks
->metaclass_decl
= gnu_runtime_abi_01_metaclass_decl
;
156 rthooks
->category_decl
= gnu_runtime_abi_01_category_decl
;
157 rthooks
->protocol_decl
= gnu_runtime_abi_01_protocol_decl
;
158 rthooks
->string_decl
= gnu_runtime_abi_01_string_decl
;
160 rthooks
->get_class_reference
= gnu_runtime_abi_01_get_class_reference
;
161 rthooks
->build_selector_reference
= gnu_runtime_abi_01_build_typed_selector_reference
;
162 rthooks
->get_protocol_reference
= gnu_runtime_abi_01_get_protocol_reference
;
163 rthooks
->build_ivar_reference
= gnu_runtime_abi_01_build_ivar_ref
;
164 rthooks
->get_class_super_ref
= gnu_runtime_abi_01_get_class_super_ref
;
165 rthooks
->get_category_super_ref
= gnu_runtime_abi_01_get_category_super_ref
;
167 rthooks
->receiver_is_class_object
= gnu_runtime_abi_01_receiver_is_class_object
;
168 rthooks
->get_arg_type_list_base
= gnu_runtime_abi_01_get_arg_type_list_base
;
169 rthooks
->build_objc_method_call
= gnu_runtime_abi_01_build_objc_method_call
;
171 rthooks
->setup_const_string_class_decl
=
172 gnu_runtime_abi_01_setup_const_string_class_decl
;
173 rthooks
->build_const_string_constructor
=
174 gnu_runtime_abi_01_build_const_string_constructor
;
176 rthooks
->build_throw_stmt
= build_throw_stmt
;
177 rthooks
->build_exc_ptr
= objc_build_exc_ptr
;
178 rthooks
->begin_catch
= begin_catch
;
179 rthooks
->finish_catch
= finish_catch
;
180 rthooks
->finish_try_stmt
= finish_try_stmt
;
182 rthooks
->generate_metadata
= objc_generate_v1_gnu_metadata
;
186 static void build_selector_table_decl (void);
187 static void build_class_template (void);
188 static void build_category_template (void);
189 static void build_protocol_template (void);
191 static GTY(()) tree objc_meta
;
192 static GTY(()) tree meta_base
;
194 static void gnu_runtime_01_initialize (void)
196 tree type
, ftype
, IMP_type
;
198 /* We do not need to mark GNU ObjC metadata for different sections,
199 however, we do need to make sure that it is not mistaken for NeXT
201 objc_meta
= get_identifier ("OBJC1METG");
202 meta_base
= get_identifier ("NONE");
204 /* Declare type of selector-objects that represent an operation name. */
205 /* `const struct objc_selector *' */
206 type
= xref_tag (RECORD_TYPE
, get_identifier (TAG_SELECTOR
));
207 type
= build_qualified_type (type
, TYPE_QUAL_CONST
);
208 objc_selector_type
= build_pointer_type (type
);
210 /* typedef id (*IMP)(id, SEL, ...); */
211 ftype
= build_varargs_function_type_list (objc_object_type
,
216 IMP_type
= build_pointer_type (ftype
);
218 build_class_template ();
219 build_super_template ();
220 build_protocol_template ();
221 build_category_template ();
223 /* GNU runtime messenger entry points. */
224 /* TREE_NOTHROW is cleared for the message-sending functions,
225 because the function that gets called can throw in Obj-C++, or
226 could itself call something that can throw even in Obj-C. */
228 /* IMP objc_msg_lookup (id, SEL); */
229 type
= build_function_type_list (IMP_type
,
234 umsg_decl
= add_builtin_function (TAG_MSGSEND
,
235 type
, 0, NOT_BUILT_IN
,
237 TREE_NOTHROW (umsg_decl
) = 0;
239 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
240 type
= build_function_type_list (IMP_type
,
245 umsg_super_decl
= add_builtin_function (TAG_MSGSENDSUPER
,
246 type
, 0, NOT_BUILT_IN
,
248 TREE_NOTHROW (umsg_super_decl
) = 0;
250 /* The following GNU runtime entry point is called to initialize
253 __objc_exec_class (void *); */
254 type
= build_function_type_list (void_type_node
,
258 execclass_decl
= add_builtin_function (TAG_EXECCLASS
,
259 type
, 0, NOT_BUILT_IN
,
262 type
= build_function_type_list (objc_object_type
,
263 const_string_type_node
,
266 /* id objc_getClass (const char *); */
268 = add_builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
271 /* id objc_getMetaClass (const char *); */
272 objc_get_meta_class_decl
= add_builtin_function (TAG_GETMETACLASS
, type
,
273 0, NOT_BUILT_IN
, NULL
,
276 /* static SEL _OBJC_SELECTOR_TABLE[]; */
277 build_selector_table_decl ();
279 /* Stuff for properties.
280 The codegen relies on this being NULL for GNU. */
281 objc_copyStruct_decl
= NULL_TREE
;
283 /* This is the type of all of the following functions
284 bjc_getPropertyStruct() and objc_setPropertyStruct(). */
285 type
= build_function_type_list (void_type_node
,
293 /* Declare the following function:
295 objc_getPropertyStruct (void *destination, const void *source,
296 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
297 objc_getPropertyStruct_decl
= add_builtin_function ("objc_getPropertyStruct",
298 type
, 0, NOT_BUILT_IN
,
300 TREE_NOTHROW (objc_getPropertyStruct_decl
) = 0;
301 /* Declare the following function:
303 objc_setPropertyStruct (void *destination, const void *source,
304 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
305 objc_setPropertyStruct_decl
= add_builtin_function ("objc_setPropertyStruct",
306 type
, 0, NOT_BUILT_IN
,
308 TREE_NOTHROW (objc_setPropertyStruct_decl
) = 0;
310 using_eh_for_cleanups ();
311 lang_hooks
.eh_runtime_type
= objc_eh_runtime_type
;
312 lang_hooks
.eh_personality
= objc_eh_personality
;
315 /* --- templates --- */
316 /* struct _objc_selector {
322 build_selector_template (void)
324 tree decls
, *chain
= NULL
;
326 objc_selector_template
= objc_start_struct (get_identifier (UTAG_SELECTOR
));
329 decls
= add_field_decl (objc_selector_type
, "sel_id", &chain
);
331 /* char *sel_type; */
332 add_field_decl (string_type_node
, "sel_type", &chain
);
334 objc_finish_struct (objc_selector_template
, decls
);
337 /* struct _objc_class {
338 struct _objc_class *isa;
339 struct _objc_class *super_class;
344 struct _objc_ivar_list *ivars;
345 struct _objc_method_list *methods;
346 struct sarray *dtable;
347 struct _objc_class *subclass_list;
348 struct _objc_class *sibling_class;
349 struct _objc_protocol_list *protocols;
350 void *gc_object_type;
354 build_class_template (void)
356 tree ptype
, decls
, *chain
= NULL
;
358 objc_class_template
= objc_start_struct (get_identifier (UTAG_CLASS
));
360 /* struct _objc_class *isa; */
361 decls
= add_field_decl (build_pointer_type (objc_class_template
),
364 /* struct _objc_class *super_class; */
365 add_field_decl (build_pointer_type (objc_class_template
),
366 "super_class", &chain
);
369 add_field_decl (string_type_node
, "name", &chain
);
372 add_field_decl (long_integer_type_node
, "version", &chain
);
375 add_field_decl (long_integer_type_node
, "info", &chain
);
377 /* long instance_size; */
378 add_field_decl (long_integer_type_node
, "instance_size", &chain
);
380 /* struct _objc_ivar_list *ivars; */
381 add_field_decl (objc_ivar_list_ptr
,"ivars", &chain
);
383 /* struct _objc_method_list *methods; */
384 add_field_decl (objc_method_list_ptr
, "methods", &chain
);
386 /* struct sarray *dtable; */
387 ptype
= build_pointer_type(xref_tag (RECORD_TYPE
,
388 get_identifier ("sarray")));
389 add_field_decl (ptype
, "dtable", &chain
);
391 /* struct objc_class *subclass_list; */
392 ptype
= build_pointer_type (objc_class_template
);
393 add_field_decl (ptype
, "subclass_list", &chain
);
395 /* struct objc_class *sibling_class; */
396 ptype
= build_pointer_type (objc_class_template
);
397 add_field_decl (ptype
, "sibling_class", &chain
);
399 /* struct _objc_protocol **protocol_list; */
400 ptype
= build_pointer_type (build_pointer_type
401 (xref_tag (RECORD_TYPE
,
402 get_identifier (UTAG_PROTOCOL
))));
403 add_field_decl (ptype
, "protocol_list", &chain
);
405 /* void *gc_object_type; */
406 add_field_decl (build_pointer_type (void_type_node
),
407 "gc_object_type", &chain
);
409 objc_finish_struct (objc_class_template
, decls
);
412 /* struct _objc_category {
415 struct _objc_method_list *instance_methods;
416 struct _objc_method_list *class_methods;
417 struct _objc_protocol_list *protocols;
421 build_category_template (void)
423 tree ptype
, decls
, *chain
= NULL
;
425 objc_category_template
= objc_start_struct (get_identifier (UTAG_CATEGORY
));
427 /* char *category_name; */
428 decls
= add_field_decl (string_type_node
, "category_name", &chain
);
430 /* char *class_name; */
431 add_field_decl (string_type_node
, "class_name", &chain
);
433 /* struct _objc_method_list *instance_methods; */
434 add_field_decl (objc_method_list_ptr
, "instance_methods", &chain
);
436 /* struct _objc_method_list *class_methods; */
437 add_field_decl (objc_method_list_ptr
, "class_methods", &chain
);
439 /* struct _objc_protocol **protocol_list; */
440 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
441 add_field_decl (ptype
, "protocol_list", &chain
);
443 objc_finish_struct (objc_category_template
, decls
);
446 /* struct _objc_protocol {
447 struct _objc_class *isa;
449 struct _objc_protocol **protocol_list;
450 struct _objc__method_prototype_list *instance_methods;
451 struct _objc__method_prototype_list *class_methods;
455 build_protocol_template (void)
457 tree ptype
, decls
, *chain
= NULL
;
459 objc_protocol_template
= objc_start_struct (get_identifier (UTAG_PROTOCOL
));
461 /* struct _objc_class *isa; */
462 ptype
= build_pointer_type (xref_tag (RECORD_TYPE
,
463 get_identifier (UTAG_CLASS
)));
464 decls
= add_field_decl (ptype
, "isa", &chain
);
466 /* char *protocol_name; */
467 add_field_decl (string_type_node
, "protocol_name", &chain
);
469 /* struct _objc_protocol **protocol_list; */
470 ptype
= build_pointer_type (build_pointer_type (objc_protocol_template
));
471 add_field_decl (ptype
, "protocol_list", &chain
);
473 /* struct _objc__method_prototype_list *instance_methods; */
474 add_field_decl (objc_method_proto_list_ptr
, "instance_methods", &chain
);
476 /* struct _objc__method_prototype_list *class_methods; */
477 add_field_decl (objc_method_proto_list_ptr
, "class_methods", &chain
);
479 objc_finish_struct (objc_protocol_template
, decls
);
482 /* --- names, decls + identifiers --- */
485 build_selector_table_decl (void)
489 build_selector_template ();
490 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
492 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
493 /* Squash `defined but not used' warning check_global_declaration. */
494 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
495 OBJCMETA (UOBJC_SELECTOR_TABLE_decl
, objc_meta
, meta_base
);
500 gnu_runtime_abi_01_super_superclassfield_id (void)
502 if (!super_superclassfield_id
)
503 super_superclassfield_id
= get_identifier ("super_class");
504 return super_superclassfield_id
;
509 gnu_runtime_abi_01_class_decl (tree klass
)
513 snprintf (buf
, BUFSIZE
, "_OBJC_Class_%s",
514 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
515 decl
= start_var_decl (objc_class_template
, buf
);
516 OBJCMETA (decl
, objc_meta
, meta_base
);
521 gnu_runtime_abi_01_metaclass_decl (tree klass
)
525 snprintf (buf
, BUFSIZE
, "_OBJC_MetaClass_%s",
526 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
527 decl
= start_var_decl (objc_class_template
, buf
);
528 OBJCMETA (decl
, objc_meta
, meta_base
);
533 gnu_runtime_abi_01_category_decl (tree klass
)
537 snprintf (buf
, BUFSIZE
, "_OBJC_Category_%s_on_%s",
538 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass
)),
539 IDENTIFIER_POINTER (CLASS_NAME (klass
)));
540 decl
= start_var_decl (objc_category_template
, buf
);
541 OBJCMETA (decl
, objc_meta
, meta_base
);
546 gnu_runtime_abi_01_protocol_decl (tree p
)
551 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
552 snprintf (buf
, BUFSIZE
, "_OBJC_Protocol_%s",
553 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
554 decl
= start_var_decl (objc_protocol_template
, buf
);
555 OBJCMETA (decl
, objc_meta
, meta_base
);
560 gnu_runtime_abi_01_string_decl (tree type
, const char *name
,
561 string_section where ATTRIBUTE_UNUSED
)
563 tree decl
= start_var_decl (type
, name
);
564 OBJCMETA (decl
, objc_meta
, meta_base
);
571 gnu_runtime_abi_01_get_class_reference (tree ident
)
575 add_class_reference (ident
);
577 params
= build_tree_list (NULL_TREE
, my_build_string_pointer
578 (IDENTIFIER_LENGTH (ident
) + 1,
579 IDENTIFIER_POINTER (ident
)));
581 return build_function_call (input_location
, objc_get_class_decl
, params
);
584 /* Used by build_function_type_for_method. Append the types for
585 receiver & _cmd at the start of a method argument list to ARGTYPES.
586 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
587 trying to define a method or call one. SUPERFLAG says this is for a
588 send to super. METH may be NULL, in the case that there is no
592 gnu_runtime_abi_01_get_arg_type_list_base (vec
<tree
, va_gc
> **argtypes
,
593 tree meth
, int context
,
594 int superflag ATTRIBUTE_UNUSED
)
598 if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
599 receiver_type
= objc_instance_type
;
601 receiver_type
= objc_object_type
;
603 vec_safe_push (*argtypes
, receiver_type
);
604 /* Selector type - will eventually change to `int'. */
605 vec_safe_push (*argtypes
, objc_selector_type
);
608 /* Unused for GNU runtime. */
610 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED
)
615 /* sel_ref_chain is a list whose "value" fields will be instances of
616 identifier_node that represent the selector. LOC is the location of
620 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc
, tree ident
,
623 tree
*chain
= &sel_ref_chain
;
629 /* When we do a lookup for @selector () we have no idea of the
630 prototype - so match the first we find. */
631 if (TREE_VALUE (*chain
) == ident
632 && (!prototype
|| TREE_PURPOSE (*chain
) == prototype
))
633 goto return_at_index
;
636 chain
= &TREE_CHAIN (*chain
);
639 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
641 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
642 (b) provide better diagnostics for the first time an undefined
645 expr
= build_unary_op (loc
, ADDR_EXPR
,
646 build_array_ref (loc
, UOBJC_SELECTOR_TABLE_decl
,
647 build_int_cst (NULL_TREE
, index
)),
649 return convert (objc_selector_type
, expr
);
652 /* Build a tree expression to send OBJECT the operation SELECTOR,
653 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
654 assuming the method has prototype METHOD_PROTOTYPE.
655 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
656 LOC is the location of the expression to build.
657 Use METHOD_PARAMS as list of args to pass to the method.
658 If SUPER_FLAG is nonzero, we look up the superclass's method. */
661 build_objc_method_call (location_t loc
, int super_flag
, tree method_prototype
,
662 tree lookup_object
, tree selector
,
665 tree sender
= (super_flag
? umsg_super_decl
666 : (flag_objc_direct_dispatch
? umsg_fast_decl
668 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
669 vec
<tree
, va_gc
> *parms
;
670 vec
<tree
, va_gc
> *tv
;
671 unsigned nparm
= (method_params
? list_length (method_params
) : 0);
673 /* If a prototype for the method to be called exists, then cast
674 the sender's return type and arguments to match that of the method.
675 Otherwise, leave sender as is. */
678 ? TREE_VALUE (TREE_TYPE (method_prototype
))
681 = build_function_type_for_method (ret_type
, method_prototype
,
682 METHOD_REF
, super_flag
);
686 if (method_prototype
&& METHOD_TYPE_ATTRIBUTES (method_prototype
))
687 ftype
= build_type_attribute_variant (ftype
,
688 METHOD_TYPE_ATTRIBUTES
691 sender_cast
= build_pointer_type (ftype
);
693 lookup_object
= build_c_cast (loc
, rcv_p
, lookup_object
);
695 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
696 lookup_object
= save_expr (lookup_object
);
698 /* Param list + 2 slots for object and selector. */
699 vec_alloc (parms
, nparm
+ 2);
702 /* First, call the lookup function to get a pointer to the method,
703 then cast the pointer, then call it with the method arguments. */
704 tv
->quick_push (lookup_object
);
705 tv
->quick_push (selector
);
706 method
= build_function_call_vec (loc
, vNULL
, sender
, tv
, NULL
);
709 /* Pass the appropriate object to the method. */
710 parms
->quick_push ((super_flag
? self_decl
: lookup_object
));
712 /* Pass the selector to the method. */
713 parms
->quick_push (selector
);
714 /* Now append the remainder of the parms. */
716 for (; method_params
; method_params
= TREE_CHAIN (method_params
))
717 parms
->quick_push (TREE_VALUE (method_params
));
719 /* Build an obj_type_ref, with the correct cast for the method call. */
720 t
= build3 (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
721 t
= build_function_call_vec (loc
, vNULL
, t
, parms
, NULL
);
727 gnu_runtime_abi_01_build_objc_method_call (location_t loc
,
728 tree method_prototype
,
730 tree rtype ATTRIBUTE_UNUSED
,
733 int super ATTRIBUTE_UNUSED
)
736 gnu_runtime_abi_01_build_typed_selector_reference (loc
,
740 return build_objc_method_call (loc
, super
, method_prototype
, receiver
,
741 selector
, method_params
);
745 gnu_runtime_abi_01_get_protocol_reference (location_t loc
, tree p
)
747 tree expr
, protocol_struct_type
, *chain
;
748 if (!PROTOCOL_FORWARD_DECL (p
))
749 PROTOCOL_FORWARD_DECL (p
) = gnu_runtime_abi_01_protocol_decl (p
);
751 expr
= build_unary_op (loc
, ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
753 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
754 if we have it, rather than converting it here. */
755 expr
= convert (objc_protocol_type
, expr
);
757 /* The @protocol() expression is being compiled into a pointer to a
758 statically allocated instance of the Protocol class. To become
759 usable at runtime, the 'isa' pointer of the instance need to be
760 fixed up at runtime by the runtime library, to point to the
761 actual 'Protocol' class. */
763 /* For the GNU runtime, put the static Protocol instance in the list
764 of statically allocated instances, so that we make sure that its
765 'isa' pointer is fixed up at runtime by the GNU runtime library
766 to point to the Protocol class (at runtime, when loading the
767 module, the GNU runtime library loops on the statically allocated
768 instances (as found in the defs field in objc_symtab) and fixups
769 all the 'isa' pointers of those objects). */
771 /* This type is a struct containing the fields of a Protocol
772 object. (Cfr. objc_protocol_type instead is the type of a pointer
773 to such a struct). */
774 protocol_struct_type
= xref_tag (RECORD_TYPE
,
775 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
777 /* Look for the list of Protocol statically allocated instances
778 to fixup at runtime. Create a new list to hold Protocol
779 statically allocated instances, if the list is not found. At
780 present there is only another list, holding NSConstantString
781 static instances to be fixed up at runtime. */
783 for (chain
= &objc_static_instances
;
784 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
785 chain
= &TREE_CHAIN (*chain
));
789 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
790 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
794 /* Add this statically allocated instance to the Protocol list. */
795 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
796 PROTOCOL_FORWARD_DECL (p
),
797 TREE_PURPOSE (*chain
));
801 /* For ABI 8 an IVAR is just a fixed offset in the class struct. */
804 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED
,
807 return objc_build_component_ref (base
, id
);
810 /* We build super class references as we need them (but keep them once
811 built for the sake of efficiency). */
814 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED
,
815 struct imp_entry
*imp
, bool inst_meth
)
821 objc_build_component_ref (imp
->class_decl
,
822 get_identifier ("super_class"));
823 return ucls_super_ref
;
827 if (!uucls_super_ref
)
829 objc_build_component_ref (imp
->meta_decl
,
830 get_identifier ("super_class"));
831 return uucls_super_ref
;
836 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED
,
837 struct imp_entry
*imp
, bool inst_meth
)
839 tree super_name
= CLASS_SUPER_NAME (imp
->imp_template
);
842 add_class_reference (super_name
);
843 super_class
= (inst_meth
? objc_get_class_decl
: objc_get_meta_class_decl
);
844 super_name
= my_build_string_pointer (IDENTIFIER_LENGTH (super_name
) + 1,
845 IDENTIFIER_POINTER (super_name
));
846 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
847 return build_function_call (input_location
,
849 build_tree_list (NULL_TREE
, super_name
));
853 gnu_runtime_abi_01_setup_const_string_class_decl (void)
855 /* Do nothing, and create no error. */
859 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
861 static GTY(()) int num_static_inst
;
864 objc_add_static_instance (tree constructor
, tree class_decl
)
869 /* Find the list of static instances for the CLASS_DECL. Create one if
871 for (chain
= &objc_static_instances
;
872 *chain
&& TREE_VALUE (*chain
) != class_decl
;
873 chain
= &TREE_CHAIN (*chain
));
876 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
877 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
880 snprintf (buf
, BUFSIZE
, "_OBJC_INSTANCE_%d", num_static_inst
++);
881 decl
= build_decl (input_location
,
882 VAR_DECL
, get_identifier (buf
), class_decl
);
883 TREE_STATIC (decl
) = 1;
884 DECL_ARTIFICIAL (decl
) = 1;
885 TREE_USED (decl
) = 1;
886 DECL_INITIAL (decl
) = constructor
;
887 DECL_CONTEXT (decl
) = NULL
;
888 OBJCMETA (decl
, objc_meta
, meta_base
);
890 /* We may be writing something else just now.
891 Postpone till end of input. */
892 DECL_DEFER_OUTPUT (decl
) = 1;
893 lang_hooks
.decls
.pushdecl (decl
);
894 rest_of_decl_compilation (decl
, 1, 0);
896 /* Add the DECL to the head of this CLASS' list. */
897 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
903 gnu_runtime_abi_01_build_const_string_constructor (location_t loc
, tree string
,
906 tree constructor
, fields
;
907 vec
<constructor_elt
, va_gc
> *v
= NULL
;
909 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
910 fields
= TYPE_FIELDS (internal_const_str_type
);
911 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, 0));
913 fields
= DECL_CHAIN (fields
);
914 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_unary_op (loc
,
915 ADDR_EXPR
, string
, 1));
917 fields
= DECL_CHAIN (fields
);
918 CONSTRUCTOR_APPEND_ELT (v
, fields
, build_int_cst (NULL_TREE
, length
));
919 constructor
= objc_build_constructor (internal_const_str_type
, v
);
921 constructor
= objc_add_static_instance (constructor
, constant_string_type
);
925 /* --- metadata - module initializer --- */
927 /* The GNU runtime requires us to provide a static initializer function
930 static void __objc_gnu_init (void) {
931 __objc_exec_class (&L_OBJC_MODULES);
936 build_module_initializer_routine (void)
941 push_lang_context (lang_name_c
); /* extern "C" */
944 objc_push_parm (build_decl (input_location
,
945 PARM_DECL
, NULL_TREE
, void_type_node
));
947 objc_start_function (get_identifier (TAG_GNUINIT
),
948 build_function_type_list (void_type_node
, NULL_TREE
),
949 NULL_TREE
, NULL_TREE
);
951 objc_start_function (get_identifier (TAG_GNUINIT
),
952 build_function_type_list (void_type_node
, NULL_TREE
),
953 NULL_TREE
, objc_get_parm_info (0, NULL_TREE
));
955 body
= c_begin_compound_stmt (true);
956 add_stmt (build_function_call
961 build_unary_op (input_location
, ADDR_EXPR
,
962 UOBJC_MODULES_decl
, 0))));
963 add_stmt (c_end_compound_stmt (input_location
, body
, true));
965 TREE_PUBLIC (current_function_decl
) = 0;
968 /* For Objective-C++, we will need to call __objc_gnu_init
969 from objc_generate_static_init_call() below. */
970 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
973 GNU_INIT_decl
= current_function_decl
;
982 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
983 to be called by the module initializer routine. */
986 objc_static_init_needed_p (void)
988 return (GNU_INIT_decl
!= NULL_TREE
);
991 /* Generate a call to the __objc_gnu_init initializer function. */
994 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
996 add_stmt (build_stmt (input_location
, EXPR_STMT
,
997 build_function_call (input_location
,
998 GNU_INIT_decl
, NULL_TREE
)));
1002 #endif /* OBJCPLUS */
1004 /* --- Output GNU Meta-data --- */
1007 generate_classref_translation_entry (tree chain
)
1009 tree expr
, decl
, type
;
1011 decl
= TREE_PURPOSE (chain
);
1012 type
= TREE_TYPE (decl
);
1014 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
1015 expr
= convert (type
, expr
); /* cast! */
1017 /* This is a class reference. It is re-written by the runtime,
1018 but will be optimized away unless we force it. */
1019 DECL_PRESERVE_P (decl
) = 1;
1020 OBJCMETA (decl
, objc_meta
, meta_base
);
1021 finish_var_decl (decl
, expr
);
1027 handle_impent (struct imp_entry
*impent
)
1031 /* objc_implementation_context = impent->imp_context;
1032 implementation_template = impent->imp_template;*/
1034 switch (TREE_CODE (impent
->imp_context
))
1036 case CLASS_IMPLEMENTATION_TYPE
:
1038 const char *const class_name
=
1039 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
1041 string
= (char *) alloca (strlen (class_name
) + 30);
1043 sprintf (string
, "__objc_class_name_%s", class_name
);
1046 case CATEGORY_IMPLEMENTATION_TYPE
:
1048 const char *const class_name
=
1049 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
1050 const char *const class_super_name
=
1051 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
1053 string
= (char *) alloca (strlen (class_name
)
1054 + strlen (class_super_name
) + 30);
1056 /* Do the same for categories. Even though no references to
1057 these symbols are generated automatically by the compiler,
1058 it gives you a handle to pull them into an archive by
1060 sprintf (string
, "*__objc_category_name_%s_%s", class_name
, class_super_name
);
1070 init
= integer_zero_node
;
1071 decl
= build_decl (input_location
,
1072 VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
1073 TREE_PUBLIC (decl
) = 1;
1074 TREE_READONLY (decl
) = 1;
1075 TREE_USED (decl
) = 1;
1076 TREE_CONSTANT (decl
) = 1;
1077 DECL_CONTEXT (decl
) = NULL_TREE
;
1078 DECL_ARTIFICIAL (decl
) = 1;
1079 TREE_STATIC (decl
) = 1;
1080 DECL_INITIAL (decl
) = error_mark_node
; /* A real initializer is coming... */
1081 /* We must force the reference. */
1082 DECL_PRESERVE_P (decl
) = 1;
1084 finish_var_decl(decl
, init
) ;
1089 build_protocol_initializer (tree type
, tree protocol_name
, tree protocol_list
,
1090 tree inst_methods
, tree class_methods
)
1094 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1096 /* TODO: pass the loc in or find it from args. */
1097 loc
= input_location
;
1098 ttyp
= build_pointer_type (xref_tag (RECORD_TYPE
,
1099 get_identifier (UTAG_CLASS
)));
1100 /* Filling the "isa" in with a version allows the runtime system to
1102 expr
= build_int_cst (ttyp
, PROTOCOL_VERSION
);
1104 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1106 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_name
);
1107 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, protocol_list
);
1109 ttyp
= objc_method_proto_list_ptr
;
1111 expr
= convert (ttyp
, build_unary_op (loc
, ADDR_EXPR
, inst_methods
, 0));
1113 expr
= convert (ttyp
, null_pointer_node
);
1114 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1117 expr
= convert (ttyp
, build_unary_op (loc
, ADDR_EXPR
, class_methods
, 0));
1119 expr
= convert (ttyp
, null_pointer_node
);
1120 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1122 return objc_build_constructor (type
, inits
);
1126 generate_protocol_list (tree i_or_p
, tree klass_ctxt
)
1128 tree array_type
, ptype
, refs_decl
, lproto
, e
, plist
;
1129 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1133 switch (TREE_CODE (i_or_p
))
1135 case CLASS_INTERFACE_TYPE
:
1136 case CATEGORY_INTERFACE_TYPE
:
1137 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
1139 case PROTOCOL_INTERFACE_TYPE
:
1140 plist
= PROTOCOL_LIST (i_or_p
);
1147 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
1148 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
1149 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
1152 /* Build initializer. */
1153 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1154 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
1155 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
1157 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
1159 tree pval
= TREE_VALUE (lproto
);
1161 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
1162 && PROTOCOL_FORWARD_DECL (pval
))
1164 tree fwref
= PROTOCOL_FORWARD_DECL (pval
);
1165 location_t loc
= DECL_SOURCE_LOCATION (fwref
) ;
1166 e
= build_unary_op (loc
, ADDR_EXPR
, fwref
, 0);
1167 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, e
);
1171 /* static struct objc_protocol *refs[n]; */
1173 switch (TREE_CODE (i_or_p
))
1175 case PROTOCOL_INTERFACE_TYPE
:
1176 snprintf (buf
, BUFSIZE
, "_OBJC_ProtocolRefs_%s",
1177 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p
)));
1179 case CLASS_INTERFACE_TYPE
:
1180 snprintf (buf
, BUFSIZE
, "_OBJC_ClassProtocols_%s",
1181 IDENTIFIER_POINTER (CLASS_NAME (i_or_p
)));
1183 case CATEGORY_INTERFACE_TYPE
:
1184 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryProtocols_%s_%s",
1185 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt
)),
1186 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt
)));
1192 ptype
= build_pointer_type (objc_protocol_template
);
1193 array_type
= build_sized_array_type (ptype
, size
+ 3);
1194 refs_decl
= start_var_decl (array_type
, buf
);
1195 OBJCMETA (refs_decl
, objc_meta
, meta_base
);
1196 finish_var_decl (refs_decl
,
1197 objc_build_constructor (TREE_TYPE (refs_decl
), v
));
1203 generate_v1_meth_descriptor_table (tree chain
, tree protocol
, const char *prefix
)
1205 tree method_list_template
, initlist
, decl
;
1207 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1210 if (!chain
|| !prefix
)
1213 if (!objc_method_prototype_template
)
1214 objc_method_prototype_template
= build_method_prototype_template ();
1216 size
= list_length (chain
);
1217 method_list_template
=
1218 build_method_prototype_list_template (objc_method_prototype_template
,
1220 snprintf (buf
, BUFSIZE
, "%s_%s", prefix
,
1221 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol
)));
1223 decl
= start_var_decl (method_list_template
, buf
);
1225 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
1227 build_descriptor_table_initializer (objc_method_prototype_template
,
1229 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, initlist
);
1230 OBJCMETA (decl
, objc_meta
, meta_base
);
1231 finish_var_decl (decl
, objc_build_constructor (method_list_template
, v
));
1235 /* For each protocol which was referenced either from a @protocol()
1236 expression, or because a class/category implements it (then a
1237 pointer to the protocol is stored in the struct describing the
1238 class/category), we create a statically allocated instance of the
1239 Protocol class. The code is written in such a way as to generate
1240 as few Protocol objects as possible; we generate a unique Protocol
1241 instance for each protocol, and we don't generate a Protocol
1242 instance if the protocol is never referenced (either from a
1243 @protocol() or from a class/category implementation). These
1244 statically allocated objects can be referred to via the static
1245 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1247 The statically allocated Protocol objects that we generate here
1248 need to be fixed up at runtime in order to be used: the 'isa'
1249 pointer of the objects need to be set up to point to the 'Protocol'
1250 class, as known at runtime.
1252 The GNU runtime fixes up all protocols before user code from the module
1253 is executed; it requires pointers to those symbols
1254 to be put in the objc_symtab (which is then passed as argument to
1255 the function __objc_exec_class() which the compiler sets up to be
1256 executed automatically when the module is loaded); setup of those
1257 Protocol objects happen in two ways in the GNU runtime: all
1258 Protocol objects referred to by a class or category implementation
1259 are fixed up when the class/category is loaded; all Protocol
1260 objects referred to by a @protocol() expression are added by the
1261 compiler to the list of statically allocated instances to fixup
1262 (the same list holding the statically allocated constant string
1263 objects). Because, as explained above, the compiler generates as
1264 few Protocol objects as possible, some Protocol object might end up
1265 being referenced multiple times when compiled with the GNU runtime,
1266 and end up being fixed up multiple times at runtime initialization.
1267 But that doesn't hurt, it's just a little inefficient. */
1270 generate_protocols (void)
1274 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
1276 /* If a protocol was directly referenced, pull in indirect references. */
1277 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
1278 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
1279 generate_protocol_references (PROTOCOL_LIST (p
));
1281 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
1283 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
1284 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
1286 /* If protocol wasn't referenced, don't generate any code. */
1287 decl
= PROTOCOL_FORWARD_DECL (p
);
1292 /* Make sure we link in the Protocol class. */
1293 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
1297 if (! METHOD_ENCODING (nst_methods
))
1299 encoding
= encode_method_prototype (nst_methods
);
1300 METHOD_ENCODING (nst_methods
) = encoding
;
1302 nst_methods
= DECL_CHAIN (nst_methods
);
1305 UOBJC_INSTANCE_METHODS_decl
=
1306 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p
), p
,
1307 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1311 if (! METHOD_ENCODING (cls_methods
))
1313 encoding
= encode_method_prototype (cls_methods
);
1314 METHOD_ENCODING (cls_methods
) = encoding
;
1317 cls_methods
= DECL_CHAIN (cls_methods
);
1320 UOBJC_CLASS_METHODS_decl
=
1321 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p
), p
,
1322 "_OBJC_PROTOCOL_CLASS_METHODS");
1323 /* generate_method_descriptors (p);*/
1325 if (PROTOCOL_LIST (p
))
1326 refs_decl
= generate_protocol_list (p
, NULL_TREE
);
1330 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1331 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
1334 refs_expr
= convert (build_pointer_type (build_pointer_type
1335 (objc_protocol_template
)),
1336 build_unary_op (input_location
,
1337 ADDR_EXPR
, refs_decl
, 0));
1339 refs_expr
= build_int_cst (NULL_TREE
, 0);
1341 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1342 by generate_method_descriptors, which is called above. */
1343 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
1344 protocol_name_expr
, refs_expr
,
1345 UOBJC_INSTANCE_METHODS_decl
,
1346 UOBJC_CLASS_METHODS_decl
);
1347 finish_var_decl (decl
, initlist
);
1352 generate_dispatch_table (tree chain
, const char *name
)
1354 tree decl
, method_list_template
, initlist
;
1355 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1356 int size
= list_length (chain
);
1358 if (!objc_method_template
)
1359 objc_method_template
= build_method_template ();
1361 method_list_template
= build_method_list_template (objc_method_template
,
1363 initlist
= build_dispatch_table_initializer (objc_method_template
, chain
);
1365 decl
= start_var_decl (method_list_template
, name
);
1367 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1368 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1369 build_int_cst (integer_type_node
, size
));
1370 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, initlist
);
1372 OBJCMETA (decl
, objc_meta
, meta_base
);
1373 finish_var_decl (decl
,
1374 objc_build_constructor (TREE_TYPE (decl
), v
));
1379 /* Init a category. */
1381 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
1382 tree inst_methods
, tree class_methods
,
1387 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1389 /* TODO: pass the loc in or find it from args. */
1390 /* TODO: pass the loc in or find it from args. */
1391 loc
= UNKNOWN_LOCATION
;
1392 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, cat_name
);
1393 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, class_name
);
1395 ltyp
= objc_method_list_ptr
;
1397 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, inst_methods
, 0));
1399 expr
= convert (ltyp
, null_pointer_node
);
1400 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1403 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, class_methods
, 0));
1405 expr
= convert (ltyp
, null_pointer_node
);
1406 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1408 /* protocol_list = */
1409 ltyp
= build_pointer_type (build_pointer_type (objc_protocol_template
));
1411 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
, protocol_list
, 0));
1413 expr
= convert (ltyp
, null_pointer_node
);
1414 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1416 return objc_build_constructor (type
, v
);
1419 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1422 generate_category (struct imp_entry
*impent
)
1424 tree initlist
, cat_name_expr
, class_name_expr
;
1425 tree protocol_decl
, category
, cat_decl
;
1426 tree inst_methods
= NULL_TREE
, class_methods
= NULL_TREE
;
1427 tree cat
= impent
->imp_context
;
1430 cat_decl
= impent
->class_decl
;
1432 add_class_reference (CLASS_NAME (cat
));
1433 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
1435 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
1437 category
= lookup_category (impent
->imp_template
, CLASS_SUPER_NAME (cat
));
1439 if (category
&& CLASS_PROTOCOL_LIST (category
))
1441 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
1442 protocol_decl
= generate_protocol_list (category
, cat
);
1447 if (CLASS_NST_METHODS (cat
))
1449 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryInstanceMethods_%s_%s",
1450 IDENTIFIER_POINTER (CLASS_NAME (cat
)),
1451 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat
)));
1452 inst_methods
= generate_dispatch_table (CLASS_NST_METHODS (cat
), buf
);
1455 if (CLASS_CLS_METHODS (cat
))
1457 snprintf (buf
, BUFSIZE
, "_OBJC_CategoryClassMethods_%s_%s",
1458 IDENTIFIER_POINTER (CLASS_NAME (cat
)),
1459 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat
)));
1460 class_methods
= generate_dispatch_table (CLASS_CLS_METHODS (cat
), buf
);
1463 initlist
= build_category_initializer (TREE_TYPE (cat_decl
),
1464 cat_name_expr
, class_name_expr
,
1465 inst_methods
, class_methods
,
1467 /* Finish and initialize the forward decl. */
1468 finish_var_decl (cat_decl
, initlist
);
1469 impent
->class_decl
= cat_decl
;
1472 /* struct _objc_class {
1473 struct objc_class *isa;
1474 struct objc_class *super_class;
1479 struct objc_ivar_list *ivars;
1480 struct objc_method_list *methods;
1481 struct sarray *dtable;
1482 struct objc_class *subclass_list;
1483 struct objc_class *sibling_class;
1484 struct objc_protocol_list *protocols;
1485 void *gc_object_type;
1489 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
1490 tree name
, tree size
, int status
,
1491 tree dispatch_table
, tree ivar_list
,
1495 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1498 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, isa
);
1501 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, super
);
1504 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, default_conversion (name
));
1507 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1508 build_int_cst (long_integer_type_node
, 0));
1511 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1512 build_int_cst (long_integer_type_node
, status
));
1514 /* instance_size = */
1515 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1516 convert (long_integer_type_node
, size
));
1518 /* objc_ivar_list = */
1520 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1521 build_int_cst (objc_ivar_list_ptr
, 0));
1524 expr
= convert (objc_ivar_list_ptr
,
1525 build_unary_op (input_location
, ADDR_EXPR
,
1527 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1530 /* objc_method_list = */
1531 if (!dispatch_table
)
1532 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1533 convert (objc_method_list_ptr
, null_pointer_node
));
1536 expr
= convert (objc_method_list_ptr
,
1537 build_unary_op (input_location
, ADDR_EXPR
,
1538 dispatch_table
, 0));
1539 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1542 /* FIXME: Remove NeXT runtime code. */
1543 if (flag_next_runtime
)
1545 ltyp
= build_pointer_type (xref_tag (RECORD_TYPE
,
1546 get_identifier ("objc_cache")));
1547 /* method_cache = */
1548 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, convert (ltyp
, null_pointer_node
));
1553 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1555 /* subclass_list = */
1556 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1558 /* sibling_class = */
1559 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1562 /* protocol_list = */
1563 ltyp
= build_pointer_type (build_pointer_type (objc_protocol_template
));
1564 if (! protocol_list
)
1565 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (ltyp
, 0));
1568 expr
= convert (ltyp
,
1569 build_unary_op (input_location
, ADDR_EXPR
,
1571 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1574 /* FIXME: Remove NeXT runtime code. */
1575 if (flag_next_runtime
)
1577 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1579 /* gc_object_type = NULL */
1580 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1582 return objc_build_constructor (type
, v
);
1587 generate_ivars_list (tree chain
, const char *name
)
1589 tree initlist
, ivar_list_template
, decl
;
1591 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1596 if (!objc_ivar_template
)
1597 objc_ivar_template
= build_ivar_template ();
1599 size
= ivar_list_length (chain
);
1601 generating_instance_variables
= 1;
1602 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
1603 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
1604 generating_instance_variables
= 0;
1606 decl
= start_var_decl (ivar_list_template
, name
);
1608 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, build_int_cst (NULL_TREE
, size
));
1609 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, initlist
);
1611 OBJCMETA (decl
, objc_meta
, meta_base
);
1612 finish_var_decl (decl
,
1613 objc_build_constructor (TREE_TYPE (decl
), inits
));
1618 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1619 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1622 generate_class_structures (struct imp_entry
*impent
)
1624 tree name_expr
, super_expr
, root_expr
, class_decl
, meta_decl
;
1625 tree my_root_id
, my_super_id
;
1626 tree cast_type
, initlist
, protocol_decl
;
1627 tree inst_methods
= NULL_TREE
, class_methods
= NULL_TREE
;
1628 tree chain
, inst_ivars
= NULL_TREE
, class_ivars
= NULL_TREE
;
1633 /* objc_implementation_context = impent->imp_context;
1634 implementation_template = impent->imp_template;*/
1635 class_decl
= impent
->class_decl
;
1636 meta_decl
= impent
->meta_decl
;
1637 /* UOBJC_CLASS_decl = impent->class_decl;
1638 UOBJC_METACLASS_decl = impent->meta_decl;*/
1640 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1642 my_super_id
= CLASS_SUPER_NAME (impent
->imp_template
);
1645 add_class_reference (my_super_id
);
1647 /* Compute "my_root_id" - this is required for code generation.
1648 the "isa" for all meta class structures points to the root of
1649 the inheritance hierarchy (e.g. "__Object")... */
1650 my_root_id
= my_super_id
;
1653 tree my_root_int
= lookup_interface (my_root_id
);
1655 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
1656 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
1663 /* No super class. */
1664 my_root_id
= CLASS_NAME (impent
->imp_template
);
1666 cast_type
= build_pointer_type (objc_class_template
);
1667 name_expr
= add_objc_string (CLASS_NAME (impent
->imp_template
),
1670 /* Install class `isa' and `super' pointers at runtime. */
1672 super_expr
= add_objc_string (my_super_id
, class_names
);
1674 super_expr
= null_pointer_node
;
1676 super_expr
= build_c_cast (loc
, cast_type
, super_expr
);
1678 root_expr
= add_objc_string (my_root_id
, class_names
);
1679 root_expr
= build_c_cast (loc
, cast_type
, root_expr
);
1681 if (CLASS_PROTOCOL_LIST (impent
->imp_template
))
1683 generate_protocol_references (CLASS_PROTOCOL_LIST (impent
->imp_template
));
1684 protocol_decl
= generate_protocol_list (impent
->imp_template
,
1685 impent
->imp_context
);
1688 protocol_decl
= NULL_TREE
;
1690 if (CLASS_CLS_METHODS (impent
->imp_context
))
1692 snprintf (buf
, BUFSIZE
, "_OBJC_ClassMethods_%s",
1693 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1694 class_methods
= generate_dispatch_table (CLASS_CLS_METHODS (impent
->imp_context
),
1698 if (CLASS_SUPER_NAME (impent
->imp_template
) == NULL_TREE
1699 && (chain
= TYPE_FIELDS (objc_class_template
)))
1701 snprintf (buf
, BUFSIZE
, "_OBJC_ClassIvars_%s",
1702 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1703 class_ivars
= generate_ivars_list (chain
, buf
);
1706 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1709 build_shared_structure_initializer
1710 (TREE_TYPE (meta_decl
),
1711 root_expr
, super_expr
, name_expr
,
1712 convert (integer_type_node
,
1713 TYPE_SIZE_UNIT (objc_class_template
)),
1714 CLS_META
, class_methods
, class_ivars
,
1717 finish_var_decl (meta_decl
, initlist
);
1718 impent
->meta_decl
= meta_decl
;
1720 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1721 if (CLASS_NST_METHODS (impent
->imp_context
))
1723 snprintf (buf
, BUFSIZE
, "_OBJC_InstanceMethods_%s",
1724 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1725 inst_methods
= generate_dispatch_table (CLASS_NST_METHODS (impent
->imp_context
),
1729 if ((chain
= CLASS_IVARS (impent
->imp_template
)))
1731 snprintf (buf
, BUFSIZE
, "_OBJC_InstanceIvars_%s",
1732 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
)));
1733 inst_ivars
= generate_ivars_list (chain
, buf
);
1737 build_shared_structure_initializer
1738 (TREE_TYPE (class_decl
),
1739 build_unary_op (loc
, ADDR_EXPR
, meta_decl
, 0),
1740 super_expr
, name_expr
,
1741 convert (integer_type_node
,
1742 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1743 (impent
->imp_template
))),
1744 CLS_FACTORY
| cls_flags
, inst_methods
, inst_ivars
,
1747 finish_var_decl (class_decl
, initlist
);
1748 impent
->class_decl
= class_decl
;
1751 /* --- Output GNU Metadata --- */
1753 /* TODO: Make this into an array of refs. */
1755 handle_class_ref (tree chain
)
1757 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
1758 char *string
= (char *) alloca (strlen (name
) + 30);
1762 sprintf (string
, "__objc_class_name_%s", name
);
1764 /* Make a decl for this name, so we can use its address in a tree. */
1765 decl
= build_decl (input_location
,
1766 VAR_DECL
, get_identifier (string
), TREE_TYPE (integer_zero_node
));
1767 DECL_EXTERNAL (decl
) = 1;
1768 TREE_PUBLIC (decl
) = 1;
1769 DECL_CONTEXT (decl
) = NULL_TREE
;
1770 finish_var_decl (decl
, 0);
1772 /* Make a decl for the address. */
1773 sprintf (string
, "__objc_class_ref_%s", name
);
1774 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
1775 decl
= build_decl (input_location
,
1776 VAR_DECL
, get_identifier (string
), string_type_node
);
1777 TREE_STATIC (decl
) = 1;
1778 TREE_USED (decl
) = 1;
1779 DECL_READ_P (decl
) = 1;
1780 DECL_ARTIFICIAL (decl
) = 1;
1781 DECL_INITIAL (decl
) = error_mark_node
;
1783 /* We must force the reference. */
1784 DECL_PRESERVE_P (decl
) = 1;
1786 DECL_CONTEXT (decl
) = NULL_TREE
;
1787 finish_var_decl (decl
, exp
);
1791 get_proto_encoding (tree proto
)
1796 if (! METHOD_ENCODING (proto
))
1798 encoding
= encode_method_prototype (proto
);
1799 METHOD_ENCODING (proto
) = encoding
;
1802 encoding
= METHOD_ENCODING (proto
);
1804 return add_objc_string (encoding
, meth_var_types
);
1807 return build_int_cst (NULL_TREE
, 0);
1811 build_gnu_selector_translation_table (void)
1814 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
1815 vec
<constructor_elt
, va_gc
> *v
;
1817 /* Cause the selector table (previously forward-declared)
1818 to be actually output. */
1820 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1825 /* TODO: improve on the location for the diagnostic. */
1826 location_t loc
= input_location
;
1827 diagnose_missing_method (TREE_VALUE (chain
), loc
);
1831 expr
= build_selector (TREE_VALUE (chain
));
1832 encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1833 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1834 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, encoding
);
1835 expr
= objc_build_constructor (objc_selector_template
, v
);
1837 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1838 } /* each element in the chain */
1840 /* List terminator. */
1842 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1843 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, integer_zero_node
);
1844 expr
= objc_build_constructor (objc_selector_template
, v
);
1846 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, expr
);
1847 expr
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
1849 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, expr
);
1852 /* Output references to all statically allocated objects. Return the DECL
1853 for the array built. */
1856 generate_static_references (void)
1858 tree expr
= NULL_TREE
;
1859 tree class_name
, klass
, decl
;
1860 tree cl_chain
, in_chain
, type
1861 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
1862 int num_inst
, num_class
;
1864 vec
<constructor_elt
, va_gc
> *decls
= NULL
;
1866 /* FIXME: Remove NeXT runtime code. */
1867 if (flag_next_runtime
)
1870 for (cl_chain
= objc_static_instances
, num_class
= 0;
1871 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1873 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1875 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1876 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1878 snprintf (buf
, BUFSIZE
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1879 decl
= start_var_decl (type
, buf
);
1881 /* Output {class_name, ...}. */
1882 klass
= TREE_VALUE (cl_chain
);
1883 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (klass
), class_names
);
1884 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
1885 build_unary_op (input_location
,
1886 ADDR_EXPR
, class_name
, 1));
1888 /* Output {..., instance, ...}. */
1889 for (in_chain
= TREE_PURPOSE (cl_chain
);
1890 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1892 expr
= build_unary_op (input_location
,
1893 ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1894 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1897 /* Output {..., NULL}. */
1898 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1900 expr
= objc_build_constructor (TREE_TYPE (decl
), v
);
1901 OBJCMETA (decl
, objc_meta
, meta_base
);
1902 finish_var_decl (decl
, expr
);
1903 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
,
1904 build_unary_op (input_location
,
1905 ADDR_EXPR
, decl
, 1));
1908 CONSTRUCTOR_APPEND_ELT (decls
, NULL_TREE
, build_int_cst (NULL_TREE
, 0));
1909 expr
= objc_build_constructor (type
, decls
);
1910 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
1911 OBJCMETA (static_instances_decl
, objc_meta
, meta_base
);
1912 finish_var_decl (static_instances_decl
, expr
);
1915 /* Create the initial value for the `defs' field of _objc_symtab.
1916 This is a CONSTRUCTOR. */
1919 init_def_list (tree type
)
1922 struct imp_entry
*impent
;
1924 vec
<constructor_elt
, va_gc
> *v
= NULL
;
1927 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1929 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1931 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1932 expr
= build_unary_op (loc
,
1933 ADDR_EXPR
, impent
->class_decl
, 0);
1934 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1939 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1941 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1943 loc
= DECL_SOURCE_LOCATION (impent
->class_decl
);
1944 expr
= build_unary_op (loc
,
1945 ADDR_EXPR
, impent
->class_decl
, 0);
1946 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1950 loc
= UNKNOWN_LOCATION
;
1951 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1952 if (static_instances_decl
)
1953 expr
= build_unary_op (loc
, ADDR_EXPR
, static_instances_decl
, 0);
1955 expr
= integer_zero_node
;
1956 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
1958 return objc_build_constructor (type
, v
);
1961 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1963 /* Predefine the following data type:
1971 void *defs[cls_def_cnt + cat_def_cnt];
1975 build_objc_symtab_template (void)
1977 tree fields
, array_type
, *chain
= NULL
;
1980 objc_symtab_template
= objc_start_struct (get_identifier (UTAG_SYMTAB
));
1982 /* long sel_ref_cnt; */
1983 fields
= add_field_decl (long_integer_type_node
, "sel_ref_cnt", &chain
);
1986 add_field_decl (build_pointer_type (objc_selector_type
), "refs", &chain
);
1988 /* short cls_def_cnt; */
1989 add_field_decl (short_integer_type_node
, "cls_def_cnt", &chain
);
1991 /* short cat_def_cnt; */
1992 add_field_decl (short_integer_type_node
, "cat_def_cnt", &chain
);
1994 /* Note that padding will be added here on LP64. */
1996 /* void *defs[imp_count + cat_count (+ 1)]; */
1997 /* NB: The index is one less than the size of the array. */
1998 index
= imp_count
+ cat_count
;
1999 array_type
= build_sized_array_type (ptr_type_node
, index
+ 1);
2000 add_field_decl (array_type
, "defs", &chain
);
2002 objc_finish_struct (objc_symtab_template
, fields
);
2004 /* Construct the initial value for all of _objc_symtab. */
2007 init_objc_symtab (tree type
)
2009 tree field
, expr
, ltyp
;
2011 vec
<constructor_elt
, va_gc
> *v
= NULL
;
2013 loc
= UNKNOWN_LOCATION
;
2015 /* sel_ref_cnt = { ..., 5, ... } */
2017 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2018 build_int_cst (long_integer_type_node
, 0));
2020 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2022 ltyp
= build_pointer_type (objc_selector_type
);
2024 expr
= convert (ltyp
, build_unary_op (loc
, ADDR_EXPR
,
2025 UOBJC_SELECTOR_TABLE_decl
, 1));
2027 expr
= convert (ltyp
, null_pointer_node
);
2028 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, expr
);
2030 /* cls_def_cnt = { ..., 5, ... } */
2032 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2033 build_int_cst (short_integer_type_node
, imp_count
));
2035 /* cat_def_cnt = { ..., 5, ... } */
2037 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
,
2038 build_int_cst (short_integer_type_node
, cat_count
));
2040 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2042 field
= TYPE_FIELDS (type
);
2043 field
= DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field
))));
2045 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, init_def_list (TREE_TYPE (field
)));
2047 return objc_build_constructor (type
, v
);
2050 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2051 and initialized appropriately. */
2054 generate_objc_symtab_decl (void)
2056 build_objc_symtab_template ();
2057 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
2058 OBJCMETA (UOBJC_SYMBOLS_decl
, objc_meta
, meta_base
);
2059 finish_var_decl (UOBJC_SYMBOLS_decl
,
2060 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2064 objc_generate_v1_gnu_metadata (void)
2066 struct imp_entry
*impent
;
2069 /* Process the static instances here because initialization of objc_symtab
2071 if (objc_static_instances
)
2072 generate_static_references ();
2074 objc_implementation_context
=
2075 implementation_template
=
2077 UOBJC_METACLASS_decl
= NULL_TREE
;
2079 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2081 /* If -gen-decls is present, Dump the @interface of each class.
2082 TODO: Dump the classes in the order they were found, rather than in
2083 reverse order as we are doing now. */
2084 if (flag_gen_declaration
)
2085 dump_interface (gen_declaration_file
, impent
->imp_context
);
2087 /* all of the following reference the string pool... */
2088 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
2089 generate_class_structures (impent
);
2091 generate_category (impent
);
2094 /* If we are using an array of selectors, we must always
2095 finish up the array decl even if no selectors were used. */
2096 build_gnu_selector_translation_table ();
2099 generate_protocols ();
2101 /* Arrange for ObjC data structures to be initialized at run time. */
2102 /* FIXME: Have some more elegant way to determine if we need to
2103 generate objc_symtab_decl or not, instead of checking these
2105 if (imp_list
|| class_names_chain
2106 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
2107 || prop_names_attr_chain
)
2108 generate_objc_symtab_decl ();
2110 if (imp_list
|| class_names_chain
|| objc_static_instances
2111 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
2113 /* Make sure that the meta-data are identified as being
2115 build_module_descriptor (OBJC_VERSION
,
2116 build_tree_list (objc_meta
, meta_base
));
2117 build_module_initializer_routine ();
2120 /* Dump the class references. This forces the appropriate classes
2121 to be linked into the executable image, preserving unix archive
2122 semantics. This can be removed when we move to a more dynamically
2123 linked environment. */
2125 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2127 handle_class_ref (chain
);
2128 if (TREE_PURPOSE (chain
))
2129 generate_classref_translation_entry (chain
);
2132 for (impent
= imp_list
; impent
; impent
= impent
->next
)
2133 handle_impent (impent
);
2135 generate_strings ();
2138 /* --- exceptions --- */
2140 static GTY(()) tree objc_eh_personality_decl
;
2143 objc_eh_runtime_type (tree type
)
2145 tree ident
, eh_id
, decl
, str
;
2147 if (type
== error_mark_node
2148 || errorcount
|| sorrycount
)
2150 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2151 to prevent an ICE. Note that we know that the compiler will
2152 terminate with an error and this 'ErrorMarkNode' class name will
2153 never be actually used. */
2154 ident
= get_identifier ("ErrorMarkNode");
2155 goto make_err_class
;
2158 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
2159 /* We don't want to identify 'id' for GNU. Instead, build a 0
2160 entry in the exceptions table. */
2161 return null_pointer_node
;
2163 if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
2166 /* This routine is also called for c++ catch clauses; in which case,
2167 we use the c++ typeinfo decl. */
2168 return build_eh_type_type (type
);
2170 error ("non-objective-c type %qT cannot be caught", type
);
2171 ident
= get_identifier ("ErrorMarkNode");
2172 goto make_err_class
;
2176 ident
= OBJC_TYPE_NAME (TREE_TYPE (type
));
2179 /* If this class was already referenced, then it will be output during
2180 meta-data emission, so we don't need to do it here. */
2181 decl
= get_objc_string_decl (ident
, class_names
);
2182 eh_id
= add_objc_string (ident
, class_names
);
2185 /* Not found ... so we need to build it - from the freshly-entered id. */
2186 decl
= get_objc_string_decl (ident
, class_names
);
2187 str
= my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2188 IDENTIFIER_POINTER (ident
));
2189 /* We have to finalize this var here, because this might be called after
2190 all the other metadata strings have been emitted. */
2191 finish_var_decl (decl
, str
);
2197 objc_eh_personality (void)
2199 if (!objc_eh_personality_decl
)
2201 objc_eh_personality_decl
= build_personality_function ("gnu_objc");
2203 objc_eh_personality_decl
= build_personality_function ("gxx");
2205 return objc_eh_personality_decl
;
2208 /* -- interfaces --- */
2211 build_throw_stmt (location_t loc
, tree throw_expr
, bool rethrown ATTRIBUTE_UNUSED
)
2214 vec
<tree
, va_gc
> *parms
;
2215 vec_alloc (parms
, 1);
2216 /* A throw is just a call to the runtime throw function with the
2217 object as a parameter. */
2218 parms
->quick_push (throw_expr
);
2219 t
= build_function_call_vec (loc
, vNULL
, objc_exception_throw_decl
, parms
,
2222 return add_stmt (t
);
2225 /* Build __builtin_eh_pointer. */
2228 objc_build_exc_ptr (struct objc_try_context
**x ATTRIBUTE_UNUSED
)
2231 t
= builtin_decl_explicit (BUILT_IN_EH_POINTER
);
2232 t
= build_call_expr (t
, 1, integer_zero_node
);
2233 return fold_convert (objc_object_type
, t
);
2237 begin_catch (struct objc_try_context
**cur_try_context
, tree type
,
2238 tree decl
, tree compound
, bool ellipsis ATTRIBUTE_UNUSED
)
2241 /* Record the data for the catch in the try context so that we can
2242 finalize it later. */
2244 t
= build_stmt (input_location
, CATCH_EXPR
, NULL
, compound
);
2246 t
= build_stmt (input_location
, CATCH_EXPR
, type
, compound
);
2247 (*cur_try_context
)->current_catch
= t
;
2249 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2250 t
= objc_build_exc_ptr (cur_try_context
);
2251 t
= convert (TREE_TYPE (decl
), t
);
2252 return build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
2256 finish_catch (struct objc_try_context
**cur_try_context
, tree current_catch
)
2258 append_to_statement_list (current_catch
, &((*cur_try_context
)->catch_list
));
2262 finish_try_stmt (struct objc_try_context
**cur_try_context
)
2264 struct objc_try_context
*c
= *cur_try_context
;
2265 tree stmt
= c
->try_body
;
2267 stmt
= build_stmt (c
->try_locus
, TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
2268 if (c
->finally_body
)
2269 stmt
= build_stmt (c
->try_locus
, TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
2273 #include "gt-objc-objc-gnu-runtime-abi-01.h"