PR target/58115
[official-gcc.git] / gcc / objc / objc-runtime-shared-support.c
blobbfdbb4d7db7b82ab2bcbefc23161e1cb5c10e12d
1 /* Support routines shared by all runtimes.
2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
3 Contributed by Iain Sandoe (partially split from objc-act.c)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "stringpool.h"
28 #ifdef OBJCPLUS
29 #include "cp/cp-tree.h"
30 #else
31 #include "c/c-tree.h"
32 #include "c/c-lang.h"
33 #endif
34 #include "langhooks.h"
35 #include "c-family/c-objc.h"
36 #include "objc-act.h"
38 /* When building Objective-C++, we are not linking against the C front-end
39 and so need to replicate the C tree-construction functions in some way. */
40 #ifdef OBJCPLUS
41 #define OBJCP_REMAP_FUNCTIONS
42 #include "objcp-decl.h"
43 #endif /* OBJCPLUS */
45 /* Hooks for string decls etc. */
46 #include "objc-runtime-hooks.h"
48 #include "objc-runtime-shared-support.h"
49 #include "objc-encoding.h"
51 /* rt_trees identifiers - shared between NeXT implementations. These allow
52 the FE to tag meta-data in a manner that survives LTO and can be used when
53 the runtime requires that certain meta-data items appear in particular
54 named sections. */
55 #include "objc-next-metadata-tags.h"
56 extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX];
58 /* Rather than repeatedly looking up the identifiers, we save them here. */
59 tree objc_rt_trees[OCTI_RT_META_MAX];
61 /* For building an objc struct. These might not be used when this file
62 is compiled as part of obj-c++. */
64 static bool objc_building_struct;
65 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
67 /* Start building a struct for objc. */
69 tree
70 objc_start_struct (tree name)
72 gcc_assert (!objc_building_struct);
73 objc_building_struct = true;
74 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
77 /* Finish building a struct for objc. */
79 tree
80 objc_finish_struct (tree type, tree fieldlist)
82 gcc_assert (objc_building_struct);
83 objc_building_struct = false;
84 return finish_struct (input_location, type, fieldlist, NULL_TREE,
85 objc_struct_info);
88 tree
89 build_sized_array_type (tree base_type, int size)
91 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
92 return build_array_type (base_type, index_type);
95 /* Create a declaration for field NAME of a given TYPE. */
97 static tree
98 create_field_decl (tree type, const char *name)
100 return build_decl (input_location,
101 FIELD_DECL, get_identifier (name), type);
104 tree
105 add_field_decl (tree type, const char *name, tree **chain)
107 tree field = create_field_decl (type, name);
109 if (*chain != NULL)
110 **chain = field;
111 *chain = &DECL_CHAIN (field);
113 return field;
116 /* Create a global, static declaration for variable NAME of a given TYPE. The
117 finish_var_decl() routine will need to be called on it afterwards. */
119 tree
120 start_var_decl (tree type, const char *name)
122 tree var = build_decl (input_location,
123 VAR_DECL, get_identifier (name), type);
124 TREE_STATIC (var) = 1;
125 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
126 DECL_IGNORED_P (var) = 1;
127 DECL_ARTIFICIAL (var) = 1;
128 DECL_CONTEXT (var) = NULL_TREE;
129 #ifdef OBJCPLUS
130 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
131 #endif
132 return var;
135 /* Finish off the variable declaration created by start_var_decl(). */
137 void
138 finish_var_decl (tree var, tree initializer)
140 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
143 /* Just a handy wrapper for add_objc_string. */
145 tree
146 build_selector (tree ident)
148 return convert (objc_selector_type, add_objc_string (ident, meth_var_names));
151 /* --- templates --- */
153 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
154 This needs to be done just once per compilation. */
156 /* struct _objc_super {
157 struct _objc_object *self;
158 struct _objc_class *super_class;
159 [or Class cls; for the abi v2]
160 }; */
162 void
163 build_super_template (void)
165 tree decls, *chain = NULL;
167 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
169 /* struct _objc_object *self; */
170 decls = add_field_decl (objc_object_type, "self", &chain);
172 /* struct _objc_class *super_class; */
173 add_field_decl (build_pointer_type (objc_class_template),
174 "super_class", &chain);
176 objc_finish_struct (objc_super_template, decls);
179 /* To accomplish method prototyping without generating all kinds of
180 inane warnings, the definition of the dispatch table entries were
181 changed from:
183 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
185 struct objc_method { SEL _cmd; ...; void *_imp; }; */
187 tree
188 build_method_template (void)
190 tree _SLT_record;
191 tree decls, *chain = NULL;
193 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
195 /* SEL _cmd; */
196 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
198 /* char *method_types; */
199 add_field_decl (string_type_node, "method_types", &chain);
201 /* void *_imp; */
202 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
204 objc_finish_struct (_SLT_record, decls);
206 return _SLT_record;
209 tree
210 build_method_prototype_template (void)
212 tree proto_record;
213 tree decls, *chain = NULL;
215 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
217 /* SEL _cmd; */
218 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
220 /* char *method_types; */
221 add_field_decl (string_type_node, "method_types", &chain);
223 objc_finish_struct (proto_record, decls);
225 return proto_record;
228 /* struct {
229 struct _objc__method_prototype_list *method_next;
230 int method_count;
231 struct objc_method method_list[method_count];
232 }; */
234 tree
235 build_method_list_template (tree list_type, int size)
237 tree objc_ivar_list_record;
238 tree array_type, decls, *chain = NULL;
240 objc_ivar_list_record = objc_start_struct (NULL_TREE);
242 /* struct _objc__method_prototype_list *method_next; */
243 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
245 /* int method_count; */
246 add_field_decl (integer_type_node, "method_count", &chain);
248 /* struct objc_method method_list[]; */
249 array_type = build_sized_array_type (list_type, size);
250 add_field_decl (array_type, "method_list", &chain);
252 objc_finish_struct (objc_ivar_list_record, decls);
254 return objc_ivar_list_record;
257 /* struct objc_method_prototype_list {
258 int count;
259 struct objc_method_prototype {
260 SEL name;
261 char *types;
262 } list[1];
263 }; */
265 tree
266 build_method_prototype_list_template (tree list_type, int size)
268 tree objc_ivar_list_record;
269 tree array_type, decls, *chain = NULL;
271 /* Generate an unnamed struct definition. */
273 objc_ivar_list_record = objc_start_struct (NULL_TREE);
275 /* int method_count; */
276 decls = add_field_decl (integer_type_node, "method_count", &chain);
278 /* struct objc_method method_list[]; */
279 array_type = build_sized_array_type (list_type, size);
280 add_field_decl (array_type, "method_list", &chain);
282 objc_finish_struct (objc_ivar_list_record, decls);
284 return objc_ivar_list_record;
287 /* --- names, decls entry --- */
289 /* For each string section we have a chain which maps identifier nodes
290 to decls for the strings. */
292 static GTY(()) int meth_var_names_idx;
293 static GTY(()) int meth_var_types_idx;
294 static GTY(()) int property_name_attr_idx;
296 tree
297 add_objc_string (tree ident, string_section section)
299 tree *chain, decl, type;
300 char buf[BUFSIZE];
302 switch (section)
304 case class_names:
305 chain = &class_names_chain;
306 snprintf (buf, BUFSIZE, "_OBJC_ClassName_%s", IDENTIFIER_POINTER (ident));
307 break;
308 case meth_var_names:
309 chain = &meth_var_names_chain;
310 snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
311 break;
312 case meth_var_types:
313 chain = &meth_var_types_chain;
314 snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
315 break;
316 case prop_names_attr:
317 chain = &prop_names_attr_chain;
318 snprintf (buf, BUFSIZE, "_OBJC_PropertyAttributeOrName_%d", property_name_attr_idx++);
319 break;
320 default:
321 gcc_unreachable ();
324 while (*chain)
326 if (TREE_VALUE (*chain) == ident)
327 return convert (string_type_node,
328 build_unary_op (input_location,
329 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
331 chain = &TREE_CHAIN (*chain);
334 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
335 /* Get a runtime-specific string decl which will be finish_var()'ed in
336 generate_strings (). */
337 decl = (*runtime.string_decl) (type, buf, section);
338 TREE_CONSTANT (decl) = 1;
339 *chain = tree_cons (decl, ident, NULL_TREE);
341 return convert (string_type_node,
342 build_unary_op (input_location, ADDR_EXPR, decl, 1));
345 /* --- shared metadata routines --- */
347 tree
348 build_descriptor_table_initializer (tree type, tree entries)
350 vec<constructor_elt, va_gc> *inits = NULL;
354 vec<constructor_elt, va_gc> *elts = NULL;
356 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
357 build_selector (METHOD_SEL_NAME (entries)));
358 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
359 add_objc_string (METHOD_ENCODING (entries),
360 meth_var_types));
362 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
363 objc_build_constructor (type, elts));
365 entries = DECL_CHAIN (entries);
367 while (entries);
369 return objc_build_constructor (build_array_type (type, 0), inits);
372 tree
373 build_dispatch_table_initializer (tree type, tree entries)
375 vec<constructor_elt, va_gc> *inits = NULL;
379 vec<constructor_elt, va_gc> *elems = NULL;
380 tree expr;
382 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
383 build_selector (METHOD_SEL_NAME (entries)));
385 /* Generate the method encoding if we don't have one already. */
386 if (! METHOD_ENCODING (entries))
387 METHOD_ENCODING (entries) =
388 encode_method_prototype (entries);
390 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
391 add_objc_string (METHOD_ENCODING (entries),
392 meth_var_types));
394 expr = convert (ptr_type_node,
395 build_unary_op (input_location, ADDR_EXPR,
396 METHOD_DEFINITION (entries), 1));
397 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
399 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
400 objc_build_constructor (type, elems));
402 entries = DECL_CHAIN (entries);
404 while (entries);
406 return objc_build_constructor (build_array_type (type, 0), inits);
409 /* Used only by build_*_selector_translation_table (). */
410 void
411 diagnose_missing_method (tree meth, location_t here)
413 tree method_chain;
414 bool found = false;
415 for (method_chain = meth_var_names_chain;
416 method_chain;
417 method_chain = TREE_CHAIN (method_chain))
419 if (TREE_VALUE (method_chain) == meth)
421 found = true;
422 break;
426 if (!found)
427 warning_at (here, 0, "creating selector for nonexistent method %qE",
428 meth);
432 static tree
433 init_module_descriptor (tree type, long vers)
435 tree expr, ltyp;
436 location_t loc;
437 vec<constructor_elt, va_gc> *v = NULL;
439 /* No really useful place to point to. */
440 loc = UNKNOWN_LOCATION;
442 /* version = { 1, ... } */
444 expr = build_int_cst (long_integer_type_node, vers);
445 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
447 /* size = { ..., sizeof (struct _objc_module), ... } */
449 expr = convert (long_integer_type_node,
450 size_in_bytes (objc_module_template));
451 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
453 /* Don't provide any file name for security reasons. */
454 /* name = { ..., "", ... } */
456 expr = add_objc_string (get_identifier (""), class_names);
457 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
459 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
461 ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
462 get_identifier (UTAG_SYMTAB)));
463 if (UOBJC_SYMBOLS_decl)
464 expr = convert (ltyp, build_unary_op (loc,
465 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0));
466 else
467 expr = convert (ltyp, null_pointer_node);
468 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
470 return objc_build_constructor (type, v);
473 /* Write out the data structures to describe Objective C classes defined.
475 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
477 void
478 build_module_descriptor (long vers, tree attr)
480 tree decls, *chain = NULL;
482 #ifdef OBJCPLUS
483 push_lang_context (lang_name_c); /* extern "C" */
484 #endif
486 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
488 /* long version; */
489 decls = add_field_decl (long_integer_type_node, "version", &chain);
491 /* long size; */
492 add_field_decl (long_integer_type_node, "size", &chain);
494 /* char *name; */
495 add_field_decl (string_type_node, "name", &chain);
497 /* struct _objc_symtab *symtab; */
498 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
499 get_identifier (UTAG_SYMTAB))),
500 "symtab", &chain);
502 objc_finish_struct (objc_module_template, decls);
504 /* Create an instance of "_objc_module". */
505 UOBJC_MODULES_decl = start_var_decl (objc_module_template,
506 /* FIXME - why the conditional
507 if the symbol is the
508 same. */
509 flag_next_runtime ? "_OBJC_Module" : "_OBJC_Module");
511 /* This is the root of the metadata for defined classes and categories, it
512 is referenced by the runtime and, therefore, needed. */
513 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
515 /* Allow the runtime to mark meta-data such that it can be assigned to target
516 specific sections by the back-end. */
517 if (attr)
518 DECL_ATTRIBUTES (UOBJC_MODULES_decl) = attr;
520 finish_var_decl (UOBJC_MODULES_decl,
521 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl),
522 vers));
524 #ifdef OBJCPLUS
525 pop_lang_context ();
526 #endif
529 tree
530 build_ivar_list_initializer (tree type, tree field_decl)
532 vec<constructor_elt, va_gc> *inits = NULL;
536 vec<constructor_elt, va_gc> *ivar = NULL;
537 tree id;
539 /* Set name. */
540 if (DECL_NAME (field_decl))
541 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
542 add_objc_string (DECL_NAME (field_decl),
543 meth_var_names));
544 else
545 /* Unnamed bit-field ivar (yuck). */
546 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
548 /* Set type. */
549 id = add_objc_string (encode_field_decl (field_decl),
550 meth_var_types);
551 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
553 /* Set offset. */
554 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
555 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
556 objc_build_constructor (type, ivar));
558 field_decl = DECL_CHAIN (field_decl);
559 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
561 while (field_decl);
563 return objc_build_constructor (build_array_type (type, 0), inits);
566 /* struct {
567 int ivar_count;
568 struct objc_ivar ivar_list[ivar_count];
569 }; */
571 tree
572 build_ivar_list_template (tree list_type, int size)
574 tree objc_ivar_list_record;
575 tree array_type, decls, *chain = NULL;
577 objc_ivar_list_record = objc_start_struct (NULL_TREE);
579 /* int ivar_count; */
580 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
582 /* struct objc_ivar ivar_list[]; */
583 array_type = build_sized_array_type (list_type, size);
584 add_field_decl (array_type, "ivar_list", &chain);
586 objc_finish_struct (objc_ivar_list_record, decls);
588 return objc_ivar_list_record;
591 /* struct _objc_ivar {
592 char *ivar_name;
593 char *ivar_type;
594 int ivar_offset;
595 }; */
597 tree
598 build_ivar_template (void)
600 tree objc_ivar_id, objc_ivar_record;
601 tree decls, *chain = NULL;
603 objc_ivar_id = get_identifier (UTAG_IVAR);
604 objc_ivar_record = objc_start_struct (objc_ivar_id);
606 /* char *ivar_name; */
607 decls = add_field_decl (string_type_node, "ivar_name", &chain);
609 /* char *ivar_type; */
610 add_field_decl (string_type_node, "ivar_type", &chain);
612 /* int ivar_offset; */
613 add_field_decl (integer_type_node, "ivar_offset", &chain);
615 objc_finish_struct (objc_ivar_record, decls);
617 return objc_ivar_record;
620 /* Used by NeXT ABI=0..2 */
621 void
622 build_next_selector_translation_table (void)
624 tree chain;
625 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
627 tree expr;
628 tree decl = TREE_PURPOSE (chain);
629 if (warn_selector)
631 location_t loc;
632 if (decl)
633 loc = DECL_SOURCE_LOCATION (decl);
634 else
635 loc = UNKNOWN_LOCATION;
636 diagnose_missing_method (TREE_VALUE (chain), loc);
639 expr = build_selector (TREE_VALUE (chain));
641 if (decl)
643 /* Entries of this form are used for references to methods.
644 The runtime re-writes these on start-up, but the compiler can't see
645 that and optimizes it away unless we force it. */
646 DECL_PRESERVE_P (decl) = 1;
647 finish_var_decl (decl, expr);
652 void
653 generate_protocol_references (tree plist)
655 tree lproto;
657 /* Forward declare protocols referenced. */
658 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
660 tree proto = TREE_VALUE (lproto);
662 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
663 && PROTOCOL_NAME (proto))
665 if (! PROTOCOL_FORWARD_DECL (proto))
666 PROTOCOL_FORWARD_DECL (proto) = (*runtime.protocol_decl) (proto);
668 if (PROTOCOL_LIST (proto))
669 generate_protocol_references (PROTOCOL_LIST (proto));
674 /* --- new routines --- */
676 /* Output all strings. */
678 /* FIXME: don't use global vars for all this... */
680 /* This emits all the meta-data string tables (and finalizes each var
681 as it goes). */
682 void
683 generate_strings (void)
685 tree chain, string_expr;
686 tree string, decl; /* , type;*/
688 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
690 string = TREE_VALUE (chain);
691 decl = TREE_PURPOSE (chain);
692 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
693 IDENTIFIER_POINTER (string));
694 finish_var_decl (decl, string_expr);
697 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
699 string = TREE_VALUE (chain);
700 decl = TREE_PURPOSE (chain);
701 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
702 IDENTIFIER_POINTER (string));
703 finish_var_decl (decl, string_expr);
706 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
708 string = TREE_VALUE (chain);
709 decl = TREE_PURPOSE (chain);
710 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
711 IDENTIFIER_POINTER (string));
712 finish_var_decl (decl, string_expr);
715 for (chain = prop_names_attr_chain; chain; chain = TREE_CHAIN (chain))
717 string = TREE_VALUE (chain);
718 decl = TREE_PURPOSE (chain);
719 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
720 IDENTIFIER_POINTER (string));
721 finish_var_decl (decl, string_expr);
725 #include "gt-objc-objc-runtime-shared-support.h"