OSDN Git Service

* back-end.adb (Call_Back_End): Pass Standard_Character to gigi.
[pf3gnuchains/gcc-fork.git] / gcc / ada / gcc-interface / misc.c
index ca672f8..481c85a 100644 (file)
@@ -6,24 +6,17 @@
  *                                                                          *
  *                           C Implementation File                          *
  *                                                                          *
- *          Copyright (C) 1992-2009, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2010, Free Software Foundation, Inc.         *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
- * ware  Foundation;  either version 2,  or (at your option) any later ver- *
+ * ware  Foundation;  either version 3,  or (at your option) any later ver- *
  * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
  * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License *
  * for  more details.  You should have  received  a copy of the GNU General *
- * Public License  distributed with GNAT;  see file COPYING.  If not, write *
- * to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, *
- * Boston, MA 02110-1301, USA.                                              *
- *                                                                          *
- * As a  special  exception,  if you  link  this file  with other  files to *
- * produce an executable,  this file does not by itself cause the resulting *
- * executable to be covered by the GNU General Public License. This except- *
- * ion does not  however invalidate  any other reasons  why the  executable *
- * file might be covered by the  GNU Public License.                        *
+ * Public License  distributed  with GNAT;  see file  COPYING3.  If not see *
+ * <http://www.gnu.org/licenses/>.                                          *
  *                                                                          *
  * GNAT was originally developed  by the GNAT team at  New York University. *
  * Extensive contributions were provided by Ada Core Technologies Inc.      *
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "real.h"
-#include "rtl.h"
 #include "diagnostic.h"
+#include "target.h"
 #include "expr.h"
 #include "libfuncs.h"
 #include "ggc.h"
 #include "flags.h"
 #include "debug.h"
 #include "cgraph.h"
-#include "tree-inline.h"
-#include "insn-codes.h"
-#include "insn-flags.h"
-#include "insn-config.h"
 #include "optabs.h"
-#include "recog.h"
 #include "toplev.h"
-#include "output.h"
 #include "except.h"
-#include "tm_p.h"
 #include "langhooks.h"
 #include "langhooks-def.h"
-#include "target.h"
+#include "opts.h"
+#include "options.h"
+#include "tree-inline.h"
 
 #include "ada.h"
+#include "adadecode.h"
 #include "types.h"
 #include "atree.h"
 #include "elists.h"
 #include "einfo.h"
 #include "ada-tree.h"
 #include "gigi.h"
-#include "adadecode.h"
-#include "opts.h"
-#include "options.h"
-
-extern FILE *asm_out_file;
-
-/* The largest alignment, in bits, that is needed for using the widest
-   move instruction.  */
-unsigned int largest_move_alignment;
 
 static bool gnat_init                  (void);
-static void gnat_finish_incomplete_decl        (tree);
 static unsigned int gnat_init_options  (unsigned int, const char **);
-static int gnat_handle_option          (size_t, const char *, int);
+static int gnat_handle_option          (size_t, const char *, int, int);
 static bool gnat_post_options          (const char **);
 static alias_set_type gnat_get_alias_set (tree);
 static void gnat_print_decl            (FILE *, tree, int);
@@ -96,12 +74,11 @@ static void gnat_print_type         (FILE *, tree, int);
 static const char *gnat_printable_name (tree, int);
 static const char *gnat_dwarf_name     (tree, int);
 static tree gnat_return_tree           (tree);
-static int gnat_eh_type_covers         (tree, tree);
 static void gnat_parse_file            (int);
-static rtx gnat_expand_expr            (tree, rtx, enum machine_mode, int,
-                                        rtx *);
 static void internal_error_function    (const char *, va_list *);
 static tree gnat_type_max_size         (const_tree);
+static void gnat_get_subrange_bounds   (const_tree, tree *, tree *);
+static tree gnat_eh_personality                (void);
 
 /* Definitions for our language-specific hooks.  */
 
@@ -127,14 +104,8 @@ static tree gnat_type_max_size             (const_tree);
 #define LANG_HOOKS_PUSHDECL            gnat_return_tree
 #undef  LANG_HOOKS_WRITE_GLOBALS
 #define LANG_HOOKS_WRITE_GLOBALS       gnat_write_global_declarations
-#undef  LANG_HOOKS_FINISH_INCOMPLETE_DECL
-#define LANG_HOOKS_FINISH_INCOMPLETE_DECL gnat_finish_incomplete_decl
 #undef  LANG_HOOKS_GET_ALIAS_SET
 #define LANG_HOOKS_GET_ALIAS_SET       gnat_get_alias_set
-#undef  LANG_HOOKS_EXPAND_EXPR
-#define LANG_HOOKS_EXPAND_EXPR         gnat_expand_expr
-#undef  LANG_HOOKS_MARK_ADDRESSABLE
-#define LANG_HOOKS_MARK_ADDRESSABLE    gnat_mark_addressable
 #undef  LANG_HOOKS_PRINT_DECL
 #define LANG_HOOKS_PRINT_DECL          gnat_print_decl
 #undef  LANG_HOOKS_PRINT_TYPE
@@ -153,33 +124,32 @@ static tree gnat_type_max_size            (const_tree);
 #define LANG_HOOKS_TYPE_FOR_SIZE       gnat_type_for_size
 #undef  LANG_HOOKS_TYPES_COMPATIBLE_P
 #define LANG_HOOKS_TYPES_COMPATIBLE_P  gnat_types_compatible_p
+#undef  LANG_HOOKS_GET_SUBRANGE_BOUNDS
+#define LANG_HOOKS_GET_SUBRANGE_BOUNDS  gnat_get_subrange_bounds
 #undef  LANG_HOOKS_ATTRIBUTE_TABLE
 #define LANG_HOOKS_ATTRIBUTE_TABLE     gnat_internal_attribute_table
 #undef  LANG_HOOKS_BUILTIN_FUNCTION
-#define LANG_HOOKS_BUILTIN_FUNCTION        gnat_builtin_function
+#define LANG_HOOKS_BUILTIN_FUNCTION    gnat_builtin_function
+#undef  LANG_HOOKS_EH_PERSONALITY
+#define LANG_HOOKS_EH_PERSONALITY      gnat_eh_personality
 
-const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
 /* How much we want of our DWARF extensions.  Some of our dwarf+ extensions
    are incompatible with regular GDB versions, so we must make sure to only
    produce them on explicit request.  This is eventually reflected into the
    use_gnu_debug_info_extensions common flag for later processing.  */
-
 static int gnat_dwarf_extensions = 0;
 
-/* Command-line argc and argv.
-   These variables are global, since they are imported and used in
-   back_end.adb  */
-
+/* Command-line argc and argv.  These variables are global
+   since they are imported in back_end.adb.  */
 unsigned int save_argc;
 const char **save_argv;
 
-/* gnat standard argc argv */
-
+/* GNAT argc and argv.  */
 extern int gnat_argc;
 extern char **gnat_argv;
 
-\f
 /* Declare functions we use as part of startup.  */
 extern void __gnat_initialize           (void *);
 extern void __gnat_install_SEH_handler  (void *);
@@ -206,18 +176,16 @@ gnat_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
 
   /* Call the front end.  */
   _ada_gnat1drv ();
-
-  /* We always have a single compilation unit in Ada.  */
-  cgraph_finalize_compilation_unit ();
 }
 
 /* Decode all the language specific options that cannot be decoded by GCC.
    The option decoding phase of GCC calls this routine on the flags that
-   it cannot decode.  This routine returns the number of consecutive arguments
-   from ARGV that it successfully decoded; 0 indicates failure.  */
+   it cannot decode.  Return the number of consecutive arguments from ARGV
+   that have been successfully decoded or 0 on failure.  */
 
 static int
-gnat_handle_option (size_t scode, const char *arg, int value)
+gnat_handle_option (size_t scode, const char *arg, int value,
+                   int kind ATTRIBUTE_UNUSED)
 {
   const struct cl_option *option = &cl_options[scode];
   enum opt_code code = (enum opt_code) scode;
@@ -241,12 +209,7 @@ gnat_handle_option (size_t scode, const char *arg, int value)
 
     case OPT_Wall:
       warn_unused = value;
-
-      /* We save the value of warn_uninitialized, since if they put
-        -Wuninitialized on the command line, we need to generate a
-        warning about not using it without also specifying -O.  */
-      if (warn_uninitialized != 1)
-       warn_uninitialized = (value ? 2 : 0);
+      warn_uninitialized = value;
       break;
 
       /* These are used in the GCC Makefile.  */
@@ -302,8 +265,8 @@ gnat_handle_option (size_t scode, const char *arg, int value)
       gnat_argc++;
       break;
 
-    case OPT_gdwarf_:
-      gnat_dwarf_extensions ++;
+    case OPT_gdwarfplus:
+      gnat_dwarf_extensions = 1;
       break;
 
     default:
@@ -337,6 +300,13 @@ gnat_init_options (unsigned int argc, const char **argv)
 bool
 gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
 {
+  /* Excess precision other than "fast" requires front-end
+     support.  */
+  if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD
+      && TARGET_FLT_EVAL_METHOD_NON_DEFAULT)
+    sorry ("-fexcess-precision=standard for Ada");
+  flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
+
   /* ??? The warning machinery is outsmarted by Ada.  */
   warn_unused_parameter = 0;
 
@@ -380,7 +350,7 @@ internal_error_function (const char *msgid, va_list *ap)
   pp_format_verbatim (global_dc->printer, &tinfo);
 
   /* Extract a (writable) pointer to the formatted text.  */
-  buffer = (char*) pp_formatted_text (global_dc->printer);
+  buffer = xstrdup (pp_formatted_text (global_dc->printer));
 
   /* Go up to the first newline.  */
   for (p = buffer; *p; p++)
@@ -414,49 +384,48 @@ internal_error_function (const char *msgid, va_list *ap)
 static bool
 gnat_init (void)
 {
-  /* Performs whatever initialization steps needed by the language-dependent
-     lexical analyzer.  */
-  gnat_init_decl_processing ();
-
-  /* Add the input filename as the last argument.  */
-  gnat_argv[gnat_argc] = (char *) main_input_filename;
-  gnat_argc++;
-  gnat_argv[gnat_argc] = 0;
-
-  global_dc->internal_error = &internal_error_function;
+  /* Do little here, most of the standard declarations are set up after the
+     front-end has been run.  Use the same `char' as C, this doesn't really
+     matter since we'll use the explicit `unsigned char' for Character.  */
+  build_common_tree_nodes (flag_signed_char, true);
+
+  /* In Ada, we use a signed type for SIZETYPE.  Use the signed type
+     corresponding to the width of Pmode.  In most cases when ptr_mode
+     and Pmode differ, C will use the width of ptr_mode for SIZETYPE.
+     But we get far better code using the width of Pmode.  */
+  size_type_node = gnat_type_for_mode (Pmode, 0);
+  set_sizetype (size_type_node);
+  TYPE_NAME (sizetype) = get_identifier ("size_type");
+
+  /* In Ada, we use an unsigned 8-bit type for the default boolean type.  */
+  boolean_type_node = make_unsigned_type (8);
+  TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
+  SET_TYPE_RM_MAX_VALUE (boolean_type_node,
+                        build_int_cst (boolean_type_node, 1));
+  SET_TYPE_RM_SIZE (boolean_type_node, bitsize_int (1));
+
+  build_common_tree_nodes_2 (0);
+  sbitsize_one_node = sbitsize_int (1);
+  sbitsize_unit_node = sbitsize_int (BITS_PER_UNIT);
+  boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
+
+  ptr_void_type_node = build_pointer_type (void_type_node);
 
   /* Show that REFERENCE_TYPEs are internal and should be Pmode.  */
   internal_reference_types ();
 
-  return true;
-}
-
-/* This function is called indirectly from toplev.c to handle incomplete
-   declarations, i.e. VAR_DECL nodes whose DECL_SIZE is zero.  To be precise,
-   compile_file in toplev.c makes an indirect call through the function pointer
-   incomplete_decl_finalize_hook which is initialized to this routine in
-   init_decl_processing.  */
-
-static void
-gnat_finish_incomplete_decl (tree dont_care ATTRIBUTE_UNUSED)
-{
-  gcc_unreachable ();
-}
-\f
-/* Compute the alignment of the largest mode that can be used for copying
-   objects.  */
+  /* Add the input filename as the last argument.  */
+  if (main_input_filename)
+    {
+      gnat_argv[gnat_argc] = xstrdup (main_input_filename);
+      gnat_argc++;
+      gnat_argv[gnat_argc] = NULL;
+    }
 
-void
-gnat_compute_largest_alignment (void)
-{
-  enum machine_mode mode;
+  /* Register our internal error function.  */
+  global_dc->internal_error = &internal_error_function;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
-    if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing)
-      largest_move_alignment = MIN (BIGGEST_ALIGNMENT,
-                                   MAX (largest_move_alignment,
-                                        GET_MODE_ALIGNMENT (mode)));
+  return true;
 }
 
 /* If we are using the GCC mechanism to process exception handling, we
@@ -484,13 +453,6 @@ gnat_init_gcc_eh (void)
      right exception regions.  */
   using_eh_for_cleanups ();
 
-  eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
-                                            ? "__gnat_eh_personality_sj"
-                                            : "__gnat_eh_personality");
-  lang_eh_type_covers = gnat_eh_type_covers;
-  lang_eh_runtime_type = gnat_return_tree;
-  default_init_unwind_resume_libfunc ();
-
   /* Turn on -fexceptions and -fnon-call-exceptions. The first one triggers
      the generation of the necessary exception runtime tables. The second one
      is useful for two reasons: 1/ we map some asynchronous signals like SEGV
@@ -510,7 +472,7 @@ gnat_init_gcc_eh (void)
 #endif
 }
 
-/* Language hooks, first one to print language-specific items in a DECL.  */
+/* Print language-specific items in declaration NODE.  */
 
 static void
 gnat_print_decl (FILE *file, tree node, int indent)
@@ -518,17 +480,17 @@ gnat_print_decl (FILE *file, tree node, int indent)
   switch (TREE_CODE (node))
     {
     case CONST_DECL:
-      print_node (file, "const_corresponding_var",
+      print_node (file, "corresponding var",
                  DECL_CONST_CORRESPONDING_VAR (node), indent + 4);
       break;
 
     case FIELD_DECL:
-      print_node (file, "original_field", DECL_ORIGINAL_FIELD (node),
+      print_node (file, "original field", DECL_ORIGINAL_FIELD (node),
                  indent + 4);
       break;
 
     case VAR_DECL:
-      print_node (file, "renamed_object", DECL_RENAMED_OBJECT (node),
+      print_node (file, "renamed object", DECL_RENAMED_OBJECT (node),
                  indent + 4);
       break;
 
@@ -537,23 +499,20 @@ gnat_print_decl (FILE *file, tree node, int indent)
     }
 }
 
+/* Print language-specific items in type NODE.  */
+
 static void
 gnat_print_type (FILE *file, tree node, int indent)
 {
   switch (TREE_CODE (node))
     {
     case FUNCTION_TYPE:
-      print_node (file, "ci_co_list", TYPE_CI_CO_LIST (node), indent + 4);
-      break;
-
-    case ENUMERAL_TYPE:
-    case BOOLEAN_TYPE:
-      print_node (file, "RM size", TYPE_RM_SIZE_NUM (node), indent + 4);
+      print_node (file, "ci/co list", TYPE_CI_CO_LIST (node), indent + 4);
       break;
 
     case INTEGER_TYPE:
       if (TYPE_MODULAR_P (node))
-       print_node (file, "modulus", TYPE_MODULUS (node), indent + 4);
+       print_node_brief (file, "modulus", TYPE_MODULUS (node), indent + 4);
       else if (TYPE_HAS_ACTUAL_BOUNDS_P (node))
        print_node (file, "actual bounds", TYPE_ACTUAL_BOUNDS (node),
                    indent + 4);
@@ -562,15 +521,30 @@ gnat_print_type (FILE *file, tree node, int indent)
       else
        print_node (file, "index type", TYPE_INDEX_TYPE (node), indent + 4);
 
-      print_node (file, "RM size", TYPE_RM_SIZE_NUM (node), indent + 4);
+      /* ... fall through ... */
+
+    case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
+      print_node_brief (file, "RM size", TYPE_RM_SIZE (node), indent + 4);
+
+      /* ... fall through ... */
+
+    case REAL_TYPE:
+      print_node_brief (file, "RM min", TYPE_RM_MIN_VALUE (node), indent + 4);
+      print_node_brief (file, "RM max", TYPE_RM_MAX_VALUE (node), indent + 4);
       break;
 
     case ARRAY_TYPE:
       print_node (file,"actual bounds", TYPE_ACTUAL_BOUNDS (node), indent + 4);
       break;
 
+    case VECTOR_TYPE:
+      print_node (file,"representative array",
+                 TYPE_REPRESENTATIVE_ARRAY (node), indent + 4);
+      break;
+
     case RECORD_TYPE:
-      if (TYPE_IS_FAT_POINTER_P (node) || TYPE_CONTAINS_TEMPLATE_P (node))
+      if (TYPE_FAT_POINTER_P (node) || TYPE_CONTAINS_TEMPLATE_P (node))
        print_node (file, "unconstrained array",
                    TYPE_UNCONSTRAINED_ARRAY (node), indent + 4);
       else
@@ -587,13 +561,7 @@ gnat_print_type (FILE *file, tree node, int indent)
     }
 }
 
-static const char *
-gnat_dwarf_name (tree t, int verbosity ATTRIBUTE_UNUSED)
-{
-  gcc_assert (DECL_P (t));
-
-  return (const char *) IDENTIFIER_POINTER (DECL_NAME (t));
-}
+/* Return the name to be printed for DECL.  */
 
 static const char *
 gnat_printable_name (tree decl, int verbosity)
@@ -603,52 +571,22 @@ gnat_printable_name (tree decl, int verbosity)
 
   __gnat_decode (coded_name, ada_name, 0);
 
-  if (verbosity == 2)
+  if (verbosity == 2 && !DECL_IS_BUILTIN (decl))
     {
-      Set_Identifier_Casing (ada_name, (char *) DECL_SOURCE_FILE (decl));
+      Set_Identifier_Casing (ada_name, DECL_SOURCE_FILE (decl));
       return ggc_strdup (Name_Buffer);
     }
-  else
-    return ada_name;
+
+  return ada_name;
 }
 
-/* Expands GNAT-specific GCC tree nodes.  The only ones we support
-   here are  and NULL_EXPR.  */
+/* Return the name to be used in DWARF debug info for DECL.  */
 
-static rtx
-gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode,
-                 int modifier, rtx *alt_rtl)
+static const char *
+gnat_dwarf_name (tree decl, int verbosity ATTRIBUTE_UNUSED)
 {
-  tree type = TREE_TYPE (exp);
-  tree new;
-
-  /* Update EXP to be the new expression to expand.  */
-  switch (TREE_CODE (exp))
-    {
-#if 0
-    case ALLOCATE_EXPR:
-      return
-       allocate_dynamic_stack_space
-         (expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, TYPE_MODE (sizetype),
-                       EXPAND_NORMAL),
-          NULL_RTX, tree_low_cst (TREE_OPERAND (exp, 1), 1));
-#endif
-
-    case UNCONSTRAINED_ARRAY_REF:
-      /* If we are evaluating just for side-effects, just evaluate our
-        operand.  Otherwise, abort since this code should never appear
-        in a tree to be evaluated (objects aren't unconstrained).  */
-      if (target == const0_rtx || TREE_CODE (type) == VOID_TYPE)
-       return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
-                           VOIDmode, modifier);
-
-      /* ... fall through ... */
-
-    default:
-      gcc_unreachable ();
-    }
-
-  return expand_expr_real (new, target, tmode, modifier, alt_rtl);
+  gcc_assert (DECL_P (decl));
+  return (const char *) IDENTIFIER_POINTER (DECL_NAME (decl));
 }
 
 /* Do nothing (return the tree node passed).  */
@@ -659,28 +597,13 @@ gnat_return_tree (tree t)
   return t;
 }
 
-/* Return true if type A catches type B. Callback for flow analysis from
-   the exception handling part of the back-end.  */
-
-static int
-gnat_eh_type_covers (tree a, tree b)
-{
-  /* a catches b if they represent the same exception id or if a
-     is an "others".
-
-     ??? integer_zero_node for "others" is hardwired in too many places
-     currently.  */
-  return (a == b || a == integer_zero_node);
-}
-\f
 /* Get the alias set corresponding to a type or expression.  */
 
 static alias_set_type
 gnat_get_alias_set (tree type)
 {
   /* If this is a padding type, use the type of the first field.  */
-  if (TREE_CODE (type) == RECORD_TYPE
-      && TYPE_IS_PADDING_P (type))
+  if (TYPE_IS_PADDING_P (type))
     return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)));
 
   /* If the type is an unconstrained array, use the type of the
@@ -730,6 +653,16 @@ gnat_type_max_size (const_tree gnu_type)
   return max_unitsize;
 }
 
+/* GNU_TYPE is a subtype of an integral type.  Set LOWVAL to the low bound
+   and HIGHVAL to the high bound, respectively.  */
+
+static void
+gnat_get_subrange_bounds (const_tree gnu_type, tree *lowval, tree *highval)
+{
+  *lowval = TYPE_MIN_VALUE (gnu_type);
+  *highval = TYPE_MAX_VALUE (gnu_type);
+}
+
 /* GNU_TYPE is a type. Determine if it should be passed by reference by
    default.  */
 
@@ -770,7 +703,7 @@ must_pass_by_ref (tree gnu_type)
      and does not produce compatibility problems with C, since C does
      not have such objects.  */
   return (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE
-         || (AGGREGATE_TYPE_P (gnu_type) && TYPE_BY_REFERENCE_P (gnu_type))
+         || TREE_ADDRESSABLE (gnu_type)
          || (TYPE_SIZE (gnu_type)
              && TREE_CODE (TYPE_SIZE (gnu_type)) != INTEGER_CST));
 }
@@ -790,10 +723,11 @@ must_pass_by_ref (tree gnu_type)
 void
 enumerate_modes (void (*f) (int, int, int, int, int, int, unsigned int))
 {
-  enum machine_mode i;
+  int iloop;
 
-  for (i = 0; i < NUM_MACHINE_MODES; i++)
+  for (iloop = 0; iloop < NUM_MACHINE_MODES; iloop++)
     {
+      enum machine_mode i = (enum machine_mode) iloop;
       enum machine_mode j;
       bool float_p = 0;
       bool complex_p = 0;
@@ -853,6 +787,8 @@ enumerate_modes (void (*f) (int, int, int, int, int, int, unsigned int))
     }
 }
 
+/* Return the size of the FP mode with precision PREC.  */
+
 int
 fp_prec_to_size (int prec)
 {
@@ -866,6 +802,8 @@ fp_prec_to_size (int prec)
   gcc_unreachable ();
 }
 
+/* Return the precision of the FP mode with size SIZE.  */
+
 int
 fp_size_to_prec (int size)
 {
@@ -878,3 +816,19 @@ fp_size_to_prec (int size)
 
   gcc_unreachable ();
 }
+
+static GTY(()) tree gnat_eh_personality_decl;
+
+static tree
+gnat_eh_personality (void)
+{
+  if (!gnat_eh_personality_decl)
+    gnat_eh_personality_decl
+      = build_personality_function (USING_SJLJ_EXCEPTIONS
+                                   ? "__gnat_eh_personality_sj"
+                                   : "__gnat_eh_personality");
+
+  return gnat_eh_personality_decl;
+}
+
+#include "gt-ada-misc.h"