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