Updated comments - no change in code
[official-gcc.git] / gcc / objc / objc-gnu-runtime-abi-01.c
blobe2a3ce7b339e455aa81b883a949d85fa6b5d8988
1 /* GNU Runtime ABI version 8
2 Copyright (C) 2011 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 "tm.h"
25 #include "tree.h"
27 #ifdef OBJCPLUS
28 #include "cp-tree.h"
29 #else
30 #include "c-tree.h"
31 #include "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"
52 /* GNU runtime private definitions. */
53 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
55 #define TAG_GETCLASS "objc_get_class"
56 #define TAG_GETMETACLASS "objc_get_meta_class"
58 #define TAG_MSGSEND "objc_msg_lookup"
59 #define TAG_MSGSENDSUPER "objc_msg_lookup_super"
61 /* GNU-specific tags. */
63 #define TAG_EXECCLASS "__objc_exec_class"
64 #define TAG_GNUINIT "__objc_gnu_init"
66 /* The version identifies which language generation and runtime
67 the module (file) was compiled for, and is recorded in the
68 module descriptor. */
69 #define OBJC_VERSION 8
71 #define PROTOCOL_VERSION 2
73 /* This macro provides a method of removing ambiguity between runtimes
74 when LTO is in use on targets supporting multiple runtimes.
76 For example, at present, any target that includes an implementation of
77 the NeXT runtime needs to place Objective-C meta-data into specific
78 named sections. This should _not_ be done for the GNU runtime, and the
79 folowing macro is used to attach Objective-C private attributes that may
80 be used to identify the runtime for which the meta-data are intended. */
82 #define OBJCMETA(DECL,VERS,KIND) \
83 if (VERS) \
84 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
86 /* FIXME: Remove this macro, not needed. */
87 #ifndef TARGET_64BIT
88 #define TARGET_64BIT 0
89 #endif
91 static void gnu_runtime_01_initialize (void);
93 static void build_selector_template (void);
95 static tree gnu_runtime_abi_01_super_superclassfield_id (void);
97 static tree gnu_runtime_abi_01_class_decl (tree);
98 static tree gnu_runtime_abi_01_metaclass_decl (tree);
99 static tree gnu_runtime_abi_01_category_decl (tree);
100 static tree gnu_runtime_abi_01_protocol_decl (tree);
101 static tree gnu_runtime_abi_01_string_decl (tree, const char *, string_section);
103 static tree gnu_runtime_abi_01_get_class_reference (tree);
104 static tree gnu_runtime_abi_01_build_typed_selector_reference (location_t, tree,
105 tree);
106 static tree gnu_runtime_abi_01_get_protocol_reference (location_t, tree);
107 static tree gnu_runtime_abi_01_build_ivar_ref (location_t, tree, tree);
108 static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool);
109 static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
111 static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
112 static tree gnu_runtime_abi_01_get_arg_type_list_base (tree, int, int);
113 static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
114 tree, tree, tree, int);
116 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
117 static tree gnu_runtime_abi_01_build_const_string_constructor (location_t, tree,int);
119 static void objc_generate_v1_gnu_metadata (void);
121 static tree objc_eh_runtime_type (tree type);
122 static tree objc_eh_personality (void);
123 static tree objc_build_exc_ptr (struct objc_try_context **);
124 static tree build_throw_stmt (location_t, tree, bool);
125 static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool);
126 static void finish_catch (struct objc_try_context **, tree);
127 static tree finish_try_stmt (struct objc_try_context **);
129 bool
130 objc_gnu_runtime_abi_01_init (objc_runtime_hooks *rthooks)
132 /* GNU runtime does not need the compiler to change code in order to do GC. */
133 if (flag_objc_gc)
135 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
136 flag_objc_gc = 0;
139 /* Although I guess we could, we don't currently support SJLJ exceptions for the
140 GNU runtime. */
141 if (flag_objc_sjlj_exceptions)
143 inform (UNKNOWN_LOCATION, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
144 flag_objc_sjlj_exceptions = 0;
147 /* TODO: Complain if -fobjc-abi-version=N was used. */
149 /* TODO: Complain if -fobj-nilcheck was used. */
151 rthooks->initialize = gnu_runtime_01_initialize;
152 rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
153 rthooks->tag_getclass = TAG_GETCLASS;
154 rthooks->super_superclassfield_ident = gnu_runtime_abi_01_super_superclassfield_id;
156 rthooks->class_decl = gnu_runtime_abi_01_class_decl;
157 rthooks->metaclass_decl = gnu_runtime_abi_01_metaclass_decl;
158 rthooks->category_decl = gnu_runtime_abi_01_category_decl;
159 rthooks->protocol_decl = gnu_runtime_abi_01_protocol_decl;
160 rthooks->string_decl = gnu_runtime_abi_01_string_decl;
162 rthooks->get_class_reference = gnu_runtime_abi_01_get_class_reference;
163 rthooks->build_selector_reference = gnu_runtime_abi_01_build_typed_selector_reference;
164 rthooks->get_protocol_reference = gnu_runtime_abi_01_get_protocol_reference;
165 rthooks->build_ivar_reference = gnu_runtime_abi_01_build_ivar_ref;
166 rthooks->get_class_super_ref = gnu_runtime_abi_01_get_class_super_ref;
167 rthooks->get_category_super_ref = gnu_runtime_abi_01_get_category_super_ref;
169 rthooks->receiver_is_class_object = gnu_runtime_abi_01_receiver_is_class_object;
170 rthooks->get_arg_type_list_base = gnu_runtime_abi_01_get_arg_type_list_base;
171 rthooks->build_objc_method_call = gnu_runtime_abi_01_build_objc_method_call;
173 rthooks->setup_const_string_class_decl =
174 gnu_runtime_abi_01_setup_const_string_class_decl;
175 rthooks->build_const_string_constructor =
176 gnu_runtime_abi_01_build_const_string_constructor;
178 rthooks->build_throw_stmt = build_throw_stmt;
179 rthooks->build_exc_ptr = objc_build_exc_ptr;
180 rthooks->begin_catch = begin_catch;
181 rthooks->finish_catch = finish_catch;
182 rthooks->finish_try_stmt = finish_try_stmt;
184 rthooks->generate_metadata = objc_generate_v1_gnu_metadata;
185 return true;
188 static void build_selector_table_decl (void);
189 static void build_class_template (void);
190 static void build_category_template (void);
191 static void build_protocol_template (void);
193 static GTY(()) tree objc_meta;
194 static GTY(()) tree meta_base;
196 static void gnu_runtime_01_initialize (void)
198 tree type, ftype, IMP_type;
200 /* We do not need to mark GNU ObjC metadata for different sections,
201 however, we do need to make sure that it is not mistaken for NeXT
202 metadata. */
203 objc_meta = get_identifier ("OBJC1METG");
204 meta_base = get_identifier ("NONE");
206 /* Declare type of selector-objects that represent an operation name. */
207 /* `const struct objc_selector *' */
208 type = xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR));
209 type = build_qualified_type (type, TYPE_QUAL_CONST);
210 objc_selector_type = build_pointer_type (type);
212 /* typedef id (*IMP)(id, SEL, ...); */
213 ftype = build_varargs_function_type_list (objc_object_type,
214 objc_object_type,
215 objc_selector_type,
216 NULL_TREE);
218 IMP_type = build_pointer_type (ftype);
220 build_class_template ();
221 build_super_template ();
222 build_protocol_template ();
223 build_category_template ();
225 /* GNU runtime messenger entry points. */
226 /* TREE_NOTHROW is cleared for the message-sending functions,
227 because the function that gets called can throw in Obj-C++, or
228 could itself call something that can throw even in Obj-C. */
230 /* IMP objc_msg_lookup (id, SEL); */
231 type = build_function_type_list (IMP_type,
232 objc_object_type,
233 objc_selector_type,
234 NULL_TREE);
236 umsg_decl = add_builtin_function (TAG_MSGSEND,
237 type, 0, NOT_BUILT_IN,
238 NULL, NULL_TREE);
239 TREE_NOTHROW (umsg_decl) = 0;
241 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
242 type = build_function_type_list (IMP_type,
243 objc_super_type,
244 objc_selector_type,
245 NULL_TREE);
247 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
248 type, 0, NOT_BUILT_IN,
249 NULL, NULL_TREE);
250 TREE_NOTHROW (umsg_super_decl) = 0;
252 /* The following GNU runtime entry point is called to initialize
253 each module:
255 __objc_exec_class (void *); */
256 type = build_function_type_list (void_type_node,
257 ptr_type_node,
258 NULL_TREE);
260 execclass_decl = add_builtin_function (TAG_EXECCLASS,
261 type, 0, NOT_BUILT_IN,
262 NULL, NULL_TREE);
264 type = build_function_type_list (objc_object_type,
265 const_string_type_node,
266 NULL_TREE);
268 /* id objc_getClass (const char *); */
269 objc_get_class_decl
270 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
271 NULL, NULL_TREE);
273 /* id objc_getMetaClass (const char *); */
274 objc_get_meta_class_decl = add_builtin_function (TAG_GETMETACLASS, type,
275 0, NOT_BUILT_IN, NULL,
276 NULL_TREE);
278 /* static SEL _OBJC_SELECTOR_TABLE[]; */
279 build_selector_table_decl ();
281 /* Stuff for properties.
282 The codegen relies on this being NULL for GNU. */
283 objc_copyStruct_decl = NULL_TREE;
285 /* This is the type of all of the following functions
286 bjc_getPropertyStruct() and objc_setPropertyStruct(). */
287 type = build_function_type_list (void_type_node,
288 ptr_type_node,
289 const_ptr_type_node,
290 ptrdiff_type_node,
291 boolean_type_node,
292 boolean_type_node,
293 NULL_TREE);
295 /* Declare the following function:
296 void
297 objc_getPropertyStruct (void *destination, const void *source,
298 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
299 objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
300 type, 0, NOT_BUILT_IN,
301 NULL, NULL_TREE);
302 TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
303 /* Declare the following function:
304 void
305 objc_setPropertyStruct (void *destination, const void *source,
306 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
307 objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
308 type, 0, NOT_BUILT_IN,
309 NULL, NULL_TREE);
310 TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
312 using_eh_for_cleanups ();
313 lang_hooks.eh_runtime_type = objc_eh_runtime_type;
314 lang_hooks.eh_personality = objc_eh_personality;
317 /* --- templates --- */
318 /* struct _objc_selector {
319 SEL sel_id;
320 char *sel_type;
321 }; */
323 static void
324 build_selector_template (void)
326 tree decls, *chain = NULL;
328 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
330 /* SEL sel_id; */
331 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
333 /* char *sel_type; */
334 add_field_decl (string_type_node, "sel_type", &chain);
336 objc_finish_struct (objc_selector_template, decls);
339 /* struct _objc_class {
340 struct _objc_class *isa;
341 struct _objc_class *super_class;
342 char *name;
343 long version;
344 long info;
345 long instance_size;
346 struct _objc_ivar_list *ivars;
347 struct _objc_method_list *methods;
348 struct sarray *dtable;
349 struct _objc_class *subclass_list;
350 struct _objc_class *sibling_class;
351 struct _objc_protocol_list *protocols;
352 void *gc_object_type;
353 }; */
355 static void
356 build_class_template (void)
358 tree ptype, decls, *chain = NULL;
360 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
362 /* struct _objc_class *isa; */
363 decls = add_field_decl (build_pointer_type (objc_class_template),
364 "isa", &chain);
366 /* struct _objc_class *super_class; */
367 add_field_decl (build_pointer_type (objc_class_template),
368 "super_class", &chain);
370 /* char *name; */
371 add_field_decl (string_type_node, "name", &chain);
373 /* long version; */
374 add_field_decl (long_integer_type_node, "version", &chain);
376 /* long info; */
377 add_field_decl (long_integer_type_node, "info", &chain);
379 /* long instance_size; */
380 add_field_decl (long_integer_type_node, "instance_size", &chain);
382 /* struct _objc_ivar_list *ivars; */
383 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
385 /* struct _objc_method_list *methods; */
386 add_field_decl (objc_method_list_ptr, "methods", &chain);
388 /* struct sarray *dtable; */
389 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
390 get_identifier ("sarray")));
391 add_field_decl (ptype, "dtable", &chain);
393 /* struct objc_class *subclass_list; */
394 ptype = build_pointer_type (objc_class_template);
395 add_field_decl (ptype, "subclass_list", &chain);
397 /* struct objc_class *sibling_class; */
398 ptype = build_pointer_type (objc_class_template);
399 add_field_decl (ptype, "sibling_class", &chain);
401 /* struct _objc_protocol **protocol_list; */
402 ptype = build_pointer_type (build_pointer_type
403 (xref_tag (RECORD_TYPE,
404 get_identifier (UTAG_PROTOCOL))));
405 add_field_decl (ptype, "protocol_list", &chain);
407 /* void *gc_object_type; */
408 add_field_decl (build_pointer_type (void_type_node),
409 "gc_object_type", &chain);
411 objc_finish_struct (objc_class_template, decls);
414 /* struct _objc_category {
415 char *category_name;
416 char *class_name;
417 struct _objc_method_list *instance_methods;
418 struct _objc_method_list *class_methods;
419 struct _objc_protocol_list *protocols;
420 }; */
422 static void
423 build_category_template (void)
425 tree ptype, decls, *chain = NULL;
427 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
429 /* char *category_name; */
430 decls = add_field_decl (string_type_node, "category_name", &chain);
432 /* char *class_name; */
433 add_field_decl (string_type_node, "class_name", &chain);
435 /* struct _objc_method_list *instance_methods; */
436 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
438 /* struct _objc_method_list *class_methods; */
439 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
441 /* struct _objc_protocol **protocol_list; */
442 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
443 add_field_decl (ptype, "protocol_list", &chain);
445 objc_finish_struct (objc_category_template, decls);
448 /* struct _objc_protocol {
449 struct _objc_class *isa;
450 char *protocol_name;
451 struct _objc_protocol **protocol_list;
452 struct _objc__method_prototype_list *instance_methods;
453 struct _objc__method_prototype_list *class_methods;
454 }; */
456 static void
457 build_protocol_template (void)
459 tree ptype, decls, *chain = NULL;
461 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
463 /* struct _objc_class *isa; */
464 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
465 get_identifier (UTAG_CLASS)));
466 decls = add_field_decl (ptype, "isa", &chain);
468 /* char *protocol_name; */
469 add_field_decl (string_type_node, "protocol_name", &chain);
471 /* struct _objc_protocol **protocol_list; */
472 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
473 add_field_decl (ptype, "protocol_list", &chain);
475 /* struct _objc__method_prototype_list *instance_methods; */
476 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
478 /* struct _objc__method_prototype_list *class_methods; */
479 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
481 objc_finish_struct (objc_protocol_template, decls);
484 /* --- names, decls + identifers --- */
486 static void
487 build_selector_table_decl (void)
489 tree temp;
491 build_selector_template ();
492 temp = build_array_type (objc_selector_template, NULL_TREE);
494 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
495 OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base);
499 static tree
500 gnu_runtime_abi_01_super_superclassfield_id (void)
502 if (!super_superclassfield_id)
503 super_superclassfield_id = get_identifier ("super_class");
504 return super_superclassfield_id;
508 static tree
509 gnu_runtime_abi_01_class_decl (tree klass)
511 tree decl;
512 char buf[BUFSIZE];
513 snprintf (buf, BUFSIZE, "_OBJC_Class_%s",
514 IDENTIFIER_POINTER (CLASS_NAME (klass)));
515 decl = start_var_decl (objc_class_template, buf);
516 OBJCMETA (decl, objc_meta, meta_base);
517 return decl;
520 static tree
521 gnu_runtime_abi_01_metaclass_decl (tree klass)
523 tree decl;
524 char buf[BUFSIZE];
525 snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s",
526 IDENTIFIER_POINTER (CLASS_NAME (klass)));
527 decl = start_var_decl (objc_class_template, buf);
528 OBJCMETA (decl, objc_meta, meta_base);
529 return decl;
532 static tree
533 gnu_runtime_abi_01_category_decl (tree klass)
535 tree decl;
536 char buf[BUFSIZE];
537 snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
538 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)),
539 IDENTIFIER_POINTER (CLASS_NAME (klass)));
540 decl = start_var_decl (objc_category_template, buf);
541 OBJCMETA (decl, objc_meta, meta_base);
542 return decl;
545 static tree
546 gnu_runtime_abi_01_protocol_decl (tree p)
548 tree decl;
549 char buf[BUFSIZE];
551 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
552 snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
553 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
554 decl = start_var_decl (objc_protocol_template, buf);
555 OBJCMETA (decl, objc_meta, meta_base);
556 return decl;
559 static tree
560 gnu_runtime_abi_01_string_decl (tree type, const char *name,
561 string_section where ATTRIBUTE_UNUSED)
563 tree decl = start_var_decl (type, name);
564 OBJCMETA (decl, objc_meta, meta_base);
565 return decl;
568 /* --- entry --- */
570 static tree
571 gnu_runtime_abi_01_get_class_reference (tree ident)
573 tree params;
575 add_class_reference (ident);
577 params = build_tree_list (NULL_TREE, my_build_string_pointer
578 (IDENTIFIER_LENGTH (ident) + 1,
579 IDENTIFIER_POINTER (ident)));
581 /* FIXME: Do we need this assemble_external() ? */
582 /* assemble_external (objc_get_class_decl);*/
583 return build_function_call (input_location, objc_get_class_decl, params);
586 /* Used by get_arg_type_list.
587 Return the types for receiver & _cmd at the start of a method argument list.
588 context is either METHOD_DEF or METHOD_REF, saying whether we are trying
589 to define a method or call one. superflag says this is for a send to super.
590 meth may be NULL, in the case that there is no prototype. */
592 static tree
593 gnu_runtime_abi_01_get_arg_type_list_base (tree meth, int context,
594 int superflag ATTRIBUTE_UNUSED)
596 tree arglist;
598 /* Receiver type. */
599 if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
600 arglist = build_tree_list (NULL_TREE, objc_instance_type);
601 else
602 arglist = build_tree_list (NULL_TREE, objc_object_type);
604 /* Selector type - will eventually change to `int'. */
605 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
606 return arglist;
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, gc) *parms;
671 VEC(tree, 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);
682 tree method_param_types =
683 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
684 tree ftype = build_function_type (ret_type, method_param_types);
685 tree sender_cast;
686 tree method, t;
688 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
689 ftype = build_type_attribute_variant (ftype,
690 METHOD_TYPE_ATTRIBUTES
691 (method_prototype));
693 sender_cast = build_pointer_type (ftype);
695 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
697 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
698 lookup_object = save_expr (lookup_object);
700 /* Param list + 2 slots for object and selector. */
701 parms = VEC_alloc (tree, gc, nparm + 2);
702 tv = VEC_alloc (tree, gc, 2);
704 /* First, call the lookup function to get a pointer to the method,
705 then cast the pointer, then call it with the method arguments. */
706 VEC_quick_push (tree, tv, lookup_object);
707 VEC_quick_push (tree, tv, selector);
708 method = build_function_call_vec (loc, sender, tv, NULL);
709 VEC_free (tree, gc, tv);
711 /* Pass the appropriate object to the method. */
712 VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
714 /* Pass the selector to the method. */
715 VEC_quick_push (tree, parms, selector);
716 /* Now append the remainder of the parms. */
717 if (nparm)
718 for (; method_params; method_params = TREE_CHAIN (method_params))
719 VEC_quick_push (tree, parms, TREE_VALUE (method_params));
721 /* Build an obj_type_ref, with the correct cast for the method call. */
722 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
723 t = build_function_call_vec (loc, t, parms, NULL);
724 VEC_free (tree, gc, parms);
725 return t;
728 static tree
729 gnu_runtime_abi_01_build_objc_method_call (location_t loc,
730 tree method_prototype,
731 tree receiver,
732 tree rtype ATTRIBUTE_UNUSED,
733 tree sel_name,
734 tree method_params,
735 int super ATTRIBUTE_UNUSED)
737 tree selector =
738 gnu_runtime_abi_01_build_typed_selector_reference (loc,
739 sel_name,
740 method_prototype);
742 return build_objc_method_call (loc, super, method_prototype, receiver,
743 selector, method_params);
746 static tree
747 gnu_runtime_abi_01_get_protocol_reference (location_t loc, tree p)
749 tree expr, protocol_struct_type, *chain;
750 if (!PROTOCOL_FORWARD_DECL (p))
751 PROTOCOL_FORWARD_DECL (p) = gnu_runtime_abi_01_protocol_decl (p);
753 expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
755 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
756 if we have it, rather than converting it here. */
757 expr = convert (objc_protocol_type, expr);
759 /* The @protocol() expression is being compiled into a pointer to a
760 statically allocated instance of the Protocol class. To become
761 usable at runtime, the 'isa' pointer of the instance need to be
762 fixed up at runtime by the runtime library, to point to the
763 actual 'Protocol' class. */
765 /* For the GNU runtime, put the static Protocol instance in the list
766 of statically allocated instances, so that we make sure that its
767 'isa' pointer is fixed up at runtime by the GNU runtime library
768 to point to the Protocol class (at runtime, when loading the
769 module, the GNU runtime library loops on the statically allocated
770 instances (as found in the defs field in objc_symtab) and fixups
771 all the 'isa' pointers of those objects). */
773 /* This type is a struct containing the fields of a Protocol
774 object. (Cfr. objc_protocol_type instead is the type of a pointer
775 to such a struct). */
776 protocol_struct_type = xref_tag (RECORD_TYPE,
777 get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
779 /* Look for the list of Protocol statically allocated instances
780 to fixup at runtime. Create a new list to hold Protocol
781 statically allocated instances, if the list is not found. At
782 present there is only another list, holding NSConstantString
783 static instances to be fixed up at runtime. */
785 for (chain = &objc_static_instances;
786 *chain && TREE_VALUE (*chain) != protocol_struct_type;
787 chain = &TREE_CHAIN (*chain));
789 if (!*chain)
791 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
792 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
793 class_names);
796 /* Add this statically allocated instance to the Protocol list. */
797 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
798 PROTOCOL_FORWARD_DECL (p),
799 TREE_PURPOSE (*chain));
800 return expr;
803 /* For ABI 8 an IVAR is just a fixed offset in the class struct. */
805 static tree
806 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
807 tree base, tree id)
809 return objc_build_component_ref (base, id);
812 /* We build super class references as we need them (but keep them once
813 built for the sake of efficiency). */
815 static tree
816 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
817 struct imp_entry *imp, bool inst_meth)
819 if (inst_meth)
821 if (!ucls_super_ref)
822 ucls_super_ref =
823 objc_build_component_ref (imp->class_decl,
824 get_identifier ("super_class"));
825 return ucls_super_ref;
827 else
829 if (!uucls_super_ref)
830 uucls_super_ref =
831 objc_build_component_ref (imp->meta_decl,
832 get_identifier ("super_class"));
833 return uucls_super_ref;
837 static tree
838 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
839 struct imp_entry *imp, bool inst_meth)
841 tree super_name = CLASS_SUPER_NAME (imp->imp_template);
842 tree super_class;
844 add_class_reference (super_name);
845 super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
846 /* FIXME: Do we need this assemble_external() ? */
847 /* assemble_external (super_class);*/
848 super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
849 IDENTIFIER_POINTER (super_name));
850 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
851 return build_function_call (input_location,
852 super_class,
853 build_tree_list (NULL_TREE, super_name));
856 static bool
857 gnu_runtime_abi_01_setup_const_string_class_decl (void)
859 /* Do nothing, and create no error. */
860 return true;
863 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
865 static GTY(()) int num_static_inst;
867 static tree
868 objc_add_static_instance (tree constructor, tree class_decl)
870 tree *chain, decl;
871 char buf[BUFSIZE];
873 /* Find the list of static instances for the CLASS_DECL. Create one if
874 not found. */
875 for (chain = &objc_static_instances;
876 *chain && TREE_VALUE (*chain) != class_decl;
877 chain = &TREE_CHAIN (*chain));
878 if (!*chain)
880 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
881 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
884 snprintf (buf, BUFSIZE, "_OBJC_INSTANCE_%d", num_static_inst++);
885 decl = build_decl (input_location,
886 VAR_DECL, get_identifier (buf), class_decl);
887 TREE_STATIC (decl) = 1;
888 DECL_ARTIFICIAL (decl) = 1;
889 TREE_USED (decl) = 1;
890 DECL_INITIAL (decl) = constructor;
891 DECL_CONTEXT (decl) = NULL;
892 OBJCMETA (decl, objc_meta, meta_base);
894 /* We may be writing something else just now.
895 Postpone till end of input. */
896 DECL_DEFER_OUTPUT (decl) = 1;
897 pushdecl_top_level (decl);
898 rest_of_decl_compilation (decl, 1, 0);
900 /* Add the DECL to the head of this CLASS' list. */
901 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
903 return decl;
906 static tree
907 gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string,
908 int length)
910 tree constructor, fields;
911 VEC(constructor_elt,gc) *v = NULL;
913 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
914 fields = TYPE_FIELDS (internal_const_str_type);
915 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0));
917 fields = DECL_CHAIN (fields);
918 CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc,
919 ADDR_EXPR, string, 1));
921 fields = DECL_CHAIN (fields);
922 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
923 constructor = objc_build_constructor (internal_const_str_type, v);
925 constructor = objc_add_static_instance (constructor, constant_string_type);
926 return constructor;
929 /* --- metadata - module initializer --- */
931 /* The GNU runtime requires us to provide a static initializer function
932 for each module:
934 static void __objc_gnu_init (void) {
935 __objc_exec_class (&L_OBJC_MODULES);
936 } */
939 static void
940 build_module_initializer_routine (void)
942 tree body;
944 #ifdef OBJCPLUS
945 push_lang_context (lang_name_c); /* extern "C" */
946 #endif
948 objc_push_parm (build_decl (input_location,
949 PARM_DECL, NULL_TREE, void_type_node));
950 #ifdef OBJCPLUS
951 objc_start_function (get_identifier (TAG_GNUINIT),
952 build_function_type_list (void_type_node, NULL_TREE),
953 NULL_TREE, NULL_TREE);
954 #else
955 objc_start_function (get_identifier (TAG_GNUINIT),
956 build_function_type_list (void_type_node, NULL_TREE),
957 NULL_TREE, objc_get_parm_info (0));
958 #endif
959 body = c_begin_compound_stmt (true);
960 add_stmt (build_function_call
961 (input_location,
962 execclass_decl,
963 build_tree_list
964 (NULL_TREE,
965 build_unary_op (input_location, ADDR_EXPR,
966 UOBJC_MODULES_decl, 0))));
967 add_stmt (c_end_compound_stmt (input_location, body, true));
969 TREE_PUBLIC (current_function_decl) = 0;
971 #ifndef OBJCPLUS
972 /* For Objective-C++, we will need to call __objc_gnu_init
973 from objc_generate_static_init_call() below. */
974 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
975 #endif
977 GNU_INIT_decl = current_function_decl;
978 finish_function ();
980 #ifdef OBJCPLUS
981 pop_lang_context ();
982 #endif
985 #ifdef OBJCPLUS
986 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
987 to be called by the module initializer routine. */
990 objc_static_init_needed_p (void)
992 return (GNU_INIT_decl != NULL_TREE);
995 /* Generate a call to the __objc_gnu_init initializer function. */
997 tree
998 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
1000 add_stmt (build_stmt (input_location, EXPR_STMT,
1001 build_function_call (input_location,
1002 GNU_INIT_decl, NULL_TREE)));
1004 return ctors;
1006 #endif /* OBJCPLUS */
1008 /* --- Output GNU Meta-data --- */
1010 static void
1011 generate_classref_translation_entry (tree chain)
1013 tree expr, decl, type;
1015 decl = TREE_PURPOSE (chain);
1016 type = TREE_TYPE (decl);
1018 expr = add_objc_string (TREE_VALUE (chain), class_names);
1019 expr = convert (type, expr); /* cast! */
1021 /* This is a class reference. It is re-written by the runtime,
1022 but will be optimized away unless we force it. */
1023 DECL_PRESERVE_P (decl) = 1;
1024 OBJCMETA (decl, objc_meta, meta_base);
1025 finish_var_decl (decl, expr);
1026 return;
1030 static void
1031 handle_impent (struct imp_entry *impent)
1033 char *string;
1035 /* objc_implementation_context = impent->imp_context;
1036 implementation_template = impent->imp_template;*/
1038 switch (TREE_CODE (impent->imp_context))
1040 case CLASS_IMPLEMENTATION_TYPE:
1042 const char *const class_name =
1043 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1045 string = (char *) alloca (strlen (class_name) + 30);
1047 sprintf (string, "__objc_class_name_%s", class_name);
1048 break;
1050 case CATEGORY_IMPLEMENTATION_TYPE:
1052 const char *const class_name =
1053 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1054 const char *const class_super_name =
1055 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
1057 string = (char *) alloca (strlen (class_name)
1058 + strlen (class_super_name) + 30);
1060 /* Do the same for categories. Even though no references to
1061 these symbols are generated automatically by the compiler,
1062 it gives you a handle to pull them into an archive by
1063 hand. */
1064 sprintf (string, "*__objc_category_name_%s_%s", class_name, class_super_name);
1065 break;
1067 default:
1068 return;
1072 tree decl, init;
1074 init = integer_zero_node;
1075 decl = build_decl (input_location,
1076 VAR_DECL, get_identifier (string), TREE_TYPE (init));
1077 TREE_PUBLIC (decl) = 1;
1078 TREE_READONLY (decl) = 1;
1079 TREE_USED (decl) = 1;
1080 TREE_CONSTANT (decl) = 1;
1081 DECL_CONTEXT (decl) = NULL_TREE;
1082 DECL_ARTIFICIAL (decl) = 1;
1083 TREE_STATIC (decl) = 1;
1084 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
1085 /* We must force the reference. */
1086 DECL_PRESERVE_P (decl) = 1;
1088 finish_var_decl(decl, init) ;
1092 tree
1093 build_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
1094 tree inst_methods, tree class_methods)
1096 tree expr, ttyp;
1097 location_t loc;
1098 VEC(constructor_elt,gc) *inits = NULL;
1100 /* TODO: pass the loc in or find it from args. */
1101 loc = input_location;
1102 ttyp = build_pointer_type (xref_tag (RECORD_TYPE,
1103 get_identifier (UTAG_CLASS)));
1104 /* Filling the "isa" in with a version allows the runtime system to
1105 detect this ... */
1106 expr = build_int_cst (ttyp, PROTOCOL_VERSION);
1108 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1110 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
1111 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
1113 ttyp = objc_method_proto_list_ptr;
1114 if (inst_methods)
1115 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1116 else
1117 expr = convert (ttyp, null_pointer_node);
1118 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1120 if (class_methods)
1121 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1122 else
1123 expr = convert (ttyp, null_pointer_node);
1124 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1126 return objc_build_constructor (type, inits);
1129 static tree
1130 generate_protocol_list (tree i_or_p, tree klass_ctxt)
1132 tree array_type, ptype, refs_decl, lproto, e, plist;
1133 VEC(constructor_elt,gc) *v = NULL;
1134 char buf[BUFSIZE];
1135 int size = 0;
1137 switch (TREE_CODE (i_or_p))
1139 case CLASS_INTERFACE_TYPE:
1140 case CATEGORY_INTERFACE_TYPE:
1141 plist = CLASS_PROTOCOL_LIST (i_or_p);
1142 break;
1143 case PROTOCOL_INTERFACE_TYPE:
1144 plist = PROTOCOL_LIST (i_or_p);
1145 break;
1146 default:
1147 gcc_unreachable ();
1150 /* Compute size. */
1151 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1152 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
1153 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
1154 size++;
1156 /* Build initializer. */
1157 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1158 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
1159 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1161 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1163 tree pval = TREE_VALUE (lproto);
1165 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
1166 && PROTOCOL_FORWARD_DECL (pval))
1168 tree fwref = PROTOCOL_FORWARD_DECL (pval);
1169 location_t loc = DECL_SOURCE_LOCATION (fwref) ;
1170 e = build_unary_op (loc, ADDR_EXPR, fwref, 0);
1171 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1175 /* static struct objc_protocol *refs[n]; */
1177 switch (TREE_CODE (i_or_p))
1179 case PROTOCOL_INTERFACE_TYPE:
1180 snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
1181 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
1182 break;
1183 case CLASS_INTERFACE_TYPE:
1184 snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
1185 IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
1186 break;
1187 case CATEGORY_INTERFACE_TYPE:
1188 snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
1189 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)),
1190 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt)));
1191 break;
1192 default:
1193 gcc_unreachable ();
1196 ptype = build_pointer_type (objc_protocol_template);
1197 array_type = build_sized_array_type (ptype, size + 3);
1198 refs_decl = start_var_decl (array_type, buf);
1199 OBJCMETA (refs_decl, objc_meta, meta_base);
1200 finish_var_decl (refs_decl,
1201 objc_build_constructor (TREE_TYPE (refs_decl), v));
1203 return refs_decl;
1206 static tree
1207 generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix)
1209 tree method_list_template, initlist, decl;
1210 int size;
1211 VEC(constructor_elt,gc) *v = NULL;
1212 char buf[BUFSIZE];
1214 if (!chain || !prefix)
1215 return NULL_TREE;
1217 if (!objc_method_prototype_template)
1218 objc_method_prototype_template = build_method_prototype_template ();
1220 size = list_length (chain);
1221 method_list_template =
1222 build_method_prototype_list_template (objc_method_prototype_template,
1223 size);
1224 snprintf (buf, BUFSIZE, "%s_%s", prefix,
1225 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
1227 decl = start_var_decl (method_list_template, buf);
1229 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
1230 initlist =
1231 build_descriptor_table_initializer (objc_method_prototype_template,
1232 chain);
1233 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1234 OBJCMETA (decl, objc_meta, meta_base);
1235 finish_var_decl (decl, objc_build_constructor (method_list_template, v));
1236 return decl;
1239 /* For each protocol which was referenced either from a @protocol()
1240 expression, or because a class/category implements it (then a
1241 pointer to the protocol is stored in the struct describing the
1242 class/category), we create a statically allocated instance of the
1243 Protocol class. The code is written in such a way as to generate
1244 as few Protocol objects as possible; we generate a unique Protocol
1245 instance for each protocol, and we don't generate a Protocol
1246 instance if the protocol is never referenced (either from a
1247 @protocol() or from a class/category implementation). These
1248 statically allocated objects can be referred to via the static
1249 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1251 The statically allocated Protocol objects that we generate here
1252 need to be fixed up at runtime in order to be used: the 'isa'
1253 pointer of the objects need to be set up to point to the 'Protocol'
1254 class, as known at runtime.
1256 The GNU runtime fixes up all protocols before user code from the module
1257 is executed; it requires pointers to those symbols
1258 to be put in the objc_symtab (which is then passed as argument to
1259 the function __objc_exec_class() which the compiler sets up to be
1260 executed automatically when the module is loaded); setup of those
1261 Protocol objects happen in two ways in the GNU runtime: all
1262 Protocol objects referred to by a class or category implementation
1263 are fixed up when the class/category is loaded; all Protocol
1264 objects referred to by a @protocol() expression are added by the
1265 compiler to the list of statically allocated instances to fixup
1266 (the same list holding the statically allocated constant string
1267 objects). Because, as explained above, the compiler generates as
1268 few Protocol objects as possible, some Protocol object might end up
1269 being referenced multiple times when compiled with the GNU runtime,
1270 and end up being fixed up multiple times at runtime initialization.
1271 But that doesn't hurt, it's just a little inefficient. */
1273 static void
1274 generate_protocols (void)
1276 tree p, encoding;
1277 tree decl;
1278 tree initlist, protocol_name_expr, refs_decl, refs_expr;
1280 /* If a protocol was directly referenced, pull in indirect references. */
1281 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1282 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
1283 generate_protocol_references (PROTOCOL_LIST (p));
1285 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1287 tree nst_methods = PROTOCOL_NST_METHODS (p);
1288 tree cls_methods = PROTOCOL_CLS_METHODS (p);
1290 /* If protocol wasn't referenced, don't generate any code. */
1291 decl = PROTOCOL_FORWARD_DECL (p);
1293 if (!decl)
1294 continue;
1296 /* Make sure we link in the Protocol class. */
1297 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
1299 while (nst_methods)
1301 if (! METHOD_ENCODING (nst_methods))
1303 encoding = encode_method_prototype (nst_methods);
1304 METHOD_ENCODING (nst_methods) = encoding;
1306 nst_methods = DECL_CHAIN (nst_methods);
1309 UOBJC_INSTANCE_METHODS_decl =
1310 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
1311 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1313 while (cls_methods)
1315 if (! METHOD_ENCODING (cls_methods))
1317 encoding = encode_method_prototype (cls_methods);
1318 METHOD_ENCODING (cls_methods) = encoding;
1321 cls_methods = DECL_CHAIN (cls_methods);
1324 UOBJC_CLASS_METHODS_decl =
1325 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
1326 "_OBJC_PROTOCOL_CLASS_METHODS");
1327 /* generate_method_descriptors (p);*/
1329 if (PROTOCOL_LIST (p))
1330 refs_decl = generate_protocol_list (p, NULL_TREE);
1331 else
1332 refs_decl = 0;
1334 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1335 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
1337 if (refs_decl)
1338 refs_expr = convert (build_pointer_type (build_pointer_type
1339 (objc_protocol_template)),
1340 build_unary_op (input_location,
1341 ADDR_EXPR, refs_decl, 0));
1342 else
1343 refs_expr = build_int_cst (NULL_TREE, 0);
1345 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1346 by generate_method_descriptors, which is called above. */
1347 initlist = build_protocol_initializer (TREE_TYPE (decl),
1348 protocol_name_expr, refs_expr,
1349 UOBJC_INSTANCE_METHODS_decl,
1350 UOBJC_CLASS_METHODS_decl);
1351 finish_var_decl (decl, initlist);
1355 static tree
1356 generate_dispatch_table (tree chain, const char *name)
1358 tree decl, method_list_template, initlist;
1359 VEC(constructor_elt,gc) *v = NULL;
1360 int size = list_length (chain);
1362 if (!objc_method_template)
1363 objc_method_template = build_method_template ();
1365 method_list_template = build_method_list_template (objc_method_template,
1366 size);
1367 initlist = build_dispatch_table_initializer (objc_method_template, chain);
1369 decl = start_var_decl (method_list_template, name);
1371 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1372 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1373 build_int_cst (integer_type_node, size));
1374 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1376 OBJCMETA (decl, objc_meta, meta_base);
1377 finish_var_decl (decl,
1378 objc_build_constructor (TREE_TYPE (decl), v));
1380 return decl;
1383 /* Init a category. */
1384 static tree
1385 build_category_initializer (tree type, tree cat_name, tree class_name,
1386 tree inst_methods, tree class_methods,
1387 tree protocol_list)
1389 tree expr, ltyp;
1390 location_t loc;
1391 VEC(constructor_elt,gc) *v = NULL;
1393 /* TODO: pass the loc in or find it from args. */
1394 /* TODO: pass the loc in or find it from args. */
1395 loc = UNKNOWN_LOCATION;
1396 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
1397 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
1399 ltyp = objc_method_list_ptr;
1400 if (inst_methods)
1401 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1402 else
1403 expr = convert (ltyp, null_pointer_node);
1404 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1406 if (class_methods)
1407 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1408 else
1409 expr = convert (ltyp, null_pointer_node);
1410 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1412 /* protocol_list = */
1413 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1414 if (protocol_list)
1415 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0));
1416 else
1417 expr = convert (ltyp, null_pointer_node);
1418 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1420 return objc_build_constructor (type, v);
1423 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1425 static void
1426 generate_category (struct imp_entry *impent)
1428 tree initlist, cat_name_expr, class_name_expr;
1429 tree protocol_decl, category, cat_decl;
1430 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1431 tree cat = impent->imp_context;
1432 char buf[BUFSIZE];
1434 cat_decl = impent->class_decl;
1436 add_class_reference (CLASS_NAME (cat));
1437 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
1439 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
1441 category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat));
1443 if (category && CLASS_PROTOCOL_LIST (category))
1445 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
1446 protocol_decl = generate_protocol_list (category, cat);
1448 else
1449 protocol_decl = 0;
1451 if (CLASS_NST_METHODS (cat))
1453 snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s",
1454 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1455 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1456 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf);
1459 if (CLASS_CLS_METHODS (cat))
1461 snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s",
1462 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1463 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1464 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf);
1467 initlist = build_category_initializer (TREE_TYPE (cat_decl),
1468 cat_name_expr, class_name_expr,
1469 inst_methods, class_methods,
1470 protocol_decl);
1471 /* Finish and initialize the forward decl. */
1472 finish_var_decl (cat_decl, initlist);
1473 impent->class_decl = cat_decl;
1476 /* struct _objc_class {
1477 struct objc_class *isa;
1478 struct objc_class *super_class;
1479 char *name;
1480 long version;
1481 long info;
1482 long instance_size;
1483 struct objc_ivar_list *ivars;
1484 struct objc_method_list *methods;
1485 struct sarray *dtable;
1486 struct objc_class *subclass_list;
1487 struct objc_class *sibling_class;
1488 struct objc_protocol_list *protocols;
1489 void *gc_object_type;
1490 }; */
1492 static tree
1493 build_shared_structure_initializer (tree type, tree isa, tree super,
1494 tree name, tree size, int status,
1495 tree dispatch_table, tree ivar_list,
1496 tree protocol_list)
1498 tree expr, ltyp;
1499 VEC(constructor_elt,gc) *v = NULL;
1501 /* isa = */
1502 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
1504 /* super_class = */
1505 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
1507 /* name = */
1508 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
1510 /* version = */
1511 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1512 build_int_cst (long_integer_type_node, 0));
1514 /* info = */
1515 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1516 build_int_cst (long_integer_type_node, status));
1518 /* instance_size = */
1519 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1520 convert (long_integer_type_node, size));
1522 /* objc_ivar_list = */
1523 if (!ivar_list)
1524 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1525 build_int_cst (objc_ivar_list_ptr, 0));
1526 else
1528 expr = convert (objc_ivar_list_ptr,
1529 build_unary_op (input_location, ADDR_EXPR,
1530 ivar_list, 0));
1531 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1534 /* objc_method_list = */
1535 if (!dispatch_table)
1536 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1537 convert (objc_method_list_ptr, null_pointer_node));
1538 else
1540 expr = convert (objc_method_list_ptr,
1541 build_unary_op (input_location, ADDR_EXPR,
1542 dispatch_table, 0));
1543 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1546 /* FIXME: Remove NeXT runtime code. */
1547 if (flag_next_runtime)
1549 ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
1550 get_identifier ("objc_cache")));
1551 /* method_cache = */
1552 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
1554 else
1556 /* dtable = */
1557 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1559 /* subclass_list = */
1560 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1562 /* sibling_class = */
1563 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1566 /* protocol_list = */
1567 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1568 if (! protocol_list)
1569 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0));
1570 else
1572 expr = convert (ltyp,
1573 build_unary_op (input_location, ADDR_EXPR,
1574 protocol_list, 0));
1575 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1578 /* FIXME: Remove NeXT runtime code. */
1579 if (flag_next_runtime)
1580 /* sel_id = NULL */
1581 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1583 /* gc_object_type = NULL */
1584 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1586 return objc_build_constructor (type, v);
1590 static tree
1591 generate_ivars_list (tree chain, const char *name)
1593 tree initlist, ivar_list_template, decl;
1594 int size;
1595 VEC(constructor_elt,gc) *inits = NULL;
1597 if (!chain)
1598 return NULL_TREE;
1600 if (!objc_ivar_template)
1601 objc_ivar_template = build_ivar_template ();
1603 size = ivar_list_length (chain);
1605 generating_instance_variables = 1;
1606 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1607 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
1608 generating_instance_variables = 0;
1610 decl = start_var_decl (ivar_list_template, name);
1612 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
1613 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
1615 OBJCMETA (decl, objc_meta, meta_base);
1616 finish_var_decl (decl,
1617 objc_build_constructor (TREE_TYPE (decl), inits));
1619 return decl;
1622 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1623 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1625 static void
1626 generate_class_structures (struct imp_entry *impent)
1628 tree name_expr, super_expr, root_expr, class_decl, meta_decl;
1629 tree my_root_id, my_super_id;
1630 tree cast_type, initlist, protocol_decl;
1631 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1632 tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
1633 location_t loc;
1634 char buf[BUFSIZE];
1635 int cls_flags = 0 ;
1637 /* objc_implementation_context = impent->imp_context;
1638 implementation_template = impent->imp_template;*/
1639 class_decl = impent->class_decl;
1640 meta_decl = impent->meta_decl;
1641 /* UOBJC_CLASS_decl = impent->class_decl;
1642 UOBJC_METACLASS_decl = impent->meta_decl;*/
1644 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1646 my_super_id = CLASS_SUPER_NAME (impent->imp_template);
1647 if (my_super_id)
1649 add_class_reference (my_super_id);
1651 /* Compute "my_root_id" - this is required for code generation.
1652 the "isa" for all meta class structures points to the root of
1653 the inheritance hierarchy (e.g. "__Object")... */
1654 my_root_id = my_super_id;
1657 tree my_root_int = lookup_interface (my_root_id);
1659 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
1660 my_root_id = CLASS_SUPER_NAME (my_root_int);
1661 else
1662 break;
1664 while (1);
1666 else
1667 /* No super class. */
1668 my_root_id = CLASS_NAME (impent->imp_template);
1670 cast_type = build_pointer_type (objc_class_template);
1671 name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
1672 class_names);
1674 /* Install class `isa' and `super' pointers at runtime. */
1675 if (my_super_id)
1676 super_expr = add_objc_string (my_super_id, class_names);
1677 else
1678 super_expr = null_pointer_node;
1680 super_expr = build_c_cast (loc, cast_type, super_expr);
1682 root_expr = add_objc_string (my_root_id, class_names);
1683 root_expr = build_c_cast (loc, cast_type, root_expr);
1685 if (CLASS_PROTOCOL_LIST (impent->imp_template))
1687 generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
1688 protocol_decl = generate_protocol_list (impent->imp_template,
1689 impent->imp_context);
1691 else
1692 protocol_decl = NULL_TREE;
1694 if (CLASS_CLS_METHODS (impent->imp_context))
1696 snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
1697 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1698 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
1699 buf);
1702 if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE
1703 && (chain = TYPE_FIELDS (objc_class_template)))
1705 snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s",
1706 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1707 class_ivars = generate_ivars_list (chain, buf);
1710 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1712 initlist =
1713 build_shared_structure_initializer
1714 (TREE_TYPE (meta_decl),
1715 root_expr, super_expr, name_expr,
1716 convert (integer_type_node,
1717 TYPE_SIZE_UNIT (objc_class_template)),
1718 CLS_META, class_methods, class_ivars,
1719 protocol_decl);
1721 finish_var_decl (meta_decl, initlist);
1722 impent->meta_decl = meta_decl;
1724 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1725 if (CLASS_NST_METHODS (impent->imp_context))
1727 snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
1728 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1729 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
1730 buf);
1733 if ((chain = CLASS_IVARS (impent->imp_template)))
1735 snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
1736 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1737 inst_ivars = generate_ivars_list (chain, buf);
1740 initlist =
1741 build_shared_structure_initializer
1742 (TREE_TYPE (class_decl),
1743 build_unary_op (loc, ADDR_EXPR, meta_decl, 0),
1744 super_expr, name_expr,
1745 convert (integer_type_node,
1746 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1747 (impent->imp_template))),
1748 CLS_FACTORY | cls_flags, inst_methods, inst_ivars,
1749 protocol_decl);
1751 finish_var_decl (class_decl, initlist);
1752 impent->class_decl = class_decl;
1755 /* --- Output GNU Metadata --- */
1757 /* TODO: Make this into an array of refs. */
1758 static void
1759 handle_class_ref (tree chain)
1761 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
1762 char *string = (char *) alloca (strlen (name) + 30);
1763 tree decl;
1764 tree exp;
1766 sprintf (string, "__objc_class_name_%s", name);
1768 /* Make a decl for this name, so we can use its address in a tree. */
1769 decl = build_decl (input_location,
1770 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
1771 DECL_EXTERNAL (decl) = 1;
1772 TREE_PUBLIC (decl) = 1;
1773 DECL_CONTEXT (decl) = NULL_TREE;
1774 finish_var_decl (decl, 0);
1776 /* Make a decl for the address. */
1777 sprintf (string, "__objc_class_ref_%s", name);
1778 exp = build1 (ADDR_EXPR, string_type_node, decl);
1779 decl = build_decl (input_location,
1780 VAR_DECL, get_identifier (string), string_type_node);
1781 TREE_STATIC (decl) = 1;
1782 TREE_USED (decl) = 1;
1783 DECL_READ_P (decl) = 1;
1784 DECL_ARTIFICIAL (decl) = 1;
1785 DECL_INITIAL (decl) = error_mark_node;
1787 /* We must force the reference. */
1788 DECL_PRESERVE_P (decl) = 1;
1790 DECL_CONTEXT (decl) = NULL_TREE;
1791 finish_var_decl (decl, exp);
1794 static tree
1795 get_proto_encoding (tree proto)
1797 tree encoding;
1798 if (proto)
1800 if (! METHOD_ENCODING (proto))
1802 encoding = encode_method_prototype (proto);
1803 METHOD_ENCODING (proto) = encoding;
1805 else
1806 encoding = METHOD_ENCODING (proto);
1808 return add_objc_string (encoding, meth_var_types);
1810 else
1811 return build_int_cst (NULL_TREE, 0);
1814 static void
1815 build_gnu_selector_translation_table (void)
1817 tree chain, expr;
1818 VEC(constructor_elt,gc) *inits = NULL;
1819 VEC(constructor_elt,gc) *v ;
1821 /* Cause the selector table (previously forward-declared)
1822 to be actually output. */
1824 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1826 tree encoding;
1827 if (warn_selector)
1829 /* TODO: improve on the location for the diagnostic. */
1830 location_t loc = input_location;
1831 diagnose_missing_method (TREE_VALUE (chain), loc);
1834 v = NULL;
1835 expr = build_selector (TREE_VALUE (chain));
1836 encoding = get_proto_encoding (TREE_PURPOSE (chain));
1837 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1838 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
1839 expr = objc_build_constructor (objc_selector_template, v);
1841 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1842 } /* each element in the chain */
1844 /* List terminator. */
1845 v = NULL;
1846 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1847 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1848 expr = objc_build_constructor (objc_selector_template, v);
1850 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1851 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1852 inits);
1853 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
1856 /* Output references to all statically allocated objects. Return the DECL
1857 for the array built. */
1859 static void
1860 generate_static_references (void)
1862 tree expr = NULL_TREE;
1863 tree class_name, klass, decl;
1864 tree cl_chain, in_chain, type
1865 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
1866 int num_inst, num_class;
1867 char buf[BUFSIZE];
1868 VEC(constructor_elt,gc) *decls = NULL;
1870 /* FIXME: Remove NeXT runtime code. */
1871 if (flag_next_runtime)
1872 gcc_unreachable ();
1874 for (cl_chain = objc_static_instances, num_class = 0;
1875 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1877 VEC(constructor_elt,gc) *v = NULL;
1879 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1880 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1882 snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class);
1883 decl = start_var_decl (type, buf);
1885 /* Output {class_name, ...}. */
1886 klass = TREE_VALUE (cl_chain);
1887 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
1888 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1889 build_unary_op (input_location,
1890 ADDR_EXPR, class_name, 1));
1892 /* Output {..., instance, ...}. */
1893 for (in_chain = TREE_PURPOSE (cl_chain);
1894 in_chain; in_chain = TREE_CHAIN (in_chain))
1896 expr = build_unary_op (input_location,
1897 ADDR_EXPR, TREE_VALUE (in_chain), 1);
1898 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1901 /* Output {..., NULL}. */
1902 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1904 expr = objc_build_constructor (TREE_TYPE (decl), v);
1905 OBJCMETA (decl, objc_meta, meta_base);
1906 finish_var_decl (decl, expr);
1907 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
1908 build_unary_op (input_location,
1909 ADDR_EXPR, decl, 1));
1912 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
1913 expr = objc_build_constructor (type, decls);
1914 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
1915 OBJCMETA (static_instances_decl, objc_meta, meta_base);
1916 finish_var_decl (static_instances_decl, expr);
1919 /* Create the initial value for the `defs' field of _objc_symtab.
1920 This is a CONSTRUCTOR. */
1922 static tree
1923 init_def_list (tree type)
1925 tree expr;
1926 struct imp_entry *impent;
1927 location_t loc;
1928 VEC(constructor_elt,gc) *v = NULL;
1930 if (imp_count)
1931 for (impent = imp_list; impent; impent = impent->next)
1933 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1935 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1936 expr = build_unary_op (loc,
1937 ADDR_EXPR, impent->class_decl, 0);
1938 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1942 if (cat_count)
1943 for (impent = imp_list; impent; impent = impent->next)
1945 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1947 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1948 expr = build_unary_op (loc,
1949 ADDR_EXPR, impent->class_decl, 0);
1950 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1954 loc = UNKNOWN_LOCATION;
1955 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1956 if (static_instances_decl)
1957 expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0);
1958 else
1959 expr = integer_zero_node;
1960 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1962 return objc_build_constructor (type, v);
1965 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1967 /* Predefine the following data type:
1969 struct _objc_symtab
1971 long sel_ref_cnt;
1972 SEL *refs;
1973 short cls_def_cnt;
1974 short cat_def_cnt;
1975 void *defs[cls_def_cnt + cat_def_cnt];
1976 }; */
1978 static void
1979 build_objc_symtab_template (void)
1981 tree fields, array_type, *chain = NULL;
1982 int index;
1984 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
1986 /* long sel_ref_cnt; */
1987 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
1989 /* SEL *refs; */
1990 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
1992 /* short cls_def_cnt; */
1993 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
1995 /* short cat_def_cnt; */
1996 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
1998 /* FIXME: Remove. */
1999 if (TARGET_64BIT)
2000 add_field_decl (integer_type_node, "_explicit_padder", &chain);
2002 /* void *defs[imp_count + cat_count (+ 1)]; */
2003 /* NB: The index is one less than the size of the array. */
2004 index = imp_count + cat_count;
2005 array_type = build_sized_array_type (ptr_type_node, index + 1);
2006 add_field_decl (array_type, "defs", &chain);
2008 objc_finish_struct (objc_symtab_template, fields);
2010 /* Construct the initial value for all of _objc_symtab. */
2012 static tree
2013 init_objc_symtab (tree type)
2015 tree field, expr, ltyp;
2016 location_t loc;
2017 VEC(constructor_elt,gc) *v = NULL;
2019 loc = UNKNOWN_LOCATION;
2021 /* sel_ref_cnt = { ..., 5, ... } */
2023 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2024 build_int_cst (long_integer_type_node, 0));
2026 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2028 ltyp = build_pointer_type (objc_selector_type);
2029 if (sel_ref_chain)
2030 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,
2031 UOBJC_SELECTOR_TABLE_decl, 1));
2032 else
2033 expr = convert (ltyp, null_pointer_node);
2034 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2036 /* cls_def_cnt = { ..., 5, ... } */
2038 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2039 build_int_cst (short_integer_type_node, imp_count));
2041 /* cat_def_cnt = { ..., 5, ... } */
2043 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2044 build_int_cst (short_integer_type_node, cat_count));
2046 /* FIXME: Remove. */
2047 if (TARGET_64BIT)
2048 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2049 build_int_cst (integer_type_node, 0));
2051 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2053 field = TYPE_FIELDS (type);
2055 /* FIXME: Remove. */
2056 if (TARGET_64BIT)
2057 field = DECL_CHAIN (field);
2059 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2061 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2063 return objc_build_constructor (type, v);
2066 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2067 and initialized appropriately. */
2069 static void
2070 generate_objc_symtab_decl (void)
2072 build_objc_symtab_template ();
2073 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2074 OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base);
2075 finish_var_decl (UOBJC_SYMBOLS_decl,
2076 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2079 static void
2080 objc_generate_v1_gnu_metadata (void)
2082 struct imp_entry *impent;
2083 tree chain;
2085 /* Process the static instances here because initialization of objc_symtab
2086 depends on them. */
2087 if (objc_static_instances)
2088 generate_static_references ();
2090 objc_implementation_context =
2091 implementation_template =
2092 UOBJC_CLASS_decl =
2093 UOBJC_METACLASS_decl = NULL_TREE;
2095 for (impent = imp_list; impent; impent = impent->next)
2097 /* If -gen-decls is present, Dump the @interface of each class.
2098 TODO: Dump the classes in the order they were found, rather than in
2099 reverse order as we are doing now. */
2100 if (flag_gen_declaration)
2101 dump_interface (gen_declaration_file, impent->imp_context);
2103 /* all of the following reference the string pool... */
2104 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2105 generate_class_structures (impent);
2106 else
2107 generate_category (impent);
2110 /* If we are using an array of selectors, we must always
2111 finish up the array decl even if no selectors were used. */
2112 build_gnu_selector_translation_table ();
2114 if (protocol_chain)
2115 generate_protocols ();
2117 /* Arrange for ObjC data structures to be initialized at run time. */
2118 /* FIXME: Have some more elegant way to determine if we need to
2119 generate objc_symtab_decl or not, instead of checking these
2120 global symbols. */
2121 if (imp_list || class_names_chain
2122 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain
2123 || prop_names_attr_chain)
2124 generate_objc_symtab_decl ();
2126 if (imp_list || class_names_chain || objc_static_instances
2127 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
2129 /* Make sure that the meta-data are identified as being
2130 GNU-runtime. */
2131 build_module_descriptor (OBJC_VERSION,
2132 build_tree_list (objc_meta, meta_base));
2133 build_module_initializer_routine ();
2136 /* Dump the class references. This forces the appropriate classes
2137 to be linked into the executable image, preserving unix archive
2138 semantics. This can be removed when we move to a more dynamically
2139 linked environment. */
2141 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
2143 handle_class_ref (chain);
2144 if (TREE_PURPOSE (chain))
2145 generate_classref_translation_entry (chain);
2148 for (impent = imp_list; impent; impent = impent->next)
2149 handle_impent (impent);
2151 generate_strings ();
2154 /* --- exceptions --- */
2156 static GTY(()) tree objc_eh_personality_decl;
2158 static tree
2159 objc_eh_runtime_type (tree type)
2161 tree ident, eh_id, decl, str;
2163 if (type == error_mark_node
2164 || errorcount || sorrycount)
2166 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2167 to prevent an ICE. Note that we know that the compiler will
2168 terminate with an error and this 'ErrorMarkNode' class name will
2169 never be actually used. */
2170 ident = get_identifier ("ErrorMarkNode");
2171 goto make_err_class;
2174 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
2175 /* We don't want to identify 'id' for GNU. Instead, build a 0
2176 entry in the exceptions table. */
2177 return null_pointer_node;
2179 if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
2181 #ifdef OBJCPLUS
2182 /* This routine is also called for c++ catch clauses; in which case,
2183 we use the c++ typeinfo decl. */
2184 return build_eh_type_type (type);
2185 #else
2186 error ("non-objective-c type '%T' cannot be caught", type);
2187 ident = get_identifier ("ErrorMarkNode");
2188 goto make_err_class;
2189 #endif
2191 else
2192 ident = OBJC_TYPE_NAME (TREE_TYPE (type));
2194 make_err_class:
2195 /* If this class was already referenced, then it will be output during
2196 meta-data emission, so we don't need to do it here. */
2197 decl = get_objc_string_decl (ident, class_names);
2198 eh_id = add_objc_string (ident, class_names);
2199 if (!decl)
2201 /* Not found ... so we need to build it - from the freshly-entered id. */
2202 decl = get_objc_string_decl (ident, class_names);
2203 str = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2204 IDENTIFIER_POINTER (ident));
2205 /* We have to finalize this var here, because this might be called after
2206 all the other metadata strings have been emitted. */
2207 finish_var_decl (decl, str);
2209 return eh_id;
2212 static tree
2213 objc_eh_personality (void)
2215 if (!objc_eh_personality_decl)
2216 #ifndef OBJCPLUS
2217 objc_eh_personality_decl = build_personality_function ("gnu_objc");
2218 #else
2219 objc_eh_personality_decl = build_personality_function ("gxx");
2220 #endif
2221 return objc_eh_personality_decl;
2224 /* -- interfaces --- */
2226 static tree
2227 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
2229 tree t;
2230 VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1);
2231 /* A throw is just a call to the runtime throw function with the
2232 object as a parameter. */
2233 VEC_quick_push (tree, parms, throw_expr);
2234 t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
2235 VEC_free (tree, gc, parms);
2236 return add_stmt (t);
2239 /* Build __builtin_eh_pointer. */
2241 static tree
2242 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
2244 tree t;
2245 t = built_in_decls[BUILT_IN_EH_POINTER];
2246 t = build_call_expr (t, 1, integer_zero_node);
2247 return fold_convert (objc_object_type, t);
2250 static tree
2251 begin_catch (struct objc_try_context **cur_try_context, tree type,
2252 tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
2254 tree t;
2255 /* Record the data for the catch in the try context so that we can
2256 finalize it later. */
2257 if (ellipsis)
2258 t = build_stmt (input_location, CATCH_EXPR, NULL, compound);
2259 else
2260 t = build_stmt (input_location, CATCH_EXPR, type, compound);
2261 (*cur_try_context)->current_catch = t;
2263 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2264 t = objc_build_exc_ptr (cur_try_context);
2265 t = convert (TREE_TYPE (decl), t);
2266 return build2 (MODIFY_EXPR, void_type_node, decl, t);
2269 static void
2270 finish_catch (struct objc_try_context **cur_try_context, tree current_catch)
2272 append_to_statement_list (current_catch, &((*cur_try_context)->catch_list));
2275 static tree
2276 finish_try_stmt (struct objc_try_context **cur_try_context)
2278 struct objc_try_context *c = *cur_try_context;
2279 tree stmt = c->try_body;
2280 if (c->catch_list)
2281 stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
2282 if (c->finally_body)
2283 stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
2284 return stmt;
2287 #include "gt-objc-objc-gnu-runtime-abi-01.h"