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