1 /* Support routines shared by all runtimes.
2 Copyright (C) 2011 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)
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/>. */
23 #include "coretypes.h"
33 #include "langhooks.h"
34 #include "c-family/c-objc.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. */
40 #define OBJCP_REMAP_FUNCTIONS
41 #include "objcp-decl.h"
46 /* These are only used for encoding ivars. */
47 extern struct obstack util_obstack;
48 extern char *util_firstobj;
50 /* Hooks for string decls etc. */
51 #include "objc-runtime-hooks.h"
53 #include "objc-runtime-shared-support.h"
55 /* rt_trees identifiers - shared between NeXT implementations. These allow
56 the FE to tag meta-data in a manner that survives LTO and can be used when
57 the runtime requires that certain meta-data items appear in particular
59 #include "objc-next-metadata-tags.h"
60 extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX];
62 /* Rather than repeatedly looking up the identifiers, we save them here. */
63 tree objc_rt_trees[OCTI_RT_META_MAX];
65 /* For building an objc struct. These might not be used when this file
66 is compiled as part of obj-c++. */
68 static bool objc_building_struct;
69 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
71 /* Start building a struct for objc. */
74 objc_start_struct (tree name)
76 gcc_assert (!objc_building_struct);
77 objc_building_struct = true;
78 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
81 /* Finish building a struct for objc. */
84 objc_finish_struct (tree type, tree fieldlist)
86 gcc_assert (objc_building_struct);
87 objc_building_struct = false;
88 return finish_struct (input_location, type, fieldlist, NULL_TREE,
93 build_sized_array_type (tree base_type, int size)
95 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
96 return build_array_type (base_type, index_type);
99 /* Create a declaration for field NAME of a given TYPE. */
102 create_field_decl (tree type, const char *name)
104 return build_decl (input_location,
105 FIELD_DECL, get_identifier (name), type);
109 add_field_decl (tree type, const char *name, tree **chain)
111 tree field = create_field_decl (type, name);
115 *chain = &DECL_CHAIN (field);
120 /* Create a global, static declaration for variable NAME of a given TYPE. The
121 finish_var_decl() routine will need to be called on it afterwards. */
124 start_var_decl (tree type, const char *name)
126 tree var = build_decl (input_location,
127 VAR_DECL, get_identifier (name), type);
128 TREE_STATIC (var) = 1;
129 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
130 DECL_IGNORED_P (var) = 1;
131 DECL_ARTIFICIAL (var) = 1;
132 DECL_CONTEXT (var) = NULL_TREE;
134 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
139 /* Finish off the variable declaration created by start_var_decl(). */
142 finish_var_decl (tree var, tree initializer)
144 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
147 /* Just a handy wrapper for add_objc_string. */
150 build_selector (tree ident)
152 return convert (objc_selector_type, add_objc_string (ident, meth_var_names));
155 /* --- templates --- */
157 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
158 This needs to be done just once per compilation. */
160 /* struct _objc_super {
161 struct _objc_object *self;
162 struct _objc_class *super_class;
163 [or Class cls; for the abi v2]
167 build_super_template (void)
169 tree decls, *chain = NULL;
171 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
173 /* struct _objc_object *self; */
174 decls = add_field_decl (objc_object_type, "self", &chain);
176 /* struct _objc_class *super_class; */
177 add_field_decl (build_pointer_type (objc_class_template),
178 "super_class", &chain);
180 objc_finish_struct (objc_super_template, decls);
183 /* To accomplish method prototyping without generating all kinds of
184 inane warnings, the definition of the dispatch table entries were
187 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
189 struct objc_method { SEL _cmd; ...; void *_imp; }; */
192 build_method_template (void)
195 tree decls, *chain = NULL;
197 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
200 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
202 /* char *method_types; */
203 add_field_decl (string_type_node, "method_types", &chain);
206 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
208 objc_finish_struct (_SLT_record, decls);
214 build_method_prototype_template (void)
217 tree decls, *chain = NULL;
219 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
222 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
224 /* char *method_types; */
225 add_field_decl (string_type_node, "method_types", &chain);
227 objc_finish_struct (proto_record, decls);
233 struct _objc__method_prototype_list *method_next;
235 struct objc_method method_list[method_count];
239 build_method_list_template (tree list_type, int size)
241 tree objc_ivar_list_record;
242 tree array_type, decls, *chain = NULL;
244 objc_ivar_list_record = objc_start_struct (NULL_TREE);
246 /* struct _objc__method_prototype_list *method_next; */
247 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
249 /* int method_count; */
250 add_field_decl (integer_type_node, "method_count", &chain);
252 /* struct objc_method method_list[]; */
253 array_type = build_sized_array_type (list_type, size);
254 add_field_decl (array_type, "method_list", &chain);
256 objc_finish_struct (objc_ivar_list_record, decls);
258 return objc_ivar_list_record;
261 /* struct objc_method_prototype_list {
263 struct objc_method_prototype {
270 build_method_prototype_list_template (tree list_type, int size)
272 tree objc_ivar_list_record;
273 tree array_type, decls, *chain = NULL;
275 /* Generate an unnamed struct definition. */
277 objc_ivar_list_record = objc_start_struct (NULL_TREE);
279 /* int method_count; */
280 decls = add_field_decl (integer_type_node, "method_count", &chain);
282 /* struct objc_method method_list[]; */
283 array_type = build_sized_array_type (list_type, size);
284 add_field_decl (array_type, "method_list", &chain);
286 objc_finish_struct (objc_ivar_list_record, decls);
288 return objc_ivar_list_record;
291 /* --- names, decls entry --- */
293 /* For each string section we have a chain which maps identifier nodes
294 to decls for the strings. */
296 static GTY(()) int meth_var_names_idx;
297 static GTY(()) int meth_var_types_idx;
298 static GTY(()) int property_name_attr_idx;
301 add_objc_string (tree ident, string_section section)
303 tree *chain, decl, type;
309 chain = &class_names_chain;
310 snprintf (buf, BUFSIZE, "_OBJC_ClassName_%s", IDENTIFIER_POINTER (ident));
313 chain = &meth_var_names_chain;
314 snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
317 chain = &meth_var_types_chain;
318 snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
320 case prop_names_attr:
321 chain = &prop_names_attr_chain;
322 snprintf (buf, BUFSIZE, "_OBJC_PropertyAttributeOrName_%d", property_name_attr_idx++);
330 if (TREE_VALUE (*chain) == ident)
331 return convert (string_type_node,
332 build_unary_op (input_location,
333 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
335 chain = &TREE_CHAIN (*chain);
338 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
339 /* Get a runtime-specific string decl which will be finish_var()'ed in
340 generate_strings (). */
341 decl = (*runtime.string_decl) (type, buf, section);
342 TREE_CONSTANT (decl) = 1;
343 *chain = tree_cons (decl, ident, NULL_TREE);
345 return convert (string_type_node,
346 build_unary_op (input_location, ADDR_EXPR, decl, 1));
349 /* --- shared metadata routines --- */
352 build_descriptor_table_initializer (tree type, tree entries)
354 VEC(constructor_elt,gc) *inits = NULL;
358 VEC(constructor_elt,gc) *elts = NULL;
360 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
361 build_selector (METHOD_SEL_NAME (entries)));
362 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
363 add_objc_string (METHOD_ENCODING (entries),
366 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
367 objc_build_constructor (type, elts));
369 entries = DECL_CHAIN (entries);
373 return objc_build_constructor (build_array_type (type, 0), inits);
377 build_dispatch_table_initializer (tree type, tree entries)
379 VEC(constructor_elt,gc) *inits = NULL;
383 VEC(constructor_elt,gc) *elems = NULL;
386 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
387 build_selector (METHOD_SEL_NAME (entries)));
389 /* Generate the method encoding if we don't have one already. */
390 if (! METHOD_ENCODING (entries))
391 METHOD_ENCODING (entries) =
392 encode_method_prototype (entries);
394 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
395 add_objc_string (METHOD_ENCODING (entries),
398 expr = convert (ptr_type_node,
399 build_unary_op (input_location, ADDR_EXPR,
400 METHOD_DEFINITION (entries), 1));
401 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
403 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
404 objc_build_constructor (type, elems));
406 entries = DECL_CHAIN (entries);
410 return objc_build_constructor (build_array_type (type, 0), inits);
413 /* Used only by build_*_selector_translation_table (). */
415 diagnose_missing_method (tree meth, location_t here)
419 for (method_chain = meth_var_names_chain;
421 method_chain = TREE_CHAIN (method_chain))
423 if (TREE_VALUE (method_chain) == meth)
431 warning_at (here, 0, "creating selector for nonexistent method %qE",
437 init_module_descriptor (tree type, long vers)
441 VEC(constructor_elt,gc) *v = NULL;
443 /* No really useful place to point to. */
444 loc = UNKNOWN_LOCATION;
446 /* version = { 1, ... } */
448 expr = build_int_cst (long_integer_type_node, vers);
449 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
451 /* size = { ..., sizeof (struct _objc_module), ... } */
453 expr = convert (long_integer_type_node,
454 size_in_bytes (objc_module_template));
455 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
457 /* Don't provide any file name for security reasons. */
458 /* name = { ..., "", ... } */
460 expr = add_objc_string (get_identifier (""), class_names);
461 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
463 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
465 ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
466 get_identifier (UTAG_SYMTAB)));
467 if (UOBJC_SYMBOLS_decl)
468 expr = convert (ltyp, build_unary_op (loc,
469 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0));
471 expr = convert (ltyp, null_pointer_node);
472 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
474 return objc_build_constructor (type, v);
477 /* Write out the data structures to describe Objective C classes defined.
479 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
482 build_module_descriptor (long vers, tree attr)
484 tree decls, *chain = NULL;
487 push_lang_context (lang_name_c); /* extern "C" */
490 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
493 decls = add_field_decl (long_integer_type_node, "version", &chain);
496 add_field_decl (long_integer_type_node, "size", &chain);
499 add_field_decl (string_type_node, "name", &chain);
501 /* struct _objc_symtab *symtab; */
502 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
503 get_identifier (UTAG_SYMTAB))),
506 objc_finish_struct (objc_module_template, decls);
508 /* Create an instance of "_objc_module". */
509 UOBJC_MODULES_decl = start_var_decl (objc_module_template,
510 /* FIXME - why the conditional
513 flag_next_runtime ? "_OBJC_Module" : "_OBJC_Module");
515 /* This is the root of the metadata for defined classes and categories, it
516 is referenced by the runtime and, therefore, needed. */
517 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
519 /* Allow the runtime to mark meta-data such that it can be assigned to target
520 specific sections by the back-end. */
522 DECL_ATTRIBUTES (UOBJC_MODULES_decl) = attr;
524 finish_var_decl (UOBJC_MODULES_decl,
525 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl),
534 build_ivar_list_initializer (tree type, tree field_decl)
536 VEC(constructor_elt,gc) *inits = NULL;
540 VEC(constructor_elt,gc) *ivar = NULL;
544 if (DECL_NAME (field_decl))
545 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
546 add_objc_string (DECL_NAME (field_decl),
549 /* Unnamed bit-field ivar (yuck). */
550 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
553 encode_field_decl (field_decl,
554 obstack_object_size (&util_obstack),
555 OBJC_ENCODE_DONT_INLINE_DEFS);
557 /* Null terminate string. */
558 obstack_1grow (&util_obstack, 0);
559 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
561 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
562 obstack_free (&util_obstack, util_firstobj);
565 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
566 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
567 objc_build_constructor (type, ivar));
569 field_decl = DECL_CHAIN (field_decl);
570 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
574 return objc_build_constructor (build_array_type (type, 0), inits);
579 struct objc_ivar ivar_list[ivar_count];
583 build_ivar_list_template (tree list_type, int size)
585 tree objc_ivar_list_record;
586 tree array_type, decls, *chain = NULL;
588 objc_ivar_list_record = objc_start_struct (NULL_TREE);
590 /* int ivar_count; */
591 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
593 /* struct objc_ivar ivar_list[]; */
594 array_type = build_sized_array_type (list_type, size);
595 add_field_decl (array_type, "ivar_list", &chain);
597 objc_finish_struct (objc_ivar_list_record, decls);
599 return objc_ivar_list_record;
602 /* struct _objc_ivar {
609 build_ivar_template (void)
611 tree objc_ivar_id, objc_ivar_record;
612 tree decls, *chain = NULL;
614 objc_ivar_id = get_identifier (UTAG_IVAR);
615 objc_ivar_record = objc_start_struct (objc_ivar_id);
617 /* char *ivar_name; */
618 decls = add_field_decl (string_type_node, "ivar_name", &chain);
620 /* char *ivar_type; */
621 add_field_decl (string_type_node, "ivar_type", &chain);
623 /* int ivar_offset; */
624 add_field_decl (integer_type_node, "ivar_offset", &chain);
626 objc_finish_struct (objc_ivar_record, decls);
628 return objc_ivar_record;
631 /* Used by NeXT ABI=0..2 */
633 build_next_selector_translation_table (void)
636 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
639 tree decl = TREE_PURPOSE (chain);
644 loc = DECL_SOURCE_LOCATION (decl);
646 loc = UNKNOWN_LOCATION;
647 diagnose_missing_method (TREE_VALUE (chain), loc);
650 expr = build_selector (TREE_VALUE (chain));
654 /* Entries of this form are used for references to methods.
655 The runtime re-writes these on start-up, but the compiler can't see
656 that and optimizes it away unless we force it. */
657 DECL_PRESERVE_P (decl) = 1;
658 finish_var_decl (decl, expr);
664 generate_protocol_references (tree plist)
668 /* Forward declare protocols referenced. */
669 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
671 tree proto = TREE_VALUE (lproto);
673 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
674 && PROTOCOL_NAME (proto))
676 if (! PROTOCOL_FORWARD_DECL (proto))
677 PROTOCOL_FORWARD_DECL (proto) = (*runtime.protocol_decl) (proto);
679 if (PROTOCOL_LIST (proto))
680 generate_protocol_references (PROTOCOL_LIST (proto));
685 /* --- new routines --- */
687 /* Output all strings. */
689 /* FIXME: don't use global vars for all this... */
691 /* This emits all the meta-data string tables (and finalizes each var
694 generate_strings (void)
696 tree chain, string_expr;
697 tree string, decl; /* , type;*/
699 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
701 string = TREE_VALUE (chain);
702 decl = TREE_PURPOSE (chain);
703 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
704 IDENTIFIER_POINTER (string));
705 finish_var_decl (decl, string_expr);
708 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
710 string = TREE_VALUE (chain);
711 decl = TREE_PURPOSE (chain);
712 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
713 IDENTIFIER_POINTER (string));
714 finish_var_decl (decl, string_expr);
717 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
719 string = TREE_VALUE (chain);
720 decl = TREE_PURPOSE (chain);
721 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
722 IDENTIFIER_POINTER (string));
723 finish_var_decl (decl, string_expr);
726 for (chain = prop_names_attr_chain; chain; chain = TREE_CHAIN (chain))
728 string = TREE_VALUE (chain);
729 decl = TREE_PURPOSE (chain);
730 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
731 IDENTIFIER_POINTER (string));
732 finish_var_decl (decl, string_expr);
736 #include "gt-objc-objc-runtime-shared-support.h"