don't check in warn_logical_not_paren-check on folded result of current's lhs.
[official-gcc.git] / gcc / objc / objc-gnu-runtime-abi-01.c
blob55d6ed7964b0e8cb9cae1dd622ea82b2e44bca85
1 /* GNU Runtime ABI version 8
2 Copyright (C) 2011-2015 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 "alias.h"
25 #include "symtab.h"
26 #include "options.h"
27 #include "tree.h"
28 #include "fold-const.h"
29 #include "stringpool.h"
31 #ifdef OBJCPLUS
32 #include "cp/cp-tree.h"
33 #else
34 #include "c/c-tree.h"
35 #include "c/c-lang.h"
36 #endif
38 #include "langhooks.h"
39 #include "c-family/c-objc.h"
40 #include "objc-act.h"
42 /* When building Objective-C++, we are not linking against the C front-end
43 and so need to replicate the C tree-construction functions in some way. */
44 #ifdef OBJCPLUS
45 #define OBJCP_REMAP_FUNCTIONS
46 #include "objcp-decl.h"
47 #endif /* OBJCPLUS */
49 #include "toplev.h"
50 #include "tree-iterator.h"
52 #include "objc-runtime-hooks.h"
53 #include "objc-runtime-shared-support.h"
54 #include "objc-encoding.h"
56 /* GNU runtime private definitions. */
57 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
59 #define TAG_GETCLASS "objc_get_class"
60 #define TAG_GETMETACLASS "objc_get_meta_class"
62 #define TAG_MSGSEND "objc_msg_lookup"
63 #define TAG_MSGSENDSUPER "objc_msg_lookup_super"
65 /* GNU-specific tags. */
67 #define TAG_EXECCLASS "__objc_exec_class"
68 #define TAG_GNUINIT "__objc_gnu_init"
70 /* The version identifies which language generation and runtime
71 the module (file) was compiled for, and is recorded in the
72 module descriptor. */
73 #define OBJC_VERSION 8
75 #define PROTOCOL_VERSION 2
77 /* This macro provides a method of removing ambiguity between runtimes
78 when LTO is in use on targets supporting multiple runtimes.
80 For example, at present, any target that includes an implementation of
81 the NeXT runtime needs to place Objective-C meta-data into specific
82 named sections. This should _not_ be done for the GNU runtime, and the
83 following macro is used to attach Objective-C private attributes that may
84 be used to identify the runtime for which the meta-data are intended. */
86 #define OBJCMETA(DECL,VERS,KIND) \
87 if (VERS) \
88 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
90 static void gnu_runtime_01_initialize (void);
92 static void build_selector_template (void);
94 static tree gnu_runtime_abi_01_super_superclassfield_id (void);
96 static tree gnu_runtime_abi_01_class_decl (tree);
97 static tree gnu_runtime_abi_01_metaclass_decl (tree);
98 static tree gnu_runtime_abi_01_category_decl (tree);
99 static tree gnu_runtime_abi_01_protocol_decl (tree);
100 static tree gnu_runtime_abi_01_string_decl (tree, const char *, string_section);
102 static tree gnu_runtime_abi_01_get_class_reference (tree);
103 static tree gnu_runtime_abi_01_build_typed_selector_reference (location_t, tree,
104 tree);
105 static tree gnu_runtime_abi_01_get_protocol_reference (location_t, tree);
106 static tree gnu_runtime_abi_01_build_ivar_ref (location_t, tree, tree);
107 static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool);
108 static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
110 static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
111 static void gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **,
112 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 + identifiers --- */
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 /* Squash `defined but not used' warning check_global_declaration. */
496 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
497 OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base);
501 static tree
502 gnu_runtime_abi_01_super_superclassfield_id (void)
504 if (!super_superclassfield_id)
505 super_superclassfield_id = get_identifier ("super_class");
506 return super_superclassfield_id;
510 static tree
511 gnu_runtime_abi_01_class_decl (tree klass)
513 tree decl;
514 char buf[BUFSIZE];
515 snprintf (buf, BUFSIZE, "_OBJC_Class_%s",
516 IDENTIFIER_POINTER (CLASS_NAME (klass)));
517 decl = start_var_decl (objc_class_template, buf);
518 OBJCMETA (decl, objc_meta, meta_base);
519 return decl;
522 static tree
523 gnu_runtime_abi_01_metaclass_decl (tree klass)
525 tree decl;
526 char buf[BUFSIZE];
527 snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s",
528 IDENTIFIER_POINTER (CLASS_NAME (klass)));
529 decl = start_var_decl (objc_class_template, buf);
530 OBJCMETA (decl, objc_meta, meta_base);
531 return decl;
534 static tree
535 gnu_runtime_abi_01_category_decl (tree klass)
537 tree decl;
538 char buf[BUFSIZE];
539 snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
540 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)),
541 IDENTIFIER_POINTER (CLASS_NAME (klass)));
542 decl = start_var_decl (objc_category_template, buf);
543 OBJCMETA (decl, objc_meta, meta_base);
544 return decl;
547 static tree
548 gnu_runtime_abi_01_protocol_decl (tree p)
550 tree decl;
551 char buf[BUFSIZE];
553 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
554 snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
555 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
556 decl = start_var_decl (objc_protocol_template, buf);
557 OBJCMETA (decl, objc_meta, meta_base);
558 return decl;
561 static tree
562 gnu_runtime_abi_01_string_decl (tree type, const char *name,
563 string_section where ATTRIBUTE_UNUSED)
565 tree decl = start_var_decl (type, name);
566 OBJCMETA (decl, objc_meta, meta_base);
567 return decl;
570 /* --- entry --- */
572 static tree
573 gnu_runtime_abi_01_get_class_reference (tree ident)
575 tree params;
577 add_class_reference (ident);
579 params = build_tree_list (NULL_TREE, my_build_string_pointer
580 (IDENTIFIER_LENGTH (ident) + 1,
581 IDENTIFIER_POINTER (ident)));
583 return build_function_call (input_location, objc_get_class_decl, params);
586 /* Used by build_function_type_for_method. Append the types for
587 receiver & _cmd at the start of a method argument list to ARGTYPES.
588 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
589 trying to define a method or call one. SUPERFLAG says this is for a
590 send to super. METH may be NULL, in the case that there is no
591 prototype. */
593 static void
594 gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
595 tree meth, int context,
596 int superflag ATTRIBUTE_UNUSED)
598 tree receiver_type;
600 if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
601 receiver_type = objc_instance_type;
602 else
603 receiver_type = objc_object_type;
605 vec_safe_push (*argtypes, receiver_type);
606 /* Selector type - will eventually change to `int'. */
607 vec_safe_push (*argtypes, objc_selector_type);
610 /* Unused for GNU runtime. */
611 static tree
612 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED)
614 return NULL_TREE;
617 /* sel_ref_chain is a list whose "value" fields will be instances of
618 identifier_node that represent the selector. LOC is the location of
619 the @selector. */
621 static tree
622 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc, tree ident,
623 tree prototype)
625 tree *chain = &sel_ref_chain;
626 tree expr;
627 int index = 0;
629 while (*chain)
631 /* When we do a lookup for @selector () we have no idea of the
632 prototype - so match the first we find. */
633 if (TREE_VALUE (*chain) == ident
634 && (!prototype || TREE_PURPOSE (*chain) == prototype))
635 goto return_at_index;
637 index++;
638 chain = &TREE_CHAIN (*chain);
641 *chain = tree_cons (prototype, ident, NULL_TREE);
643 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
644 (b) provide better diagnostics for the first time an undefined
645 selector is used. */
646 return_at_index:
647 expr = build_unary_op (loc, ADDR_EXPR,
648 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
649 build_int_cst (NULL_TREE, index)),
651 return convert (objc_selector_type, expr);
654 /* Build a tree expression to send OBJECT the operation SELECTOR,
655 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
656 assuming the method has prototype METHOD_PROTOTYPE.
657 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
658 LOC is the location of the expression to build.
659 Use METHOD_PARAMS as list of args to pass to the method.
660 If SUPER_FLAG is nonzero, we look up the superclass's method. */
662 static tree
663 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
664 tree lookup_object, tree selector,
665 tree method_params)
667 tree sender = (super_flag ? umsg_super_decl
668 : (flag_objc_direct_dispatch ? umsg_fast_decl
669 : umsg_decl));
670 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
671 vec<tree, va_gc> *parms;
672 vec<tree, va_gc> *tv;
673 unsigned nparm = (method_params ? list_length (method_params) : 0);
675 /* If a prototype for the method to be called exists, then cast
676 the sender's return type and arguments to match that of the method.
677 Otherwise, leave sender as is. */
678 tree ret_type
679 = (method_prototype
680 ? TREE_VALUE (TREE_TYPE (method_prototype))
681 : objc_object_type);
682 tree ftype
683 = build_function_type_for_method (ret_type, method_prototype,
684 METHOD_REF, super_flag);
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 vec_alloc (parms, nparm + 2);
702 vec_alloc (tv, 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 tv->quick_push (lookup_object);
707 tv->quick_push (selector);
708 method = build_function_call_vec (loc, vNULL, sender, tv, NULL);
709 vec_free (tv);
711 /* Pass the appropriate object to the method. */
712 parms->quick_push ((super_flag ? self_decl : lookup_object));
714 /* Pass the selector to the method. */
715 parms->quick_push (selector);
716 /* Now append the remainder of the parms. */
717 if (nparm)
718 for (; method_params; method_params = TREE_CHAIN (method_params))
719 parms->quick_push (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, vNULL, t, parms, NULL);
724 vec_free (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 super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
847 IDENTIFIER_POINTER (super_name));
848 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
849 return build_function_call (input_location,
850 super_class,
851 build_tree_list (NULL_TREE, super_name));
854 static bool
855 gnu_runtime_abi_01_setup_const_string_class_decl (void)
857 /* Do nothing, and create no error. */
858 return true;
861 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
863 static GTY(()) int num_static_inst;
865 static tree
866 objc_add_static_instance (tree constructor, tree class_decl)
868 tree *chain, decl;
869 char buf[BUFSIZE];
871 /* Find the list of static instances for the CLASS_DECL. Create one if
872 not found. */
873 for (chain = &objc_static_instances;
874 *chain && TREE_VALUE (*chain) != class_decl;
875 chain = &TREE_CHAIN (*chain));
876 if (!*chain)
878 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
879 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
882 snprintf (buf, BUFSIZE, "_OBJC_INSTANCE_%d", num_static_inst++);
883 decl = build_decl (input_location,
884 VAR_DECL, get_identifier (buf), class_decl);
885 TREE_STATIC (decl) = 1;
886 DECL_ARTIFICIAL (decl) = 1;
887 TREE_USED (decl) = 1;
888 DECL_INITIAL (decl) = constructor;
889 DECL_CONTEXT (decl) = NULL;
890 OBJCMETA (decl, objc_meta, meta_base);
892 /* We may be writing something else just now.
893 Postpone till end of input. */
894 DECL_DEFER_OUTPUT (decl) = 1;
895 pushdecl_top_level (decl);
896 rest_of_decl_compilation (decl, 1, 0);
898 /* Add the DECL to the head of this CLASS' list. */
899 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
901 return decl;
904 static tree
905 gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string,
906 int length)
908 tree constructor, fields;
909 vec<constructor_elt, va_gc> *v = NULL;
911 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
912 fields = TYPE_FIELDS (internal_const_str_type);
913 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0));
915 fields = DECL_CHAIN (fields);
916 CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc,
917 ADDR_EXPR, string, 1));
919 fields = DECL_CHAIN (fields);
920 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
921 constructor = objc_build_constructor (internal_const_str_type, v);
923 constructor = objc_add_static_instance (constructor, constant_string_type);
924 return constructor;
927 /* --- metadata - module initializer --- */
929 /* The GNU runtime requires us to provide a static initializer function
930 for each module:
932 static void __objc_gnu_init (void) {
933 __objc_exec_class (&L_OBJC_MODULES);
934 } */
937 static void
938 build_module_initializer_routine (void)
940 tree body;
942 #ifdef OBJCPLUS
943 push_lang_context (lang_name_c); /* extern "C" */
944 #endif
946 objc_push_parm (build_decl (input_location,
947 PARM_DECL, NULL_TREE, void_type_node));
948 #ifdef OBJCPLUS
949 objc_start_function (get_identifier (TAG_GNUINIT),
950 build_function_type_list (void_type_node, NULL_TREE),
951 NULL_TREE, NULL_TREE);
952 #else
953 objc_start_function (get_identifier (TAG_GNUINIT),
954 build_function_type_list (void_type_node, NULL_TREE),
955 NULL_TREE, objc_get_parm_info (0, NULL_TREE));
956 #endif
957 body = c_begin_compound_stmt (true);
958 add_stmt (build_function_call
959 (input_location,
960 execclass_decl,
961 build_tree_list
962 (NULL_TREE,
963 build_unary_op (input_location, ADDR_EXPR,
964 UOBJC_MODULES_decl, 0))));
965 add_stmt (c_end_compound_stmt (input_location, body, true));
967 TREE_PUBLIC (current_function_decl) = 0;
969 #ifndef OBJCPLUS
970 /* For Objective-C++, we will need to call __objc_gnu_init
971 from objc_generate_static_init_call() below. */
972 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
973 #endif
975 GNU_INIT_decl = current_function_decl;
976 finish_function ();
978 #ifdef OBJCPLUS
979 pop_lang_context ();
980 #endif
983 #ifdef OBJCPLUS
984 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
985 to be called by the module initializer routine. */
988 objc_static_init_needed_p (void)
990 return (GNU_INIT_decl != NULL_TREE);
993 /* Generate a call to the __objc_gnu_init initializer function. */
995 tree
996 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
998 add_stmt (build_stmt (input_location, EXPR_STMT,
999 build_function_call (input_location,
1000 GNU_INIT_decl, NULL_TREE)));
1002 return ctors;
1004 #endif /* OBJCPLUS */
1006 /* --- Output GNU Meta-data --- */
1008 static void
1009 generate_classref_translation_entry (tree chain)
1011 tree expr, decl, type;
1013 decl = TREE_PURPOSE (chain);
1014 type = TREE_TYPE (decl);
1016 expr = add_objc_string (TREE_VALUE (chain), class_names);
1017 expr = convert (type, expr); /* cast! */
1019 /* This is a class reference. It is re-written by the runtime,
1020 but will be optimized away unless we force it. */
1021 DECL_PRESERVE_P (decl) = 1;
1022 OBJCMETA (decl, objc_meta, meta_base);
1023 finish_var_decl (decl, expr);
1024 return;
1028 static void
1029 handle_impent (struct imp_entry *impent)
1031 char *string;
1033 /* objc_implementation_context = impent->imp_context;
1034 implementation_template = impent->imp_template;*/
1036 switch (TREE_CODE (impent->imp_context))
1038 case CLASS_IMPLEMENTATION_TYPE:
1040 const char *const class_name =
1041 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1043 string = (char *) alloca (strlen (class_name) + 30);
1045 sprintf (string, "__objc_class_name_%s", class_name);
1046 break;
1048 case CATEGORY_IMPLEMENTATION_TYPE:
1050 const char *const class_name =
1051 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1052 const char *const class_super_name =
1053 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
1055 string = (char *) alloca (strlen (class_name)
1056 + strlen (class_super_name) + 30);
1058 /* Do the same for categories. Even though no references to
1059 these symbols are generated automatically by the compiler,
1060 it gives you a handle to pull them into an archive by
1061 hand. */
1062 sprintf (string, "*__objc_category_name_%s_%s", class_name, class_super_name);
1063 break;
1065 default:
1066 return;
1070 tree decl, init;
1072 init = integer_zero_node;
1073 decl = build_decl (input_location,
1074 VAR_DECL, get_identifier (string), TREE_TYPE (init));
1075 TREE_PUBLIC (decl) = 1;
1076 TREE_READONLY (decl) = 1;
1077 TREE_USED (decl) = 1;
1078 TREE_CONSTANT (decl) = 1;
1079 DECL_CONTEXT (decl) = NULL_TREE;
1080 DECL_ARTIFICIAL (decl) = 1;
1081 TREE_STATIC (decl) = 1;
1082 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
1083 /* We must force the reference. */
1084 DECL_PRESERVE_P (decl) = 1;
1086 finish_var_decl(decl, init) ;
1090 tree
1091 build_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
1092 tree inst_methods, tree class_methods)
1094 tree expr, ttyp;
1095 location_t loc;
1096 vec<constructor_elt, va_gc> *inits = NULL;
1098 /* TODO: pass the loc in or find it from args. */
1099 loc = input_location;
1100 ttyp = build_pointer_type (xref_tag (RECORD_TYPE,
1101 get_identifier (UTAG_CLASS)));
1102 /* Filling the "isa" in with a version allows the runtime system to
1103 detect this ... */
1104 expr = build_int_cst (ttyp, PROTOCOL_VERSION);
1106 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1108 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
1109 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
1111 ttyp = objc_method_proto_list_ptr;
1112 if (inst_methods)
1113 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1114 else
1115 expr = convert (ttyp, null_pointer_node);
1116 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1118 if (class_methods)
1119 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1120 else
1121 expr = convert (ttyp, null_pointer_node);
1122 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1124 return objc_build_constructor (type, inits);
1127 static tree
1128 generate_protocol_list (tree i_or_p, tree klass_ctxt)
1130 tree array_type, ptype, refs_decl, lproto, e, plist;
1131 vec<constructor_elt, va_gc> *v = NULL;
1132 char buf[BUFSIZE];
1133 int size = 0;
1135 switch (TREE_CODE (i_or_p))
1137 case CLASS_INTERFACE_TYPE:
1138 case CATEGORY_INTERFACE_TYPE:
1139 plist = CLASS_PROTOCOL_LIST (i_or_p);
1140 break;
1141 case PROTOCOL_INTERFACE_TYPE:
1142 plist = PROTOCOL_LIST (i_or_p);
1143 break;
1144 default:
1145 gcc_unreachable ();
1148 /* Compute size. */
1149 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1150 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
1151 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
1152 size++;
1154 /* Build initializer. */
1155 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1156 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
1157 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1159 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1161 tree pval = TREE_VALUE (lproto);
1163 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
1164 && PROTOCOL_FORWARD_DECL (pval))
1166 tree fwref = PROTOCOL_FORWARD_DECL (pval);
1167 location_t loc = DECL_SOURCE_LOCATION (fwref) ;
1168 e = build_unary_op (loc, ADDR_EXPR, fwref, 0);
1169 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1173 /* static struct objc_protocol *refs[n]; */
1175 switch (TREE_CODE (i_or_p))
1177 case PROTOCOL_INTERFACE_TYPE:
1178 snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
1179 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
1180 break;
1181 case CLASS_INTERFACE_TYPE:
1182 snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
1183 IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
1184 break;
1185 case CATEGORY_INTERFACE_TYPE:
1186 snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
1187 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)),
1188 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt)));
1189 break;
1190 default:
1191 gcc_unreachable ();
1194 ptype = build_pointer_type (objc_protocol_template);
1195 array_type = build_sized_array_type (ptype, size + 3);
1196 refs_decl = start_var_decl (array_type, buf);
1197 OBJCMETA (refs_decl, objc_meta, meta_base);
1198 finish_var_decl (refs_decl,
1199 objc_build_constructor (TREE_TYPE (refs_decl), v));
1201 return refs_decl;
1204 static tree
1205 generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix)
1207 tree method_list_template, initlist, decl;
1208 int size;
1209 vec<constructor_elt, va_gc> *v = NULL;
1210 char buf[BUFSIZE];
1212 if (!chain || !prefix)
1213 return NULL_TREE;
1215 if (!objc_method_prototype_template)
1216 objc_method_prototype_template = build_method_prototype_template ();
1218 size = list_length (chain);
1219 method_list_template =
1220 build_method_prototype_list_template (objc_method_prototype_template,
1221 size);
1222 snprintf (buf, BUFSIZE, "%s_%s", prefix,
1223 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
1225 decl = start_var_decl (method_list_template, buf);
1227 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
1228 initlist =
1229 build_descriptor_table_initializer (objc_method_prototype_template,
1230 chain);
1231 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1232 OBJCMETA (decl, objc_meta, meta_base);
1233 finish_var_decl (decl, objc_build_constructor (method_list_template, v));
1234 return decl;
1237 /* For each protocol which was referenced either from a @protocol()
1238 expression, or because a class/category implements it (then a
1239 pointer to the protocol is stored in the struct describing the
1240 class/category), we create a statically allocated instance of the
1241 Protocol class. The code is written in such a way as to generate
1242 as few Protocol objects as possible; we generate a unique Protocol
1243 instance for each protocol, and we don't generate a Protocol
1244 instance if the protocol is never referenced (either from a
1245 @protocol() or from a class/category implementation). These
1246 statically allocated objects can be referred to via the static
1247 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1249 The statically allocated Protocol objects that we generate here
1250 need to be fixed up at runtime in order to be used: the 'isa'
1251 pointer of the objects need to be set up to point to the 'Protocol'
1252 class, as known at runtime.
1254 The GNU runtime fixes up all protocols before user code from the module
1255 is executed; it requires pointers to those symbols
1256 to be put in the objc_symtab (which is then passed as argument to
1257 the function __objc_exec_class() which the compiler sets up to be
1258 executed automatically when the module is loaded); setup of those
1259 Protocol objects happen in two ways in the GNU runtime: all
1260 Protocol objects referred to by a class or category implementation
1261 are fixed up when the class/category is loaded; all Protocol
1262 objects referred to by a @protocol() expression are added by the
1263 compiler to the list of statically allocated instances to fixup
1264 (the same list holding the statically allocated constant string
1265 objects). Because, as explained above, the compiler generates as
1266 few Protocol objects as possible, some Protocol object might end up
1267 being referenced multiple times when compiled with the GNU runtime,
1268 and end up being fixed up multiple times at runtime initialization.
1269 But that doesn't hurt, it's just a little inefficient. */
1271 static void
1272 generate_protocols (void)
1274 tree p, encoding;
1275 tree decl;
1276 tree initlist, protocol_name_expr, refs_decl, refs_expr;
1278 /* If a protocol was directly referenced, pull in indirect references. */
1279 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1280 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
1281 generate_protocol_references (PROTOCOL_LIST (p));
1283 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1285 tree nst_methods = PROTOCOL_NST_METHODS (p);
1286 tree cls_methods = PROTOCOL_CLS_METHODS (p);
1288 /* If protocol wasn't referenced, don't generate any code. */
1289 decl = PROTOCOL_FORWARD_DECL (p);
1291 if (!decl)
1292 continue;
1294 /* Make sure we link in the Protocol class. */
1295 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
1297 while (nst_methods)
1299 if (! METHOD_ENCODING (nst_methods))
1301 encoding = encode_method_prototype (nst_methods);
1302 METHOD_ENCODING (nst_methods) = encoding;
1304 nst_methods = DECL_CHAIN (nst_methods);
1307 UOBJC_INSTANCE_METHODS_decl =
1308 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
1309 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1311 while (cls_methods)
1313 if (! METHOD_ENCODING (cls_methods))
1315 encoding = encode_method_prototype (cls_methods);
1316 METHOD_ENCODING (cls_methods) = encoding;
1319 cls_methods = DECL_CHAIN (cls_methods);
1322 UOBJC_CLASS_METHODS_decl =
1323 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
1324 "_OBJC_PROTOCOL_CLASS_METHODS");
1325 /* generate_method_descriptors (p);*/
1327 if (PROTOCOL_LIST (p))
1328 refs_decl = generate_protocol_list (p, NULL_TREE);
1329 else
1330 refs_decl = 0;
1332 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1333 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
1335 if (refs_decl)
1336 refs_expr = convert (build_pointer_type (build_pointer_type
1337 (objc_protocol_template)),
1338 build_unary_op (input_location,
1339 ADDR_EXPR, refs_decl, 0));
1340 else
1341 refs_expr = build_int_cst (NULL_TREE, 0);
1343 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1344 by generate_method_descriptors, which is called above. */
1345 initlist = build_protocol_initializer (TREE_TYPE (decl),
1346 protocol_name_expr, refs_expr,
1347 UOBJC_INSTANCE_METHODS_decl,
1348 UOBJC_CLASS_METHODS_decl);
1349 finish_var_decl (decl, initlist);
1353 static tree
1354 generate_dispatch_table (tree chain, const char *name)
1356 tree decl, method_list_template, initlist;
1357 vec<constructor_elt, va_gc> *v = NULL;
1358 int size = list_length (chain);
1360 if (!objc_method_template)
1361 objc_method_template = build_method_template ();
1363 method_list_template = build_method_list_template (objc_method_template,
1364 size);
1365 initlist = build_dispatch_table_initializer (objc_method_template, chain);
1367 decl = start_var_decl (method_list_template, name);
1369 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1370 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1371 build_int_cst (integer_type_node, size));
1372 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1374 OBJCMETA (decl, objc_meta, meta_base);
1375 finish_var_decl (decl,
1376 objc_build_constructor (TREE_TYPE (decl), v));
1378 return decl;
1381 /* Init a category. */
1382 static tree
1383 build_category_initializer (tree type, tree cat_name, tree class_name,
1384 tree inst_methods, tree class_methods,
1385 tree protocol_list)
1387 tree expr, ltyp;
1388 location_t loc;
1389 vec<constructor_elt, va_gc> *v = NULL;
1391 /* TODO: pass the loc in or find it from args. */
1392 /* TODO: pass the loc in or find it from args. */
1393 loc = UNKNOWN_LOCATION;
1394 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
1395 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
1397 ltyp = objc_method_list_ptr;
1398 if (inst_methods)
1399 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1400 else
1401 expr = convert (ltyp, null_pointer_node);
1402 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1404 if (class_methods)
1405 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1406 else
1407 expr = convert (ltyp, null_pointer_node);
1408 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1410 /* protocol_list = */
1411 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1412 if (protocol_list)
1413 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0));
1414 else
1415 expr = convert (ltyp, null_pointer_node);
1416 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1418 return objc_build_constructor (type, v);
1421 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1423 static void
1424 generate_category (struct imp_entry *impent)
1426 tree initlist, cat_name_expr, class_name_expr;
1427 tree protocol_decl, category, cat_decl;
1428 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1429 tree cat = impent->imp_context;
1430 char buf[BUFSIZE];
1432 cat_decl = impent->class_decl;
1434 add_class_reference (CLASS_NAME (cat));
1435 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
1437 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
1439 category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat));
1441 if (category && CLASS_PROTOCOL_LIST (category))
1443 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
1444 protocol_decl = generate_protocol_list (category, cat);
1446 else
1447 protocol_decl = 0;
1449 if (CLASS_NST_METHODS (cat))
1451 snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s",
1452 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1453 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1454 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf);
1457 if (CLASS_CLS_METHODS (cat))
1459 snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s",
1460 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1461 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1462 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf);
1465 initlist = build_category_initializer (TREE_TYPE (cat_decl),
1466 cat_name_expr, class_name_expr,
1467 inst_methods, class_methods,
1468 protocol_decl);
1469 /* Finish and initialize the forward decl. */
1470 finish_var_decl (cat_decl, initlist);
1471 impent->class_decl = cat_decl;
1474 /* struct _objc_class {
1475 struct objc_class *isa;
1476 struct objc_class *super_class;
1477 char *name;
1478 long version;
1479 long info;
1480 long instance_size;
1481 struct objc_ivar_list *ivars;
1482 struct objc_method_list *methods;
1483 struct sarray *dtable;
1484 struct objc_class *subclass_list;
1485 struct objc_class *sibling_class;
1486 struct objc_protocol_list *protocols;
1487 void *gc_object_type;
1488 }; */
1490 static tree
1491 build_shared_structure_initializer (tree type, tree isa, tree super,
1492 tree name, tree size, int status,
1493 tree dispatch_table, tree ivar_list,
1494 tree protocol_list)
1496 tree expr, ltyp;
1497 vec<constructor_elt, va_gc> *v = NULL;
1499 /* isa = */
1500 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
1502 /* super_class = */
1503 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
1505 /* name = */
1506 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
1508 /* version = */
1509 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1510 build_int_cst (long_integer_type_node, 0));
1512 /* info = */
1513 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1514 build_int_cst (long_integer_type_node, status));
1516 /* instance_size = */
1517 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1518 convert (long_integer_type_node, size));
1520 /* objc_ivar_list = */
1521 if (!ivar_list)
1522 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1523 build_int_cst (objc_ivar_list_ptr, 0));
1524 else
1526 expr = convert (objc_ivar_list_ptr,
1527 build_unary_op (input_location, ADDR_EXPR,
1528 ivar_list, 0));
1529 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1532 /* objc_method_list = */
1533 if (!dispatch_table)
1534 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1535 convert (objc_method_list_ptr, null_pointer_node));
1536 else
1538 expr = convert (objc_method_list_ptr,
1539 build_unary_op (input_location, ADDR_EXPR,
1540 dispatch_table, 0));
1541 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1544 /* FIXME: Remove NeXT runtime code. */
1545 if (flag_next_runtime)
1547 ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
1548 get_identifier ("objc_cache")));
1549 /* method_cache = */
1550 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
1552 else
1554 /* dtable = */
1555 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1557 /* subclass_list = */
1558 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1560 /* sibling_class = */
1561 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1564 /* protocol_list = */
1565 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1566 if (! protocol_list)
1567 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0));
1568 else
1570 expr = convert (ltyp,
1571 build_unary_op (input_location, ADDR_EXPR,
1572 protocol_list, 0));
1573 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1576 /* FIXME: Remove NeXT runtime code. */
1577 if (flag_next_runtime)
1578 /* sel_id = NULL */
1579 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1581 /* gc_object_type = NULL */
1582 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1584 return objc_build_constructor (type, v);
1588 static tree
1589 generate_ivars_list (tree chain, const char *name)
1591 tree initlist, ivar_list_template, decl;
1592 int size;
1593 vec<constructor_elt, va_gc> *inits = NULL;
1595 if (!chain)
1596 return NULL_TREE;
1598 if (!objc_ivar_template)
1599 objc_ivar_template = build_ivar_template ();
1601 size = ivar_list_length (chain);
1603 generating_instance_variables = 1;
1604 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1605 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
1606 generating_instance_variables = 0;
1608 decl = start_var_decl (ivar_list_template, name);
1610 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
1611 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
1613 OBJCMETA (decl, objc_meta, meta_base);
1614 finish_var_decl (decl,
1615 objc_build_constructor (TREE_TYPE (decl), inits));
1617 return decl;
1620 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1621 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1623 static void
1624 generate_class_structures (struct imp_entry *impent)
1626 tree name_expr, super_expr, root_expr, class_decl, meta_decl;
1627 tree my_root_id, my_super_id;
1628 tree cast_type, initlist, protocol_decl;
1629 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1630 tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
1631 location_t loc;
1632 char buf[BUFSIZE];
1633 int cls_flags = 0 ;
1635 /* objc_implementation_context = impent->imp_context;
1636 implementation_template = impent->imp_template;*/
1637 class_decl = impent->class_decl;
1638 meta_decl = impent->meta_decl;
1639 /* UOBJC_CLASS_decl = impent->class_decl;
1640 UOBJC_METACLASS_decl = impent->meta_decl;*/
1642 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1644 my_super_id = CLASS_SUPER_NAME (impent->imp_template);
1645 if (my_super_id)
1647 add_class_reference (my_super_id);
1649 /* Compute "my_root_id" - this is required for code generation.
1650 the "isa" for all meta class structures points to the root of
1651 the inheritance hierarchy (e.g. "__Object")... */
1652 my_root_id = my_super_id;
1655 tree my_root_int = lookup_interface (my_root_id);
1657 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
1658 my_root_id = CLASS_SUPER_NAME (my_root_int);
1659 else
1660 break;
1662 while (1);
1664 else
1665 /* No super class. */
1666 my_root_id = CLASS_NAME (impent->imp_template);
1668 cast_type = build_pointer_type (objc_class_template);
1669 name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
1670 class_names);
1672 /* Install class `isa' and `super' pointers at runtime. */
1673 if (my_super_id)
1674 super_expr = add_objc_string (my_super_id, class_names);
1675 else
1676 super_expr = null_pointer_node;
1678 super_expr = build_c_cast (loc, cast_type, super_expr);
1680 root_expr = add_objc_string (my_root_id, class_names);
1681 root_expr = build_c_cast (loc, cast_type, root_expr);
1683 if (CLASS_PROTOCOL_LIST (impent->imp_template))
1685 generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
1686 protocol_decl = generate_protocol_list (impent->imp_template,
1687 impent->imp_context);
1689 else
1690 protocol_decl = NULL_TREE;
1692 if (CLASS_CLS_METHODS (impent->imp_context))
1694 snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
1695 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1696 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
1697 buf);
1700 if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE
1701 && (chain = TYPE_FIELDS (objc_class_template)))
1703 snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s",
1704 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1705 class_ivars = generate_ivars_list (chain, buf);
1708 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1710 initlist =
1711 build_shared_structure_initializer
1712 (TREE_TYPE (meta_decl),
1713 root_expr, super_expr, name_expr,
1714 convert (integer_type_node,
1715 TYPE_SIZE_UNIT (objc_class_template)),
1716 CLS_META, class_methods, class_ivars,
1717 protocol_decl);
1719 finish_var_decl (meta_decl, initlist);
1720 impent->meta_decl = meta_decl;
1722 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1723 if (CLASS_NST_METHODS (impent->imp_context))
1725 snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
1726 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1727 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
1728 buf);
1731 if ((chain = CLASS_IVARS (impent->imp_template)))
1733 snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
1734 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1735 inst_ivars = generate_ivars_list (chain, buf);
1738 initlist =
1739 build_shared_structure_initializer
1740 (TREE_TYPE (class_decl),
1741 build_unary_op (loc, ADDR_EXPR, meta_decl, 0),
1742 super_expr, name_expr,
1743 convert (integer_type_node,
1744 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1745 (impent->imp_template))),
1746 CLS_FACTORY | cls_flags, inst_methods, inst_ivars,
1747 protocol_decl);
1749 finish_var_decl (class_decl, initlist);
1750 impent->class_decl = class_decl;
1753 /* --- Output GNU Metadata --- */
1755 /* TODO: Make this into an array of refs. */
1756 static void
1757 handle_class_ref (tree chain)
1759 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
1760 char *string = (char *) alloca (strlen (name) + 30);
1761 tree decl;
1762 tree exp;
1764 sprintf (string, "__objc_class_name_%s", name);
1766 /* Make a decl for this name, so we can use its address in a tree. */
1767 decl = build_decl (input_location,
1768 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
1769 DECL_EXTERNAL (decl) = 1;
1770 TREE_PUBLIC (decl) = 1;
1771 DECL_CONTEXT (decl) = NULL_TREE;
1772 finish_var_decl (decl, 0);
1774 /* Make a decl for the address. */
1775 sprintf (string, "__objc_class_ref_%s", name);
1776 exp = build1 (ADDR_EXPR, string_type_node, decl);
1777 decl = build_decl (input_location,
1778 VAR_DECL, get_identifier (string), string_type_node);
1779 TREE_STATIC (decl) = 1;
1780 TREE_USED (decl) = 1;
1781 DECL_READ_P (decl) = 1;
1782 DECL_ARTIFICIAL (decl) = 1;
1783 DECL_INITIAL (decl) = error_mark_node;
1785 /* We must force the reference. */
1786 DECL_PRESERVE_P (decl) = 1;
1788 DECL_CONTEXT (decl) = NULL_TREE;
1789 finish_var_decl (decl, exp);
1792 static tree
1793 get_proto_encoding (tree proto)
1795 tree encoding;
1796 if (proto)
1798 if (! METHOD_ENCODING (proto))
1800 encoding = encode_method_prototype (proto);
1801 METHOD_ENCODING (proto) = encoding;
1803 else
1804 encoding = METHOD_ENCODING (proto);
1806 return add_objc_string (encoding, meth_var_types);
1808 else
1809 return build_int_cst (NULL_TREE, 0);
1812 static void
1813 build_gnu_selector_translation_table (void)
1815 tree chain, expr;
1816 vec<constructor_elt, va_gc> *inits = NULL;
1817 vec<constructor_elt, va_gc> *v ;
1819 /* Cause the selector table (previously forward-declared)
1820 to be actually output. */
1822 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1824 tree encoding;
1825 if (warn_selector)
1827 /* TODO: improve on the location for the diagnostic. */
1828 location_t loc = input_location;
1829 diagnose_missing_method (TREE_VALUE (chain), loc);
1832 v = NULL;
1833 expr = build_selector (TREE_VALUE (chain));
1834 encoding = get_proto_encoding (TREE_PURPOSE (chain));
1835 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1836 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
1837 expr = objc_build_constructor (objc_selector_template, v);
1839 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1840 } /* each element in the chain */
1842 /* List terminator. */
1843 v = NULL;
1844 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1845 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1846 expr = objc_build_constructor (objc_selector_template, v);
1848 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1849 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1850 inits);
1851 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
1854 /* Output references to all statically allocated objects. Return the DECL
1855 for the array built. */
1857 static void
1858 generate_static_references (void)
1860 tree expr = NULL_TREE;
1861 tree class_name, klass, decl;
1862 tree cl_chain, in_chain, type
1863 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
1864 int num_inst, num_class;
1865 char buf[BUFSIZE];
1866 vec<constructor_elt, va_gc> *decls = NULL;
1868 /* FIXME: Remove NeXT runtime code. */
1869 if (flag_next_runtime)
1870 gcc_unreachable ();
1872 for (cl_chain = objc_static_instances, num_class = 0;
1873 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1875 vec<constructor_elt, va_gc> *v = NULL;
1877 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1878 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1880 snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class);
1881 decl = start_var_decl (type, buf);
1883 /* Output {class_name, ...}. */
1884 klass = TREE_VALUE (cl_chain);
1885 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
1886 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1887 build_unary_op (input_location,
1888 ADDR_EXPR, class_name, 1));
1890 /* Output {..., instance, ...}. */
1891 for (in_chain = TREE_PURPOSE (cl_chain);
1892 in_chain; in_chain = TREE_CHAIN (in_chain))
1894 expr = build_unary_op (input_location,
1895 ADDR_EXPR, TREE_VALUE (in_chain), 1);
1896 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1899 /* Output {..., NULL}. */
1900 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1902 expr = objc_build_constructor (TREE_TYPE (decl), v);
1903 OBJCMETA (decl, objc_meta, meta_base);
1904 finish_var_decl (decl, expr);
1905 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
1906 build_unary_op (input_location,
1907 ADDR_EXPR, decl, 1));
1910 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
1911 expr = objc_build_constructor (type, decls);
1912 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
1913 OBJCMETA (static_instances_decl, objc_meta, meta_base);
1914 finish_var_decl (static_instances_decl, expr);
1917 /* Create the initial value for the `defs' field of _objc_symtab.
1918 This is a CONSTRUCTOR. */
1920 static tree
1921 init_def_list (tree type)
1923 tree expr;
1924 struct imp_entry *impent;
1925 location_t loc;
1926 vec<constructor_elt, va_gc> *v = NULL;
1928 if (imp_count)
1929 for (impent = imp_list; impent; impent = impent->next)
1931 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1933 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1934 expr = build_unary_op (loc,
1935 ADDR_EXPR, impent->class_decl, 0);
1936 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1940 if (cat_count)
1941 for (impent = imp_list; impent; impent = impent->next)
1943 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1945 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1946 expr = build_unary_op (loc,
1947 ADDR_EXPR, impent->class_decl, 0);
1948 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1952 loc = UNKNOWN_LOCATION;
1953 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1954 if (static_instances_decl)
1955 expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0);
1956 else
1957 expr = integer_zero_node;
1958 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1960 return objc_build_constructor (type, v);
1963 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1965 /* Predefine the following data type:
1967 struct _objc_symtab
1969 long sel_ref_cnt;
1970 SEL *refs;
1971 short cls_def_cnt;
1972 short cat_def_cnt;
1973 void *defs[cls_def_cnt + cat_def_cnt];
1974 }; */
1976 static void
1977 build_objc_symtab_template (void)
1979 tree fields, array_type, *chain = NULL;
1980 int index;
1982 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
1984 /* long sel_ref_cnt; */
1985 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
1987 /* SEL *refs; */
1988 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
1990 /* short cls_def_cnt; */
1991 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
1993 /* short cat_def_cnt; */
1994 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
1996 /* Note that padding will be added here on LP64. */
1998 /* void *defs[imp_count + cat_count (+ 1)]; */
1999 /* NB: The index is one less than the size of the array. */
2000 index = imp_count + cat_count;
2001 array_type = build_sized_array_type (ptr_type_node, index + 1);
2002 add_field_decl (array_type, "defs", &chain);
2004 objc_finish_struct (objc_symtab_template, fields);
2006 /* Construct the initial value for all of _objc_symtab. */
2008 static tree
2009 init_objc_symtab (tree type)
2011 tree field, expr, ltyp;
2012 location_t loc;
2013 vec<constructor_elt, va_gc> *v = NULL;
2015 loc = UNKNOWN_LOCATION;
2017 /* sel_ref_cnt = { ..., 5, ... } */
2019 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2020 build_int_cst (long_integer_type_node, 0));
2022 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2024 ltyp = build_pointer_type (objc_selector_type);
2025 if (sel_ref_chain)
2026 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,
2027 UOBJC_SELECTOR_TABLE_decl, 1));
2028 else
2029 expr = convert (ltyp, null_pointer_node);
2030 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2032 /* cls_def_cnt = { ..., 5, ... } */
2034 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2035 build_int_cst (short_integer_type_node, imp_count));
2037 /* cat_def_cnt = { ..., 5, ... } */
2039 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2040 build_int_cst (short_integer_type_node, cat_count));
2042 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2044 field = TYPE_FIELDS (type);
2045 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2047 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2049 return objc_build_constructor (type, v);
2052 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2053 and initialized appropriately. */
2055 static void
2056 generate_objc_symtab_decl (void)
2058 build_objc_symtab_template ();
2059 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2060 OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base);
2061 finish_var_decl (UOBJC_SYMBOLS_decl,
2062 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2065 static void
2066 objc_generate_v1_gnu_metadata (void)
2068 struct imp_entry *impent;
2069 tree chain;
2071 /* Process the static instances here because initialization of objc_symtab
2072 depends on them. */
2073 if (objc_static_instances)
2074 generate_static_references ();
2076 objc_implementation_context =
2077 implementation_template =
2078 UOBJC_CLASS_decl =
2079 UOBJC_METACLASS_decl = NULL_TREE;
2081 for (impent = imp_list; impent; impent = impent->next)
2083 /* If -gen-decls is present, Dump the @interface of each class.
2084 TODO: Dump the classes in the order they were found, rather than in
2085 reverse order as we are doing now. */
2086 if (flag_gen_declaration)
2087 dump_interface (gen_declaration_file, impent->imp_context);
2089 /* all of the following reference the string pool... */
2090 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2091 generate_class_structures (impent);
2092 else
2093 generate_category (impent);
2096 /* If we are using an array of selectors, we must always
2097 finish up the array decl even if no selectors were used. */
2098 build_gnu_selector_translation_table ();
2100 if (protocol_chain)
2101 generate_protocols ();
2103 /* Arrange for ObjC data structures to be initialized at run time. */
2104 /* FIXME: Have some more elegant way to determine if we need to
2105 generate objc_symtab_decl or not, instead of checking these
2106 global symbols. */
2107 if (imp_list || class_names_chain
2108 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain
2109 || prop_names_attr_chain)
2110 generate_objc_symtab_decl ();
2112 if (imp_list || class_names_chain || objc_static_instances
2113 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
2115 /* Make sure that the meta-data are identified as being
2116 GNU-runtime. */
2117 build_module_descriptor (OBJC_VERSION,
2118 build_tree_list (objc_meta, meta_base));
2119 build_module_initializer_routine ();
2122 /* Dump the class references. This forces the appropriate classes
2123 to be linked into the executable image, preserving unix archive
2124 semantics. This can be removed when we move to a more dynamically
2125 linked environment. */
2127 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
2129 handle_class_ref (chain);
2130 if (TREE_PURPOSE (chain))
2131 generate_classref_translation_entry (chain);
2134 for (impent = imp_list; impent; impent = impent->next)
2135 handle_impent (impent);
2137 generate_strings ();
2140 /* --- exceptions --- */
2142 static GTY(()) tree objc_eh_personality_decl;
2144 static tree
2145 objc_eh_runtime_type (tree type)
2147 tree ident, eh_id, decl, str;
2149 if (type == error_mark_node
2150 || errorcount || sorrycount)
2152 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2153 to prevent an ICE. Note that we know that the compiler will
2154 terminate with an error and this 'ErrorMarkNode' class name will
2155 never be actually used. */
2156 ident = get_identifier ("ErrorMarkNode");
2157 goto make_err_class;
2160 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
2161 /* We don't want to identify 'id' for GNU. Instead, build a 0
2162 entry in the exceptions table. */
2163 return null_pointer_node;
2165 if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
2167 #ifdef OBJCPLUS
2168 /* This routine is also called for c++ catch clauses; in which case,
2169 we use the c++ typeinfo decl. */
2170 return build_eh_type_type (type);
2171 #else
2172 error ("non-objective-c type '%T' cannot be caught", type);
2173 ident = get_identifier ("ErrorMarkNode");
2174 goto make_err_class;
2175 #endif
2177 else
2178 ident = OBJC_TYPE_NAME (TREE_TYPE (type));
2180 make_err_class:
2181 /* If this class was already referenced, then it will be output during
2182 meta-data emission, so we don't need to do it here. */
2183 decl = get_objc_string_decl (ident, class_names);
2184 eh_id = add_objc_string (ident, class_names);
2185 if (!decl)
2187 /* Not found ... so we need to build it - from the freshly-entered id. */
2188 decl = get_objc_string_decl (ident, class_names);
2189 str = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2190 IDENTIFIER_POINTER (ident));
2191 /* We have to finalize this var here, because this might be called after
2192 all the other metadata strings have been emitted. */
2193 finish_var_decl (decl, str);
2195 return eh_id;
2198 static tree
2199 objc_eh_personality (void)
2201 if (!objc_eh_personality_decl)
2202 #ifndef OBJCPLUS
2203 objc_eh_personality_decl = build_personality_function ("gnu_objc");
2204 #else
2205 objc_eh_personality_decl = build_personality_function ("gxx");
2206 #endif
2207 return objc_eh_personality_decl;
2210 /* -- interfaces --- */
2212 static tree
2213 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
2215 tree t;
2216 vec<tree, va_gc> *parms;
2217 vec_alloc (parms, 1);
2218 /* A throw is just a call to the runtime throw function with the
2219 object as a parameter. */
2220 parms->quick_push (throw_expr);
2221 t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl, parms,
2222 NULL);
2223 vec_free (parms);
2224 return add_stmt (t);
2227 /* Build __builtin_eh_pointer. */
2229 static tree
2230 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
2232 tree t;
2233 t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
2234 t = build_call_expr (t, 1, integer_zero_node);
2235 return fold_convert (objc_object_type, t);
2238 static tree
2239 begin_catch (struct objc_try_context **cur_try_context, tree type,
2240 tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
2242 tree t;
2243 /* Record the data for the catch in the try context so that we can
2244 finalize it later. */
2245 if (ellipsis)
2246 t = build_stmt (input_location, CATCH_EXPR, NULL, compound);
2247 else
2248 t = build_stmt (input_location, CATCH_EXPR, type, compound);
2249 (*cur_try_context)->current_catch = t;
2251 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2252 t = objc_build_exc_ptr (cur_try_context);
2253 t = convert (TREE_TYPE (decl), t);
2254 return build2 (MODIFY_EXPR, void_type_node, decl, t);
2257 static void
2258 finish_catch (struct objc_try_context **cur_try_context, tree current_catch)
2260 append_to_statement_list (current_catch, &((*cur_try_context)->catch_list));
2263 static tree
2264 finish_try_stmt (struct objc_try_context **cur_try_context)
2266 struct objc_try_context *c = *cur_try_context;
2267 tree stmt = c->try_body;
2268 if (c->catch_list)
2269 stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
2270 if (c->finally_body)
2271 stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
2272 return stmt;
2275 #include "gt-objc-objc-gnu-runtime-abi-01.h"