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