Merge branch 'vendor/OPENSSL'
[dragonfly.git] / contrib / gcc-4.7 / gcc / objc / objc-runtime-shared-support.c
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"