/* com.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Contributed by James Craig Burley.
#include "proj.h"
#include "flags.h"
+#include "real.h"
#include "rtl.h"
#include "toplev.h"
#include "tree.h"
#include "convert.h"
#include "ggc.h"
#include "diagnostic.h"
+#include "intl.h"
#include "langhooks.h"
#include "langhooks-def.h"
+#include "debug.h"
/* VMS-specific definitions */
#ifdef VMS
inventions should be renamed to be canonical. Note that only
the ones currently required to be global are so. */
-static tree ffecom_tree_fun_type_void;
+static GTY(()) tree ffecom_tree_fun_type_void;
tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
just use build_function_type and build_pointer_type on the
appropriate _tree_type array element. */
-static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
-static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
-static tree ffecom_tree_subr_type;
-static tree ffecom_tree_ptr_to_subr_type;
-static tree ffecom_tree_blockdata_type;
+static GTY(()) tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
+static GTY(()) tree
+ ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
+static GTY(()) tree ffecom_tree_subr_type;
+static GTY(()) tree ffecom_tree_ptr_to_subr_type;
+static GTY(()) tree ffecom_tree_blockdata_type;
-static tree ffecom_tree_xargc_;
+static GTY(()) tree ffecom_tree_xargc_;
ffecomSymbol ffecom_symbol_null_
=
int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
tree ffecom_f2c_integer_type_node;
-tree ffecom_f2c_ptr_to_integer_type_node;
+static GTY(()) tree ffecom_f2c_ptr_to_integer_type_node;
tree ffecom_f2c_address_type_node;
tree ffecom_f2c_real_type_node;
-tree ffecom_f2c_ptr_to_real_type_node;
+static GTY(()) tree ffecom_f2c_ptr_to_real_type_node;
tree ffecom_f2c_doublereal_type_node;
tree ffecom_f2c_complex_type_node;
tree ffecom_f2c_doublecomplex_type_node;
/* Static functions (internal). */
+static tree ffe_type_for_mode PARAMS ((enum machine_mode, int));
+static tree ffe_type_for_size PARAMS ((unsigned int, int));
+static tree ffe_unsigned_type PARAMS ((tree));
+static tree ffe_signed_type PARAMS ((tree));
+static tree ffe_signed_or_unsigned_type PARAMS ((int, tree));
+static bool ffe_mark_addressable PARAMS ((tree));
+static tree ffe_truthvalue_conversion PARAMS ((tree));
+static void ffecom_init_decl_processing PARAMS ((void));
static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
static tree ffecom_widest_expr_type_ (ffebld list);
static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
static int duplicate_decls (tree newdecl, tree olddecl);
static void finish_decl (tree decl, tree init, bool is_top_level);
static void finish_function (int nested);
-static const char *lang_printable_name (tree decl, int v);
+static const char *ffe_printable_name (tree decl, int v);
+static void ffe_print_error_function (diagnostic_context *, const char *);
static tree lookup_name_current_level (tree name);
-static struct binding_level *make_binding_level (void);
+static struct f_binding_level *make_binding_level (void);
static void pop_f_function_context (void);
static void push_f_function_context (void);
static void push_parm_decl (tree parm);
static ffesymbol ffecom_nested_entry_ = NULL;
static ffeinfoKind ffecom_primary_entry_kind_;
static bool ffecom_primary_entry_is_proc_;
-static tree ffecom_outer_function_decl_;
-static tree ffecom_previous_function_decl_;
-static tree ffecom_which_entrypoint_decl_;
-static tree ffecom_float_zero_ = NULL_TREE;
-static tree ffecom_float_half_ = NULL_TREE;
-static tree ffecom_double_zero_ = NULL_TREE;
-static tree ffecom_double_half_ = NULL_TREE;
-static tree ffecom_func_result_;/* For functions. */
-static tree ffecom_func_length_;/* For CHARACTER fns. */
+static GTY(()) tree ffecom_outer_function_decl_;
+static GTY(()) tree ffecom_previous_function_decl_;
+static GTY(()) tree ffecom_which_entrypoint_decl_;
+static GTY(()) tree ffecom_float_zero_;
+static GTY(()) tree ffecom_float_half_;
+static GTY(()) tree ffecom_double_zero_;
+static GTY(()) tree ffecom_double_half_;
+static GTY(()) tree ffecom_func_result_;/* For functions. */
+static GTY(()) tree ffecom_func_length_;/* For CHARACTER fns. */
static ffebld ffecom_list_blockdata_;
static ffebld ffecom_list_common_;
static ffebld ffecom_master_arglist_;
static int ffecom_num_fns_ = 0;
static int ffecom_num_entrypoints_ = 0;
static bool ffecom_is_altreturning_ = FALSE;
-static tree ffecom_multi_type_node_;
-static tree ffecom_multi_retval_;
-static tree
+static GTY(()) tree ffecom_multi_type_node_;
+static GTY(()) tree ffecom_multi_retval_;
+static GTY(()) tree
ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
static bool ffecom_doing_entry_ = FALSE;
/* Holds pointer-to-function expressions. */
-static tree ffecom_gfrt_[FFECOM_gfrt]
-=
-{
-#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
-#include "com-rt.def"
-#undef DEFGFRT
-};
+static GTY(()) tree ffecom_gfrt_[FFECOM_gfrt];
/* Holds the external names of the functions. */
/* Whether the function returns. */
-static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
+static const bool ffecom_gfrt_volatile_[FFECOM_gfrt]
=
{
#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
/* Whether the function returns type complex. */
-static bool ffecom_gfrt_complex_[FFECOM_gfrt]
+static const bool ffecom_gfrt_complex_[FFECOM_gfrt]
=
{
#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
/* Whether the function is const
(i.e., has no side effects and only depends on its arguments). */
-static bool ffecom_gfrt_const_[FFECOM_gfrt]
+static const bool ffecom_gfrt_const_[FFECOM_gfrt]
=
{
#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
/* Type code for the function return value. */
-static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
+static const ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
=
{
#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
/* Note that the information in the `names' component of the global contour
is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
-struct binding_level
+struct f_binding_level GTY(())
{
/* A chain of _DECL nodes for all variables, constants, functions,
and typedef types. These are in the reverse of the order supplied.
tree this_block;
/* The binding level which this one is contained in (inherits from). */
- struct binding_level *level_chain;
+ struct f_binding_level *level_chain;
/* 0: no ffecom_prepare_* functions called at this level yet;
1: ffecom_prepare* functions called, except not ffecom_prepare_end;
int prep_state;
};
-#define NULL_BINDING_LEVEL (struct binding_level *) NULL
+#define NULL_BINDING_LEVEL (struct f_binding_level *) NULL
/* The binding level currently in effect. */
-static struct binding_level *current_binding_level;
+static GTY(()) struct f_binding_level *current_binding_level;
/* A chain of binding_level structures awaiting reuse. */
-static struct binding_level *free_binding_level;
+static GTY((deletable (""))) struct f_binding_level *free_binding_level;
/* The outermost binding level, for names of file scope.
This is created when the compiler is started and exists
through the entire run. */
-static struct binding_level *global_binding_level;
+static struct f_binding_level *global_binding_level;
/* Binding level structures are initialized by copying this one. */
-static struct binding_level clear_binding_level
+static const struct f_binding_level clear_binding_level
=
{NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
/* Language-dependent contents of an identifier. */
-struct lang_identifier
- {
- struct tree_identifier ignore;
- tree global_value, local_value, label_value;
- bool invented;
- };
+struct lang_identifier GTY(())
+{
+ struct tree_identifier common;
+ tree global_value;
+ tree local_value;
+ tree label_value;
+ bool invented;
+};
/* Macros for access to language-specific slots in an identifier. */
/* Each of these slots contains a DECL node or null. */
#define IDENTIFIER_INVENTED(NODE) \
(((struct lang_identifier *)(NODE))->invented)
+/* The resulting tree type. */
+union lang_tree_node
+ GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE")))
+{
+ union tree_node GTY ((tag ("0"),
+ desc ("tree_node_structure (&%h)")))
+ generic;
+ struct lang_identifier GTY ((tag ("1"))) identifier;
+};
+
+/* Fortran doesn't use either of these. */
+struct lang_decl GTY(())
+{
+};
+struct lang_type GTY(())
+{
+};
+
/* In identifiers, C uses the following fields in a special way:
TREE_PUBLIC to record that there was a previous local extern decl.
TREE_USED to record that such a decl was used.
that have names. Here so we can clear out their names' definitions
at the end of the function. */
-static tree named_labels;
+static GTY(()) tree named_labels;
/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
-static tree shadowed_labels;
+static GTY(()) tree shadowed_labels;
\f
/* Return the subscript expression, modified to do range-checking.
return item;
if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
- && ! mark_addressable (item))
+ && ! ffe_mark_addressable (item))
return error_mark_node;
}
tree item;
bool ptr = FALSE;
tree wanted = NULL_TREE;
- static char zed[] = "0";
+ static const char zed[] = "0";
if (c == NULL)
c = &zed[0];
if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
return type;
+ /* An array is too large if size is negative or the type_size overflows
+ or its "upper half" is larger than 3 (which would make the signed
+ byte size and offset computations overflow). */
+
if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
- || (!dummy && TREE_OVERFLOW (TYPE_SIZE (type))))
+ || (!dummy && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) > 3
+ || TREE_OVERFLOW (TYPE_SIZE (type)))))
{
ffebad_start (FFEBAD_ARRAY_LARGE);
ffebad_string (ffesymbol_text (s));
if (ffesymbol_hook (s).assign_tree == NULL_TREE)
{
+ /* xgettext:no-c-format */
ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
FFEBAD_severityWARNING);
ffebad_string (ffesymbol_text (s));
item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
return convert (tree_type, item);
+ case FFEBLD_opPERCENT_VAL:
+ item = ffecom_arg_expr (ffebld_left (expr), &list);
+ return convert (tree_type, item);
+
case FFEBLD_opITEM:
case FFEBLD_opSTAR:
case FFEBLD_opBOUNDS:
basetypeof_l_is_int
= build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
- se = expand_start_stmt_expr ();
+ se = expand_start_stmt_expr (/*has_scope=*/1);
ffecom_start_compstmt ();
/* A somewhat evil way to prevent the garbage collector
from collecting 'tree' structures. */
#define NUM_TRACKED_CHUNK 63
-static struct tree_ggc_tracker
+struct tree_ggc_tracker GTY(())
{
struct tree_ggc_tracker *next;
tree trees[NUM_TRACKED_CHUNK];
-} *tracker_head = NULL;
-
-static void
-mark_tracker_head (void *arg)
-{
- struct tree_ggc_tracker *head;
- int i;
-
- for (head = * (struct tree_ggc_tracker **) arg;
- head != NULL;
- head = head->next)
- {
- ggc_mark (head);
- for (i = 0; i < NUM_TRACKED_CHUNK; i++)
- ggc_mark_tree (head->trees[i]);
- }
-}
+};
+static GTY(()) struct tree_ggc_tracker *tracker_head;
void
ffecom_save_tree_forever (tree t)
/* Build Namelist type. */
+static GTY(()) tree ffecom_type_namelist_var;
static tree
ffecom_type_namelist_ ()
{
- static tree type = NULL_TREE;
-
- if (type == NULL_TREE)
+ if (ffecom_type_namelist_var == NULL_TREE)
{
- static tree namefield, varsfield, nvarsfield;
- tree vardesctype;
+ tree namefield, varsfield, nvarsfield, vardesctype, type;
vardesctype = ffecom_type_vardesc_ ();
TYPE_FIELDS (type) = namefield;
layout_type (type);
- ggc_add_tree_root (&type, 1);
+ ffecom_type_namelist_var = type;
}
- return type;
+ return ffecom_type_namelist_var;
}
/* Build Vardesc type. */
+static GTY(()) tree ffecom_type_vardesc_var;
static tree
ffecom_type_vardesc_ ()
{
- static tree type = NULL_TREE;
- static tree namefield, addrfield, dimsfield, typefield;
-
- if (type == NULL_TREE)
+ if (ffecom_type_vardesc_var == NULL_TREE)
{
+ tree namefield, addrfield, dimsfield, typefield, type;
type = make_node (RECORD_TYPE);
namefield = ffecom_decl_field (type, NULL_TREE, "name",
TYPE_FIELDS (type) = namefield;
layout_type (type);
- ggc_add_tree_root (&type, 1);
+ ffecom_type_vardesc_var = type;
}
- return type;
+ return ffecom_type_vardesc_var;
}
static tree
if (code == ADDR_EXPR)
{
- if (!mark_addressable (node))
+ if (!ffe_mark_addressable (node))
assert ("can't mark_addressable this node!" == NULL);
}
if (TREE_SIDE_EFFECTS (node))
TREE_SIDE_EFFECTS (item) = 1;
- if ((code == ADDR_EXPR) && staticp (node))
+ if (code == ADDR_EXPR && staticp (node))
TREE_CONSTANT (item) = 1;
+ else if (code == INDIRECT_REF)
+ TREE_READONLY (item) = TYPE_READONLY (type);
return fold (item);
}
= build_function_type (void_type_node, NULL_TREE);
builtin_function ("__builtin_sqrtf", float_ftype_float,
- BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtf");
- builtin_function ("__builtin_fsqrt", double_ftype_double,
- BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrt");
+ BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf");
+ builtin_function ("__builtin_sqrt", double_ftype_double,
+ BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt");
builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
- BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtl");
+ BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl");
builtin_function ("__builtin_sinf", float_ftype_float,
- BUILT_IN_SIN, BUILT_IN_NORMAL, "sinf");
+ BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf");
builtin_function ("__builtin_sin", double_ftype_double,
BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
- BUILT_IN_SIN, BUILT_IN_NORMAL, "sinl");
+ BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl");
builtin_function ("__builtin_cosf", float_ftype_float,
- BUILT_IN_COS, BUILT_IN_NORMAL, "cosf");
+ BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf");
builtin_function ("__builtin_cos", double_ftype_double,
BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
- BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
+ BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl");
pedantic_lvalues = FALSE;
{
REAL_VALUE_TYPE point_5;
-#ifdef REAL_ARITHMETIC
REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
-#else
- point_5 = .5;
-#endif
ffecom_float_half_ = build_real (float_type_node, point_5);
ffecom_double_half_ = build_real (double_type_node, point_5);
}
(int) FLOAT_TYPE_SIZE);
warning ("and pointers are %d bits wide, but g77 doesn't yet work",
(int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
- warning ("properly unless they all are 32 bits wide.");
- warning ("Please keep this in mind before you report bugs. g77 should");
- warning ("support non-32-bit machines better as of version 0.6.");
+ warning ("properly unless they all are 32 bits wide");
+ warning ("Please keep this in mind before you report bugs.");
}
#endif
tree
ffecom_truth_value (tree expr)
{
- return truthvalue_conversion (expr);
+ return ffe_truthvalue_conversion (expr);
}
/* Return the inversion of a truth value (the inversion of what
nested function and all). */
static const char *
-lang_printable_name (tree decl, int v)
+ffe_printable_name (tree decl, int v)
{
/* Just to keep GCC quiet about the unused variable.
In theory, differing values of V should produce different
an error. */
static void
-lang_print_error_function (diagnostic_context *context __attribute__((unused)),
- const char *file)
+ffe_print_error_function (diagnostic_context *context __attribute__((unused)),
+ const char *file)
{
static ffeglobal last_g = NULL;
static ffesymbol last_s = NULL;
if (ffecom_nested_entry_ == NULL)
{
s = ffecom_primary_entry_;
- switch (ffesymbol_kind (s))
- {
- case FFEINFO_kindFUNCTION:
- kind = "function";
- break;
-
- case FFEINFO_kindSUBROUTINE:
- kind = "subroutine";
- break;
-
- case FFEINFO_kindPROGRAM:
- kind = "program";
- break;
-
- case FFEINFO_kindBLOCKDATA:
- kind = "block-data";
- break;
-
- default:
- kind = ffeinfo_kind_message (ffesymbol_kind (s));
- break;
- }
+ kind = _(ffeinfo_kind_message (ffesymbol_kind (s)));
}
else
{
s = ffecom_nested_entry_;
- kind = "statement function";
+ kind = _("In statement function");
}
}
fprintf (stderr, "%s: ", file);
if (s == NULL)
- fprintf (stderr, "Outside of any program unit:\n");
+ fprintf (stderr, _("Outside of any program unit:\n"));
else
{
const char *name = ffesymbol_text (s);
- fprintf (stderr, "In %s `%s':\n", kind, name);
+ fprintf (stderr, "%s `%s':\n", kind, name);
}
last_g = g;
return t;
}
-/* Create a new `struct binding_level'. */
+/* Create a new `struct f_binding_level'. */
-static struct binding_level *
+static struct f_binding_level *
make_binding_level ()
{
/* NOSTRICT */
- return (struct binding_level *) xmalloc (sizeof (struct binding_level));
+ return ggc_alloc (sizeof (struct f_binding_level));
}
/* Save and restore the variables in this file and elsewhere
struct f_function *next;
tree named_labels;
tree shadowed_labels;
- struct binding_level *binding_level;
+ struct f_binding_level *binding_level;
};
struct f_function *f_function_chain;
tree x;
{
register tree t;
- register struct binding_level *b = current_binding_level;
+ register struct f_binding_level *b = current_binding_level;
register tree f = current_function_decl;
current_binding_level = global_binding_level;
Returns 1 on success. If the DECLARATOR is not suitable for a function
(it defines a datum instead), we return 0, which tells
- yyparse to report a parse error.
+ ffe_parse_file to report a parse error.
NESTED is nonzero for a function nested within another function. */
return error_mark_node;
}
-/* integrate_decl_tree calls this function, but since we don't use the
- DECL_LANG_SPECIFIC field, this is a no-op. */
-
-void
-copy_lang_decl (node)
- tree node UNUSED;
-{
-}
-
/* Return the list of declarations of the current level.
Note that this list is in reverse order unless/until
you nreverse it; and when you do nreverse it, you must
return current_binding_level == global_binding_level;
}
-/* Print an error message for invalid use of an incomplete type.
- VALUE is the expression that was used (or 0 if that isn't known)
- and TYPE is the type that was invalid. */
-
-void
-incomplete_type_error (value, type)
- tree value UNUSED;
- tree type;
-{
- if (TREE_CODE (type) == ERROR_MARK)
- return;
-
- assert ("incomplete type?!?" == NULL);
-}
-
-/* Mark ARG for GC. */
static void
-mark_binding_level (void *arg)
-{
- struct binding_level *level = *(struct binding_level **) arg;
-
- while (level)
- {
- ggc_mark_tree (level->names);
- ggc_mark_tree (level->blocks);
- ggc_mark_tree (level->this_block);
- level = level->level_chain;
- }
-}
-
-void
-init_decl_processing ()
+ffecom_init_decl_processing ()
{
- static tree *const tree_roots[] = {
- ¤t_function_decl,
- &string_type_node,
- &ffecom_tree_fun_type_void,
- &ffecom_integer_zero_node,
- &ffecom_integer_one_node,
- &ffecom_tree_subr_type,
- &ffecom_tree_ptr_to_subr_type,
- &ffecom_tree_blockdata_type,
- &ffecom_tree_xargc_,
- &ffecom_f2c_integer_type_node,
- &ffecom_f2c_ptr_to_integer_type_node,
- &ffecom_f2c_address_type_node,
- &ffecom_f2c_real_type_node,
- &ffecom_f2c_ptr_to_real_type_node,
- &ffecom_f2c_doublereal_type_node,
- &ffecom_f2c_complex_type_node,
- &ffecom_f2c_doublecomplex_type_node,
- &ffecom_f2c_longint_type_node,
- &ffecom_f2c_logical_type_node,
- &ffecom_f2c_flag_type_node,
- &ffecom_f2c_ftnlen_type_node,
- &ffecom_f2c_ftnlen_zero_node,
- &ffecom_f2c_ftnlen_one_node,
- &ffecom_f2c_ftnlen_two_node,
- &ffecom_f2c_ptr_to_ftnlen_type_node,
- &ffecom_f2c_ftnint_type_node,
- &ffecom_f2c_ptr_to_ftnint_type_node,
- &ffecom_outer_function_decl_,
- &ffecom_previous_function_decl_,
- &ffecom_which_entrypoint_decl_,
- &ffecom_float_zero_,
- &ffecom_float_half_,
- &ffecom_double_zero_,
- &ffecom_double_half_,
- &ffecom_func_result_,
- &ffecom_func_length_,
- &ffecom_multi_type_node_,
- &ffecom_multi_retval_,
- &named_labels,
- &shadowed_labels
- };
- size_t i;
-
malloc_init ();
- /* Record our roots. */
- for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
- ggc_add_tree_root (tree_roots[i], 1);
- ggc_add_tree_root (&ffecom_tree_type[0][0],
- FFEINFO_basictype*FFEINFO_kindtype);
- ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
- FFEINFO_basictype*FFEINFO_kindtype);
- ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
- FFEINFO_basictype*FFEINFO_kindtype);
- ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
- ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level,
- mark_binding_level);
- ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
- mark_binding_level);
- ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
-
ffe_init_0 ();
}
-const char *
-init_parse (filename)
- const char *filename;
-{
- /* Open input file. */
- if (filename == 0 || !strcmp (filename, "-"))
- {
- finput = stdin;
- filename = "stdin";
- }
- else
- finput = fopen (filename, "r");
- if (finput == 0)
- fatal_io_error ("can't open %s", filename);
-
-#ifdef IO_BUFFER_SIZE
- setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
-#endif
-
- decl_printable_name = lang_printable_name;
- print_error_function = lang_print_error_function;
-
- return filename;
-}
-
-void
-finish_parse ()
-{
- fclose (finput);
-}
-
/* Delete the node BLOCK from the current binding level.
This is used for the block inside a stmt expr ({...})
so that the block can be reinserted where appropriate. */
}
/* Each front end provides its own. */
-static void ffe_init PARAMS ((void));
+static const char *ffe_init PARAMS ((const char *));
static void ffe_finish PARAMS ((void));
static void ffe_init_options PARAMS ((void));
+static void ffe_print_identifier PARAMS ((FILE *, tree, int));
+
+struct language_function GTY(())
+{
+ int unused;
+};
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU F77"
#define LANG_HOOKS_INIT_OPTIONS ffe_init_options
#undef LANG_HOOKS_DECODE_OPTION
#define LANG_HOOKS_DECODE_OPTION ffe_decode_option
+#undef LANG_HOOKS_PARSE_FILE
+#define LANG_HOOKS_PARSE_FILE ffe_parse_file
+#undef LANG_HOOKS_MARK_ADDRESSABLE
+#define LANG_HOOKS_MARK_ADDRESSABLE ffe_mark_addressable
+#undef LANG_HOOKS_PRINT_IDENTIFIER
+#define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
+#undef LANG_HOOKS_DECL_PRINTABLE_NAME
+#define LANG_HOOKS_DECL_PRINTABLE_NAME ffe_printable_name
+#undef LANG_HOOKS_PRINT_ERROR_FUNCTION
+#define LANG_HOOKS_PRINT_ERROR_FUNCTION ffe_print_error_function
+#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
+#define LANG_HOOKS_TRUTHVALUE_CONVERSION ffe_truthvalue_conversion
+
+#undef LANG_HOOKS_TYPE_FOR_MODE
+#define LANG_HOOKS_TYPE_FOR_MODE ffe_type_for_mode
+#undef LANG_HOOKS_TYPE_FOR_SIZE
+#define LANG_HOOKS_TYPE_FOR_SIZE ffe_type_for_size
+#undef LANG_HOOKS_SIGNED_TYPE
+#define LANG_HOOKS_SIGNED_TYPE ffe_signed_type
+#undef LANG_HOOKS_UNSIGNED_TYPE
+#define LANG_HOOKS_UNSIGNED_TYPE ffe_unsigned_type
+#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
+#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE ffe_signed_or_unsigned_type
/* We do not wish to use alias-set based aliasing at all. Used in the
extreme (every object with its own set, with equivalences recorded) it
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
-/* used by print-tree.c */
+/* Table indexed by tree code giving a string containing a character
+ classifying the tree code. Possibilities are
+ t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */
-void
-lang_print_xnode (file, node, indent)
- FILE *file UNUSED;
- tree node UNUSED;
- int indent UNUSED;
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
+
+const char tree_code_type[] = {
+#include "tree.def"
+};
+#undef DEFTREECODE
+
+/* Table indexed by tree code giving number of expression
+ operands beyond the fixed part of the node structure.
+ Not used for types or decls. */
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
+
+const unsigned char tree_code_length[] = {
+#include "tree.def"
+};
+#undef DEFTREECODE
+
+/* Names of tree components.
+ Used for printing out the tree and error messages. */
+#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
+
+const char *const tree_code_name[] = {
+#include "tree.def"
+};
+#undef DEFTREECODE
+
+static const char *
+ffe_init (filename)
+ const char *filename;
{
+ /* Open input file. */
+ if (filename == 0 || !strcmp (filename, "-"))
+ {
+ finput = stdin;
+ filename = "stdin";
+ }
+ else
+ finput = fopen (filename, "r");
+ if (finput == 0)
+ fatal_io_error ("can't open %s", filename);
+
+#ifdef IO_BUFFER_SIZE
+ setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
+#endif
+
+ ffecom_init_decl_processing ();
+
+ /* If the file is output from cpp, it should contain a first line
+ `# 1 "real-filename"', and the current design of gcc (toplev.c
+ in particular and the way it sets up information relied on by
+ INCLUDE) requires that we read this now, and store the
+ "real-filename" info in master_input_filename. Ask the lexer
+ to try doing this. */
+ ffelex_hash_kludge (finput);
+
+ /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
+ return the new file name. */
+ if (main_input_filename)
+ filename = main_input_filename;
+
+ return filename;
}
static void
if (ffe_is_ffedebug ())
malloc_pool_display (malloc_pool_image ());
+
+ fclose (finput);
}
static void
flag_complex_divide_method = 1;
}
-static void
-ffe_init ()
-{
- /* If the file is output from cpp, it should contain a first line
- `# 1 "real-filename"', and the current design of gcc (toplev.c
- in particular and the way it sets up information relied on by
- INCLUDE) requires that we read this now, and store the
- "real-filename" info in master_input_filename. Ask the lexer
- to try doing this. */
- ffelex_hash_kludge (finput);
-}
-
-int
-mark_addressable (exp)
+static bool
+ffe_mark_addressable (exp)
tree exp;
{
register tree x = exp;
case CONSTRUCTOR:
TREE_ADDRESSABLE (x) = 1;
- return 1;
+ return true;
case VAR_DECL:
case CONST_DECL:
if (TREE_PUBLIC (x))
{
assert ("address of global register var requested" == NULL);
- return 0;
+ return false;
}
assert ("address of register variable requested" == NULL);
}
if (TREE_PUBLIC (x))
{
assert ("address of global register var requested" == NULL);
- return 0;
+ return false;
}
assert ("address of register var requested" == NULL);
}
#endif
default:
- return 1;
+ return true;
}
}
-/* If DECL has a cleanup, build and return that cleanup here.
- This is a callback called by expand_expr. */
-
-tree
-maybe_build_cleanup (decl)
- tree decl UNUSED;
-{
- /* There are no cleanups in Fortran. */
- return NULL_TREE;
-}
-
/* Exit a binding level.
Pop the level off, and restore the state of the identifier-decl mappings
that were in effect when this level was entered.
/* Pop the current level, and free the structure for reuse. */
{
- register struct binding_level *level = current_binding_level;
+ register struct f_binding_level *level = current_binding_level;
current_binding_level = current_binding_level->level_chain;
level->level_chain = free_binding_level;
return block;
}
-void
-print_lang_decl (file, node, indent)
- FILE *file UNUSED;
- tree node UNUSED;
- int indent UNUSED;
-{
-}
-
-void
-print_lang_identifier (file, node, indent)
+static void
+ffe_print_identifier (file, node, indent)
FILE *file;
tree node;
int indent;
print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
}
-void
-print_lang_statistics ()
-{
-}
-
-void
-print_lang_type (file, node, indent)
- FILE *file UNUSED;
- tree node UNUSED;
- int indent UNUSED;
-{
-}
-
/* Record a decl-node X as belonging to the current lexical scope.
Check for errors (such as an incompatible declaration for the same
name already seen in the same scope).
{
register tree t;
register tree name = DECL_NAME (x);
- register struct binding_level *b = current_binding_level;
+ register struct f_binding_level *b = current_binding_level;
if ((TREE_CODE (x) == FUNCTION_DECL)
&& (DECL_INITIAL (x) == 0)
pushlevel (tag_transparent)
int tag_transparent;
{
- register struct binding_level *newlevel = NULL_BINDING_LEVEL;
+ register struct f_binding_level *newlevel = NULL_BINDING_LEVEL;
assert (! tag_transparent);
BLOCK_SUBBLOCKS (block));
}
-/* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
-
-/* Can't 'yydebug' a front end not generated by yacc/bison! */
-
-void
-set_yydebug (value)
- int value;
-{
- if (value)
- fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
-}
-
-tree
-signed_or_unsigned_type (unsignedp, type)
+static tree
+ffe_signed_or_unsigned_type (unsignedp, type)
int unsignedp;
tree type;
{
return (unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node);
- type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
+ type2 = ffe_type_for_size (TYPE_PRECISION (type), unsignedp);
if (type2 == NULL_TREE)
return type;
return type2;
}
-tree
-signed_type (type)
+static tree
+ffe_signed_type (type)
tree type;
{
tree type1 = TYPE_MAIN_VARIANT (type);
return intQI_type_node;
#endif
- type2 = type_for_size (TYPE_PRECISION (type1), 0);
+ type2 = ffe_type_for_size (TYPE_PRECISION (type1), 0);
if (type2 != NULL_TREE)
return type2;
The resulting type should always be `integer_type_node'. */
-tree
-truthvalue_conversion (expr)
+static tree
+ffe_truthvalue_conversion (expr)
tree expr;
{
if (TREE_CODE (expr) == ERROR_MARK)
return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
integer_type_node,
- truthvalue_conversion (TREE_OPERAND (expr, 0)),
- truthvalue_conversion (TREE_OPERAND (expr, 1)));
+ ffe_truthvalue_conversion (TREE_OPERAND (expr, 0)),
+ ffe_truthvalue_conversion (TREE_OPERAND (expr, 1)));
case NEGATE_EXPR:
case ABS_EXPR:
case FLOAT_EXPR:
case FFS_EXPR:
/* These don't change whether an object is non-zero or zero. */
- return truthvalue_conversion (TREE_OPERAND (expr, 0));
+ return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
case LROTATE_EXPR:
case RROTATE_EXPR:
we can't ignore them if their second arg has side-effects. */
if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
- truthvalue_conversion (TREE_OPERAND (expr, 0)));
+ ffe_truthvalue_conversion (TREE_OPERAND (expr, 0)));
else
- return truthvalue_conversion (TREE_OPERAND (expr, 0));
+ return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
case COND_EXPR:
/* Distribute the conversion into the arms of a COND_EXPR. */
return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
- truthvalue_conversion (TREE_OPERAND (expr, 1)),
- truthvalue_conversion (TREE_OPERAND (expr, 2))));
+ ffe_truthvalue_conversion (TREE_OPERAND (expr, 1)),
+ ffe_truthvalue_conversion (TREE_OPERAND (expr, 2))));
case CONVERT_EXPR:
/* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
/* If this is widening the argument, we can ignore it. */
if (TYPE_PRECISION (TREE_TYPE (expr))
>= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
- return truthvalue_conversion (TREE_OPERAND (expr, 0));
+ return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
break;
case MINUS_EXPR:
((TREE_SIDE_EFFECTS (expr)
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
integer_type_node,
- truthvalue_conversion (ffecom_1 (REALPART_EXPR,
- TREE_TYPE (TREE_TYPE (expr)),
- expr)),
- truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
- TREE_TYPE (TREE_TYPE (expr)),
- expr))));
+ ffe_truthvalue_conversion (ffecom_1 (REALPART_EXPR,
+ TREE_TYPE (TREE_TYPE (expr)),
+ expr)),
+ ffe_truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
+ TREE_TYPE (TREE_TYPE (expr)),
+ expr))));
return ffecom_2 (NE_EXPR, integer_type_node,
expr,
convert (TREE_TYPE (expr), integer_zero_node));
}
-tree
-type_for_mode (mode, unsignedp)
+static tree
+ffe_type_for_mode (mode, unsignedp)
enum machine_mode mode;
int unsignedp;
{
return 0;
}
-tree
-type_for_size (bits, unsignedp)
+static tree
+ffe_type_for_size (bits, unsignedp)
unsigned bits;
int unsignedp;
{
return 0;
}
-tree
-unsigned_type (type)
+static tree
+ffe_unsigned_type (type)
tree type;
{
tree type1 = TYPE_MAIN_VARIANT (type);
return unsigned_intQI_type_node;
#endif
- type2 = type_for_size (TYPE_PRECISION (type1), 1);
+ type2 = ffe_type_for_size (TYPE_PRECISION (type1), 1);
if (type2 != NULL_TREE)
return type2;
return type;
}
-
-void
-lang_mark_tree (t)
- union tree_node *t ATTRIBUTE_UNUSED;
-{
- if (TREE_CODE (t) == IDENTIFIER_NODE)
- {
- struct lang_identifier *i = (struct lang_identifier *) t;
- ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
- ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
- ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
- }
- else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
- ggc_mark (TYPE_LANG_SPECIFIC (t));
-}
\f
/* From gcc/cccp.c, the code to handle -I. */
else
str2 = "";
+ /* xgettext:no-c-format */
ffebad_start_msg ("%A from %B at %0%C", sev);
ffebad_here (0, ip->line, ip->column);
ffebad_string (str1);
dirtmp->fname = spec;
dirtmp->got_name_map = 0;
if (spec[0] == 0)
- error ("Directory name must immediately follow -I");
+ error ("directory name must immediately follow -I");
else
append_include_chain (dirtmp, dirtmp);
}
if (f == NULL && errno == EACCES)
{
print_containing_files (FFEBAD_severityWARNING);
+ /* xgettext:no-c-format */
ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
FFEBAD_severityWARNING);
ffebad_string (fname);
if (indepth >= (INPUT_STACK_MAX - 1))
{
print_containing_files (FFEBAD_severityFATAL);
+ /* xgettext:no-c-format */
ffebad_start_msg ("At %0, INCLUDE nesting too deep",
FFEBAD_severityFATAL);
ffebad_string (fname);
// (No such symbols should be defined in a strict ANSI C compiler.
We can avoid trouble with f2c-translated code by using
- gcc -ansi [-traditional].) //
+ gcc -ansi.) //
-------- (end output file from f2c)
*/
+
+#include "gt-f-com.h"
+#include "gtype-f.h"