Remove a trivial assert (missed in previous checkin)
[official-gcc.git] / gcc / objc / objc-gnu-runtime-abi-01.c
blobf0116831e25bbab4bc59b40aa8124ec8cb28ae20
1 /* GNU Runtime ABI version 8
2 Copyright (C) 2011-2013 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"
26 #ifdef OBJCPLUS
27 #include "cp/cp-tree.h"
28 #else
29 #include "c/c-tree.h"
30 #include "c/c-lang.h"
31 #endif
33 #include "langhooks.h"
34 #include "c-family/c-objc.h"
35 #include "objc-act.h"
37 /* When building Objective-C++, we are not linking against the C front-end
38 and so need to replicate the C tree-construction functions in some way. */
39 #ifdef OBJCPLUS
40 #define OBJCP_REMAP_FUNCTIONS
41 #include "objcp-decl.h"
42 #endif /* OBJCPLUS */
44 #include "toplev.h"
45 #include "ggc.h"
46 #include "tree-iterator.h"
48 #include "objc-runtime-hooks.h"
49 #include "objc-runtime-shared-support.h"
50 #include "objc-encoding.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 following 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 static void gnu_runtime_01_initialize (void);
88 static void build_selector_template (void);
90 static tree gnu_runtime_abi_01_super_superclassfield_id (void);
92 static tree gnu_runtime_abi_01_class_decl (tree);
93 static tree gnu_runtime_abi_01_metaclass_decl (tree);
94 static tree gnu_runtime_abi_01_category_decl (tree);
95 static tree gnu_runtime_abi_01_protocol_decl (tree);
96 static tree gnu_runtime_abi_01_string_decl (tree, const char *, string_section);
98 static tree gnu_runtime_abi_01_get_class_reference (tree);
99 static tree gnu_runtime_abi_01_build_typed_selector_reference (location_t, tree,
100 tree);
101 static tree gnu_runtime_abi_01_get_protocol_reference (location_t, tree);
102 static tree gnu_runtime_abi_01_build_ivar_ref (location_t, tree, tree);
103 static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool);
104 static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
106 static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
107 static void gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **,
108 tree, int, int);
109 static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
110 tree, tree, tree, int);
112 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
113 static tree gnu_runtime_abi_01_build_const_string_constructor (location_t, tree,int);
115 static void objc_generate_v1_gnu_metadata (void);
117 static tree objc_eh_runtime_type (tree type);
118 static tree objc_eh_personality (void);
119 static tree objc_build_exc_ptr (struct objc_try_context **);
120 static tree build_throw_stmt (location_t, tree, bool);
121 static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool);
122 static void finish_catch (struct objc_try_context **, tree);
123 static tree finish_try_stmt (struct objc_try_context **);
125 bool
126 objc_gnu_runtime_abi_01_init (objc_runtime_hooks *rthooks)
128 /* GNU runtime does not need the compiler to change code in order to do GC. */
129 if (flag_objc_gc)
131 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
132 flag_objc_gc = 0;
135 /* Although I guess we could, we don't currently support SJLJ exceptions for the
136 GNU runtime. */
137 if (flag_objc_sjlj_exceptions)
139 inform (UNKNOWN_LOCATION, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
140 flag_objc_sjlj_exceptions = 0;
143 /* TODO: Complain if -fobjc-abi-version=N was used. */
145 /* TODO: Complain if -fobj-nilcheck was used. */
147 rthooks->initialize = gnu_runtime_01_initialize;
148 rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
149 rthooks->tag_getclass = TAG_GETCLASS;
150 rthooks->super_superclassfield_ident = gnu_runtime_abi_01_super_superclassfield_id;
152 rthooks->class_decl = gnu_runtime_abi_01_class_decl;
153 rthooks->metaclass_decl = gnu_runtime_abi_01_metaclass_decl;
154 rthooks->category_decl = gnu_runtime_abi_01_category_decl;
155 rthooks->protocol_decl = gnu_runtime_abi_01_protocol_decl;
156 rthooks->string_decl = gnu_runtime_abi_01_string_decl;
158 rthooks->get_class_reference = gnu_runtime_abi_01_get_class_reference;
159 rthooks->build_selector_reference = gnu_runtime_abi_01_build_typed_selector_reference;
160 rthooks->get_protocol_reference = gnu_runtime_abi_01_get_protocol_reference;
161 rthooks->build_ivar_reference = gnu_runtime_abi_01_build_ivar_ref;
162 rthooks->get_class_super_ref = gnu_runtime_abi_01_get_class_super_ref;
163 rthooks->get_category_super_ref = gnu_runtime_abi_01_get_category_super_ref;
165 rthooks->receiver_is_class_object = gnu_runtime_abi_01_receiver_is_class_object;
166 rthooks->get_arg_type_list_base = gnu_runtime_abi_01_get_arg_type_list_base;
167 rthooks->build_objc_method_call = gnu_runtime_abi_01_build_objc_method_call;
169 rthooks->setup_const_string_class_decl =
170 gnu_runtime_abi_01_setup_const_string_class_decl;
171 rthooks->build_const_string_constructor =
172 gnu_runtime_abi_01_build_const_string_constructor;
174 rthooks->build_throw_stmt = build_throw_stmt;
175 rthooks->build_exc_ptr = objc_build_exc_ptr;
176 rthooks->begin_catch = begin_catch;
177 rthooks->finish_catch = finish_catch;
178 rthooks->finish_try_stmt = finish_try_stmt;
180 rthooks->generate_metadata = objc_generate_v1_gnu_metadata;
181 return true;
184 static void build_selector_table_decl (void);
185 static void build_class_template (void);
186 static void build_category_template (void);
187 static void build_protocol_template (void);
189 static GTY(()) tree objc_meta;
190 static GTY(()) tree meta_base;
192 static void gnu_runtime_01_initialize (void)
194 tree type, ftype, IMP_type;
196 /* We do not need to mark GNU ObjC metadata for different sections,
197 however, we do need to make sure that it is not mistaken for NeXT
198 metadata. */
199 objc_meta = get_identifier ("OBJC1METG");
200 meta_base = get_identifier ("NONE");
202 /* Declare type of selector-objects that represent an operation name. */
203 /* `const struct objc_selector *' */
204 type = xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR));
205 type = build_qualified_type (type, TYPE_QUAL_CONST);
206 objc_selector_type = build_pointer_type (type);
208 /* typedef id (*IMP)(id, SEL, ...); */
209 ftype = build_varargs_function_type_list (objc_object_type,
210 objc_object_type,
211 objc_selector_type,
212 NULL_TREE);
214 IMP_type = build_pointer_type (ftype);
216 build_class_template ();
217 build_super_template ();
218 build_protocol_template ();
219 build_category_template ();
221 /* GNU runtime messenger entry points. */
222 /* TREE_NOTHROW is cleared for the message-sending functions,
223 because the function that gets called can throw in Obj-C++, or
224 could itself call something that can throw even in Obj-C. */
226 /* IMP objc_msg_lookup (id, SEL); */
227 type = build_function_type_list (IMP_type,
228 objc_object_type,
229 objc_selector_type,
230 NULL_TREE);
232 umsg_decl = add_builtin_function (TAG_MSGSEND,
233 type, 0, NOT_BUILT_IN,
234 NULL, NULL_TREE);
235 TREE_NOTHROW (umsg_decl) = 0;
237 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
238 type = build_function_type_list (IMP_type,
239 objc_super_type,
240 objc_selector_type,
241 NULL_TREE);
243 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
244 type, 0, NOT_BUILT_IN,
245 NULL, NULL_TREE);
246 TREE_NOTHROW (umsg_super_decl) = 0;
248 /* The following GNU runtime entry point is called to initialize
249 each module:
251 __objc_exec_class (void *); */
252 type = build_function_type_list (void_type_node,
253 ptr_type_node,
254 NULL_TREE);
256 execclass_decl = add_builtin_function (TAG_EXECCLASS,
257 type, 0, NOT_BUILT_IN,
258 NULL, NULL_TREE);
260 type = build_function_type_list (objc_object_type,
261 const_string_type_node,
262 NULL_TREE);
264 /* id objc_getClass (const char *); */
265 objc_get_class_decl
266 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
267 NULL, NULL_TREE);
269 /* id objc_getMetaClass (const char *); */
270 objc_get_meta_class_decl = add_builtin_function (TAG_GETMETACLASS, type,
271 0, NOT_BUILT_IN, NULL,
272 NULL_TREE);
274 /* static SEL _OBJC_SELECTOR_TABLE[]; */
275 build_selector_table_decl ();
277 /* Stuff for properties.
278 The codegen relies on this being NULL for GNU. */
279 objc_copyStruct_decl = NULL_TREE;
281 /* This is the type of all of the following functions
282 bjc_getPropertyStruct() and objc_setPropertyStruct(). */
283 type = build_function_type_list (void_type_node,
284 ptr_type_node,
285 const_ptr_type_node,
286 ptrdiff_type_node,
287 boolean_type_node,
288 boolean_type_node,
289 NULL_TREE);
291 /* Declare the following function:
292 void
293 objc_getPropertyStruct (void *destination, const void *source,
294 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
295 objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
296 type, 0, NOT_BUILT_IN,
297 NULL, NULL_TREE);
298 TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
299 /* Declare the following function:
300 void
301 objc_setPropertyStruct (void *destination, const void *source,
302 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
303 objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
304 type, 0, NOT_BUILT_IN,
305 NULL, NULL_TREE);
306 TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
308 using_eh_for_cleanups ();
309 lang_hooks.eh_runtime_type = objc_eh_runtime_type;
310 lang_hooks.eh_personality = objc_eh_personality;
313 /* --- templates --- */
314 /* struct _objc_selector {
315 SEL sel_id;
316 char *sel_type;
317 }; */
319 static void
320 build_selector_template (void)
322 tree decls, *chain = NULL;
324 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
326 /* SEL sel_id; */
327 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
329 /* char *sel_type; */
330 add_field_decl (string_type_node, "sel_type", &chain);
332 objc_finish_struct (objc_selector_template, decls);
335 /* struct _objc_class {
336 struct _objc_class *isa;
337 struct _objc_class *super_class;
338 char *name;
339 long version;
340 long info;
341 long instance_size;
342 struct _objc_ivar_list *ivars;
343 struct _objc_method_list *methods;
344 struct sarray *dtable;
345 struct _objc_class *subclass_list;
346 struct _objc_class *sibling_class;
347 struct _objc_protocol_list *protocols;
348 void *gc_object_type;
349 }; */
351 static void
352 build_class_template (void)
354 tree ptype, decls, *chain = NULL;
356 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
358 /* struct _objc_class *isa; */
359 decls = add_field_decl (build_pointer_type (objc_class_template),
360 "isa", &chain);
362 /* struct _objc_class *super_class; */
363 add_field_decl (build_pointer_type (objc_class_template),
364 "super_class", &chain);
366 /* char *name; */
367 add_field_decl (string_type_node, "name", &chain);
369 /* long version; */
370 add_field_decl (long_integer_type_node, "version", &chain);
372 /* long info; */
373 add_field_decl (long_integer_type_node, "info", &chain);
375 /* long instance_size; */
376 add_field_decl (long_integer_type_node, "instance_size", &chain);
378 /* struct _objc_ivar_list *ivars; */
379 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
381 /* struct _objc_method_list *methods; */
382 add_field_decl (objc_method_list_ptr, "methods", &chain);
384 /* struct sarray *dtable; */
385 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
386 get_identifier ("sarray")));
387 add_field_decl (ptype, "dtable", &chain);
389 /* struct objc_class *subclass_list; */
390 ptype = build_pointer_type (objc_class_template);
391 add_field_decl (ptype, "subclass_list", &chain);
393 /* struct objc_class *sibling_class; */
394 ptype = build_pointer_type (objc_class_template);
395 add_field_decl (ptype, "sibling_class", &chain);
397 /* struct _objc_protocol **protocol_list; */
398 ptype = build_pointer_type (build_pointer_type
399 (xref_tag (RECORD_TYPE,
400 get_identifier (UTAG_PROTOCOL))));
401 add_field_decl (ptype, "protocol_list", &chain);
403 /* void *gc_object_type; */
404 add_field_decl (build_pointer_type (void_type_node),
405 "gc_object_type", &chain);
407 objc_finish_struct (objc_class_template, decls);
410 /* struct _objc_category {
411 char *category_name;
412 char *class_name;
413 struct _objc_method_list *instance_methods;
414 struct _objc_method_list *class_methods;
415 struct _objc_protocol_list *protocols;
416 }; */
418 static void
419 build_category_template (void)
421 tree ptype, decls, *chain = NULL;
423 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
425 /* char *category_name; */
426 decls = add_field_decl (string_type_node, "category_name", &chain);
428 /* char *class_name; */
429 add_field_decl (string_type_node, "class_name", &chain);
431 /* struct _objc_method_list *instance_methods; */
432 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
434 /* struct _objc_method_list *class_methods; */
435 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
437 /* struct _objc_protocol **protocol_list; */
438 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
439 add_field_decl (ptype, "protocol_list", &chain);
441 objc_finish_struct (objc_category_template, decls);
444 /* struct _objc_protocol {
445 struct _objc_class *isa;
446 char *protocol_name;
447 struct _objc_protocol **protocol_list;
448 struct _objc__method_prototype_list *instance_methods;
449 struct _objc__method_prototype_list *class_methods;
450 }; */
452 static void
453 build_protocol_template (void)
455 tree ptype, decls, *chain = NULL;
457 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
459 /* struct _objc_class *isa; */
460 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
461 get_identifier (UTAG_CLASS)));
462 decls = add_field_decl (ptype, "isa", &chain);
464 /* char *protocol_name; */
465 add_field_decl (string_type_node, "protocol_name", &chain);
467 /* struct _objc_protocol **protocol_list; */
468 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
469 add_field_decl (ptype, "protocol_list", &chain);
471 /* struct _objc__method_prototype_list *instance_methods; */
472 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
474 /* struct _objc__method_prototype_list *class_methods; */
475 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
477 objc_finish_struct (objc_protocol_template, decls);
480 /* --- names, decls + identifiers --- */
482 static void
483 build_selector_table_decl (void)
485 tree temp;
487 build_selector_template ();
488 temp = build_array_type (objc_selector_template, NULL_TREE);
490 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
491 OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base);
495 static tree
496 gnu_runtime_abi_01_super_superclassfield_id (void)
498 if (!super_superclassfield_id)
499 super_superclassfield_id = get_identifier ("super_class");
500 return super_superclassfield_id;
504 static tree
505 gnu_runtime_abi_01_class_decl (tree klass)
507 tree decl;
508 char buf[BUFSIZE];
509 snprintf (buf, BUFSIZE, "_OBJC_Class_%s",
510 IDENTIFIER_POINTER (CLASS_NAME (klass)));
511 decl = start_var_decl (objc_class_template, buf);
512 OBJCMETA (decl, objc_meta, meta_base);
513 return decl;
516 static tree
517 gnu_runtime_abi_01_metaclass_decl (tree klass)
519 tree decl;
520 char buf[BUFSIZE];
521 snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s",
522 IDENTIFIER_POINTER (CLASS_NAME (klass)));
523 decl = start_var_decl (objc_class_template, buf);
524 OBJCMETA (decl, objc_meta, meta_base);
525 return decl;
528 static tree
529 gnu_runtime_abi_01_category_decl (tree klass)
531 tree decl;
532 char buf[BUFSIZE];
533 snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
534 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)),
535 IDENTIFIER_POINTER (CLASS_NAME (klass)));
536 decl = start_var_decl (objc_category_template, buf);
537 OBJCMETA (decl, objc_meta, meta_base);
538 return decl;
541 static tree
542 gnu_runtime_abi_01_protocol_decl (tree p)
544 tree decl;
545 char buf[BUFSIZE];
547 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
548 snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
549 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
550 decl = start_var_decl (objc_protocol_template, buf);
551 OBJCMETA (decl, objc_meta, meta_base);
552 return decl;
555 static tree
556 gnu_runtime_abi_01_string_decl (tree type, const char *name,
557 string_section where ATTRIBUTE_UNUSED)
559 tree decl = start_var_decl (type, name);
560 OBJCMETA (decl, objc_meta, meta_base);
561 return decl;
564 /* --- entry --- */
566 static tree
567 gnu_runtime_abi_01_get_class_reference (tree ident)
569 tree params;
571 add_class_reference (ident);
573 params = build_tree_list (NULL_TREE, my_build_string_pointer
574 (IDENTIFIER_LENGTH (ident) + 1,
575 IDENTIFIER_POINTER (ident)));
577 return build_function_call (input_location, objc_get_class_decl, params);
580 /* Used by build_function_type_for_method. Append the types for
581 receiver & _cmd at the start of a method argument list to ARGTYPES.
582 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
583 trying to define a method or call one. SUPERFLAG says this is for a
584 send to super. METH may be NULL, in the case that there is no
585 prototype. */
587 static void
588 gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
589 tree meth, int context,
590 int superflag ATTRIBUTE_UNUSED)
592 tree receiver_type;
594 if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
595 receiver_type = objc_instance_type;
596 else
597 receiver_type = objc_object_type;
599 vec_safe_push (*argtypes, receiver_type);
600 /* Selector type - will eventually change to `int'. */
601 vec_safe_push (*argtypes, objc_selector_type);
604 /* Unused for GNU runtime. */
605 static tree
606 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED)
608 return NULL_TREE;
611 /* sel_ref_chain is a list whose "value" fields will be instances of
612 identifier_node that represent the selector. LOC is the location of
613 the @selector. */
615 static tree
616 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc, tree ident,
617 tree prototype)
619 tree *chain = &sel_ref_chain;
620 tree expr;
621 int index = 0;
623 while (*chain)
625 /* When we do a lookup for @selector () we have no idea of the
626 prototype - so match the first we find. */
627 if (TREE_VALUE (*chain) == ident
628 && (!prototype || TREE_PURPOSE (*chain) == prototype))
629 goto return_at_index;
631 index++;
632 chain = &TREE_CHAIN (*chain);
635 *chain = tree_cons (prototype, ident, NULL_TREE);
637 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
638 (b) provide better diagnostics for the first time an undefined
639 selector is used. */
640 return_at_index:
641 expr = build_unary_op (loc, ADDR_EXPR,
642 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
643 build_int_cst (NULL_TREE, index)),
645 return convert (objc_selector_type, expr);
648 /* Build a tree expression to send OBJECT the operation SELECTOR,
649 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
650 assuming the method has prototype METHOD_PROTOTYPE.
651 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
652 LOC is the location of the expression to build.
653 Use METHOD_PARAMS as list of args to pass to the method.
654 If SUPER_FLAG is nonzero, we look up the superclass's method. */
656 static tree
657 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
658 tree lookup_object, tree selector,
659 tree method_params)
661 tree sender = (super_flag ? umsg_super_decl
662 : (flag_objc_direct_dispatch ? umsg_fast_decl
663 : umsg_decl));
664 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
665 vec<tree, va_gc> *parms;
666 vec<tree, va_gc> *tv;
667 unsigned nparm = (method_params ? list_length (method_params) : 0);
669 /* If a prototype for the method to be called exists, then cast
670 the sender's return type and arguments to match that of the method.
671 Otherwise, leave sender as is. */
672 tree ret_type
673 = (method_prototype
674 ? TREE_VALUE (TREE_TYPE (method_prototype))
675 : objc_object_type);
676 tree ftype
677 = build_function_type_for_method (ret_type, method_prototype,
678 METHOD_REF, super_flag);
679 tree sender_cast;
680 tree method, t;
682 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
683 ftype = build_type_attribute_variant (ftype,
684 METHOD_TYPE_ATTRIBUTES
685 (method_prototype));
687 sender_cast = build_pointer_type (ftype);
689 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
691 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
692 lookup_object = save_expr (lookup_object);
694 /* Param list + 2 slots for object and selector. */
695 vec_alloc (parms, nparm + 2);
696 vec_alloc (tv, 2);
698 /* First, call the lookup function to get a pointer to the method,
699 then cast the pointer, then call it with the method arguments. */
700 tv->quick_push (lookup_object);
701 tv->quick_push (selector);
702 method = build_function_call_vec (loc, sender, tv, NULL);
703 vec_free (tv);
705 /* Pass the appropriate object to the method. */
706 parms->quick_push ((super_flag ? self_decl : lookup_object));
708 /* Pass the selector to the method. */
709 parms->quick_push (selector);
710 /* Now append the remainder of the parms. */
711 if (nparm)
712 for (; method_params; method_params = TREE_CHAIN (method_params))
713 parms->quick_push (TREE_VALUE (method_params));
715 /* Build an obj_type_ref, with the correct cast for the method call. */
716 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
717 t = build_function_call_vec (loc, t, parms, NULL);
718 vec_free (parms);
719 return t;
722 static tree
723 gnu_runtime_abi_01_build_objc_method_call (location_t loc,
724 tree method_prototype,
725 tree receiver,
726 tree rtype ATTRIBUTE_UNUSED,
727 tree sel_name,
728 tree method_params,
729 int super ATTRIBUTE_UNUSED)
731 tree selector =
732 gnu_runtime_abi_01_build_typed_selector_reference (loc,
733 sel_name,
734 method_prototype);
736 return build_objc_method_call (loc, super, method_prototype, receiver,
737 selector, method_params);
740 static tree
741 gnu_runtime_abi_01_get_protocol_reference (location_t loc, tree p)
743 tree expr, protocol_struct_type, *chain;
744 if (!PROTOCOL_FORWARD_DECL (p))
745 PROTOCOL_FORWARD_DECL (p) = gnu_runtime_abi_01_protocol_decl (p);
747 expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
749 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
750 if we have it, rather than converting it here. */
751 expr = convert (objc_protocol_type, expr);
753 /* The @protocol() expression is being compiled into a pointer to a
754 statically allocated instance of the Protocol class. To become
755 usable at runtime, the 'isa' pointer of the instance need to be
756 fixed up at runtime by the runtime library, to point to the
757 actual 'Protocol' class. */
759 /* For the GNU runtime, put the static Protocol instance in the list
760 of statically allocated instances, so that we make sure that its
761 'isa' pointer is fixed up at runtime by the GNU runtime library
762 to point to the Protocol class (at runtime, when loading the
763 module, the GNU runtime library loops on the statically allocated
764 instances (as found in the defs field in objc_symtab) and fixups
765 all the 'isa' pointers of those objects). */
767 /* This type is a struct containing the fields of a Protocol
768 object. (Cfr. objc_protocol_type instead is the type of a pointer
769 to such a struct). */
770 protocol_struct_type = xref_tag (RECORD_TYPE,
771 get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
773 /* Look for the list of Protocol statically allocated instances
774 to fixup at runtime. Create a new list to hold Protocol
775 statically allocated instances, if the list is not found. At
776 present there is only another list, holding NSConstantString
777 static instances to be fixed up at runtime. */
779 for (chain = &objc_static_instances;
780 *chain && TREE_VALUE (*chain) != protocol_struct_type;
781 chain = &TREE_CHAIN (*chain));
783 if (!*chain)
785 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
786 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
787 class_names);
790 /* Add this statically allocated instance to the Protocol list. */
791 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
792 PROTOCOL_FORWARD_DECL (p),
793 TREE_PURPOSE (*chain));
794 return expr;
797 /* For ABI 8 an IVAR is just a fixed offset in the class struct. */
799 static tree
800 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
801 tree base, tree id)
803 return objc_build_component_ref (base, id);
806 /* We build super class references as we need them (but keep them once
807 built for the sake of efficiency). */
809 static tree
810 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
811 struct imp_entry *imp, bool inst_meth)
813 if (inst_meth)
815 if (!ucls_super_ref)
816 ucls_super_ref =
817 objc_build_component_ref (imp->class_decl,
818 get_identifier ("super_class"));
819 return ucls_super_ref;
821 else
823 if (!uucls_super_ref)
824 uucls_super_ref =
825 objc_build_component_ref (imp->meta_decl,
826 get_identifier ("super_class"));
827 return uucls_super_ref;
831 static tree
832 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
833 struct imp_entry *imp, bool inst_meth)
835 tree super_name = CLASS_SUPER_NAME (imp->imp_template);
836 tree super_class;
838 add_class_reference (super_name);
839 super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
840 super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
841 IDENTIFIER_POINTER (super_name));
842 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
843 return build_function_call (input_location,
844 super_class,
845 build_tree_list (NULL_TREE, super_name));
848 static bool
849 gnu_runtime_abi_01_setup_const_string_class_decl (void)
851 /* Do nothing, and create no error. */
852 return true;
855 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
857 static GTY(()) int num_static_inst;
859 static tree
860 objc_add_static_instance (tree constructor, tree class_decl)
862 tree *chain, decl;
863 char buf[BUFSIZE];
865 /* Find the list of static instances for the CLASS_DECL. Create one if
866 not found. */
867 for (chain = &objc_static_instances;
868 *chain && TREE_VALUE (*chain) != class_decl;
869 chain = &TREE_CHAIN (*chain));
870 if (!*chain)
872 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
873 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
876 snprintf (buf, BUFSIZE, "_OBJC_INSTANCE_%d", num_static_inst++);
877 decl = build_decl (input_location,
878 VAR_DECL, get_identifier (buf), class_decl);
879 TREE_STATIC (decl) = 1;
880 DECL_ARTIFICIAL (decl) = 1;
881 TREE_USED (decl) = 1;
882 DECL_INITIAL (decl) = constructor;
883 DECL_CONTEXT (decl) = NULL;
884 OBJCMETA (decl, objc_meta, meta_base);
886 /* We may be writing something else just now.
887 Postpone till end of input. */
888 DECL_DEFER_OUTPUT (decl) = 1;
889 pushdecl_top_level (decl);
890 rest_of_decl_compilation (decl, 1, 0);
892 /* Add the DECL to the head of this CLASS' list. */
893 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
895 return decl;
898 static tree
899 gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string,
900 int length)
902 tree constructor, fields;
903 vec<constructor_elt, va_gc> *v = NULL;
905 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
906 fields = TYPE_FIELDS (internal_const_str_type);
907 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0));
909 fields = DECL_CHAIN (fields);
910 CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc,
911 ADDR_EXPR, string, 1));
913 fields = DECL_CHAIN (fields);
914 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
915 constructor = objc_build_constructor (internal_const_str_type, v);
917 constructor = objc_add_static_instance (constructor, constant_string_type);
918 return constructor;
921 /* --- metadata - module initializer --- */
923 /* The GNU runtime requires us to provide a static initializer function
924 for each module:
926 static void __objc_gnu_init (void) {
927 __objc_exec_class (&L_OBJC_MODULES);
928 } */
931 static void
932 build_module_initializer_routine (void)
934 tree body;
936 #ifdef OBJCPLUS
937 push_lang_context (lang_name_c); /* extern "C" */
938 #endif
940 objc_push_parm (build_decl (input_location,
941 PARM_DECL, NULL_TREE, void_type_node));
942 #ifdef OBJCPLUS
943 objc_start_function (get_identifier (TAG_GNUINIT),
944 build_function_type_list (void_type_node, NULL_TREE),
945 NULL_TREE, NULL_TREE);
946 #else
947 objc_start_function (get_identifier (TAG_GNUINIT),
948 build_function_type_list (void_type_node, NULL_TREE),
949 NULL_TREE, objc_get_parm_info (0, NULL_TREE));
950 #endif
951 body = c_begin_compound_stmt (true);
952 add_stmt (build_function_call
953 (input_location,
954 execclass_decl,
955 build_tree_list
956 (NULL_TREE,
957 build_unary_op (input_location, ADDR_EXPR,
958 UOBJC_MODULES_decl, 0))));
959 add_stmt (c_end_compound_stmt (input_location, body, true));
961 TREE_PUBLIC (current_function_decl) = 0;
963 #ifndef OBJCPLUS
964 /* For Objective-C++, we will need to call __objc_gnu_init
965 from objc_generate_static_init_call() below. */
966 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
967 #endif
969 GNU_INIT_decl = current_function_decl;
970 finish_function ();
972 #ifdef OBJCPLUS
973 pop_lang_context ();
974 #endif
977 #ifdef OBJCPLUS
978 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
979 to be called by the module initializer routine. */
982 objc_static_init_needed_p (void)
984 return (GNU_INIT_decl != NULL_TREE);
987 /* Generate a call to the __objc_gnu_init initializer function. */
989 tree
990 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
992 add_stmt (build_stmt (input_location, EXPR_STMT,
993 build_function_call (input_location,
994 GNU_INIT_decl, NULL_TREE)));
996 return ctors;
998 #endif /* OBJCPLUS */
1000 /* --- Output GNU Meta-data --- */
1002 static void
1003 generate_classref_translation_entry (tree chain)
1005 tree expr, decl, type;
1007 decl = TREE_PURPOSE (chain);
1008 type = TREE_TYPE (decl);
1010 expr = add_objc_string (TREE_VALUE (chain), class_names);
1011 expr = convert (type, expr); /* cast! */
1013 /* This is a class reference. It is re-written by the runtime,
1014 but will be optimized away unless we force it. */
1015 DECL_PRESERVE_P (decl) = 1;
1016 OBJCMETA (decl, objc_meta, meta_base);
1017 finish_var_decl (decl, expr);
1018 return;
1022 static void
1023 handle_impent (struct imp_entry *impent)
1025 char *string;
1027 /* objc_implementation_context = impent->imp_context;
1028 implementation_template = impent->imp_template;*/
1030 switch (TREE_CODE (impent->imp_context))
1032 case CLASS_IMPLEMENTATION_TYPE:
1034 const char *const class_name =
1035 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1037 string = (char *) alloca (strlen (class_name) + 30);
1039 sprintf (string, "__objc_class_name_%s", class_name);
1040 break;
1042 case CATEGORY_IMPLEMENTATION_TYPE:
1044 const char *const class_name =
1045 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1046 const char *const class_super_name =
1047 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
1049 string = (char *) alloca (strlen (class_name)
1050 + strlen (class_super_name) + 30);
1052 /* Do the same for categories. Even though no references to
1053 these symbols are generated automatically by the compiler,
1054 it gives you a handle to pull them into an archive by
1055 hand. */
1056 sprintf (string, "*__objc_category_name_%s_%s", class_name, class_super_name);
1057 break;
1059 default:
1060 return;
1064 tree decl, init;
1066 init = integer_zero_node;
1067 decl = build_decl (input_location,
1068 VAR_DECL, get_identifier (string), TREE_TYPE (init));
1069 TREE_PUBLIC (decl) = 1;
1070 TREE_READONLY (decl) = 1;
1071 TREE_USED (decl) = 1;
1072 TREE_CONSTANT (decl) = 1;
1073 DECL_CONTEXT (decl) = NULL_TREE;
1074 DECL_ARTIFICIAL (decl) = 1;
1075 TREE_STATIC (decl) = 1;
1076 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
1077 /* We must force the reference. */
1078 DECL_PRESERVE_P (decl) = 1;
1080 finish_var_decl(decl, init) ;
1084 tree
1085 build_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
1086 tree inst_methods, tree class_methods)
1088 tree expr, ttyp;
1089 location_t loc;
1090 vec<constructor_elt, va_gc> *inits = NULL;
1092 /* TODO: pass the loc in or find it from args. */
1093 loc = input_location;
1094 ttyp = build_pointer_type (xref_tag (RECORD_TYPE,
1095 get_identifier (UTAG_CLASS)));
1096 /* Filling the "isa" in with a version allows the runtime system to
1097 detect this ... */
1098 expr = build_int_cst (ttyp, PROTOCOL_VERSION);
1100 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1102 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
1103 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
1105 ttyp = objc_method_proto_list_ptr;
1106 if (inst_methods)
1107 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1108 else
1109 expr = convert (ttyp, null_pointer_node);
1110 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1112 if (class_methods)
1113 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1114 else
1115 expr = convert (ttyp, null_pointer_node);
1116 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1118 return objc_build_constructor (type, inits);
1121 static tree
1122 generate_protocol_list (tree i_or_p, tree klass_ctxt)
1124 tree array_type, ptype, refs_decl, lproto, e, plist;
1125 vec<constructor_elt, va_gc> *v = NULL;
1126 char buf[BUFSIZE];
1127 int size = 0;
1129 switch (TREE_CODE (i_or_p))
1131 case CLASS_INTERFACE_TYPE:
1132 case CATEGORY_INTERFACE_TYPE:
1133 plist = CLASS_PROTOCOL_LIST (i_or_p);
1134 break;
1135 case PROTOCOL_INTERFACE_TYPE:
1136 plist = PROTOCOL_LIST (i_or_p);
1137 break;
1138 default:
1139 gcc_unreachable ();
1142 /* Compute size. */
1143 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1144 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
1145 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
1146 size++;
1148 /* Build initializer. */
1149 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1150 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
1151 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1153 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1155 tree pval = TREE_VALUE (lproto);
1157 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
1158 && PROTOCOL_FORWARD_DECL (pval))
1160 tree fwref = PROTOCOL_FORWARD_DECL (pval);
1161 location_t loc = DECL_SOURCE_LOCATION (fwref) ;
1162 e = build_unary_op (loc, ADDR_EXPR, fwref, 0);
1163 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1167 /* static struct objc_protocol *refs[n]; */
1169 switch (TREE_CODE (i_or_p))
1171 case PROTOCOL_INTERFACE_TYPE:
1172 snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
1173 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
1174 break;
1175 case CLASS_INTERFACE_TYPE:
1176 snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
1177 IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
1178 break;
1179 case CATEGORY_INTERFACE_TYPE:
1180 snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
1181 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)),
1182 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt)));
1183 break;
1184 default:
1185 gcc_unreachable ();
1188 ptype = build_pointer_type (objc_protocol_template);
1189 array_type = build_sized_array_type (ptype, size + 3);
1190 refs_decl = start_var_decl (array_type, buf);
1191 OBJCMETA (refs_decl, objc_meta, meta_base);
1192 finish_var_decl (refs_decl,
1193 objc_build_constructor (TREE_TYPE (refs_decl), v));
1195 return refs_decl;
1198 static tree
1199 generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix)
1201 tree method_list_template, initlist, decl;
1202 int size;
1203 vec<constructor_elt, va_gc> *v = NULL;
1204 char buf[BUFSIZE];
1206 if (!chain || !prefix)
1207 return NULL_TREE;
1209 if (!objc_method_prototype_template)
1210 objc_method_prototype_template = build_method_prototype_template ();
1212 size = list_length (chain);
1213 method_list_template =
1214 build_method_prototype_list_template (objc_method_prototype_template,
1215 size);
1216 snprintf (buf, BUFSIZE, "%s_%s", prefix,
1217 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
1219 decl = start_var_decl (method_list_template, buf);
1221 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
1222 initlist =
1223 build_descriptor_table_initializer (objc_method_prototype_template,
1224 chain);
1225 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1226 OBJCMETA (decl, objc_meta, meta_base);
1227 finish_var_decl (decl, objc_build_constructor (method_list_template, v));
1228 return decl;
1231 /* For each protocol which was referenced either from a @protocol()
1232 expression, or because a class/category implements it (then a
1233 pointer to the protocol is stored in the struct describing the
1234 class/category), we create a statically allocated instance of the
1235 Protocol class. The code is written in such a way as to generate
1236 as few Protocol objects as possible; we generate a unique Protocol
1237 instance for each protocol, and we don't generate a Protocol
1238 instance if the protocol is never referenced (either from a
1239 @protocol() or from a class/category implementation). These
1240 statically allocated objects can be referred to via the static
1241 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1243 The statically allocated Protocol objects that we generate here
1244 need to be fixed up at runtime in order to be used: the 'isa'
1245 pointer of the objects need to be set up to point to the 'Protocol'
1246 class, as known at runtime.
1248 The GNU runtime fixes up all protocols before user code from the module
1249 is executed; it requires pointers to those symbols
1250 to be put in the objc_symtab (which is then passed as argument to
1251 the function __objc_exec_class() which the compiler sets up to be
1252 executed automatically when the module is loaded); setup of those
1253 Protocol objects happen in two ways in the GNU runtime: all
1254 Protocol objects referred to by a class or category implementation
1255 are fixed up when the class/category is loaded; all Protocol
1256 objects referred to by a @protocol() expression are added by the
1257 compiler to the list of statically allocated instances to fixup
1258 (the same list holding the statically allocated constant string
1259 objects). Because, as explained above, the compiler generates as
1260 few Protocol objects as possible, some Protocol object might end up
1261 being referenced multiple times when compiled with the GNU runtime,
1262 and end up being fixed up multiple times at runtime initialization.
1263 But that doesn't hurt, it's just a little inefficient. */
1265 static void
1266 generate_protocols (void)
1268 tree p, encoding;
1269 tree decl;
1270 tree initlist, protocol_name_expr, refs_decl, refs_expr;
1272 /* If a protocol was directly referenced, pull in indirect references. */
1273 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1274 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
1275 generate_protocol_references (PROTOCOL_LIST (p));
1277 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1279 tree nst_methods = PROTOCOL_NST_METHODS (p);
1280 tree cls_methods = PROTOCOL_CLS_METHODS (p);
1282 /* If protocol wasn't referenced, don't generate any code. */
1283 decl = PROTOCOL_FORWARD_DECL (p);
1285 if (!decl)
1286 continue;
1288 /* Make sure we link in the Protocol class. */
1289 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
1291 while (nst_methods)
1293 if (! METHOD_ENCODING (nst_methods))
1295 encoding = encode_method_prototype (nst_methods);
1296 METHOD_ENCODING (nst_methods) = encoding;
1298 nst_methods = DECL_CHAIN (nst_methods);
1301 UOBJC_INSTANCE_METHODS_decl =
1302 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
1303 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1305 while (cls_methods)
1307 if (! METHOD_ENCODING (cls_methods))
1309 encoding = encode_method_prototype (cls_methods);
1310 METHOD_ENCODING (cls_methods) = encoding;
1313 cls_methods = DECL_CHAIN (cls_methods);
1316 UOBJC_CLASS_METHODS_decl =
1317 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
1318 "_OBJC_PROTOCOL_CLASS_METHODS");
1319 /* generate_method_descriptors (p);*/
1321 if (PROTOCOL_LIST (p))
1322 refs_decl = generate_protocol_list (p, NULL_TREE);
1323 else
1324 refs_decl = 0;
1326 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1327 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
1329 if (refs_decl)
1330 refs_expr = convert (build_pointer_type (build_pointer_type
1331 (objc_protocol_template)),
1332 build_unary_op (input_location,
1333 ADDR_EXPR, refs_decl, 0));
1334 else
1335 refs_expr = build_int_cst (NULL_TREE, 0);
1337 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1338 by generate_method_descriptors, which is called above. */
1339 initlist = build_protocol_initializer (TREE_TYPE (decl),
1340 protocol_name_expr, refs_expr,
1341 UOBJC_INSTANCE_METHODS_decl,
1342 UOBJC_CLASS_METHODS_decl);
1343 finish_var_decl (decl, initlist);
1347 static tree
1348 generate_dispatch_table (tree chain, const char *name)
1350 tree decl, method_list_template, initlist;
1351 vec<constructor_elt, va_gc> *v = NULL;
1352 int size = list_length (chain);
1354 if (!objc_method_template)
1355 objc_method_template = build_method_template ();
1357 method_list_template = build_method_list_template (objc_method_template,
1358 size);
1359 initlist = build_dispatch_table_initializer (objc_method_template, chain);
1361 decl = start_var_decl (method_list_template, name);
1363 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1364 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1365 build_int_cst (integer_type_node, size));
1366 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1368 OBJCMETA (decl, objc_meta, meta_base);
1369 finish_var_decl (decl,
1370 objc_build_constructor (TREE_TYPE (decl), v));
1372 return decl;
1375 /* Init a category. */
1376 static tree
1377 build_category_initializer (tree type, tree cat_name, tree class_name,
1378 tree inst_methods, tree class_methods,
1379 tree protocol_list)
1381 tree expr, ltyp;
1382 location_t loc;
1383 vec<constructor_elt, va_gc> *v = NULL;
1385 /* TODO: pass the loc in or find it from args. */
1386 /* TODO: pass the loc in or find it from args. */
1387 loc = UNKNOWN_LOCATION;
1388 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
1389 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
1391 ltyp = objc_method_list_ptr;
1392 if (inst_methods)
1393 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1394 else
1395 expr = convert (ltyp, null_pointer_node);
1396 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1398 if (class_methods)
1399 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1400 else
1401 expr = convert (ltyp, null_pointer_node);
1402 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1404 /* protocol_list = */
1405 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1406 if (protocol_list)
1407 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0));
1408 else
1409 expr = convert (ltyp, null_pointer_node);
1410 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1412 return objc_build_constructor (type, v);
1415 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1417 static void
1418 generate_category (struct imp_entry *impent)
1420 tree initlist, cat_name_expr, class_name_expr;
1421 tree protocol_decl, category, cat_decl;
1422 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1423 tree cat = impent->imp_context;
1424 char buf[BUFSIZE];
1426 cat_decl = impent->class_decl;
1428 add_class_reference (CLASS_NAME (cat));
1429 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
1431 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
1433 category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat));
1435 if (category && CLASS_PROTOCOL_LIST (category))
1437 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
1438 protocol_decl = generate_protocol_list (category, cat);
1440 else
1441 protocol_decl = 0;
1443 if (CLASS_NST_METHODS (cat))
1445 snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s",
1446 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1447 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1448 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf);
1451 if (CLASS_CLS_METHODS (cat))
1453 snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s",
1454 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1455 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1456 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf);
1459 initlist = build_category_initializer (TREE_TYPE (cat_decl),
1460 cat_name_expr, class_name_expr,
1461 inst_methods, class_methods,
1462 protocol_decl);
1463 /* Finish and initialize the forward decl. */
1464 finish_var_decl (cat_decl, initlist);
1465 impent->class_decl = cat_decl;
1468 /* struct _objc_class {
1469 struct objc_class *isa;
1470 struct objc_class *super_class;
1471 char *name;
1472 long version;
1473 long info;
1474 long instance_size;
1475 struct objc_ivar_list *ivars;
1476 struct objc_method_list *methods;
1477 struct sarray *dtable;
1478 struct objc_class *subclass_list;
1479 struct objc_class *sibling_class;
1480 struct objc_protocol_list *protocols;
1481 void *gc_object_type;
1482 }; */
1484 static tree
1485 build_shared_structure_initializer (tree type, tree isa, tree super,
1486 tree name, tree size, int status,
1487 tree dispatch_table, tree ivar_list,
1488 tree protocol_list)
1490 tree expr, ltyp;
1491 vec<constructor_elt, va_gc> *v = NULL;
1493 /* isa = */
1494 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
1496 /* super_class = */
1497 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
1499 /* name = */
1500 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
1502 /* version = */
1503 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1504 build_int_cst (long_integer_type_node, 0));
1506 /* info = */
1507 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1508 build_int_cst (long_integer_type_node, status));
1510 /* instance_size = */
1511 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1512 convert (long_integer_type_node, size));
1514 /* objc_ivar_list = */
1515 if (!ivar_list)
1516 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1517 build_int_cst (objc_ivar_list_ptr, 0));
1518 else
1520 expr = convert (objc_ivar_list_ptr,
1521 build_unary_op (input_location, ADDR_EXPR,
1522 ivar_list, 0));
1523 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1526 /* objc_method_list = */
1527 if (!dispatch_table)
1528 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1529 convert (objc_method_list_ptr, null_pointer_node));
1530 else
1532 expr = convert (objc_method_list_ptr,
1533 build_unary_op (input_location, ADDR_EXPR,
1534 dispatch_table, 0));
1535 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1538 /* FIXME: Remove NeXT runtime code. */
1539 if (flag_next_runtime)
1541 ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
1542 get_identifier ("objc_cache")));
1543 /* method_cache = */
1544 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
1546 else
1548 /* dtable = */
1549 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1551 /* subclass_list = */
1552 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1554 /* sibling_class = */
1555 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1558 /* protocol_list = */
1559 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1560 if (! protocol_list)
1561 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0));
1562 else
1564 expr = convert (ltyp,
1565 build_unary_op (input_location, ADDR_EXPR,
1566 protocol_list, 0));
1567 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1570 /* FIXME: Remove NeXT runtime code. */
1571 if (flag_next_runtime)
1572 /* sel_id = NULL */
1573 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1575 /* gc_object_type = NULL */
1576 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1578 return objc_build_constructor (type, v);
1582 static tree
1583 generate_ivars_list (tree chain, const char *name)
1585 tree initlist, ivar_list_template, decl;
1586 int size;
1587 vec<constructor_elt, va_gc> *inits = NULL;
1589 if (!chain)
1590 return NULL_TREE;
1592 if (!objc_ivar_template)
1593 objc_ivar_template = build_ivar_template ();
1595 size = ivar_list_length (chain);
1597 generating_instance_variables = 1;
1598 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1599 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
1600 generating_instance_variables = 0;
1602 decl = start_var_decl (ivar_list_template, name);
1604 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
1605 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
1607 OBJCMETA (decl, objc_meta, meta_base);
1608 finish_var_decl (decl,
1609 objc_build_constructor (TREE_TYPE (decl), inits));
1611 return decl;
1614 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1615 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1617 static void
1618 generate_class_structures (struct imp_entry *impent)
1620 tree name_expr, super_expr, root_expr, class_decl, meta_decl;
1621 tree my_root_id, my_super_id;
1622 tree cast_type, initlist, protocol_decl;
1623 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1624 tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
1625 location_t loc;
1626 char buf[BUFSIZE];
1627 int cls_flags = 0 ;
1629 /* objc_implementation_context = impent->imp_context;
1630 implementation_template = impent->imp_template;*/
1631 class_decl = impent->class_decl;
1632 meta_decl = impent->meta_decl;
1633 /* UOBJC_CLASS_decl = impent->class_decl;
1634 UOBJC_METACLASS_decl = impent->meta_decl;*/
1636 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1638 my_super_id = CLASS_SUPER_NAME (impent->imp_template);
1639 if (my_super_id)
1641 add_class_reference (my_super_id);
1643 /* Compute "my_root_id" - this is required for code generation.
1644 the "isa" for all meta class structures points to the root of
1645 the inheritance hierarchy (e.g. "__Object")... */
1646 my_root_id = my_super_id;
1649 tree my_root_int = lookup_interface (my_root_id);
1651 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
1652 my_root_id = CLASS_SUPER_NAME (my_root_int);
1653 else
1654 break;
1656 while (1);
1658 else
1659 /* No super class. */
1660 my_root_id = CLASS_NAME (impent->imp_template);
1662 cast_type = build_pointer_type (objc_class_template);
1663 name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
1664 class_names);
1666 /* Install class `isa' and `super' pointers at runtime. */
1667 if (my_super_id)
1668 super_expr = add_objc_string (my_super_id, class_names);
1669 else
1670 super_expr = null_pointer_node;
1672 super_expr = build_c_cast (loc, cast_type, super_expr);
1674 root_expr = add_objc_string (my_root_id, class_names);
1675 root_expr = build_c_cast (loc, cast_type, root_expr);
1677 if (CLASS_PROTOCOL_LIST (impent->imp_template))
1679 generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
1680 protocol_decl = generate_protocol_list (impent->imp_template,
1681 impent->imp_context);
1683 else
1684 protocol_decl = NULL_TREE;
1686 if (CLASS_CLS_METHODS (impent->imp_context))
1688 snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
1689 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1690 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
1691 buf);
1694 if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE
1695 && (chain = TYPE_FIELDS (objc_class_template)))
1697 snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s",
1698 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1699 class_ivars = generate_ivars_list (chain, buf);
1702 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1704 initlist =
1705 build_shared_structure_initializer
1706 (TREE_TYPE (meta_decl),
1707 root_expr, super_expr, name_expr,
1708 convert (integer_type_node,
1709 TYPE_SIZE_UNIT (objc_class_template)),
1710 CLS_META, class_methods, class_ivars,
1711 protocol_decl);
1713 finish_var_decl (meta_decl, initlist);
1714 impent->meta_decl = meta_decl;
1716 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1717 if (CLASS_NST_METHODS (impent->imp_context))
1719 snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
1720 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1721 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
1722 buf);
1725 if ((chain = CLASS_IVARS (impent->imp_template)))
1727 snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
1728 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1729 inst_ivars = generate_ivars_list (chain, buf);
1732 initlist =
1733 build_shared_structure_initializer
1734 (TREE_TYPE (class_decl),
1735 build_unary_op (loc, ADDR_EXPR, meta_decl, 0),
1736 super_expr, name_expr,
1737 convert (integer_type_node,
1738 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1739 (impent->imp_template))),
1740 CLS_FACTORY | cls_flags, inst_methods, inst_ivars,
1741 protocol_decl);
1743 finish_var_decl (class_decl, initlist);
1744 impent->class_decl = class_decl;
1747 /* --- Output GNU Metadata --- */
1749 /* TODO: Make this into an array of refs. */
1750 static void
1751 handle_class_ref (tree chain)
1753 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
1754 char *string = (char *) alloca (strlen (name) + 30);
1755 tree decl;
1756 tree exp;
1758 sprintf (string, "__objc_class_name_%s", name);
1760 /* Make a decl for this name, so we can use its address in a tree. */
1761 decl = build_decl (input_location,
1762 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
1763 DECL_EXTERNAL (decl) = 1;
1764 TREE_PUBLIC (decl) = 1;
1765 DECL_CONTEXT (decl) = NULL_TREE;
1766 finish_var_decl (decl, 0);
1768 /* Make a decl for the address. */
1769 sprintf (string, "__objc_class_ref_%s", name);
1770 exp = build1 (ADDR_EXPR, string_type_node, decl);
1771 decl = build_decl (input_location,
1772 VAR_DECL, get_identifier (string), string_type_node);
1773 TREE_STATIC (decl) = 1;
1774 TREE_USED (decl) = 1;
1775 DECL_READ_P (decl) = 1;
1776 DECL_ARTIFICIAL (decl) = 1;
1777 DECL_INITIAL (decl) = error_mark_node;
1779 /* We must force the reference. */
1780 DECL_PRESERVE_P (decl) = 1;
1782 DECL_CONTEXT (decl) = NULL_TREE;
1783 finish_var_decl (decl, exp);
1786 static tree
1787 get_proto_encoding (tree proto)
1789 tree encoding;
1790 if (proto)
1792 if (! METHOD_ENCODING (proto))
1794 encoding = encode_method_prototype (proto);
1795 METHOD_ENCODING (proto) = encoding;
1797 else
1798 encoding = METHOD_ENCODING (proto);
1800 return add_objc_string (encoding, meth_var_types);
1802 else
1803 return build_int_cst (NULL_TREE, 0);
1806 static void
1807 build_gnu_selector_translation_table (void)
1809 tree chain, expr;
1810 vec<constructor_elt, va_gc> *inits = NULL;
1811 vec<constructor_elt, va_gc> *v ;
1813 /* Cause the selector table (previously forward-declared)
1814 to be actually output. */
1816 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1818 tree encoding;
1819 if (warn_selector)
1821 /* TODO: improve on the location for the diagnostic. */
1822 location_t loc = input_location;
1823 diagnose_missing_method (TREE_VALUE (chain), loc);
1826 v = NULL;
1827 expr = build_selector (TREE_VALUE (chain));
1828 encoding = get_proto_encoding (TREE_PURPOSE (chain));
1829 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1830 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
1831 expr = objc_build_constructor (objc_selector_template, v);
1833 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1834 } /* each element in the chain */
1836 /* List terminator. */
1837 v = NULL;
1838 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1839 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1840 expr = objc_build_constructor (objc_selector_template, v);
1842 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1843 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1844 inits);
1845 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
1848 /* Output references to all statically allocated objects. Return the DECL
1849 for the array built. */
1851 static void
1852 generate_static_references (void)
1854 tree expr = NULL_TREE;
1855 tree class_name, klass, decl;
1856 tree cl_chain, in_chain, type
1857 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
1858 int num_inst, num_class;
1859 char buf[BUFSIZE];
1860 vec<constructor_elt, va_gc> *decls = NULL;
1862 /* FIXME: Remove NeXT runtime code. */
1863 if (flag_next_runtime)
1864 gcc_unreachable ();
1866 for (cl_chain = objc_static_instances, num_class = 0;
1867 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1869 vec<constructor_elt, va_gc> *v = NULL;
1871 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1872 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1874 snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class);
1875 decl = start_var_decl (type, buf);
1877 /* Output {class_name, ...}. */
1878 klass = TREE_VALUE (cl_chain);
1879 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
1880 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1881 build_unary_op (input_location,
1882 ADDR_EXPR, class_name, 1));
1884 /* Output {..., instance, ...}. */
1885 for (in_chain = TREE_PURPOSE (cl_chain);
1886 in_chain; in_chain = TREE_CHAIN (in_chain))
1888 expr = build_unary_op (input_location,
1889 ADDR_EXPR, TREE_VALUE (in_chain), 1);
1890 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1893 /* Output {..., NULL}. */
1894 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1896 expr = objc_build_constructor (TREE_TYPE (decl), v);
1897 OBJCMETA (decl, objc_meta, meta_base);
1898 finish_var_decl (decl, expr);
1899 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
1900 build_unary_op (input_location,
1901 ADDR_EXPR, decl, 1));
1904 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
1905 expr = objc_build_constructor (type, decls);
1906 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
1907 OBJCMETA (static_instances_decl, objc_meta, meta_base);
1908 finish_var_decl (static_instances_decl, expr);
1911 /* Create the initial value for the `defs' field of _objc_symtab.
1912 This is a CONSTRUCTOR. */
1914 static tree
1915 init_def_list (tree type)
1917 tree expr;
1918 struct imp_entry *impent;
1919 location_t loc;
1920 vec<constructor_elt, va_gc> *v = NULL;
1922 if (imp_count)
1923 for (impent = imp_list; impent; impent = impent->next)
1925 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1927 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1928 expr = build_unary_op (loc,
1929 ADDR_EXPR, impent->class_decl, 0);
1930 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1934 if (cat_count)
1935 for (impent = imp_list; impent; impent = impent->next)
1937 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1939 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1940 expr = build_unary_op (loc,
1941 ADDR_EXPR, impent->class_decl, 0);
1942 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1946 loc = UNKNOWN_LOCATION;
1947 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1948 if (static_instances_decl)
1949 expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0);
1950 else
1951 expr = integer_zero_node;
1952 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1954 return objc_build_constructor (type, v);
1957 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1959 /* Predefine the following data type:
1961 struct _objc_symtab
1963 long sel_ref_cnt;
1964 SEL *refs;
1965 short cls_def_cnt;
1966 short cat_def_cnt;
1967 void *defs[cls_def_cnt + cat_def_cnt];
1968 }; */
1970 static void
1971 build_objc_symtab_template (void)
1973 tree fields, array_type, *chain = NULL;
1974 int index;
1976 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
1978 /* long sel_ref_cnt; */
1979 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
1981 /* SEL *refs; */
1982 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
1984 /* short cls_def_cnt; */
1985 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
1987 /* short cat_def_cnt; */
1988 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
1990 /* Note that padding will be added here on LP64. */
1992 /* void *defs[imp_count + cat_count (+ 1)]; */
1993 /* NB: The index is one less than the size of the array. */
1994 index = imp_count + cat_count;
1995 array_type = build_sized_array_type (ptr_type_node, index + 1);
1996 add_field_decl (array_type, "defs", &chain);
1998 objc_finish_struct (objc_symtab_template, fields);
2000 /* Construct the initial value for all of _objc_symtab. */
2002 static tree
2003 init_objc_symtab (tree type)
2005 tree field, expr, ltyp;
2006 location_t loc;
2007 vec<constructor_elt, va_gc> *v = NULL;
2009 loc = UNKNOWN_LOCATION;
2011 /* sel_ref_cnt = { ..., 5, ... } */
2013 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2014 build_int_cst (long_integer_type_node, 0));
2016 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2018 ltyp = build_pointer_type (objc_selector_type);
2019 if (sel_ref_chain)
2020 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,
2021 UOBJC_SELECTOR_TABLE_decl, 1));
2022 else
2023 expr = convert (ltyp, null_pointer_node);
2024 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2026 /* cls_def_cnt = { ..., 5, ... } */
2028 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2029 build_int_cst (short_integer_type_node, imp_count));
2031 /* cat_def_cnt = { ..., 5, ... } */
2033 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2034 build_int_cst (short_integer_type_node, cat_count));
2036 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2038 field = TYPE_FIELDS (type);
2039 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2041 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2043 return objc_build_constructor (type, v);
2046 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2047 and initialized appropriately. */
2049 static void
2050 generate_objc_symtab_decl (void)
2052 build_objc_symtab_template ();
2053 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2054 OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base);
2055 finish_var_decl (UOBJC_SYMBOLS_decl,
2056 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2059 static void
2060 objc_generate_v1_gnu_metadata (void)
2062 struct imp_entry *impent;
2063 tree chain;
2065 /* Process the static instances here because initialization of objc_symtab
2066 depends on them. */
2067 if (objc_static_instances)
2068 generate_static_references ();
2070 objc_implementation_context =
2071 implementation_template =
2072 UOBJC_CLASS_decl =
2073 UOBJC_METACLASS_decl = NULL_TREE;
2075 for (impent = imp_list; impent; impent = impent->next)
2077 /* If -gen-decls is present, Dump the @interface of each class.
2078 TODO: Dump the classes in the order they were found, rather than in
2079 reverse order as we are doing now. */
2080 if (flag_gen_declaration)
2081 dump_interface (gen_declaration_file, impent->imp_context);
2083 /* all of the following reference the string pool... */
2084 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2085 generate_class_structures (impent);
2086 else
2087 generate_category (impent);
2090 /* If we are using an array of selectors, we must always
2091 finish up the array decl even if no selectors were used. */
2092 build_gnu_selector_translation_table ();
2094 if (protocol_chain)
2095 generate_protocols ();
2097 /* Arrange for ObjC data structures to be initialized at run time. */
2098 /* FIXME: Have some more elegant way to determine if we need to
2099 generate objc_symtab_decl or not, instead of checking these
2100 global symbols. */
2101 if (imp_list || class_names_chain
2102 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain
2103 || prop_names_attr_chain)
2104 generate_objc_symtab_decl ();
2106 if (imp_list || class_names_chain || objc_static_instances
2107 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
2109 /* Make sure that the meta-data are identified as being
2110 GNU-runtime. */
2111 build_module_descriptor (OBJC_VERSION,
2112 build_tree_list (objc_meta, meta_base));
2113 build_module_initializer_routine ();
2116 /* Dump the class references. This forces the appropriate classes
2117 to be linked into the executable image, preserving unix archive
2118 semantics. This can be removed when we move to a more dynamically
2119 linked environment. */
2121 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
2123 handle_class_ref (chain);
2124 if (TREE_PURPOSE (chain))
2125 generate_classref_translation_entry (chain);
2128 for (impent = imp_list; impent; impent = impent->next)
2129 handle_impent (impent);
2131 generate_strings ();
2134 /* --- exceptions --- */
2136 static GTY(()) tree objc_eh_personality_decl;
2138 static tree
2139 objc_eh_runtime_type (tree type)
2141 tree ident, eh_id, decl, str;
2143 if (type == error_mark_node
2144 || errorcount || sorrycount)
2146 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2147 to prevent an ICE. Note that we know that the compiler will
2148 terminate with an error and this 'ErrorMarkNode' class name will
2149 never be actually used. */
2150 ident = get_identifier ("ErrorMarkNode");
2151 goto make_err_class;
2154 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
2155 /* We don't want to identify 'id' for GNU. Instead, build a 0
2156 entry in the exceptions table. */
2157 return null_pointer_node;
2159 if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
2161 #ifdef OBJCPLUS
2162 /* This routine is also called for c++ catch clauses; in which case,
2163 we use the c++ typeinfo decl. */
2164 return build_eh_type_type (type);
2165 #else
2166 error ("non-objective-c type '%T' cannot be caught", type);
2167 ident = get_identifier ("ErrorMarkNode");
2168 goto make_err_class;
2169 #endif
2171 else
2172 ident = OBJC_TYPE_NAME (TREE_TYPE (type));
2174 make_err_class:
2175 /* If this class was already referenced, then it will be output during
2176 meta-data emission, so we don't need to do it here. */
2177 decl = get_objc_string_decl (ident, class_names);
2178 eh_id = add_objc_string (ident, class_names);
2179 if (!decl)
2181 /* Not found ... so we need to build it - from the freshly-entered id. */
2182 decl = get_objc_string_decl (ident, class_names);
2183 str = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2184 IDENTIFIER_POINTER (ident));
2185 /* We have to finalize this var here, because this might be called after
2186 all the other metadata strings have been emitted. */
2187 finish_var_decl (decl, str);
2189 return eh_id;
2192 static tree
2193 objc_eh_personality (void)
2195 if (!objc_eh_personality_decl)
2196 #ifndef OBJCPLUS
2197 objc_eh_personality_decl = build_personality_function ("gnu_objc");
2198 #else
2199 objc_eh_personality_decl = build_personality_function ("gxx");
2200 #endif
2201 return objc_eh_personality_decl;
2204 /* -- interfaces --- */
2206 static tree
2207 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
2209 tree t;
2210 vec<tree, va_gc> *parms;
2211 vec_alloc (parms, 1);
2212 /* A throw is just a call to the runtime throw function with the
2213 object as a parameter. */
2214 parms->quick_push (throw_expr);
2215 t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
2216 vec_free (parms);
2217 return add_stmt (t);
2220 /* Build __builtin_eh_pointer. */
2222 static tree
2223 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
2225 tree t;
2226 t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
2227 t = build_call_expr (t, 1, integer_zero_node);
2228 return fold_convert (objc_object_type, t);
2231 static tree
2232 begin_catch (struct objc_try_context **cur_try_context, tree type,
2233 tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
2235 tree t;
2236 /* Record the data for the catch in the try context so that we can
2237 finalize it later. */
2238 if (ellipsis)
2239 t = build_stmt (input_location, CATCH_EXPR, NULL, compound);
2240 else
2241 t = build_stmt (input_location, CATCH_EXPR, type, compound);
2242 (*cur_try_context)->current_catch = t;
2244 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2245 t = objc_build_exc_ptr (cur_try_context);
2246 t = convert (TREE_TYPE (decl), t);
2247 return build2 (MODIFY_EXPR, void_type_node, decl, t);
2250 static void
2251 finish_catch (struct objc_try_context **cur_try_context, tree current_catch)
2253 append_to_statement_list (current_catch, &((*cur_try_context)->catch_list));
2256 static tree
2257 finish_try_stmt (struct objc_try_context **cur_try_context)
2259 struct objc_try_context *c = *cur_try_context;
2260 tree stmt = c->try_body;
2261 if (c->catch_list)
2262 stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
2263 if (c->finally_body)
2264 stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
2265 return stmt;
2268 #include "gt-objc-objc-gnu-runtime-abi-01.h"