* *
* C Implementation File *
* *
- * Copyright (C) 1992-2008, 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);
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. */
#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
#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 *);
/* 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;
break;
case OPT_Wall:
- set_Wunused (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_unused = value;
+ warn_uninitialized = value;
break;
/* These are used in the GCC Makefile. */
gnat_argc++;
break;
- case OPT_gdwarf_:
- gnat_dwarf_extensions ++;
+ case OPT_gdwarfplus:
+ gnat_dwarf_extensions = 1;
break;
default:
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;
+ /* No psABI change warnings for Ada. */
+ warn_psabi = 0;
+
/* Force eliminate_unused_debug_types to 0 unless an explicit positive
-f has been passed. This forces the default to 0 for Ada, which might
differ from the common default. */
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++)
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
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
#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)
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;
}
}
+/* 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:
- 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);
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
}
}
-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)
__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));
- ada_name = Name_Buffer;
+ Set_Identifier_Casing (ada_name, DECL_SOURCE_FILE (decl));
+ return ggc_strdup (Name_Buffer);
}
- return (const char *) 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). */
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
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. */
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));
}
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;
}
}
+/* Return the size of the FP mode with precision PREC. */
+
int
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)
{
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"