1/* Support routines shared by all runtimes.
2   Copyright (C) 2011-2015 Free Software Foundation, Inc.
3   Contributed by Iain Sandoe (partially split from objc-act.c)
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3.  If not see
19<http://www.gnu.org/licenses/>.  */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "hash-set.h"
26#include "machmode.h"
27#include "vec.h"
28#include "double-int.h"
29#include "input.h"
30#include "alias.h"
31#include "symtab.h"
32#include "options.h"
33#include "wide-int.h"
34#include "inchash.h"
35#include "tree.h"
36#include "stringpool.h"
37
38#ifdef OBJCPLUS
39#include "cp/cp-tree.h"
40#else
41#include "c/c-tree.h"
42#include "c/c-lang.h"
43#endif
44#include "langhooks.h"
45#include "c-family/c-objc.h"
46#include "objc-act.h"
47
48/* When building Objective-C++, we are not linking against the C front-end
49   and so need to replicate the C tree-construction functions in some way.  */
50#ifdef OBJCPLUS
51#define OBJCP_REMAP_FUNCTIONS
52#include "objcp-decl.h"
53#endif  /* OBJCPLUS */
54
55/* Hooks for string decls etc.  */
56#include "objc-runtime-hooks.h"
57
58#include "objc-runtime-shared-support.h"
59#include "objc-encoding.h"
60
61/* rt_trees identifiers - shared between NeXT implementations.  These allow
62   the FE to tag meta-data in a manner that survives LTO and can be used when
63   the  runtime requires that certain meta-data items appear in particular
64   named sections.  */
65#include "objc-next-metadata-tags.h"
66extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX];
67
68/* Rather than repeatedly looking up the identifiers, we save them here.  */
69tree objc_rt_trees[OCTI_RT_META_MAX];
70
71/* For building an objc struct.  These might not be used when this file
72   is compiled as part of obj-c++.  */
73
74static bool objc_building_struct;
75static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
76
77/* Start building a struct for objc.  */
78
79tree
80objc_start_struct (tree name)
81{
82  gcc_assert (!objc_building_struct);
83  objc_building_struct = true;
84  return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
85}
86
87/* Finish building a struct for objc.  */
88
89tree
90objc_finish_struct (tree type, tree fieldlist)
91{
92  gcc_assert (objc_building_struct);
93  objc_building_struct = false;
94  return finish_struct (input_location, type, fieldlist, NULL_TREE,
95			objc_struct_info);
96}
97
98tree
99build_sized_array_type (tree base_type, int size)
100{
101  tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
102  return build_array_type (base_type, index_type);
103}
104
105/* Create a declaration for field NAME of a given TYPE.  */
106
107static tree
108create_field_decl (tree type, const char *name)
109{
110  return build_decl (input_location,
111		     FIELD_DECL, get_identifier (name), type);
112}
113
114tree
115add_field_decl (tree type, const char *name, tree **chain)
116{
117  tree field = create_field_decl (type, name);
118
119  if (*chain != NULL)
120    **chain = field;
121  *chain = &DECL_CHAIN (field);
122
123  return field;
124}
125
126/* Create a global, static declaration for variable NAME of a given TYPE.  The
127   finish_var_decl() routine will need to be called on it afterwards.  */
128
129tree
130start_var_decl (tree type, const char *name)
131{
132  tree var = build_decl (input_location,
133			 VAR_DECL, get_identifier (name), type);
134  TREE_STATIC (var) = 1;
135  DECL_INITIAL (var) = error_mark_node;  /* A real initializer is coming... */
136  DECL_IGNORED_P (var) = 1;
137  DECL_ARTIFICIAL (var) = 1;
138  DECL_CONTEXT (var) = NULL_TREE;
139#ifdef OBJCPLUS
140  DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
141#endif
142  return var;
143}
144
145/* Finish off the variable declaration created by start_var_decl().  */
146
147void
148finish_var_decl (tree var, tree initializer)
149{
150  finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
151}
152
153/* Just a handy wrapper for add_objc_string.  */
154
155tree
156build_selector (tree ident)
157{
158  return convert (objc_selector_type, add_objc_string (ident, meth_var_names));
159}
160
161/* --- templates --- */
162
163/* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
164   This needs to be done just once per compilation.  */
165
166/* struct _objc_super {
167     struct _objc_object *self;
168     struct _objc_class *super_class;
169		[or Class cls; for the abi v2]
170   };  */
171
172void
173build_super_template (void)
174{
175  tree decls, *chain = NULL;
176
177  objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
178
179  /* struct _objc_object *self; */
180  decls = add_field_decl (objc_object_type, "self", &chain);
181
182  /* struct _objc_class *super_class; */
183  add_field_decl (build_pointer_type (objc_class_template),
184		  "super_class", &chain);
185
186  objc_finish_struct (objc_super_template, decls);
187}
188
189/* To accomplish method prototyping without generating all kinds of
190   inane warnings, the definition of the dispatch table entries were
191   changed from:
192
193	struct objc_method { SEL _cmd; ...; id (*_imp)(); };
194   to:
195	struct objc_method { SEL _cmd; ...; void *_imp; };  */
196
197tree
198build_method_template (void)
199{
200  tree _SLT_record;
201  tree decls, *chain = NULL;
202
203  _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
204
205  /* SEL _cmd; */
206  decls = add_field_decl (objc_selector_type, "_cmd", &chain);
207
208  /* char *method_types; */
209  add_field_decl (string_type_node, "method_types", &chain);
210
211  /* void *_imp; */
212  add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
213
214  objc_finish_struct (_SLT_record, decls);
215
216  return _SLT_record;
217}
218
219tree
220build_method_prototype_template (void)
221{
222  tree proto_record;
223  tree decls, *chain = NULL;
224
225  proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
226
227  /* SEL _cmd; */
228  decls = add_field_decl (objc_selector_type, "_cmd", &chain);
229
230  /* char *method_types; */
231  add_field_decl (string_type_node, "method_types", &chain);
232
233  objc_finish_struct (proto_record, decls);
234
235  return proto_record;
236}
237
238/* struct {
239     struct _objc__method_prototype_list *method_next;
240     int method_count;
241     struct objc_method method_list[method_count];
242   };  */
243
244tree
245build_method_list_template (tree list_type, int size)
246{
247  tree objc_ivar_list_record;
248  tree array_type, decls, *chain = NULL;
249
250  objc_ivar_list_record = objc_start_struct (NULL_TREE);
251
252  /* struct _objc__method_prototype_list *method_next; */
253  decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
254
255  /* int method_count; */
256  add_field_decl (integer_type_node, "method_count", &chain);
257
258  /* struct objc_method method_list[]; */
259  array_type = build_sized_array_type (list_type, size);
260  add_field_decl (array_type, "method_list", &chain);
261
262  objc_finish_struct (objc_ivar_list_record, decls);
263
264  return objc_ivar_list_record;
265}
266
267/* struct objc_method_prototype_list {
268     int count;
269     struct objc_method_prototype {
270	SEL name;
271	char *types;
272     } list[1];
273   };  */
274
275tree
276build_method_prototype_list_template (tree list_type, int size)
277{
278  tree objc_ivar_list_record;
279  tree array_type, decls, *chain = NULL;
280
281  /* Generate an unnamed struct definition.  */
282
283  objc_ivar_list_record = objc_start_struct (NULL_TREE);
284
285  /* int method_count; */
286  decls = add_field_decl (integer_type_node, "method_count", &chain);
287
288  /* struct objc_method method_list[]; */
289  array_type = build_sized_array_type (list_type, size);
290  add_field_decl (array_type, "method_list", &chain);
291
292  objc_finish_struct (objc_ivar_list_record, decls);
293
294  return objc_ivar_list_record;
295}
296
297/* --- names, decls entry --- */
298
299/* For each string section we have a chain which maps identifier nodes
300   to decls for the strings.  */
301
302static GTY(()) int meth_var_names_idx;
303static GTY(()) int meth_var_types_idx;
304static GTY(()) int property_name_attr_idx;
305
306tree
307add_objc_string (tree ident, string_section section)
308{
309  tree *chain, decl, type;
310  char buf[BUFSIZE];
311
312  switch (section)
313    {
314    case class_names:
315      chain = &class_names_chain;
316      snprintf (buf, BUFSIZE, "_OBJC_ClassName_%s", IDENTIFIER_POINTER (ident));
317      break;
318    case meth_var_names:
319      chain = &meth_var_names_chain;
320      snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
321      break;
322    case meth_var_types:
323      chain = &meth_var_types_chain;
324      snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
325      break;
326    case prop_names_attr:
327      chain = &prop_names_attr_chain;
328      snprintf (buf, BUFSIZE, "_OBJC_PropertyAttributeOrName_%d", property_name_attr_idx++);
329      break;
330    default:
331      gcc_unreachable ();
332    }
333
334  while (*chain)
335    {
336      if (TREE_VALUE (*chain) == ident)
337	return convert (string_type_node,
338			build_unary_op (input_location,
339					ADDR_EXPR, TREE_PURPOSE (*chain), 1));
340
341      chain = &TREE_CHAIN (*chain);
342    }
343
344  type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
345  /* Get a runtime-specific string decl which will be finish_var()'ed in
346     generate_strings ().  */
347  decl = (*runtime.string_decl) (type, buf, section);
348  TREE_CONSTANT (decl) = 1;
349  *chain = tree_cons (decl, ident, NULL_TREE);
350
351  return convert (string_type_node,
352		  build_unary_op (input_location, ADDR_EXPR, decl, 1));
353}
354
355/* --- shared metadata routines --- */
356
357tree
358build_descriptor_table_initializer (tree type, tree entries)
359{
360  vec<constructor_elt, va_gc> *inits = NULL;
361
362  do
363    {
364      vec<constructor_elt, va_gc> *elts = NULL;
365
366      CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
367			      build_selector (METHOD_SEL_NAME (entries)));
368      CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
369			      add_objc_string (METHOD_ENCODING (entries),
370					       meth_var_types));
371
372      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
373			      objc_build_constructor (type, elts));
374
375      entries = DECL_CHAIN (entries);
376    }
377  while (entries);
378
379  return objc_build_constructor (build_array_type (type, 0), inits);
380}
381
382tree
383build_dispatch_table_initializer (tree type, tree entries)
384{
385  vec<constructor_elt, va_gc> *inits = NULL;
386
387  do
388    {
389      vec<constructor_elt, va_gc> *elems = NULL;
390      tree expr;
391
392      CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
393			      build_selector (METHOD_SEL_NAME (entries)));
394
395      /* Generate the method encoding if we don't have one already.  */
396      if (! METHOD_ENCODING (entries))
397	METHOD_ENCODING (entries) =
398	  encode_method_prototype (entries);
399
400      CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
401			      add_objc_string (METHOD_ENCODING (entries),
402					       meth_var_types));
403
404      expr = convert (ptr_type_node,
405		      build_unary_op (input_location, ADDR_EXPR,
406				      METHOD_DEFINITION (entries), 1));
407      CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
408
409      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
410			      objc_build_constructor (type, elems));
411
412      entries = DECL_CHAIN (entries);
413    }
414  while (entries);
415
416  return objc_build_constructor (build_array_type (type, 0), inits);
417}
418
419/* Used only by build_*_selector_translation_table (). */
420void
421diagnose_missing_method (tree meth, location_t here)
422{
423  tree method_chain;
424  bool found = false;
425  for (method_chain = meth_var_names_chain;
426       method_chain;
427       method_chain = TREE_CHAIN (method_chain))
428    {
429      if (TREE_VALUE (method_chain) == meth)
430	{
431	  found = true;
432	  break;
433	}
434     }
435
436  if (!found)
437    warning_at (here, 0, "creating selector for nonexistent method %qE",
438			meth);
439}
440
441
442static tree
443init_module_descriptor (tree type, long vers)
444{
445  tree expr, ltyp;
446  location_t loc;
447  vec<constructor_elt, va_gc> *v = NULL;
448
449  /* No really useful place to point to.  */
450  loc = UNKNOWN_LOCATION;
451
452  /* version = { 1, ... } */
453
454  expr = build_int_cst (long_integer_type_node, vers);
455  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
456
457  /* size = { ..., sizeof (struct _objc_module), ... } */
458
459  expr = convert (long_integer_type_node,
460		  size_in_bytes (objc_module_template));
461  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
462
463  /* Don't provide any file name for security reasons. */
464  /* name = { ..., "", ... } */
465
466  expr = add_objc_string (get_identifier (""), class_names);
467  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
468
469  /* symtab = { ..., _OBJC_SYMBOLS, ... } */
470
471  ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
472				       get_identifier (UTAG_SYMTAB)));
473  if (UOBJC_SYMBOLS_decl)
474    expr = convert (ltyp, build_unary_op (loc,
475			   ADDR_EXPR, UOBJC_SYMBOLS_decl, 0));
476  else
477    expr = convert (ltyp, null_pointer_node);
478  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
479
480  return objc_build_constructor (type, v);
481}
482
483/* Write out the data structures to describe Objective C classes defined.
484
485   struct _objc_module { ... } _OBJC_MODULE = { ... };   */
486
487void
488build_module_descriptor (long vers, tree attr)
489{
490  tree decls, *chain = NULL;
491
492#ifdef OBJCPLUS
493  push_lang_context (lang_name_c); /* extern "C" */
494#endif
495
496  objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
497
498  /* long version; */
499  decls = add_field_decl (long_integer_type_node, "version", &chain);
500
501  /* long size; */
502  add_field_decl (long_integer_type_node, "size", &chain);
503
504  /* char *name; */
505  add_field_decl (string_type_node, "name", &chain);
506
507  /* struct _objc_symtab *symtab; */
508  add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
509						get_identifier (UTAG_SYMTAB))),
510		  "symtab", &chain);
511
512  objc_finish_struct (objc_module_template, decls);
513
514  /* Create an instance of "_objc_module".  */
515  UOBJC_MODULES_decl = start_var_decl (objc_module_template,
516				       /* FIXME - why the conditional
517					  if the symbol is the
518					  same.  */
519				       flag_next_runtime ? "_OBJC_Module" :  "_OBJC_Module");
520
521  /* This is the root of the metadata for defined classes and categories, it
522     is referenced by the runtime and, therefore, needed.  */
523  DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
524
525  /* Allow the runtime to mark meta-data such that it can be assigned to target
526     specific sections by the back-end.  */
527  if (attr)
528    DECL_ATTRIBUTES (UOBJC_MODULES_decl) = attr;
529
530  finish_var_decl (UOBJC_MODULES_decl,
531		   init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl),
532					   vers));
533
534#ifdef OBJCPLUS
535  pop_lang_context ();
536#endif
537}
538
539tree
540build_ivar_list_initializer (tree type, tree field_decl)
541{
542  vec<constructor_elt, va_gc> *inits = NULL;
543
544  do
545    {
546      vec<constructor_elt, va_gc> *ivar = NULL;
547      tree id;
548
549      /* Set name.  */
550      if (DECL_NAME (field_decl))
551	CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
552				add_objc_string (DECL_NAME (field_decl),
553						 meth_var_names));
554      else
555	/* Unnamed bit-field ivar (yuck).  */
556	CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
557
558      /* Set type.  */
559      id = add_objc_string (encode_field_decl (field_decl),
560                            meth_var_types);
561      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
562
563      /* Set offset.  */
564      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
565      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
566			      objc_build_constructor (type, ivar));
567      do
568	field_decl = DECL_CHAIN (field_decl);
569      while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
570    }
571  while (field_decl);
572
573  return objc_build_constructor (build_array_type (type, 0), inits);
574}
575
576/* struct {
577     int ivar_count;
578     struct objc_ivar ivar_list[ivar_count];
579   };  */
580
581tree
582build_ivar_list_template (tree list_type, int size)
583{
584  tree objc_ivar_list_record;
585  tree array_type, decls, *chain = NULL;
586
587  objc_ivar_list_record = objc_start_struct (NULL_TREE);
588
589  /* int ivar_count; */
590  decls = add_field_decl (integer_type_node, "ivar_count", &chain);
591
592  /* struct objc_ivar ivar_list[]; */
593  array_type = build_sized_array_type (list_type, size);
594  add_field_decl (array_type, "ivar_list", &chain);
595
596  objc_finish_struct (objc_ivar_list_record, decls);
597
598  return objc_ivar_list_record;
599}
600
601/* struct _objc_ivar {
602     char *ivar_name;
603     char *ivar_type;
604     int ivar_offset;
605   };  */
606
607tree
608build_ivar_template (void)
609{
610  tree objc_ivar_id, objc_ivar_record;
611  tree decls, *chain = NULL;
612
613  objc_ivar_id = get_identifier (UTAG_IVAR);
614  objc_ivar_record = objc_start_struct (objc_ivar_id);
615
616  /* char *ivar_name; */
617  decls = add_field_decl (string_type_node, "ivar_name", &chain);
618
619  /* char *ivar_type; */
620  add_field_decl (string_type_node, "ivar_type", &chain);
621
622  /* int ivar_offset; */
623  add_field_decl (integer_type_node, "ivar_offset", &chain);
624
625  objc_finish_struct (objc_ivar_record, decls);
626
627  return objc_ivar_record;
628}
629
630/* Used by NeXT ABI=0..2 */
631void
632build_next_selector_translation_table (void)
633{
634  tree chain;
635  for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
636    {
637      tree expr;
638      tree decl = TREE_PURPOSE (chain);
639      if (warn_selector)
640	{
641	  location_t loc;
642	  if (decl)
643	    loc = DECL_SOURCE_LOCATION (decl);
644	  else
645	    loc = UNKNOWN_LOCATION;
646	  diagnose_missing_method (TREE_VALUE (chain), loc);
647	}
648
649      expr = build_selector (TREE_VALUE (chain));
650
651      if (decl)
652	{
653	  /* Entries of this form are used for references to methods.
654	  The runtime re-writes these on start-up, but the compiler can't see
655	  that and optimizes it away unless we force it.  */
656	  DECL_PRESERVE_P (decl) = 1;
657	  finish_var_decl (decl, expr);
658	}
659    }
660}
661
662void
663generate_protocol_references (tree plist)
664{
665  tree lproto;
666
667  /* Forward declare protocols referenced.  */
668  for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
669    {
670      tree proto = TREE_VALUE (lproto);
671
672      if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
673	  && PROTOCOL_NAME (proto))
674	{
675          if (! PROTOCOL_FORWARD_DECL (proto))
676            PROTOCOL_FORWARD_DECL (proto) = (*runtime.protocol_decl) (proto);
677
678          if (PROTOCOL_LIST (proto))
679            generate_protocol_references (PROTOCOL_LIST (proto));
680        }
681    }
682}
683
684/* --- new routines --- */
685
686/* Output all strings.  */
687
688/* FIXME: don't use global vars for all this... */
689
690/* This emits all the meta-data string tables (and finalizes each var
691   as it goes).  */
692void
693generate_strings (void)
694{
695  tree chain, string_expr;
696  tree string, decl; /* , type;*/
697
698  for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
699    {
700      string = TREE_VALUE (chain);
701      decl = TREE_PURPOSE (chain);
702      string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
703				     IDENTIFIER_POINTER (string));
704      finish_var_decl (decl, string_expr);
705    }
706
707  for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
708    {
709      string = TREE_VALUE (chain);
710      decl = TREE_PURPOSE (chain);
711      string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
712				     IDENTIFIER_POINTER (string));
713      finish_var_decl (decl, string_expr);
714    }
715
716  for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
717    {
718      string = TREE_VALUE (chain);
719      decl = TREE_PURPOSE (chain);
720      string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
721				     IDENTIFIER_POINTER (string));
722      finish_var_decl (decl, string_expr);
723    }
724
725  for (chain = prop_names_attr_chain; chain; chain = TREE_CHAIN (chain))
726    {
727      string = TREE_VALUE (chain);
728      decl = TREE_PURPOSE (chain);
729      string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
730				     IDENTIFIER_POINTER (string));
731      finish_var_decl (decl, string_expr);
732    }
733}
734
735#include "gt-objc-objc-runtime-shared-support.h"
736