OSDN Git Service

01b33a3f9c4341cd3a76b305a3685e4543289705
[pf3gnuchains/gcc-fork.git] / gcc / ada / gcc-interface / misc.c
1 /****************************************************************************
2  *                                                                          *
3  *                         GNAT COMPILER COMPONENTS                         *
4  *                                                                          *
5  *                                 M I S C                                  *
6  *                                                                          *
7  *                           C Implementation File                          *
8  *                                                                          *
9  *          Copyright (C) 1992-2010, Free Software Foundation, Inc.         *
10  *                                                                          *
11  * GNAT is free software;  you can  redistribute it  and/or modify it under *
12  * terms of the  GNU General Public License as published  by the Free Soft- *
13  * ware  Foundation;  either version 3,  or (at your option) any later ver- *
14  * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
15  * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
16  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License *
17  * for  more details.  You should have  received  a copy of the GNU General *
18  * Public License  distributed  with GNAT;  see file  COPYING3.  If not see *
19  * <http://www.gnu.org/licenses/>.                                          *
20  *                                                                          *
21  * GNAT was originally developed  by the GNAT team at  New York University. *
22  * Extensive contributions were provided by Ada Core Technologies Inc.      *
23  *                                                                          *
24  ****************************************************************************/
25
26 /* This file contains parts of the compiler that are required for interfacing
27    with GCC but otherwise do nothing and parts of Gigi that need to know
28    about GIMPLE.  */
29
30 #include "config.h"
31 #include "system.h"
32 #include "coretypes.h"
33 #include "tm.h"
34 #include "tree.h"
35 #include "diagnostic.h"
36 #include "target.h"
37 #include "ggc.h"
38 #include "flags.h"
39 #include "debug.h"
40 #include "toplev.h"
41 #include "langhooks.h"
42 #include "langhooks-def.h"
43 #include "opts.h"
44 #include "options.h"
45 #include "plugin.h"
46 #include "function.h"   /* For pass_by_reference.  */
47
48 #include "ada.h"
49 #include "adadecode.h"
50 #include "types.h"
51 #include "atree.h"
52 #include "elists.h"
53 #include "namet.h"
54 #include "nlists.h"
55 #include "stringt.h"
56 #include "uintp.h"
57 #include "fe.h"
58 #include "sinfo.h"
59 #include "einfo.h"
60 #include "ada-tree.h"
61 #include "gigi.h"
62
63 static bool gnat_init                   (void);
64 static unsigned int gnat_option_lang_mask (void);
65 static void gnat_init_options           (unsigned int,
66                                          struct cl_decoded_option *);
67 static bool gnat_handle_option          (size_t, const char *, int, int,
68                                          const struct cl_option_handlers *);
69 static bool gnat_post_options           (const char **);
70 static alias_set_type gnat_get_alias_set (tree);
71 static void gnat_print_decl             (FILE *, tree, int);
72 static void gnat_print_type             (FILE *, tree, int);
73 static const char *gnat_printable_name  (tree, int);
74 static const char *gnat_dwarf_name      (tree, int);
75 static tree gnat_return_tree            (tree);
76 static void gnat_parse_file             (int);
77 static void internal_error_function     (diagnostic_context *,
78                                          const char *, va_list *);
79 static tree gnat_type_max_size          (const_tree);
80 static void gnat_get_subrange_bounds    (const_tree, tree *, tree *);
81 static tree gnat_eh_personality         (void);
82
83 /* Definitions for our language-specific hooks.  */
84
85 #undef  LANG_HOOKS_NAME
86 #define LANG_HOOKS_NAME                 "GNU Ada"
87 #undef  LANG_HOOKS_IDENTIFIER_SIZE
88 #define LANG_HOOKS_IDENTIFIER_SIZE      sizeof (struct tree_identifier)
89 #undef  LANG_HOOKS_INIT
90 #define LANG_HOOKS_INIT                 gnat_init
91 #undef  LANG_HOOKS_OPTION_LANG_MASK
92 #define LANG_HOOKS_OPTION_LANG_MASK     gnat_option_lang_mask
93 #undef  LANG_HOOKS_INIT_OPTIONS
94 #define LANG_HOOKS_INIT_OPTIONS         gnat_init_options
95 #undef  LANG_HOOKS_HANDLE_OPTION
96 #define LANG_HOOKS_HANDLE_OPTION        gnat_handle_option
97 #undef  LANG_HOOKS_POST_OPTIONS
98 #define LANG_HOOKS_POST_OPTIONS         gnat_post_options
99 #undef  LANG_HOOKS_PARSE_FILE
100 #define LANG_HOOKS_PARSE_FILE           gnat_parse_file
101 #undef  LANG_HOOKS_HASH_TYPES
102 #define LANG_HOOKS_HASH_TYPES           false
103 #undef  LANG_HOOKS_GETDECLS
104 #define LANG_HOOKS_GETDECLS             lhd_return_null_tree_v
105 #undef  LANG_HOOKS_PUSHDECL
106 #define LANG_HOOKS_PUSHDECL             gnat_return_tree
107 #undef  LANG_HOOKS_WRITE_GLOBALS
108 #define LANG_HOOKS_WRITE_GLOBALS        gnat_write_global_declarations
109 #undef  LANG_HOOKS_GET_ALIAS_SET
110 #define LANG_HOOKS_GET_ALIAS_SET        gnat_get_alias_set
111 #undef  LANG_HOOKS_PRINT_DECL
112 #define LANG_HOOKS_PRINT_DECL           gnat_print_decl
113 #undef  LANG_HOOKS_PRINT_TYPE
114 #define LANG_HOOKS_PRINT_TYPE           gnat_print_type
115 #undef  LANG_HOOKS_TYPE_MAX_SIZE
116 #define LANG_HOOKS_TYPE_MAX_SIZE        gnat_type_max_size
117 #undef  LANG_HOOKS_DECL_PRINTABLE_NAME
118 #define LANG_HOOKS_DECL_PRINTABLE_NAME  gnat_printable_name
119 #undef  LANG_HOOKS_DWARF_NAME
120 #define LANG_HOOKS_DWARF_NAME           gnat_dwarf_name
121 #undef  LANG_HOOKS_GIMPLIFY_EXPR
122 #define LANG_HOOKS_GIMPLIFY_EXPR        gnat_gimplify_expr
123 #undef  LANG_HOOKS_TYPE_FOR_MODE
124 #define LANG_HOOKS_TYPE_FOR_MODE        gnat_type_for_mode
125 #undef  LANG_HOOKS_TYPE_FOR_SIZE
126 #define LANG_HOOKS_TYPE_FOR_SIZE        gnat_type_for_size
127 #undef  LANG_HOOKS_TYPES_COMPATIBLE_P
128 #define LANG_HOOKS_TYPES_COMPATIBLE_P   gnat_types_compatible_p
129 #undef  LANG_HOOKS_GET_SUBRANGE_BOUNDS
130 #define LANG_HOOKS_GET_SUBRANGE_BOUNDS  gnat_get_subrange_bounds
131 #undef  LANG_HOOKS_ATTRIBUTE_TABLE
132 #define LANG_HOOKS_ATTRIBUTE_TABLE      gnat_internal_attribute_table
133 #undef  LANG_HOOKS_BUILTIN_FUNCTION
134 #define LANG_HOOKS_BUILTIN_FUNCTION     gnat_builtin_function
135 #undef  LANG_HOOKS_EH_PERSONALITY
136 #define LANG_HOOKS_EH_PERSONALITY       gnat_eh_personality
137 #undef  LANG_HOOKS_DEEP_UNSHARING
138 #define LANG_HOOKS_DEEP_UNSHARING       true
139
140 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
141
142 /* This symbol needs to be defined for the front-end.  */
143 void *callgraph_info_file = NULL;
144
145 /* How much we want of our DWARF extensions.  Some of our dwarf+ extensions
146    are incompatible with regular GDB versions, so we must make sure to only
147    produce them on explicit request.  This is eventually reflected into the
148    use_gnu_debug_info_extensions common flag for later processing.  */
149 static int gnat_dwarf_extensions = 0;
150
151 /* Command-line argc and argv.  These variables are global
152    since they are imported in back_end.adb.  */
153 unsigned int save_argc;
154 const char **save_argv;
155
156 /* GNAT argc and argv.  */
157 extern int gnat_argc;
158 extern char **gnat_argv;
159
160 /* Declare functions we use as part of startup.  */
161 extern void __gnat_initialize           (void *);
162 extern void __gnat_install_SEH_handler  (void *);
163 extern void adainit                     (void);
164 extern void _ada_gnat1drv               (void);
165
166 /* The parser for the language.  For us, we process the GNAT tree.  */
167
168 static void
169 gnat_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
170 {
171   int seh[2];
172
173   /* Call the target specific initializations.  */
174   __gnat_initialize (NULL);
175
176   /* ??? Call the SEH initialization routine.  This is to workaround
177   a bootstrap path problem.  The call below should be removed at some
178   point and the SEH pointer passed to __gnat_initialize() above.  */
179   __gnat_install_SEH_handler((void *)seh);
180
181   /* Call the front-end elaboration procedures.  */
182   adainit ();
183
184   /* Call the front end.  */
185   _ada_gnat1drv ();
186 }
187
188 /* Decode all the language specific options that cannot be decoded by GCC.
189    The option decoding phase of GCC calls this routine on the flags that
190    are marked as Ada-specific.  Return true on success or false on failure.  */
191
192 static bool
193 gnat_handle_option (size_t scode, const char *arg ATTRIBUTE_UNUSED, int value,
194                     int kind ATTRIBUTE_UNUSED,
195                     const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
196 {
197   enum opt_code code = (enum opt_code) scode;
198
199   switch (code)
200     {
201     case OPT_Wall:
202       warn_unused = value;
203       warn_uninitialized = value;
204       break;
205
206     case OPT_Wmissing_prototypes:
207     case OPT_Wstrict_prototypes:
208     case OPT_Wwrite_strings:
209     case OPT_Wlong_long:
210     case OPT_Wvariadic_macros:
211     case OPT_Wold_style_definition:
212     case OPT_Wmissing_format_attribute:
213     case OPT_Woverlength_strings:
214       /* These are used in the GCC Makefile.  */
215       break;
216
217     case OPT_feliminate_unused_debug_types:
218       /* We arrange for post_option to be able to only set the corresponding
219          flag to 1 when explicitly requested by the user.  We expect the
220          default flag value to be either 0 or positive, and expose a positive
221          -f as a negative value to post_option.  */
222       flag_eliminate_unused_debug_types = -value;
223       break;
224
225     case OPT_gdwarfplus:
226       gnat_dwarf_extensions = 1;
227       break;
228
229     case OPT_gant:
230       warning (0, "%<-gnat%> misspelled as %<-gant%>");
231
232       /* ... fall through ... */
233
234     case OPT_gnat:
235     case OPT_gnatO:
236     case OPT_fRTS_:
237     case OPT_I:
238     case OPT_nostdinc:
239     case OPT_nostdlib:
240       /* These are handled by the front-end.  */
241       break;
242
243     default:
244       gcc_unreachable ();
245     }
246
247   return true;
248 }
249
250 /* Return language mask for option processing.  */
251
252 static unsigned int
253 gnat_option_lang_mask (void)
254 {
255   return CL_Ada;
256 }
257
258 /* Initialize for option processing.  */
259
260 static void
261 gnat_init_options (unsigned int decoded_options_count,
262                    struct cl_decoded_option *decoded_options)
263 {
264   /* Reconstruct an argv array for use of back_end.adb.
265
266      ??? back_end.adb should not rely on this; instead, it should work
267      with decoded options without such reparsing, to ensure
268      consistency in how options are decoded.  */
269   unsigned int i;
270
271   save_argv = XNEWVEC (const char *, 2 * decoded_options_count + 1);
272   save_argc = 0;
273   for (i = 0; i < decoded_options_count; i++)
274     {
275       save_argv[save_argc++] = decoded_options[i].canonical_option[0];
276       if (decoded_options[i].canonical_option[1] != NULL)
277         save_argv[save_argc++] = decoded_options[i].canonical_option[1];
278     }
279   save_argv[save_argc] = NULL;
280
281   gnat_argv = (char **) xmalloc (sizeof (save_argv[0]));
282   gnat_argv[0] = xstrdup (save_argv[0]);     /* name of the command */
283   gnat_argc = 1;
284
285   /* Uninitialized really means uninitialized in Ada.  */
286   flag_zero_initialized_in_bss = 0;
287 }
288
289 /* Post-switch processing.  */
290
291 bool
292 gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
293 {
294   /* Excess precision other than "fast" requires front-end
295      support.  */
296   if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD
297       && TARGET_FLT_EVAL_METHOD_NON_DEFAULT)
298     sorry ("-fexcess-precision=standard for Ada");
299   flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
300
301   /* ??? The warning machinery is outsmarted by Ada.  */
302   warn_unused_parameter = 0;
303
304   /* No psABI change warnings for Ada.  */
305   warn_psabi = 0;
306
307   /* Force eliminate_unused_debug_types to 0 unless an explicit positive
308      -f has been passed.  This forces the default to 0 for Ada, which might
309      differ from the common default.  */
310   if (flag_eliminate_unused_debug_types < 0)
311     flag_eliminate_unused_debug_types = 1;
312   else
313     flag_eliminate_unused_debug_types = 0;
314
315   /* Reflect the explicit request of DWARF extensions into the common
316      flag for use by later passes.  */
317   if (write_symbols == DWARF2_DEBUG)
318     use_gnu_debug_info_extensions = gnat_dwarf_extensions > 0;
319
320   return false;
321 }
322
323 /* Here is the function to handle the compiler error processing in GCC.  */
324
325 static void
326 internal_error_function (diagnostic_context *context,
327                          const char *msgid, va_list *ap)
328 {
329   text_info tinfo;
330   char *buffer, *p, *loc;
331   String_Template temp, temp_loc;
332   Fat_Pointer fp, fp_loc;
333   expanded_location s;
334
335   /* Warn if plugins present.  */
336   warn_if_plugins ();
337
338   /* Reset the pretty-printer.  */
339   pp_clear_output_area (context->printer);
340
341   /* Format the message into the pretty-printer.  */
342   tinfo.format_spec = msgid;
343   tinfo.args_ptr = ap;
344   tinfo.err_no = errno;
345   pp_format_verbatim (context->printer, &tinfo);
346
347   /* Extract a (writable) pointer to the formatted text.  */
348   buffer = xstrdup (pp_formatted_text (context->printer));
349
350   /* Go up to the first newline.  */
351   for (p = buffer; *p; p++)
352     if (*p == '\n')
353       {
354         *p = '\0';
355         break;
356       }
357
358   temp.Low_Bound = 1;
359   temp.High_Bound = p - buffer;
360   fp.Bounds = &temp;
361   fp.Array = buffer;
362
363   s = expand_location (input_location);
364   if (context->show_column && s.column != 0)
365     asprintf (&loc, "%s:%d:%d", s.file, s.line, s.column);
366   else
367     asprintf (&loc, "%s:%d", s.file, s.line);
368   temp_loc.Low_Bound = 1;
369   temp_loc.High_Bound = strlen (loc);
370   fp_loc.Bounds = &temp_loc;
371   fp_loc.Array = loc;
372
373   Current_Error_Node = error_gnat_node;
374   Compiler_Abort (fp, -1, fp_loc);
375 }
376
377 /* Perform all the initialization steps that are language-specific.  */
378
379 static bool
380 gnat_init (void)
381 {
382   /* Do little here, most of the standard declarations are set up after the
383      front-end has been run.  Use the same `char' as C, this doesn't really
384      matter since we'll use the explicit `unsigned char' for Character.  */
385   build_common_tree_nodes (flag_signed_char);
386
387   /* In Ada, we use the unsigned type corresponding to the width of Pmode as
388      SIZETYPE.  In most cases when ptr_mode and Pmode differ, C will use the
389      width of ptr_mode for SIZETYPE, but we get better code using the width
390      of Pmode.  Note that, although we manipulate negative offsets for some
391      internal constructs and rely on compile time overflow detection in size
392      computations, using unsigned types for SIZETYPEs is fine since they are
393      treated specially by the middle-end, in particular sign-extended.  */
394   size_type_node = gnat_type_for_mode (Pmode, 1);
395   set_sizetype (size_type_node);
396   TYPE_NAME (sizetype) = get_identifier ("size_type");
397
398   /* In Ada, we use an unsigned 8-bit type for the default boolean type.  */
399   boolean_type_node = make_unsigned_type (8);
400   TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
401   SET_TYPE_RM_MAX_VALUE (boolean_type_node,
402                          build_int_cst (boolean_type_node, 1));
403   SET_TYPE_RM_SIZE (boolean_type_node, bitsize_int (1));
404
405   build_common_tree_nodes_2 (0);
406   sbitsize_one_node = sbitsize_int (1);
407   sbitsize_unit_node = sbitsize_int (BITS_PER_UNIT);
408   boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
409
410   ptr_void_type_node = build_pointer_type (void_type_node);
411
412   /* Show that REFERENCE_TYPEs are internal and should be Pmode.  */
413   internal_reference_types ();
414
415   /* Register our internal error function.  */
416   global_dc->internal_error = &internal_error_function;
417
418   return true;
419 }
420
421 /* If we are using the GCC mechanism to process exception handling, we
422    have to register the personality routine for Ada and to initialize
423    various language dependent hooks.  */
424
425 void
426 gnat_init_gcc_eh (void)
427 {
428 #ifdef DWARF2_UNWIND_INFO
429   /* lang_dependent_init already called dwarf2out_frame_init if true.  */
430   int dwarf2out_frame_initialized = dwarf2out_do_frame ();
431 #endif
432
433   /* We shouldn't do anything if the No_Exceptions_Handler pragma is set,
434      though. This could for instance lead to the emission of tables with
435      references to symbols (such as the Ada eh personality routine) within
436      libraries we won't link against.  */
437   if (No_Exception_Handlers_Set ())
438     return;
439
440   /* Tell GCC we are handling cleanup actions through exception propagation.
441      This opens possibilities that we don't take advantage of yet, but is
442      nonetheless necessary to ensure that fixup code gets assigned to the
443      right exception regions.  */
444   using_eh_for_cleanups ();
445
446   /* Turn on -fexceptions and -fnon-call-exceptions.  The first one triggers
447      the generation of the necessary exception tables.  The second one is
448      useful for two reasons: 1/ we map some asynchronous signals like SEGV to
449      exceptions, so we need to ensure that the insns which can lead to such
450      signals are correctly attached to the exception region they pertain to,
451      2/ Some calls to pure subprograms are handled as libcall blocks and then
452      marked as "cannot trap" if the flag is not set (see emit_libcall_block).
453      We should not let this be since it is possible for such calls to actually
454      raise in Ada.  */
455   flag_exceptions = 1;
456   flag_non_call_exceptions = 1;
457
458   init_eh ();
459 #ifdef DWARF2_UNWIND_INFO
460   if (!dwarf2out_frame_initialized && dwarf2out_do_frame ())
461     dwarf2out_frame_init ();
462 #endif
463 }
464
465 /* Print language-specific items in declaration NODE.  */
466
467 static void
468 gnat_print_decl (FILE *file, tree node, int indent)
469 {
470   switch (TREE_CODE (node))
471     {
472     case CONST_DECL:
473       print_node (file, "corresponding var",
474                   DECL_CONST_CORRESPONDING_VAR (node), indent + 4);
475       break;
476
477     case FIELD_DECL:
478       print_node (file, "original field", DECL_ORIGINAL_FIELD (node),
479                   indent + 4);
480       break;
481
482     case VAR_DECL:
483       print_node (file, "renamed object", DECL_RENAMED_OBJECT (node),
484                   indent + 4);
485       break;
486
487     default:
488       break;
489     }
490 }
491
492 /* Print language-specific items in type NODE.  */
493
494 static void
495 gnat_print_type (FILE *file, tree node, int indent)
496 {
497   switch (TREE_CODE (node))
498     {
499     case FUNCTION_TYPE:
500       print_node (file, "ci/co list", TYPE_CI_CO_LIST (node), indent + 4);
501       break;
502
503     case INTEGER_TYPE:
504       if (TYPE_MODULAR_P (node))
505         print_node_brief (file, "modulus", TYPE_MODULUS (node), indent + 4);
506       else if (TYPE_HAS_ACTUAL_BOUNDS_P (node))
507         print_node (file, "actual bounds", TYPE_ACTUAL_BOUNDS (node),
508                     indent + 4);
509       else if (TYPE_VAX_FLOATING_POINT_P (node))
510         ;
511       else
512         print_node (file, "index type", TYPE_INDEX_TYPE (node), indent + 4);
513
514       /* ... fall through ... */
515
516     case ENUMERAL_TYPE:
517     case BOOLEAN_TYPE:
518       print_node_brief (file, "RM size", TYPE_RM_SIZE (node), indent + 4);
519
520       /* ... fall through ... */
521
522     case REAL_TYPE:
523       print_node_brief (file, "RM min", TYPE_RM_MIN_VALUE (node), indent + 4);
524       print_node_brief (file, "RM max", TYPE_RM_MAX_VALUE (node), indent + 4);
525       break;
526
527     case ARRAY_TYPE:
528       print_node (file,"actual bounds", TYPE_ACTUAL_BOUNDS (node), indent + 4);
529       break;
530
531     case VECTOR_TYPE:
532       print_node (file,"representative array",
533                   TYPE_REPRESENTATIVE_ARRAY (node), indent + 4);
534       break;
535
536     case RECORD_TYPE:
537       if (TYPE_FAT_POINTER_P (node) || TYPE_CONTAINS_TEMPLATE_P (node))
538         print_node (file, "unconstrained array",
539                     TYPE_UNCONSTRAINED_ARRAY (node), indent + 4);
540       else
541         print_node (file, "Ada size", TYPE_ADA_SIZE (node), indent + 4);
542       break;
543
544     case UNION_TYPE:
545     case QUAL_UNION_TYPE:
546       print_node (file, "Ada size", TYPE_ADA_SIZE (node), indent + 4);
547       break;
548
549     default:
550       break;
551     }
552 }
553
554 /* Return the name to be printed for DECL.  */
555
556 static const char *
557 gnat_printable_name (tree decl, int verbosity)
558 {
559   const char *coded_name = IDENTIFIER_POINTER (DECL_NAME (decl));
560   char *ada_name = (char *) ggc_alloc_atomic (strlen (coded_name) * 2 + 60);
561
562   __gnat_decode (coded_name, ada_name, 0);
563
564   if (verbosity == 2 && !DECL_IS_BUILTIN (decl))
565     {
566       Set_Identifier_Casing (ada_name, DECL_SOURCE_FILE (decl));
567       return ggc_strdup (Name_Buffer);
568     }
569
570   return ada_name;
571 }
572
573 /* Return the name to be used in DWARF debug info for DECL.  */
574
575 static const char *
576 gnat_dwarf_name (tree decl, int verbosity ATTRIBUTE_UNUSED)
577 {
578   gcc_assert (DECL_P (decl));
579   return (const char *) IDENTIFIER_POINTER (DECL_NAME (decl));
580 }
581
582 /* Do nothing (return the tree node passed).  */
583
584 static tree
585 gnat_return_tree (tree t)
586 {
587   return t;
588 }
589
590 /* Get the alias set corresponding to a type or expression.  */
591
592 static alias_set_type
593 gnat_get_alias_set (tree type)
594 {
595   /* If this is a padding type, use the type of the first field.  */
596   if (TYPE_IS_PADDING_P (type))
597     return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)));
598
599   /* If the type is an unconstrained array, use the type of the
600      self-referential array we make.  */
601   else if (TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
602     return
603       get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))));
604
605   /* If the type can alias any other types, return the alias set 0.  */
606   else if (TYPE_P (type)
607            && TYPE_UNIVERSAL_ALIASING_P (TYPE_MAIN_VARIANT (type)))
608     return 0;
609
610   return -1;
611 }
612
613 /* GNU_TYPE is a type.  Return its maximum size in bytes, if known,
614    as a constant when possible.  */
615
616 static tree
617 gnat_type_max_size (const_tree gnu_type)
618 {
619   /* First see what we can get from TYPE_SIZE_UNIT, which might not
620      be constant even for simple expressions if it has already been
621      elaborated and possibly replaced by a VAR_DECL.  */
622   tree max_unitsize = max_size (TYPE_SIZE_UNIT (gnu_type), true);
623
624   /* If we don't have a constant, see what we can get from TYPE_ADA_SIZE,
625      which should stay untouched.  */
626   if (!host_integerp (max_unitsize, 1)
627       && (TREE_CODE (gnu_type) == RECORD_TYPE
628           || TREE_CODE (gnu_type) == UNION_TYPE
629           || TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
630       && TYPE_ADA_SIZE (gnu_type))
631     {
632       tree max_adasize = max_size (TYPE_ADA_SIZE (gnu_type), true);
633
634       /* If we have succeeded in finding a constant, round it up to the
635          type's alignment and return the result in units.  */
636       if (host_integerp (max_adasize, 1))
637         max_unitsize
638           = size_binop (CEIL_DIV_EXPR,
639                         round_up (max_adasize, TYPE_ALIGN (gnu_type)),
640                         bitsize_unit_node);
641     }
642
643   return max_unitsize;
644 }
645
646 /* GNU_TYPE is a subtype of an integral type.  Set LOWVAL to the low bound
647    and HIGHVAL to the high bound, respectively.  */
648
649 static void
650 gnat_get_subrange_bounds (const_tree gnu_type, tree *lowval, tree *highval)
651 {
652   *lowval = TYPE_MIN_VALUE (gnu_type);
653   *highval = TYPE_MAX_VALUE (gnu_type);
654 }
655
656 /* GNU_TYPE is a type. Determine if it should be passed by reference by
657    default.  */
658
659 bool
660 default_pass_by_ref (tree gnu_type)
661 {
662   /* We pass aggregates by reference if they are sufficiently large.  The
663      choice of constant here is somewhat arbitrary.  We also pass by
664      reference if the target machine would either pass or return by
665      reference.  Strictly speaking, we need only check the return if this
666      is an In Out parameter, but it's probably best to err on the side of
667      passing more things by reference.  */
668
669   if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, 1))
670     return true;
671
672   if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))
673     return true;
674
675   if (AGGREGATE_TYPE_P (gnu_type)
676       && (!host_integerp (TYPE_SIZE (gnu_type), 1)
677           || 0 < compare_tree_int (TYPE_SIZE (gnu_type),
678                                    8 * TYPE_ALIGN (gnu_type))))
679     return true;
680
681   return false;
682 }
683
684 /* GNU_TYPE is the type of a subprogram parameter.  Determine from the type if
685    it should be passed by reference. */
686
687 bool
688 must_pass_by_ref (tree gnu_type)
689 {
690   /* We pass only unconstrained objects, those required by the language
691      to be passed by reference, and objects of variable size.  The latter
692      is more efficient, avoids problems with variable size temporaries,
693      and does not produce compatibility problems with C, since C does
694      not have such objects.  */
695   return (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE
696           || TREE_ADDRESSABLE (gnu_type)
697           || (TYPE_SIZE (gnu_type)
698               && TREE_CODE (TYPE_SIZE (gnu_type)) != INTEGER_CST));
699 }
700
701 /* Return the size of the FP mode with precision PREC.  */
702
703 int
704 fp_prec_to_size (int prec)
705 {
706   enum machine_mode mode;
707
708   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
709        mode = GET_MODE_WIDER_MODE (mode))
710     if (GET_MODE_PRECISION (mode) == prec)
711       return GET_MODE_BITSIZE (mode);
712
713   gcc_unreachable ();
714 }
715
716 /* Return the precision of the FP mode with size SIZE.  */
717
718 int
719 fp_size_to_prec (int size)
720 {
721   enum machine_mode mode;
722
723   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
724        mode = GET_MODE_WIDER_MODE (mode))
725     if (GET_MODE_BITSIZE (mode) == size)
726       return GET_MODE_PRECISION (mode);
727
728   gcc_unreachable ();
729 }
730
731 static GTY(()) tree gnat_eh_personality_decl;
732
733 static tree
734 gnat_eh_personality (void)
735 {
736   if (!gnat_eh_personality_decl)
737     gnat_eh_personality_decl
738       = build_personality_function (USING_SJLJ_EXCEPTIONS
739                                     ? "__gnat_eh_personality_sj"
740                                     : "__gnat_eh_personality");
741
742   return gnat_eh_personality_decl;
743 }
744
745 #include "gt-ada-misc.h"