aboutsummaryrefslogtreecommitdiff
path: root/gcc/f/ste.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/f/ste.c')
-rw-r--r--gcc/f/ste.c5414
1 files changed, 5414 insertions, 0 deletions
diff --git a/gcc/f/ste.c b/gcc/f/ste.c
new file mode 100644
index 00000000000..a5e9757cca3
--- /dev/null
+++ b/gcc/f/ste.c
@@ -0,0 +1,5414 @@
+/* ste.c -- Implementation File (module.c template V1.0)
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Contributed by James Craig Burley (burley@gnu.ai.mit.edu).
+
+This file is part of GNU Fortran.
+
+GNU Fortran is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Fortran is distributed in the hope that it will be useful,
+but WITHOUT 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
+along with GNU Fortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+ Related Modules:
+ ste.c
+
+ Description:
+ Implements the various statements and such like.
+
+ Modifications:
+*/
+
+/* As of 0.5.4, any statement that calls on ffecom to transform an
+ expression might need to be wrapped in ffecom_push_calltemps ()
+ and ffecom_pop_calltemps () as are some other cases. That is
+ the case when the transformation might involve generation of
+ a temporary that must be auto-popped, the specific case being
+ when a COMPLEX operation requiring a call to libf2c being
+ generated, whereby a temp is needed to hold the result since
+ libf2c doesn't return COMPLEX results directly. Cases where it
+ is known that ffecom_expr () won't need to do this, such as
+ the CALL statement (where it's the transformation of the
+ call expr itself that does the wrapping), don't need to bother
+ with this wrapping. Forgetting to do the wrapping currently
+ means a crash at an assertion when the wrapping would be helpful
+ to keep temporaries from being wasted -- see ffecom_push_tempvar. */
+
+/* Include files. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+#include "config.j"
+#include "rtl.j"
+#endif
+
+#include "proj.h"
+#include "ste.h"
+#include "bld.h"
+#include "com.h"
+#include "expr.h"
+#include "lab.h"
+#include "lex.h"
+#include "sta.h"
+#include "stp.h"
+#include "str.h"
+#include "sts.h"
+#include "stt.h"
+#include "stv.h"
+#include "stw.h"
+#include "symbol.h"
+
+/* Externals defined here. */
+
+
+/* Simple definitions and enumerations. */
+
+typedef enum
+ {
+ FFESTE_stateletSIMPLE_, /* Expecting simple/start. */
+ FFESTE_stateletATTRIB_, /* Expecting attrib/item/itemstart. */
+ FFESTE_stateletITEM_, /* Expecting item/itemstart/finish. */
+ FFESTE_stateletITEMVALS_, /* Expecting itemvalue/itemendvals. */
+ FFESTE_
+ } ffesteStatelet_;
+
+/* Internal typedefs. */
+
+
+/* Private include files. */
+
+
+/* Internal structure definitions. */
+
+
+/* Static objects accessed by functions in this module. */
+
+static ffesteStatelet_ ffeste_statelet_ = FFESTE_stateletSIMPLE_;
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static ffelab ffeste_label_formatdef_ = NULL;
+static tree (*ffeste_io_driver_) (ffebld expr); /* do?io. */
+static ffecomGfrt ffeste_io_endgfrt_; /* end function to call. */
+static tree ffeste_io_abort_; /* abort-io label or NULL_TREE. */
+static bool ffeste_io_abort_is_temp_; /* abort-io label is a temp. */
+static tree ffeste_io_end_; /* END= label or NULL_TREE. */
+static tree ffeste_io_err_; /* ERR= label or NULL_TREE. */
+static tree ffeste_io_iostat_; /* IOSTAT= var or NULL_TREE. */
+static bool ffeste_io_iostat_is_temp_; /* IOSTAT= var is a temp. */
+#endif
+
+/* Static functions (internal). */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static void ffeste_begin_iterdo_ (ffestw block, tree *tvar, tree *tincr,
+ tree *xitersvar, ffebld var,
+ ffebld start, ffelexToken start_token,
+ ffebld end, ffelexToken end_token,
+ ffebld incr, ffelexToken incr_token,
+ char *msg);
+static void ffeste_end_iterdo_ (tree tvar, tree tincr, tree itersvar);
+static void ffeste_io_call_ (tree call, bool do_check);
+static tree ffeste_io_dofio_ (ffebld expr);
+static tree ffeste_io_dolio_ (ffebld expr);
+static tree ffeste_io_douio_ (ffebld expr);
+static tree ffeste_io_ialist_ (bool have_err, ffestvUnit unit,
+ ffebld unit_expr, int unit_dflt);
+static tree ffeste_io_cilist_ (bool have_err, ffestvUnit unit,
+ ffebld unit_expr, int unit_dflt,
+ bool have_end, ffestvFormat format,
+ ffestpFile *format_spec, bool rec,
+ ffebld rec_expr);
+static tree ffeste_io_cllist_ (bool have_err, ffebld unit_expr,
+ ffestpFile *stat_spec);
+static tree ffeste_io_icilist_ (bool have_err, ffebld unit_expr,
+ bool have_end, ffestvFormat format,
+ ffestpFile *format_spec);
+static void ffeste_io_impdo_ (ffebld impdo, ffelexToken impdo_token);
+static tree ffeste_io_olist_ (bool have_err, ffebld unit_expr,
+ ffestpFile *file_spec,
+ ffestpFile *stat_spec,
+ ffestpFile *access_spec,
+ ffestpFile *form_spec,
+ ffestpFile *recl_spec,
+ ffestpFile *blank_spec);
+static void ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt);
+#elif FFECOM_targetCURRENT == FFECOM_targetFFE
+static void ffeste_subr_file_ (char *kw, ffestpFile *spec);
+#else
+#error
+#endif
+
+/* Internal macros. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+#define ffeste_emit_line_note_() \
+ emit_line_note (input_filename, lineno)
+#endif
+#define ffeste_check_simple_() \
+ assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_)
+#define ffeste_check_start_() \
+ assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_); \
+ ffeste_statelet_ = FFESTE_stateletATTRIB_
+#define ffeste_check_attrib_() \
+ assert(ffeste_statelet_ == FFESTE_stateletATTRIB_)
+#define ffeste_check_item_() \
+ assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
+ || ffeste_statelet_ == FFESTE_stateletITEM_); \
+ ffeste_statelet_ = FFESTE_stateletITEM_
+#define ffeste_check_item_startvals_() \
+ assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
+ || ffeste_statelet_ == FFESTE_stateletITEM_); \
+ ffeste_statelet_ = FFESTE_stateletITEMVALS_
+#define ffeste_check_item_value_() \
+ assert(ffeste_statelet_ == FFESTE_stateletITEMVALS_)
+#define ffeste_check_item_endvals_() \
+ assert(ffeste_statelet_ == FFESTE_stateletITEMVALS_); \
+ ffeste_statelet_ = FFESTE_stateletITEM_
+#define ffeste_check_finish_() \
+ assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
+ || ffeste_statelet_ == FFESTE_stateletITEM_); \
+ ffeste_statelet_ = FFESTE_stateletSIMPLE_
+
+#define ffeste_f2c_charnolenspec_(Spec,Exp,Init) \
+ do \
+ { \
+ if (Spec->kw_or_val_present) \
+ Exp = ffecom_arg_ptr_to_expr(Spec->u.expr,&ignore); \
+ else \
+ Exp = null_pointer_node; \
+ if (TREE_CONSTANT(Exp)) \
+ { \
+ Init = Exp; \
+ Exp = NULL_TREE; \
+ } \
+ else \
+ { \
+ Init = null_pointer_node; \
+ constantp = FALSE; \
+ } \
+ } while(0)
+
+#define ffeste_f2c_charspec_(Spec,Exp,Init,Lenexp,Leninit) \
+ do \
+ { \
+ if (Spec->kw_or_val_present) \
+ Exp = ffecom_arg_ptr_to_expr(Spec->u.expr,&Lenexp); \
+ else \
+ { \
+ Exp = null_pointer_node; \
+ Lenexp = ffecom_f2c_ftnlen_zero_node; \
+ } \
+ if (TREE_CONSTANT(Exp)) \
+ { \
+ Init = Exp; \
+ Exp = NULL_TREE; \
+ } \
+ else \
+ { \
+ Init = null_pointer_node; \
+ constantp = FALSE; \
+ } \
+ if ((Lenexp != NULL_TREE) && TREE_CONSTANT(Lenexp)) \
+ { \
+ Leninit = Lenexp; \
+ Lenexp = NULL_TREE; \
+ } \
+ else \
+ { \
+ Leninit = ffecom_f2c_ftnlen_zero_node; \
+ constantp = FALSE; \
+ } \
+ } while(0)
+
+#define ffeste_f2c_exp_(Field,Exp) \
+ do \
+ { \
+ if (Exp != NULL_TREE) \
+ { \
+ Exp = ffecom_modify(void_type_node,ffecom_2(COMPONENT_REF, \
+ TREE_TYPE(Field),t,Field),Exp); \
+ expand_expr_stmt(Exp); \
+ } \
+ } while(0)
+
+#define ffeste_f2c_init_(Init) \
+ do \
+ { \
+ TREE_CHAIN(initn) = build_tree_list((field = TREE_CHAIN(field)),Init); \
+ initn = TREE_CHAIN(initn); \
+ } while(0)
+
+#define ffeste_f2c_flagspec_(Flag,Init) \
+ do { Init = convert (ffecom_f2c_flag_type_node, \
+ Flag ? integer_one_node : integer_zero_node); } \
+ while(0)
+
+#define ffeste_f2c_intspec_(Spec,Exp,Init) \
+ do \
+ { \
+ if (Spec->kw_or_val_present) \
+ Exp = ffecom_expr(Spec->u.expr); \
+ else \
+ Exp = ffecom_integer_zero_node; \
+ if (TREE_CONSTANT(Exp)) \
+ { \
+ Init = Exp; \
+ Exp = NULL_TREE; \
+ } \
+ else \
+ { \
+ Init = ffecom_integer_zero_node; \
+ constantp = FALSE; \
+ } \
+ } while(0)
+
+#define ffeste_f2c_ptrtointspec_(Spec,Exp,Init) \
+ do \
+ { \
+ if (Spec->kw_or_val_present) \
+ Exp = ffecom_ptr_to_expr(Spec->u.expr); \
+ else \
+ Exp = null_pointer_node; \
+ if (TREE_CONSTANT(Exp)) \
+ { \
+ Init = Exp; \
+ Exp = NULL_TREE; \
+ } \
+ else \
+ { \
+ Init = null_pointer_node; \
+ constantp = FALSE; \
+ } \
+ } while(0)
+
+
+/* Begin an iterative DO loop. Pass the block to start if applicable.
+
+ NOTE: Does _two_ push_momentary () calls, which the caller must
+ undo (by calling ffeste_end_iterdo_). */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static void
+ffeste_begin_iterdo_ (ffestw block, tree *xtvar, tree *xtincr,
+ tree *xitersvar, ffebld var,
+ ffebld start, ffelexToken start_token,
+ ffebld end, ffelexToken end_token,
+ ffebld incr, ffelexToken incr_token,
+ char *msg)
+{
+ tree tvar;
+ tree expr;
+ tree tstart;
+ tree tend;
+ tree tincr;
+ tree tincr_saved;
+ tree niters;
+
+ push_momentary (); /* Want to save these throughout the loop. */
+
+ tvar = ffecom_expr_rw (var);
+ tincr = ffecom_expr (incr);
+
+ /* Check whether incr is known to be zero, complain and fix. */
+
+ if (integer_zerop (tincr) || real_zerop (tincr))
+ {
+ ffebad_start (FFEBAD_DO_STEP_ZERO);
+ ffebad_here (0, ffelex_token_where_line (incr_token),
+ ffelex_token_where_column (incr_token));
+ ffebad_string (msg);
+ ffebad_finish ();
+ tincr = convert (TREE_TYPE (tvar), integer_one_node);
+ }
+
+ tincr_saved = ffecom_save_tree (tincr);
+
+ push_momentary (); /* Want to discard the rest after the loop. */
+
+ tstart = ffecom_expr (start);
+ tend = ffecom_expr (end);
+
+ { /* For warnings only, nothing else
+ happens here. */
+ tree try;
+
+ if (!ffe_is_onetrip ())
+ {
+ try = ffecom_2 (MINUS_EXPR, TREE_TYPE (tvar),
+ tend,
+ tstart);
+
+ try = ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
+ try,
+ tincr);
+
+ if (TREE_CODE (TREE_TYPE (tvar)) != REAL_TYPE)
+ try = ffecom_2 (TRUNC_DIV_EXPR, integer_type_node, try,
+ tincr);
+ else
+ try = convert (integer_type_node,
+ ffecom_2 (RDIV_EXPR, TREE_TYPE (tvar),
+ try,
+ tincr));
+
+ /* Warn if loop never executed, since we've done the evaluation
+ of the unofficial iteration count already. */
+
+ try = ffecom_truth_value (ffecom_2 (LE_EXPR, integer_type_node,
+ try,
+ convert (TREE_TYPE (tvar),
+ integer_zero_node)));
+
+ if (integer_onep (try))
+ {
+ ffebad_start (FFEBAD_DO_NULL);
+ ffebad_here (0, ffelex_token_where_line (start_token),
+ ffelex_token_where_column (start_token));
+ ffebad_string (msg);
+ ffebad_finish ();
+ }
+ }
+
+ /* Warn if end plus incr would overflow. */
+
+ try = ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
+ tend,
+ tincr);
+
+ if ((TREE_CODE_CLASS (TREE_CODE (try)) == 'c')
+ && TREE_CONSTANT_OVERFLOW (try))
+ {
+ ffebad_start (FFEBAD_DO_END_OVERFLOW);
+ ffebad_here (0, ffelex_token_where_line (end_token),
+ ffelex_token_where_column (end_token));
+ ffebad_string (msg);
+ ffebad_finish ();
+ }
+ }
+
+ /* Do the initial assignment into the DO var. */
+
+ expr = ffecom_modify (void_type_node, tvar, tstart);
+ expand_expr_stmt (expr);
+
+ expr = ffecom_2 (MINUS_EXPR, TREE_TYPE (tvar),
+ tend,
+ TREE_CONSTANT (tstart) ? tstart : tvar);
+
+ if (!ffe_is_onetrip ())
+ {
+ expr = ffecom_2 (PLUS_EXPR, TREE_TYPE (expr),
+ expr,
+ convert (TREE_TYPE (expr), tincr_saved));
+ }
+
+ if (TREE_CODE (TREE_TYPE (tvar)) != REAL_TYPE)
+ expr = ffecom_2 (TRUNC_DIV_EXPR, TREE_TYPE (expr),
+ expr,
+ tincr_saved);
+ else
+ expr = ffecom_2 (RDIV_EXPR, TREE_TYPE (expr),
+ expr,
+ tincr_saved);
+
+#if 1 /* New, F90-approved approach: convert to default INTEGER. */
+ if (TREE_TYPE (tvar) != error_mark_node)
+ expr = convert (ffecom_integer_type_node, expr);
+#else /* Old approach; convert to INTEGER unless that's a narrowing. */
+ if ((TREE_TYPE (tvar) != error_mark_node)
+ && ((TREE_CODE (TREE_TYPE (tvar)) != INTEGER_TYPE)
+ || ((TYPE_SIZE (TREE_TYPE (tvar)) != NULL_TREE)
+ && ((TREE_CODE (TYPE_SIZE (TREE_TYPE (tvar)))
+ != INTEGER_CST)
+ || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tvar)))
+ <= TREE_INT_CST_LOW (TYPE_SIZE (ffecom_integer_type_node)))))))
+ /* Convert unless promoting INTEGER type of any kind downward to
+ default INTEGER; else leave as, say, INTEGER*8 (long long int). */
+ expr = convert (ffecom_integer_type_node, expr);
+#endif
+
+ niters = ffecom_push_tempvar (TREE_TYPE (expr),
+ FFETARGET_charactersizeNONE, -1, FALSE);
+ expr = ffecom_modify (void_type_node, niters, expr);
+ expand_expr_stmt (expr);
+
+ if (block == NULL)
+ expand_start_loop_continue_elsewhere (0);
+ else
+ ffestw_set_do_hook (block,
+ expand_start_loop_continue_elsewhere (1));
+
+ if (!ffe_is_onetrip ())
+ {
+ expr = ffecom_truth_value
+ (ffecom_2 (GE_EXPR, integer_type_node,
+ ffecom_2 (PREDECREMENT_EXPR,
+ TREE_TYPE (niters),
+ niters,
+ convert (TREE_TYPE (niters),
+ ffecom_integer_one_node)),
+ convert (TREE_TYPE (niters),
+ ffecom_integer_zero_node)));
+
+ expand_exit_loop_if_false (0, expr);
+ }
+
+ clear_momentary (); /* Discard the above now that we're done with
+ DO stmt. */
+
+ if (block == NULL)
+ {
+ *xtvar = tvar;
+ *xtincr = tincr_saved;
+ *xitersvar = niters;
+ }
+ else
+ {
+ ffestw_set_do_tvar (block, tvar);
+ ffestw_set_do_incr_saved (block, tincr_saved);
+ ffestw_set_do_count_var (block, niters);
+ }
+}
+
+#endif
+
+/* End an iterative DO loop. Pass the same iteration variable and increment
+ value trees that were generated in the paired _begin_ call. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static void
+ffeste_end_iterdo_ (tree tvar, tree tincr, tree itersvar)
+{
+ tree expr;
+ tree niters = itersvar;
+
+ expand_loop_continue_here ();
+
+ if (ffe_is_onetrip ())
+ {
+ expr = ffecom_truth_value
+ (ffecom_2 (GE_EXPR, integer_type_node,
+ ffecom_2 (PREDECREMENT_EXPR,
+ TREE_TYPE (niters),
+ niters,
+ convert (TREE_TYPE (niters),
+ ffecom_integer_one_node)),
+ convert (TREE_TYPE (niters),
+ ffecom_integer_zero_node)));
+
+ expand_exit_loop_if_false (0, expr);
+ }
+
+ expr = ffecom_modify (void_type_node, tvar,
+ ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
+ tvar,
+ tincr));
+ expand_expr_stmt (expr);
+ expand_end_loop ();
+
+ ffecom_pop_tempvar (itersvar); /* Free #iters var. */
+
+ clear_momentary ();
+ pop_momentary (); /* Lose the stuff we just built. */
+
+ clear_momentary ();
+ pop_momentary (); /* Lose the tvar and incr_saved trees. */
+}
+
+#endif
+/* ffeste_io_call_ -- Generate call to run-time I/O routine
+
+ tree callexpr = build(CALL_EXPR,...);
+ ffeste_io_call_(callexpr,TRUE);
+
+ Sets TREE_SIDE_EFFECTS(callexpr) = 1. If ffeste_io_iostat_ is not
+ NULL_TREE, replaces callexpr with "iostat = callexpr;". Expands the
+ result. If ffeste_io_abort_ is not NULL_TREE and the second argument
+ is TRUE, generates "if (iostat != 0) goto ffeste_io_abort_;". */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static void
+ffeste_io_call_ (tree call, bool do_check)
+{
+ /* Generate the call and optional assignment into iostat var. */
+
+ TREE_SIDE_EFFECTS (call) = 1;
+ if (ffeste_io_iostat_ != NULL_TREE)
+ {
+ call = ffecom_modify (do_check ? NULL_TREE : void_type_node,
+ ffeste_io_iostat_, call);
+ }
+ expand_expr_stmt (call);
+
+ if (!do_check
+ || (ffeste_io_abort_ == NULL_TREE)
+ || (TREE_CODE (ffeste_io_abort_) == ERROR_MARK))
+ return;
+
+ /* Generate optional test. */
+
+ expand_start_cond (ffecom_truth_value (ffeste_io_iostat_), 0);
+ expand_goto (ffeste_io_abort_);
+ expand_end_cond ();
+}
+
+#endif
+/* ffeste_io_dofio_ -- Generate call to do_fio for formatted I/O item
+
+ ffebld expr;
+ tree call;
+ call = ffeste_io_dofio_(expr);
+
+ Returns a tree for a CALL_EXPR to the do_fio function, which handles
+ a formatted I/O list item, along with the appropriate arguments for
+ the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
+ for the CALL_EXPR, expand (emit) the expression, emit any assignment
+ of the result to an IOSTAT= variable, and emit any checking of the
+ result for errors. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_dofio_ (ffebld expr)
+{
+ tree num_elements;
+ tree variable;
+ tree size;
+ tree arglist;
+ ffeinfoBasictype bt;
+ ffeinfoKindtype kt;
+ bool is_complex;
+
+ bt = ffeinfo_basictype (ffebld_info (expr));
+ kt = ffeinfo_kindtype (ffebld_info (expr));
+
+ if ((bt == FFEINFO_basictypeANY)
+ || (kt == FFEINFO_kindtypeANY))
+ return error_mark_node;
+
+ if (bt == FFEINFO_basictypeCOMPLEX)
+ {
+ is_complex = TRUE;
+ bt = FFEINFO_basictypeREAL;
+ }
+ else
+ is_complex = FALSE;
+
+ ffecom_push_calltemps ();
+
+ variable = ffecom_arg_ptr_to_expr (expr, &size);
+
+ if ((variable == error_mark_node)
+ || (size == error_mark_node))
+ {
+ ffecom_pop_calltemps ();
+ return error_mark_node;
+ }
+
+ if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
+ { /* "(ftnlen) sizeof(type)" */
+ size = size_binop (CEIL_DIV_EXPR,
+ TYPE_SIZE (ffecom_tree_type[bt][kt]),
+ size_int (TYPE_PRECISION (char_type_node)));
+#if 0 /* Assume that while it is possible that char * is wider than
+ ftnlen, no object in Fortran space can get big enough for its
+ size to be wider than ftnlen. I really hope nobody wastes
+ time debugging a case where it can! */
+ assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
+ >= TYPE_PRECISION (TREE_TYPE (size)));
+#endif
+ size = convert (ffecom_f2c_ftnlen_type_node, size);
+ }
+
+ if ((ffeinfo_rank (ffebld_info (expr)) == 0)
+ || (TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE))
+ num_elements = is_complex ? ffecom_f2c_ftnlen_two_node
+ : ffecom_f2c_ftnlen_one_node;
+ else
+ {
+ num_elements = size_binop (CEIL_DIV_EXPR,
+ TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), size);
+ num_elements = size_binop (CEIL_DIV_EXPR, num_elements,
+ size_int (TYPE_PRECISION
+ (char_type_node)));
+ num_elements = convert (ffecom_f2c_ftnlen_type_node,
+ num_elements);
+ }
+
+ num_elements
+ = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
+ num_elements);
+
+ variable = convert (string_type_node, variable);
+
+ arglist = build_tree_list (NULL_TREE, num_elements);
+ TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, variable);
+ TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, size);
+
+ ffecom_pop_calltemps ();
+
+ return ffecom_call_gfrt (FFECOM_gfrtDOFIO, arglist);
+}
+
+#endif
+/* ffeste_io_dolio_ -- Generate call to do_lio for list-directed I/O item
+
+ ffebld expr;
+ tree call;
+ call = ffeste_io_dolio_(expr);
+
+ Returns a tree for a CALL_EXPR to the do_lio function, which handles
+ a list-directed I/O list item, along with the appropriate arguments for
+ the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
+ for the CALL_EXPR, expand (emit) the expression, emit any assignment
+ of the result to an IOSTAT= variable, and emit any checking of the
+ result for errors. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_dolio_ (ffebld expr)
+{
+ tree type_id;
+ tree num_elements;
+ tree variable;
+ tree size;
+ tree arglist;
+ ffeinfoBasictype bt;
+ ffeinfoKindtype kt;
+ int tc;
+
+ bt = ffeinfo_basictype (ffebld_info (expr));
+ kt = ffeinfo_kindtype (ffebld_info (expr));
+
+ if ((bt == FFEINFO_basictypeANY)
+ || (kt == FFEINFO_kindtypeANY))
+ return error_mark_node;
+
+ ffecom_push_calltemps ();
+
+ tc = ffecom_f2c_typecode (bt, kt);
+ assert (tc != -1);
+ type_id = build_int_2 (tc, 0);
+
+ type_id
+ = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnint_type_node,
+ convert (ffecom_f2c_ftnint_type_node,
+ type_id));
+
+ variable = ffecom_arg_ptr_to_expr (expr, &size);
+
+ if ((type_id == error_mark_node)
+ || (variable == error_mark_node)
+ || (size == error_mark_node))
+ {
+ ffecom_pop_calltemps ();
+ return error_mark_node;
+ }
+
+ if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
+ { /* "(ftnlen) sizeof(type)" */
+ size = size_binop (CEIL_DIV_EXPR,
+ TYPE_SIZE (ffecom_tree_type[bt][kt]),
+ size_int (TYPE_PRECISION (char_type_node)));
+#if 0 /* Assume that while it is possible that char * is wider than
+ ftnlen, no object in Fortran space can get big enough for its
+ size to be wider than ftnlen. I really hope nobody wastes
+ time debugging a case where it can! */
+ assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
+ >= TYPE_PRECISION (TREE_TYPE (size)));
+#endif
+ size = convert (ffecom_f2c_ftnlen_type_node, size);
+ }
+
+ if ((ffeinfo_rank (ffebld_info (expr)) == 0)
+ || (TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE))
+ num_elements = ffecom_integer_one_node;
+ else
+ {
+ num_elements = size_binop (CEIL_DIV_EXPR,
+ TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), size);
+ num_elements = size_binop (CEIL_DIV_EXPR,
+ num_elements, size_int (TYPE_PRECISION
+ (char_type_node)));
+ num_elements = convert (ffecom_f2c_ftnlen_type_node,
+ num_elements);
+ }
+
+ num_elements
+ = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
+ num_elements);
+
+ variable = convert (string_type_node, variable);
+
+ arglist = build_tree_list (NULL_TREE, type_id);
+ TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, num_elements);
+ TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, variable);
+ TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))
+ = build_tree_list (NULL_TREE, size);
+
+ ffecom_pop_calltemps ();
+
+ return ffecom_call_gfrt (FFECOM_gfrtDOLIO, arglist);
+}
+
+#endif
+/* ffeste_io_douio_ -- Generate call to do_uio for unformatted I/O item
+
+ ffebld expr;
+ tree call;
+ call = ffeste_io_douio_(expr);
+
+ Returns a tree for a CALL_EXPR to the do_uio function, which handles
+ an unformatted I/O list item, along with the appropriate arguments for
+ the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
+ for the CALL_EXPR, expand (emit) the expression, emit any assignment
+ of the result to an IOSTAT= variable, and emit any checking of the
+ result for errors. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_douio_ (ffebld expr)
+{
+ tree num_elements;
+ tree variable;
+ tree size;
+ tree arglist;
+ ffeinfoBasictype bt;
+ ffeinfoKindtype kt;
+ bool is_complex;
+
+ bt = ffeinfo_basictype (ffebld_info (expr));
+ kt = ffeinfo_kindtype (ffebld_info (expr));
+
+ if ((bt == FFEINFO_basictypeANY)
+ || (kt == FFEINFO_kindtypeANY))
+ return error_mark_node;
+
+ if (bt == FFEINFO_basictypeCOMPLEX)
+ {
+ is_complex = TRUE;
+ bt = FFEINFO_basictypeREAL;
+ }
+ else
+ is_complex = FALSE;
+
+ ffecom_push_calltemps ();
+
+ variable = ffecom_arg_ptr_to_expr (expr, &size);
+
+ if ((variable == error_mark_node)
+ || (size == error_mark_node))
+ {
+ ffecom_pop_calltemps ();
+ return error_mark_node;
+ }
+
+ if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
+ { /* "(ftnlen) sizeof(type)" */
+ size = size_binop (CEIL_DIV_EXPR,
+ TYPE_SIZE (ffecom_tree_type[bt][kt]),
+ size_int (TYPE_PRECISION (char_type_node)));
+#if 0 /* Assume that while it is possible that char * is wider than
+ ftnlen, no object in Fortran space can get big enough for its
+ size to be wider than ftnlen. I really hope nobody wastes
+ time debugging a case where it can! */
+ assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
+ >= TYPE_PRECISION (TREE_TYPE (size)));
+#endif
+ size = convert (ffecom_f2c_ftnlen_type_node, size);
+ }
+
+ if ((ffeinfo_rank (ffebld_info (expr)) == 0)
+ || (TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE))
+ num_elements = is_complex ? ffecom_f2c_ftnlen_two_node
+ : ffecom_f2c_ftnlen_one_node;
+ else
+ {
+ num_elements = size_binop (CEIL_DIV_EXPR,
+ TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), size);
+ num_elements = size_binop (CEIL_DIV_EXPR, num_elements,
+ size_int (TYPE_PRECISION
+ (char_type_node)));
+ num_elements = convert (ffecom_f2c_ftnlen_type_node,
+ num_elements);
+ }
+
+ num_elements
+ = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
+ num_elements);
+
+ variable = convert (string_type_node, variable);
+
+ arglist = build_tree_list (NULL_TREE, num_elements);
+ TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, variable);
+ TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, size);
+
+ ffecom_pop_calltemps ();
+
+ return ffecom_call_gfrt (FFECOM_gfrtDOUIO, arglist);
+}
+
+#endif
+/* ffeste_io_ialist_ -- Make arglist with ptr to B/E/R control list
+
+ tree arglist;
+ arglist = ffeste_io_ialist_(...);
+
+ Returns a tree suitable as an argument list containing a pointer to
+ a BACKSPACE/ENDFILE/REWIND control list. First, generates that control
+ list, if necessary, along with any static and run-time initializations
+ that are needed as specified by the arguments to this function. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_ialist_ (bool have_err,
+ ffestvUnit unit,
+ ffebld unit_expr,
+ int unit_dflt)
+{
+ static tree f2c_alist_struct = NULL_TREE;
+ tree t;
+ tree ttype;
+ int yes;
+ tree field;
+ tree inits, initn;
+ bool constantp = TRUE;
+ static tree errfield, unitfield;
+ tree errinit, unitinit;
+ tree unitexp;
+ static int mynumber = 0;
+
+ if (f2c_alist_struct == NULL_TREE)
+ {
+ tree ref;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ref = make_node (RECORD_TYPE);
+
+ errfield = ffecom_decl_field (ref, NULL_TREE, "err",
+ ffecom_f2c_flag_type_node);
+ unitfield = ffecom_decl_field (ref, errfield, "unit",
+ ffecom_f2c_ftnint_type_node);
+
+ TYPE_FIELDS (ref) = errfield;
+ layout_type (ref);
+
+ resume_temporary_allocation ();
+ pop_obstacks ();
+
+ f2c_alist_struct = ref;
+ }
+
+ ffeste_f2c_flagspec_ (have_err, errinit);
+
+ switch (unit)
+ {
+ case FFESTV_unitNONE:
+ case FFESTV_unitASTERISK:
+ unitinit = build_int_2 (unit_dflt, 0);
+ unitexp = NULL_TREE;
+ break;
+
+ case FFESTV_unitINTEXPR:
+ unitexp = ffecom_expr (unit_expr);
+ if (TREE_CONSTANT (unitexp))
+ {
+ unitinit = unitexp;
+ unitexp = NULL_TREE;
+ }
+ else
+ {
+ unitinit = ffecom_integer_zero_node;
+ constantp = FALSE;
+ }
+ break;
+
+ default:
+ assert ("bad unit spec" == NULL);
+ unitexp = NULL_TREE;
+ unitinit = ffecom_integer_zero_node;
+ break;
+ }
+
+ inits = build_tree_list ((field = TYPE_FIELDS (f2c_alist_struct)), errinit);
+ initn = inits;
+ ffeste_f2c_init_ (unitinit);
+
+ inits = build (CONSTRUCTOR, f2c_alist_struct, NULL_TREE, inits);
+ TREE_CONSTANT (inits) = constantp ? 1 : 0;
+ TREE_STATIC (inits) = 1;
+
+ yes = suspend_momentary ();
+
+ t = build_decl (VAR_DECL,
+ ffecom_get_invented_identifier ("__g77_alist_%d", NULL,
+ mynumber++),
+ f2c_alist_struct);
+ TREE_STATIC (t) = 1;
+ t = ffecom_start_decl (t, 1);
+ ffecom_finish_decl (t, inits, 0);
+
+ resume_momentary (yes);
+
+ ffeste_f2c_exp_ (unitfield, unitexp);
+
+ ttype = build_pointer_type (TREE_TYPE (t));
+ t = ffecom_1 (ADDR_EXPR, ttype, t);
+
+ t = build_tree_list (NULL_TREE, t);
+
+ return t;
+}
+
+#endif
+/* ffeste_io_cilist_ -- Make arglist with ptr to external I/O control list
+
+ tree arglist;
+ arglist = ffeste_io_cilist_(...);
+
+ Returns a tree suitable as an argument list containing a pointer to
+ an external-file I/O control list. First, generates that control
+ list, if necessary, along with any static and run-time initializations
+ that are needed as specified by the arguments to this function. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_cilist_ (bool have_err,
+ ffestvUnit unit,
+ ffebld unit_expr,
+ int unit_dflt,
+ bool have_end,
+ ffestvFormat format,
+ ffestpFile *format_spec,
+ bool rec,
+ ffebld rec_expr)
+{
+ static tree f2c_cilist_struct = NULL_TREE;
+ tree t;
+ tree ttype;
+ int yes;
+ tree field;
+ tree inits, initn;
+ tree ignore; /* We ignore the length of format! */
+ bool constantp = TRUE;
+ static tree errfield, unitfield, endfield, formatfield, recfield;
+ tree errinit, unitinit, endinit, formatinit, recinit;
+ tree unitexp, formatexp, recexp;
+ static int mynumber = 0;
+
+ if (f2c_cilist_struct == NULL_TREE)
+ {
+ tree ref;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ref = make_node (RECORD_TYPE);
+
+ errfield = ffecom_decl_field (ref, NULL_TREE, "err",
+ ffecom_f2c_flag_type_node);
+ unitfield = ffecom_decl_field (ref, errfield, "unit",
+ ffecom_f2c_ftnint_type_node);
+ endfield = ffecom_decl_field (ref, unitfield, "end",
+ ffecom_f2c_flag_type_node);
+ formatfield = ffecom_decl_field (ref, endfield, "format",
+ string_type_node);
+ recfield = ffecom_decl_field (ref, formatfield, "rec",
+ ffecom_f2c_ftnint_type_node);
+
+ TYPE_FIELDS (ref) = errfield;
+ layout_type (ref);
+
+ resume_temporary_allocation ();
+ pop_obstacks ();
+
+ f2c_cilist_struct = ref;
+ }
+
+ ffeste_f2c_flagspec_ (have_err, errinit);
+
+ switch (unit)
+ {
+ case FFESTV_unitNONE:
+ case FFESTV_unitASTERISK:
+ unitinit = build_int_2 (unit_dflt, 0);
+ unitexp = NULL_TREE;
+ break;
+
+ case FFESTV_unitINTEXPR:
+ unitexp = ffecom_expr (unit_expr);
+ if (TREE_CONSTANT (unitexp))
+ {
+ unitinit = unitexp;
+ unitexp = NULL_TREE;
+ }
+ else
+ {
+ unitinit = ffecom_integer_zero_node;
+ constantp = FALSE;
+ }
+ break;
+
+ default:
+ assert ("bad unit spec" == NULL);
+ unitexp = NULL_TREE;
+ unitinit = ffecom_integer_zero_node;
+ break;
+ }
+
+ switch (format)
+ {
+ case FFESTV_formatNONE:
+ formatinit = null_pointer_node;
+ formatexp = NULL_TREE;
+ break;
+
+ case FFESTV_formatLABEL:
+ formatexp = NULL_TREE;
+ formatinit = ffecom_lookup_label (format_spec->u.label);
+ if ((formatinit == NULL_TREE)
+ || (TREE_CODE (formatinit) == ERROR_MARK))
+ break;
+ formatinit = ffecom_1 (ADDR_EXPR,
+ build_pointer_type (void_type_node),
+ formatinit);
+ TREE_CONSTANT (formatinit) = 1;
+ break;
+
+ case FFESTV_formatCHAREXPR:
+ formatexp = ffecom_arg_ptr_to_expr (format_spec->u.expr, &ignore);
+ if (TREE_CONSTANT (formatexp))
+ {
+ formatinit = formatexp;
+ formatexp = NULL_TREE;
+ }
+ else
+ {
+ formatinit = null_pointer_node;
+ constantp = FALSE;
+ }
+ break;
+
+ case FFESTV_formatASTERISK:
+ formatinit = null_pointer_node;
+ formatexp = NULL_TREE;
+ break;
+
+ case FFESTV_formatINTEXPR:
+ formatinit = null_pointer_node;
+ formatexp = ffecom_expr_assign (format_spec->u.expr);
+ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (formatexp)))
+ < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
+ error ("ASSIGNed FORMAT specifier is too small");
+ formatexp = convert (string_type_node, formatexp);
+ break;
+
+ case FFESTV_formatNAMELIST:
+ formatinit = ffecom_expr (format_spec->u.expr);
+ formatexp = NULL_TREE;
+ break;
+
+ default:
+ assert ("bad format spec" == NULL);
+ formatexp = NULL_TREE;
+ formatinit = integer_zero_node;
+ break;
+ }
+
+ ffeste_f2c_flagspec_ (have_end, endinit);
+
+ if (rec)
+ recexp = ffecom_expr (rec_expr);
+ else
+ recexp = ffecom_integer_zero_node;
+ if (TREE_CONSTANT (recexp))
+ {
+ recinit = recexp;
+ recexp = NULL_TREE;
+ }
+ else
+ {
+ recinit = ffecom_integer_zero_node;
+ constantp = FALSE;
+ }
+
+ inits = build_tree_list ((field = TYPE_FIELDS (f2c_cilist_struct)), errinit);
+ initn = inits;
+ ffeste_f2c_init_ (unitinit);
+ ffeste_f2c_init_ (endinit);
+ ffeste_f2c_init_ (formatinit);
+ ffeste_f2c_init_ (recinit);
+
+ inits = build (CONSTRUCTOR, f2c_cilist_struct, NULL_TREE, inits);
+ TREE_CONSTANT (inits) = constantp ? 1 : 0;
+ TREE_STATIC (inits) = 1;
+
+ yes = suspend_momentary ();
+
+ t = build_decl (VAR_DECL,
+ ffecom_get_invented_identifier ("__g77_cilist_%d", NULL,
+ mynumber++),
+ f2c_cilist_struct);
+ TREE_STATIC (t) = 1;
+ t = ffecom_start_decl (t, 1);
+ ffecom_finish_decl (t, inits, 0);
+
+ resume_momentary (yes);
+
+ ffeste_f2c_exp_ (unitfield, unitexp);
+ ffeste_f2c_exp_ (formatfield, formatexp);
+ ffeste_f2c_exp_ (recfield, recexp);
+
+ ttype = build_pointer_type (TREE_TYPE (t));
+ t = ffecom_1 (ADDR_EXPR, ttype, t);
+
+ t = build_tree_list (NULL_TREE, t);
+
+ return t;
+}
+
+#endif
+/* ffeste_io_cllist_ -- Make arglist with ptr to CLOSE control list
+
+ tree arglist;
+ arglist = ffeste_io_cllist_(...);
+
+ Returns a tree suitable as an argument list containing a pointer to
+ a CLOSE-statement control list. First, generates that control
+ list, if necessary, along with any static and run-time initializations
+ that are needed as specified by the arguments to this function. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_cllist_ (bool have_err,
+ ffebld unit_expr,
+ ffestpFile *stat_spec)
+{
+ static tree f2c_close_struct = NULL_TREE;
+ tree t;
+ tree ttype;
+ int yes;
+ tree field;
+ tree inits, initn;
+ tree ignore; /* Ignore length info for certain fields. */
+ bool constantp = TRUE;
+ static tree errfield, unitfield, statfield;
+ tree errinit, unitinit, statinit;
+ tree unitexp, statexp;
+ static int mynumber = 0;
+
+ if (f2c_close_struct == NULL_TREE)
+ {
+ tree ref;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ref = make_node (RECORD_TYPE);
+
+ errfield = ffecom_decl_field (ref, NULL_TREE, "err",
+ ffecom_f2c_flag_type_node);
+ unitfield = ffecom_decl_field (ref, errfield, "unit",
+ ffecom_f2c_ftnint_type_node);
+ statfield = ffecom_decl_field (ref, unitfield, "stat",
+ string_type_node);
+
+ TYPE_FIELDS (ref) = errfield;
+ layout_type (ref);
+
+ resume_temporary_allocation ();
+ pop_obstacks ();
+
+ f2c_close_struct = ref;
+ }
+
+ ffeste_f2c_flagspec_ (have_err, errinit);
+
+ unitexp = ffecom_expr (unit_expr);
+ if (TREE_CONSTANT (unitexp))
+ {
+ unitinit = unitexp;
+ unitexp = NULL_TREE;
+ }
+ else
+ {
+ unitinit = ffecom_integer_zero_node;
+ constantp = FALSE;
+ }
+
+ ffeste_f2c_charnolenspec_ (stat_spec, statexp, statinit);
+
+ inits = build_tree_list ((field = TYPE_FIELDS (f2c_close_struct)), errinit);
+ initn = inits;
+ ffeste_f2c_init_ (unitinit);
+ ffeste_f2c_init_ (statinit);
+
+ inits = build (CONSTRUCTOR, f2c_close_struct, NULL_TREE, inits);
+ TREE_CONSTANT (inits) = constantp ? 1 : 0;
+ TREE_STATIC (inits) = 1;
+
+ yes = suspend_momentary ();
+
+ t = build_decl (VAR_DECL,
+ ffecom_get_invented_identifier ("__g77_cllist_%d", NULL,
+ mynumber++),
+ f2c_close_struct);
+ TREE_STATIC (t) = 1;
+ t = ffecom_start_decl (t, 1);
+ ffecom_finish_decl (t, inits, 0);
+
+ resume_momentary (yes);
+
+ ffeste_f2c_exp_ (unitfield, unitexp);
+ ffeste_f2c_exp_ (statfield, statexp);
+
+ ttype = build_pointer_type (TREE_TYPE (t));
+ t = ffecom_1 (ADDR_EXPR, ttype, t);
+
+ t = build_tree_list (NULL_TREE, t);
+
+ return t;
+}
+
+#endif
+/* ffeste_io_icilist_ -- Make arglist with ptr to internal I/O control list
+
+ tree arglist;
+ arglist = ffeste_io_icilist_(...);
+
+ Returns a tree suitable as an argument list containing a pointer to
+ an internal-file I/O control list. First, generates that control
+ list, if necessary, along with any static and run-time initializations
+ that are needed as specified by the arguments to this function. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_icilist_ (bool have_err,
+ ffebld unit_expr,
+ bool have_end,
+ ffestvFormat format,
+ ffestpFile *format_spec)
+{
+ static tree f2c_icilist_struct = NULL_TREE;
+ tree t;
+ tree ttype;
+ int yes;
+ tree field;
+ tree inits, initn;
+ tree ignore; /* We ignore the length of format! */
+ bool constantp = TRUE;
+ static tree errfield, unitfield, endfield, formatfield, unitlenfield,
+ unitnumfield;
+ tree errinit, unitinit, endinit, formatinit, unitleninit, unitnuminit;
+ tree unitexp, formatexp, unitlenexp, unitnumexp;
+ static int mynumber = 0;
+
+ if (f2c_icilist_struct == NULL_TREE)
+ {
+ tree ref;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ref = make_node (RECORD_TYPE);
+
+ errfield = ffecom_decl_field (ref, NULL_TREE, "err",
+ ffecom_f2c_flag_type_node);
+ unitfield = ffecom_decl_field (ref, errfield, "unit",
+ string_type_node);
+ endfield = ffecom_decl_field (ref, unitfield, "end",
+ ffecom_f2c_flag_type_node);
+ formatfield = ffecom_decl_field (ref, endfield, "format",
+ string_type_node);
+ unitlenfield = ffecom_decl_field (ref, formatfield, "unitlen",
+ ffecom_f2c_ftnint_type_node);
+ unitnumfield = ffecom_decl_field (ref, unitlenfield, "unitnum",
+ ffecom_f2c_ftnint_type_node);
+
+ TYPE_FIELDS (ref) = errfield;
+ layout_type (ref);
+
+ resume_temporary_allocation ();
+ pop_obstacks ();
+
+ f2c_icilist_struct = ref;
+ }
+
+ ffeste_f2c_flagspec_ (have_err, errinit);
+
+ unitexp = ffecom_arg_ptr_to_expr (unit_expr, &unitlenexp);
+ if ((ffeinfo_rank (ffebld_info (unit_expr)) == 0)
+ || (TREE_CODE (TREE_TYPE (TREE_TYPE (unitexp))) != ARRAY_TYPE))
+ unitnumexp = ffecom_integer_one_node;
+ else
+ {
+ unitnumexp = size_binop (CEIL_DIV_EXPR,
+ TYPE_SIZE (TREE_TYPE (TREE_TYPE (unitexp))), unitlenexp);
+ unitnumexp = size_binop (CEIL_DIV_EXPR,
+ unitnumexp, size_int (TYPE_PRECISION
+ (char_type_node)));
+ }
+ if (TREE_CONSTANT (unitexp))
+ {
+ unitinit = unitexp;
+ unitexp = NULL_TREE;
+ }
+ else
+ {
+ unitinit = null_pointer_node;
+ constantp = FALSE;
+ }
+ if ((unitlenexp != NULL_TREE) && TREE_CONSTANT (unitlenexp))
+ {
+ unitleninit = unitlenexp;
+ unitlenexp = NULL_TREE;
+ }
+ else
+ {
+ unitleninit = ffecom_integer_zero_node;
+ constantp = FALSE;
+ }
+ if (TREE_CONSTANT (unitnumexp))
+ {
+ unitnuminit = unitnumexp;
+ unitnumexp = NULL_TREE;
+ }
+ else
+ {
+ unitnuminit = ffecom_integer_zero_node;
+ constantp = FALSE;
+ }
+
+ switch (format)
+ {
+ case FFESTV_formatNONE:
+ formatinit = null_pointer_node;
+ formatexp = NULL_TREE;
+ break;
+
+ case FFESTV_formatLABEL:
+ formatexp = NULL_TREE;
+ formatinit = ffecom_lookup_label (format_spec->u.label);
+ if ((formatinit == NULL_TREE)
+ || (TREE_CODE (formatinit) == ERROR_MARK))
+ break;
+ formatinit = ffecom_1 (ADDR_EXPR,
+ build_pointer_type (void_type_node),
+ formatinit);
+ TREE_CONSTANT (formatinit) = 1;
+ break;
+
+ case FFESTV_formatCHAREXPR:
+ formatexp = ffecom_arg_ptr_to_expr (format_spec->u.expr, &ignore);
+ if (TREE_CONSTANT (formatexp))
+ {
+ formatinit = formatexp;
+ formatexp = NULL_TREE;
+ }
+ else
+ {
+ formatinit = null_pointer_node;
+ constantp = FALSE;
+ }
+ break;
+
+ case FFESTV_formatASTERISK:
+ formatinit = null_pointer_node;
+ formatexp = NULL_TREE;
+ break;
+
+ case FFESTV_formatINTEXPR:
+ formatinit = null_pointer_node;
+ formatexp = ffecom_expr_assign (format_spec->u.expr);
+ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (formatexp)))
+ < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
+ error ("ASSIGNed FORMAT specifier is too small");
+ formatexp = convert (string_type_node, formatexp);
+ break;
+
+ default:
+ assert ("bad format spec" == NULL);
+ formatexp = NULL_TREE;
+ formatinit = ffecom_integer_zero_node;
+ break;
+ }
+
+ ffeste_f2c_flagspec_ (have_end, endinit);
+
+ inits = build_tree_list ((field = TYPE_FIELDS (f2c_icilist_struct)),
+ errinit);
+ initn = inits;
+ ffeste_f2c_init_ (unitinit);
+ ffeste_f2c_init_ (endinit);
+ ffeste_f2c_init_ (formatinit);
+ ffeste_f2c_init_ (unitleninit);
+ ffeste_f2c_init_ (unitnuminit);
+
+ inits = build (CONSTRUCTOR, f2c_icilist_struct, NULL_TREE, inits);
+ TREE_CONSTANT (inits) = constantp ? 1 : 0;
+ TREE_STATIC (inits) = 1;
+
+ yes = suspend_momentary ();
+
+ t = build_decl (VAR_DECL,
+ ffecom_get_invented_identifier ("__g77_icilist_%d", NULL,
+ mynumber++),
+ f2c_icilist_struct);
+ TREE_STATIC (t) = 1;
+ t = ffecom_start_decl (t, 1);
+ ffecom_finish_decl (t, inits, 0);
+
+ resume_momentary (yes);
+
+ ffeste_f2c_exp_ (unitfield, unitexp);
+ ffeste_f2c_exp_ (formatfield, formatexp);
+ ffeste_f2c_exp_ (unitlenfield, unitlenexp);
+ ffeste_f2c_exp_ (unitnumfield, unitnumexp);
+
+ ttype = build_pointer_type (TREE_TYPE (t));
+ t = ffecom_1 (ADDR_EXPR, ttype, t);
+
+ t = build_tree_list (NULL_TREE, t);
+
+ return t;
+}
+
+#endif
+/* ffeste_io_impdo_ -- Handle implied-DO in I/O list
+
+ ffebld expr;
+ ffeste_io_impdo_(expr);
+
+ Expands code to start up the DO loop. Then for each item in the
+ DO loop, handles appropriately (possibly including recursively calling
+ itself). Then expands code to end the DO loop. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static void
+ffeste_io_impdo_ (ffebld impdo, ffelexToken impdo_token)
+{
+ ffebld var = ffebld_head (ffebld_right (impdo));
+ ffebld start = ffebld_head (ffebld_trail (ffebld_right (impdo)));
+ ffebld end = ffebld_head (ffebld_trail (ffebld_trail
+ (ffebld_right (impdo))));
+ ffebld incr = ffebld_head (ffebld_trail (ffebld_trail
+ (ffebld_trail (ffebld_right (impdo)))));
+ ffebld list; /* Used for list of items in left part of
+ impdo. */
+ ffebld item; /* I/O item from head of given list. */
+ tree tvar;
+ tree tincr;
+ tree titervar;
+
+ if (incr == NULL)
+ {
+ incr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1));
+ ffebld_set_info (incr, ffeinfo_new
+ (FFEINFO_basictypeINTEGER,
+ FFEINFO_kindtypeINTEGERDEFAULT,
+ 0,
+ FFEINFO_kindENTITY,
+ FFEINFO_whereCONSTANT,
+ FFETARGET_charactersizeNONE));
+ }
+
+ /* Start the DO loop. */
+
+ start = ffeexpr_convert_expr (start, impdo_token, var, impdo_token,
+ FFEEXPR_contextLET);
+ end = ffeexpr_convert_expr (end, impdo_token, var, impdo_token,
+ FFEEXPR_contextLET);
+ incr = ffeexpr_convert_expr (incr, impdo_token, var, impdo_token,
+ FFEEXPR_contextLET);
+
+ ffeste_begin_iterdo_ (NULL, &tvar, &tincr, &titervar, var,
+ start, impdo_token,
+ end, impdo_token,
+ incr, impdo_token,
+ "Implied DO loop");
+
+ /* Handle the list of items. */
+
+ for (list = ffebld_left (impdo); list != NULL; list = ffebld_trail (list))
+ {
+ item = ffebld_head (list);
+ if (item == NULL)
+ continue;
+ while (ffebld_op (item) == FFEBLD_opPAREN)
+ item = ffebld_left (item);
+ if (ffebld_op (item) == FFEBLD_opANY)
+ continue;
+ if (ffebld_op (item) == FFEBLD_opIMPDO)
+ ffeste_io_impdo_ (item, impdo_token);
+ else
+ ffeste_io_call_ ((*ffeste_io_driver_) (item), TRUE);
+ clear_momentary ();
+ }
+
+ /* Generate end of implied-do construct. */
+
+ ffeste_end_iterdo_ (tvar, tincr, titervar);
+}
+
+#endif
+/* ffeste_io_inlist_ -- Make arglist with ptr to INQUIRE control list
+
+ tree arglist;
+ arglist = ffeste_io_inlist_(...);
+
+ Returns a tree suitable as an argument list containing a pointer to
+ an INQUIRE-statement control list. First, generates that control
+ list, if necessary, along with any static and run-time initializations
+ that are needed as specified by the arguments to this function. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_inlist_ (bool have_err,
+ ffestpFile *unit_spec,
+ ffestpFile *file_spec,
+ ffestpFile *exist_spec,
+ ffestpFile *open_spec,
+ ffestpFile *number_spec,
+ ffestpFile *named_spec,
+ ffestpFile *name_spec,
+ ffestpFile *access_spec,
+ ffestpFile *sequential_spec,
+ ffestpFile *direct_spec,
+ ffestpFile *form_spec,
+ ffestpFile *formatted_spec,
+ ffestpFile *unformatted_spec,
+ ffestpFile *recl_spec,
+ ffestpFile *nextrec_spec,
+ ffestpFile *blank_spec)
+{
+ static tree f2c_inquire_struct = NULL_TREE;
+ tree t;
+ tree ttype;
+ int yes;
+ tree field;
+ tree inits, initn;
+ bool constantp = TRUE;
+ static tree errfield, unitfield, filefield, filelenfield, existfield,
+ openfield, numberfield, namedfield, namefield, namelenfield, accessfield,
+ accesslenfield, sequentialfield, sequentiallenfield, directfield, directlenfield,
+ formfield, formlenfield, formattedfield, formattedlenfield, unformattedfield,
+ unformattedlenfield, reclfield, nextrecfield, blankfield, blanklenfield;
+ tree errinit, unitinit, fileinit, fileleninit, existinit, openinit, numberinit,
+ namedinit, nameinit, nameleninit, accessinit, accessleninit, sequentialinit,
+ sequentialleninit, directinit, directleninit, forminit, formleninit,
+ formattedinit, formattedleninit, unformattedinit, unformattedleninit,
+ reclinit, nextrecinit, blankinit, blankleninit;
+ tree
+ unitexp, fileexp, filelenexp, existexp, openexp, numberexp, namedexp,
+ nameexp, namelenexp, accessexp, accesslenexp, sequentialexp, sequentiallenexp,
+ directexp, directlenexp, formexp, formlenexp, formattedexp, formattedlenexp,
+ unformattedexp, unformattedlenexp, reclexp, nextrecexp, blankexp, blanklenexp;
+ static int mynumber = 0;
+
+ if (f2c_inquire_struct == NULL_TREE)
+ {
+ tree ref;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ref = make_node (RECORD_TYPE);
+
+ errfield = ffecom_decl_field (ref, NULL_TREE, "err",
+ ffecom_f2c_flag_type_node);
+ unitfield = ffecom_decl_field (ref, errfield, "unit",
+ ffecom_f2c_ftnint_type_node);
+ filefield = ffecom_decl_field (ref, unitfield, "file",
+ string_type_node);
+ filelenfield = ffecom_decl_field (ref, filefield, "filelen",
+ ffecom_f2c_ftnlen_type_node);
+ existfield = ffecom_decl_field (ref, filelenfield, "exist",
+ ffecom_f2c_ptr_to_ftnint_type_node);
+ openfield = ffecom_decl_field (ref, existfield, "open",
+ ffecom_f2c_ptr_to_ftnint_type_node);
+ numberfield = ffecom_decl_field (ref, openfield, "number",
+ ffecom_f2c_ptr_to_ftnint_type_node);
+ namedfield = ffecom_decl_field (ref, numberfield, "named",
+ ffecom_f2c_ptr_to_ftnint_type_node);
+ namefield = ffecom_decl_field (ref, namedfield, "name",
+ string_type_node);
+ namelenfield = ffecom_decl_field (ref, namefield, "namelen",
+ ffecom_f2c_ftnlen_type_node);
+ accessfield = ffecom_decl_field (ref, namelenfield, "access",
+ string_type_node);
+ accesslenfield = ffecom_decl_field (ref, accessfield, "accesslen",
+ ffecom_f2c_ftnlen_type_node);
+ sequentialfield = ffecom_decl_field (ref, accesslenfield, "sequential",
+ string_type_node);
+ sequentiallenfield = ffecom_decl_field (ref, sequentialfield,
+ "sequentiallen",
+ ffecom_f2c_ftnlen_type_node);
+ directfield = ffecom_decl_field (ref, sequentiallenfield, "direct",
+ string_type_node);
+ directlenfield = ffecom_decl_field (ref, directfield, "directlen",
+ ffecom_f2c_ftnlen_type_node);
+ formfield = ffecom_decl_field (ref, directlenfield, "form",
+ string_type_node);
+ formlenfield = ffecom_decl_field (ref, formfield, "formlen",
+ ffecom_f2c_ftnlen_type_node);
+ formattedfield = ffecom_decl_field (ref, formlenfield, "formatted",
+ string_type_node);
+ formattedlenfield = ffecom_decl_field (ref, formattedfield,
+ "formattedlen",
+ ffecom_f2c_ftnlen_type_node);
+ unformattedfield = ffecom_decl_field (ref, formattedlenfield,
+ "unformatted",
+ string_type_node);
+ unformattedlenfield = ffecom_decl_field (ref, unformattedfield,
+ "unformattedlen",
+ ffecom_f2c_ftnlen_type_node);
+ reclfield = ffecom_decl_field (ref, unformattedlenfield, "recl",
+ ffecom_f2c_ptr_to_ftnint_type_node);
+ nextrecfield = ffecom_decl_field (ref, reclfield, "nextrec",
+ ffecom_f2c_ptr_to_ftnint_type_node);
+ blankfield = ffecom_decl_field (ref, nextrecfield, "blank",
+ string_type_node);
+ blanklenfield = ffecom_decl_field (ref, blankfield, "blanklen",
+ ffecom_f2c_ftnlen_type_node);
+
+ TYPE_FIELDS (ref) = errfield;
+ layout_type (ref);
+
+ resume_temporary_allocation ();
+ pop_obstacks ();
+
+ f2c_inquire_struct = ref;
+ }
+
+ ffeste_f2c_flagspec_ (have_err, errinit);
+ ffeste_f2c_intspec_ (unit_spec, unitexp, unitinit);
+ ffeste_f2c_charspec_ (file_spec, fileexp, fileinit, filelenexp, fileleninit);
+ ffeste_f2c_ptrtointspec_ (exist_spec, existexp, existinit);
+ ffeste_f2c_ptrtointspec_ (open_spec, openexp, openinit);
+ ffeste_f2c_ptrtointspec_ (number_spec, numberexp, numberinit);
+ ffeste_f2c_ptrtointspec_ (named_spec, namedexp, namedinit);
+ ffeste_f2c_charspec_ (name_spec, nameexp, nameinit, namelenexp, nameleninit);
+ ffeste_f2c_charspec_ (access_spec, accessexp, accessinit, accesslenexp,
+ accessleninit);
+ ffeste_f2c_charspec_ (sequential_spec, sequentialexp, sequentialinit,
+ sequentiallenexp, sequentialleninit);
+ ffeste_f2c_charspec_ (direct_spec, directexp, directinit, directlenexp,
+ directleninit);
+ ffeste_f2c_charspec_ (form_spec, formexp, forminit, formlenexp, formleninit);
+ ffeste_f2c_charspec_ (formatted_spec, formattedexp, formattedinit,
+ formattedlenexp, formattedleninit);
+ ffeste_f2c_charspec_ (unformatted_spec, unformattedexp, unformattedinit,
+ unformattedlenexp, unformattedleninit);
+ ffeste_f2c_ptrtointspec_ (recl_spec, reclexp, reclinit);
+ ffeste_f2c_ptrtointspec_ (nextrec_spec, nextrecexp, nextrecinit);
+ ffeste_f2c_charspec_ (blank_spec, blankexp, blankinit, blanklenexp,
+ blankleninit);
+
+ inits = build_tree_list ((field = TYPE_FIELDS (f2c_inquire_struct)),
+ errinit);
+ initn = inits;
+ ffeste_f2c_init_ (unitinit);
+ ffeste_f2c_init_ (fileinit);
+ ffeste_f2c_init_ (fileleninit);
+ ffeste_f2c_init_ (existinit);
+ ffeste_f2c_init_ (openinit);
+ ffeste_f2c_init_ (numberinit);
+ ffeste_f2c_init_ (namedinit);
+ ffeste_f2c_init_ (nameinit);
+ ffeste_f2c_init_ (nameleninit);
+ ffeste_f2c_init_ (accessinit);
+ ffeste_f2c_init_ (accessleninit);
+ ffeste_f2c_init_ (sequentialinit);
+ ffeste_f2c_init_ (sequentialleninit);
+ ffeste_f2c_init_ (directinit);
+ ffeste_f2c_init_ (directleninit);
+ ffeste_f2c_init_ (forminit);
+ ffeste_f2c_init_ (formleninit);
+ ffeste_f2c_init_ (formattedinit);
+ ffeste_f2c_init_ (formattedleninit);
+ ffeste_f2c_init_ (unformattedinit);
+ ffeste_f2c_init_ (unformattedleninit);
+ ffeste_f2c_init_ (reclinit);
+ ffeste_f2c_init_ (nextrecinit);
+ ffeste_f2c_init_ (blankinit);
+ ffeste_f2c_init_ (blankleninit);
+
+ inits = build (CONSTRUCTOR, f2c_inquire_struct, NULL_TREE, inits);
+ TREE_CONSTANT (inits) = constantp ? 1 : 0;
+ TREE_STATIC (inits) = 1;
+
+ yes = suspend_momentary ();
+
+ t = build_decl (VAR_DECL,
+ ffecom_get_invented_identifier ("__g77_inlist_%d", NULL,
+ mynumber++),
+ f2c_inquire_struct);
+ TREE_STATIC (t) = 1;
+ t = ffecom_start_decl (t, 1);
+ ffecom_finish_decl (t, inits, 0);
+
+ resume_momentary (yes);
+
+ ffeste_f2c_exp_ (unitfield, unitexp);
+ ffeste_f2c_exp_ (filefield, fileexp);
+ ffeste_f2c_exp_ (filelenfield, filelenexp);
+ ffeste_f2c_exp_ (existfield, existexp);
+ ffeste_f2c_exp_ (openfield, openexp);
+ ffeste_f2c_exp_ (numberfield, numberexp);
+ ffeste_f2c_exp_ (namedfield, namedexp);
+ ffeste_f2c_exp_ (namefield, nameexp);
+ ffeste_f2c_exp_ (namelenfield, namelenexp);
+ ffeste_f2c_exp_ (accessfield, accessexp);
+ ffeste_f2c_exp_ (accesslenfield, accesslenexp);
+ ffeste_f2c_exp_ (sequentialfield, sequentialexp);
+ ffeste_f2c_exp_ (sequentiallenfield, sequentiallenexp);
+ ffeste_f2c_exp_ (directfield, directexp);
+ ffeste_f2c_exp_ (directlenfield, directlenexp);
+ ffeste_f2c_exp_ (formfield, formexp);
+ ffeste_f2c_exp_ (formlenfield, formlenexp);
+ ffeste_f2c_exp_ (formattedfield, formattedexp);
+ ffeste_f2c_exp_ (formattedlenfield, formattedlenexp);
+ ffeste_f2c_exp_ (unformattedfield, unformattedexp);
+ ffeste_f2c_exp_ (unformattedlenfield, unformattedlenexp);
+ ffeste_f2c_exp_ (reclfield, reclexp);
+ ffeste_f2c_exp_ (nextrecfield, nextrecexp);
+ ffeste_f2c_exp_ (blankfield, blankexp);
+ ffeste_f2c_exp_ (blanklenfield, blanklenexp);
+
+ ttype = build_pointer_type (TREE_TYPE (t));
+ t = ffecom_1 (ADDR_EXPR, ttype, t);
+
+ t = build_tree_list (NULL_TREE, t);
+
+ return t;
+}
+
+#endif
+/* ffeste_io_olist_ -- Make arglist with ptr to OPEN control list
+
+ tree arglist;
+ arglist = ffeste_io_olist_(...);
+
+ Returns a tree suitable as an argument list containing a pointer to
+ an OPEN-statement control list. First, generates that control
+ list, if necessary, along with any static and run-time initializations
+ that are needed as specified by the arguments to this function. */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static tree
+ffeste_io_olist_ (bool have_err,
+ ffebld unit_expr,
+ ffestpFile *file_spec,
+ ffestpFile *stat_spec,
+ ffestpFile *access_spec,
+ ffestpFile *form_spec,
+ ffestpFile *recl_spec,
+ ffestpFile *blank_spec)
+{
+ static tree f2c_open_struct = NULL_TREE;
+ tree t;
+ tree ttype;
+ int yes;
+ tree field;
+ tree inits, initn;
+ tree ignore; /* Ignore length info for certain fields. */
+ bool constantp = TRUE;
+ static tree errfield, unitfield, filefield, filelenfield, statfield,
+ accessfield, formfield, reclfield, blankfield;
+ tree errinit, unitinit, fileinit, fileleninit, statinit, accessinit,
+ forminit, reclinit, blankinit;
+ tree
+ unitexp, fileexp, filelenexp, statexp, accessexp, formexp, reclexp,
+ blankexp;
+ static int mynumber = 0;
+
+ if (f2c_open_struct == NULL_TREE)
+ {
+ tree ref;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ref = make_node (RECORD_TYPE);
+
+ errfield = ffecom_decl_field (ref, NULL_TREE, "err",
+ ffecom_f2c_flag_type_node);
+ unitfield = ffecom_decl_field (ref, errfield, "unit",
+ ffecom_f2c_ftnint_type_node);
+ filefield = ffecom_decl_field (ref, unitfield, "file",
+ string_type_node);
+ filelenfield = ffecom_decl_field (ref, filefield, "filelen",
+ ffecom_f2c_ftnlen_type_node);
+ statfield = ffecom_decl_field (ref, filelenfield, "stat",
+ string_type_node);
+ accessfield = ffecom_decl_field (ref, statfield, "access",
+ string_type_node);
+ formfield = ffecom_decl_field (ref, accessfield, "form",
+ string_type_node);
+ reclfield = ffecom_decl_field (ref, formfield, "recl",
+ ffecom_f2c_ftnint_type_node);
+ blankfield = ffecom_decl_field (ref, reclfield, "blank",
+ string_type_node);
+
+ TYPE_FIELDS (ref) = errfield;
+ layout_type (ref);
+
+ resume_temporary_allocation ();
+ pop_obstacks ();
+
+ f2c_open_struct = ref;
+ }
+
+ ffeste_f2c_flagspec_ (have_err, errinit);
+
+ unitexp = ffecom_expr (unit_expr);
+ if (TREE_CONSTANT (unitexp))
+ {
+ unitinit = unitexp;
+ unitexp = NULL_TREE;
+ }
+ else
+ {
+ unitinit = ffecom_integer_zero_node;
+ constantp = FALSE;
+ }
+
+ ffeste_f2c_charspec_ (file_spec, fileexp, fileinit, filelenexp, fileleninit);
+ ffeste_f2c_charnolenspec_ (stat_spec, statexp, statinit);
+ ffeste_f2c_charnolenspec_ (access_spec, accessexp, accessinit);
+ ffeste_f2c_charnolenspec_ (form_spec, formexp, forminit);
+ ffeste_f2c_intspec_ (recl_spec, reclexp, reclinit);
+ ffeste_f2c_charnolenspec_ (blank_spec, blankexp, blankinit);
+
+ inits = build_tree_list ((field = TYPE_FIELDS (f2c_open_struct)), errinit);
+ initn = inits;
+ ffeste_f2c_init_ (unitinit);
+ ffeste_f2c_init_ (fileinit);
+ ffeste_f2c_init_ (fileleninit);
+ ffeste_f2c_init_ (statinit);
+ ffeste_f2c_init_ (accessinit);
+ ffeste_f2c_init_ (forminit);
+ ffeste_f2c_init_ (reclinit);
+ ffeste_f2c_init_ (blankinit);
+
+ inits = build (CONSTRUCTOR, f2c_open_struct, NULL_TREE, inits);
+ TREE_CONSTANT (inits) = constantp ? 1 : 0;
+ TREE_STATIC (inits) = 1;
+
+ yes = suspend_momentary ();
+
+ t = build_decl (VAR_DECL,
+ ffecom_get_invented_identifier ("__g77_olist_%d", NULL,
+ mynumber++),
+ f2c_open_struct);
+ TREE_STATIC (t) = 1;
+ t = ffecom_start_decl (t, 1);
+ ffecom_finish_decl (t, inits, 0);
+
+ resume_momentary (yes);
+
+ ffeste_f2c_exp_ (unitfield, unitexp);
+ ffeste_f2c_exp_ (filefield, fileexp);
+ ffeste_f2c_exp_ (filelenfield, filelenexp);
+ ffeste_f2c_exp_ (statfield, statexp);
+ ffeste_f2c_exp_ (accessfield, accessexp);
+ ffeste_f2c_exp_ (formfield, formexp);
+ ffeste_f2c_exp_ (reclfield, reclexp);
+ ffeste_f2c_exp_ (blankfield, blankexp);
+
+ ttype = build_pointer_type (TREE_TYPE (t));
+ t = ffecom_1 (ADDR_EXPR, ttype, t);
+
+ t = build_tree_list (NULL_TREE, t);
+
+ return t;
+}
+
+#endif
+/* ffeste_subr_file_ -- Display file-statement specifier
+
+ ffeste_subr_file_(&specifier); */
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+static void
+ffeste_subr_file_ (char *kw, ffestpFile *spec)
+{
+ if (!spec->kw_or_val_present)
+ return;
+ fputs (kw, dmpout);
+ if (spec->value_present)
+ {
+ fputc ('=', dmpout);
+ if (spec->value_is_label)
+ {
+ assert (spec->value_is_label == 2); /* Temporary checking only. */
+ fprintf (dmpout, "%" ffelabValue_f "u",
+ ffelab_value (spec->u.label));
+ }
+ else
+ ffebld_dump (spec->u.expr);
+ }
+ fputc (',', dmpout);
+}
+#endif
+
+/* ffeste_subr_beru_ -- Generate code for BACKSPACE/ENDFILE/REWIND
+
+ ffeste_subr_beru_(FFECOM_gfrtFBACK); */
+
+#if FFECOM_targetCURRENT == FFECOM_targetGCC
+static void
+ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt)
+{
+ tree alist;
+ bool iostat;
+ bool errl;
+
+#define specified(something) (info->beru_spec[something].kw_or_val_present)
+
+ ffeste_emit_line_note_ ();
+
+ /* Do the real work. */
+
+ iostat = specified (FFESTP_beruixIOSTAT);
+ errl = specified (FFESTP_beruixERR);
+
+ /* ~~For now, we assume the unit number is specified and is not ASTERISK,
+ because the FFE doesn't support BACKSPACE(*) and rejects a BACKSPACE
+ without any unit specifier. f2c, however, supports the former
+ construct. When it is time to add this feature to the FFE, which
+ probably is fairly easy, ffestc_R919 and company will want to pass an
+ ffestvUnit indicator of FFESTV_unitINTEXPR or _unitASTERISK to
+ ffeste_R919 and company, and they will want to pass that same value to
+ this function, and that argument will replace the constant _unitINTEXPR_
+ in the call below. Right now, the default unit number, 6, is ignored. */
+
+ ffecom_push_calltemps ();
+
+ alist = ffeste_io_ialist_ (errl || iostat, FFESTV_unitINTEXPR,
+ info->beru_spec[FFESTP_beruixUNIT].u.expr, 6);
+
+ if (errl)
+ { /* ERR= */
+ ffeste_io_err_
+ = ffeste_io_abort_
+ = ffecom_lookup_label
+ (info->beru_spec[FFESTP_beruixERR].u.label);
+ ffeste_io_abort_is_temp_ = FALSE;
+ }
+ else
+ { /* no ERR= */
+ ffeste_io_err_ = NULL_TREE;
+
+ if ((ffeste_io_abort_is_temp_ = iostat))
+ ffeste_io_abort_ = ffecom_temp_label ();
+ else
+ ffeste_io_abort_ = NULL_TREE;
+ }
+
+ if (iostat)
+ { /* IOSTAT= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = ffecom_expr
+ (info->beru_spec[FFESTP_beruixIOSTAT].u.expr);
+ }
+ else if (ffeste_io_abort_ != NULL_TREE)
+ { /* no IOSTAT= but ERR= */
+ ffeste_io_iostat_is_temp_ = TRUE;
+ ffeste_io_iostat_
+ = ffecom_push_tempvar (ffecom_integer_type_node,
+ FFETARGET_charactersizeNONE, -1, FALSE);
+ }
+ else
+ { /* no IOSTAT=, or ERR= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = NULL_TREE;
+ }
+
+ /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ ffeste_io_call_ (ffecom_call_gfrt (rt, alist),
+ !ffeste_io_abort_is_temp_);
+
+ /* If we've got a temp label, generate its code here. */
+
+ if (ffeste_io_abort_is_temp_)
+ {
+ DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
+ emit_nop ();
+ expand_label (ffeste_io_abort_);
+
+ assert (ffeste_io_err_ == NULL_TREE);
+ }
+
+ /* If we've got a temp iostat, pop the temp. */
+
+ if (ffeste_io_iostat_is_temp_)
+ ffecom_pop_tempvar (ffeste_io_iostat_);
+
+ ffecom_pop_calltemps ();
+
+#undef specified
+
+ clear_momentary ();
+}
+
+#endif
+/* ffeste_do -- End of statement following DO-term-stmt etc
+
+ ffeste_do(TRUE);
+
+ Also invoked by _labeldef_branch_finish_ (or, in cases
+ of errors, other _labeldef_ functions) when the label definition is
+ for a DO-target (LOOPEND) label, once per matching/outstanding DO
+ block on the stack. These cases invoke this function with ok==TRUE, so
+ only forced stack popping (via ffeste_eof_()) invokes it with ok==FALSE. */
+
+void
+ffeste_do (ffestw block)
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ END_DO\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ if (ffestw_do_tvar (block) == 0)
+ expand_end_loop (); /* DO WHILE and just DO. */
+ else
+ ffeste_end_iterdo_ (ffestw_do_tvar (block),
+ ffestw_do_incr_saved (block),
+ ffestw_do_count_var (block));
+
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_end_R807 -- End of statement following logical IF
+
+ ffeste_end_R807(TRUE);
+
+ Applies ONLY to logical IF, not to IF-THEN. For example, does not
+ ffelex_token_kill the construct name for an IF-THEN block (the name
+ field is invalid for logical IF). ok==TRUE iff statement following
+ logical IF (substatement) is valid; else, statement is invalid or
+ stack forcibly popped due to ffeste_eof_(). */
+
+void
+ffeste_end_R807 ()
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ END_IF\n", dmpout); /* Also see ffeste_R806. */
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ expand_end_cond ();
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_labeldef_branch -- Generate "code" for branch label def
+
+ ffeste_labeldef_branch(label); */
+
+void
+ffeste_labeldef_branch (ffelab label)
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "+ label %lu\n", ffelab_value (label));
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree glabel;
+
+ glabel = ffecom_lookup_label (label);
+ assert (glabel != NULL_TREE);
+ if (TREE_CODE (glabel) == ERROR_MARK)
+ return;
+ assert (DECL_INITIAL (glabel) == NULL_TREE);
+ DECL_INITIAL (glabel) = error_mark_node;
+ DECL_SOURCE_FILE (glabel) = ffelab_definition_filename (label);
+ DECL_SOURCE_LINE (glabel) = ffelab_definition_filelinenum (label);
+ emit_nop ();
+ expand_label (glabel);
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_labeldef_format -- Generate "code" for FORMAT label def
+
+ ffeste_labeldef_format(label); */
+
+void
+ffeste_labeldef_format (ffelab label)
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "$ label %lu\n", ffelab_value (label));
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_label_formatdef_ = label;
+#else
+#error
+#endif
+}
+
+/* ffeste_R737A -- Assignment statement outside of WHERE
+
+ ffeste_R737A(dest_expr,source_expr); */
+
+void
+ffeste_R737A (ffebld dest, ffebld source)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ let ", dmpout);
+ ffebld_dump (dest);
+ fputs ("=", dmpout);
+ ffebld_dump (source);
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ ffecom_expand_let_stmt (dest, source);
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R803 -- Block IF (IF-THEN) statement
+
+ ffeste_R803(construct_name,expr,expr_token);
+
+ Make sure statement is valid here; implement. */
+
+void
+ffeste_R803 (ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ IF_block (", dmpout);
+ ffebld_dump (expr);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ expand_start_cond (ffecom_truth_value (ffecom_expr (expr)), 0);
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R804 -- ELSE IF statement
+
+ ffeste_R804(expr,expr_token,name_token);
+
+ Make sure ffeste_kind_ identifies an IF block. If not
+ NULL, make sure name_token gives the correct name. Implement the else
+ of the IF block. */
+
+void
+ffeste_R804 (ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ ELSE_IF (", dmpout);
+ ffebld_dump (expr);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ expand_start_elseif (ffecom_truth_value (ffecom_expr (expr)));
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R805 -- ELSE statement
+
+ ffeste_R805(name_token);
+
+ Make sure ffeste_kind_ identifies an IF block. If not
+ NULL, make sure name_token gives the correct name. Implement the ELSE
+ of the IF block. */
+
+void
+ffeste_R805 ()
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ ELSE\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ expand_start_else ();
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R806 -- End an IF-THEN
+
+ ffeste_R806(TRUE); */
+
+void
+ffeste_R806 ()
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ END_IF_then\n", dmpout); /* Also see ffeste_shriek_if_. */
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ expand_end_cond ();
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R807 -- Logical IF statement
+
+ ffeste_R807(expr,expr_token);
+
+ Make sure statement is valid here; implement. */
+
+void
+ffeste_R807 (ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ IF_logical (", dmpout);
+ ffebld_dump (expr);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ expand_start_cond (ffecom_truth_value (ffecom_expr (expr)), 0);
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R809 -- SELECT CASE statement
+
+ ffeste_R809(construct_name,expr,expr_token);
+
+ Make sure statement is valid here; implement. */
+
+void
+ffeste_R809 (ffestw block, ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ SELECT_CASE (", dmpout);
+ ffebld_dump (expr);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffecom_push_calltemps ();
+
+ {
+ tree texpr;
+
+ ffeste_emit_line_note_ ();
+
+ if ((expr == NULL)
+ || (ffeinfo_basictype (ffebld_info (expr))
+ == FFEINFO_basictypeANY))
+ {
+ ffestw_set_select_texpr (block, error_mark_node);
+ clear_momentary ();
+ }
+ else
+ {
+ texpr = ffecom_expr (expr);
+ if (ffeinfo_basictype (ffebld_info (expr))
+ != FFEINFO_basictypeCHARACTER)
+ {
+ expand_start_case (1, texpr, TREE_TYPE (texpr),
+ "SELECT CASE statement");
+ ffestw_set_select_texpr (block, texpr);
+ ffestw_set_select_break (block, FALSE);
+ push_momentary ();
+ }
+ else
+ {
+ ffebad_start_msg ("SELECT CASE on CHARACTER type (at %0) not supported -- sorry",
+ FFEBAD_severityFATAL);
+ ffebad_here (0, ffestw_line (block), ffestw_col (block));
+ ffebad_finish ();
+ ffestw_set_select_texpr (block, error_mark_node);
+ }
+ }
+ }
+
+ ffecom_pop_calltemps ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R810 -- CASE statement
+
+ ffeste_R810(case_value_range_list,name);
+
+ If casenum is 0, it's CASE DEFAULT. Else it's the case ranges at
+ the start of the first_stmt list in the select object at the top of
+ the stack that match casenum. */
+
+void
+ffeste_R810 (ffestw block, unsigned long casenum)
+{
+ ffestwSelect s = ffestw_select (block);
+ ffestwCase c;
+
+ ffeste_check_simple_ ();
+
+ if (s->first_stmt == (ffestwCase) &s->first_rel)
+ c = NULL;
+ else
+ c = s->first_stmt;
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ if ((c == NULL) || (casenum != c->casenum))
+ {
+ if (casenum == 0) /* Intentional CASE DEFAULT. */
+ fputs ("+ CASE_DEFAULT", dmpout);
+ }
+ else
+ {
+ bool comma = FALSE;
+
+ fputs ("+ CASE (", dmpout);
+ do
+ {
+ if (comma)
+ fputc (',', dmpout);
+ else
+ comma = TRUE;
+ if (c->low != NULL)
+ ffebld_constant_dump (c->low);
+ if (c->low != c->high)
+ {
+ fputc (':', dmpout);
+ if (c->high != NULL)
+ ffebld_constant_dump (c->high);
+ }
+ c = c->next_stmt;
+ /* Unlink prev. */
+ c->previous_stmt->previous_stmt->next_stmt = c;
+ c->previous_stmt = c->previous_stmt->previous_stmt;
+ }
+ while ((c != (ffestwCase) &s->first_rel) && (casenum == c->casenum));
+ fputc (')', dmpout);
+ }
+
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree texprlow;
+ tree texprhigh;
+ tree tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ int pushok;
+ tree duplicate;
+
+ ffeste_emit_line_note_ ();
+
+ if (TREE_CODE (ffestw_select_texpr (block)) == ERROR_MARK)
+ {
+ clear_momentary ();
+ return;
+ }
+
+ if (ffestw_select_break (block))
+ expand_exit_something ();
+ else
+ ffestw_set_select_break (block, TRUE);
+
+ if ((c == NULL) || (casenum != c->casenum))
+ {
+ if (casenum == 0) /* Intentional CASE DEFAULT. */
+ {
+ pushok = pushcase (NULL_TREE, 0, tlabel, &duplicate);
+ assert (pushok == 0);
+ }
+ }
+ else
+ do
+ {
+ texprlow = (c->low == NULL) ? NULL_TREE
+ : ffecom_constantunion (&ffebld_constant_union (c->low), s->type,
+ s->kindtype, ffecom_tree_type[s->type][s->kindtype]);
+ if (c->low != c->high)
+ {
+ texprhigh = (c->high == NULL) ? NULL_TREE
+ : ffecom_constantunion (&ffebld_constant_union (c->high),
+ s->type, s->kindtype, ffecom_tree_type[s->type][s->kindtype]);
+ pushok = pushcase_range (texprlow, texprhigh, convert,
+ tlabel, &duplicate);
+ }
+ else
+ pushok = pushcase (texprlow, convert, tlabel, &duplicate);
+ assert (pushok == 0);
+ c = c->next_stmt;
+ /* Unlink prev. */
+ c->previous_stmt->previous_stmt->next_stmt = c;
+ c->previous_stmt = c->previous_stmt->previous_stmt;
+ }
+ while ((c != (ffestwCase) &s->first_rel) && (casenum == c->casenum));
+
+ clear_momentary ();
+ } /* ~~~handle character, character*1 */
+#else
+#error
+#endif
+}
+
+/* ffeste_R811 -- End a SELECT
+
+ ffeste_R811(TRUE); */
+
+void
+ffeste_R811 (ffestw block)
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ END_SELECT\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+
+ if (TREE_CODE (ffestw_select_texpr (block)) == ERROR_MARK)
+ {
+ clear_momentary ();
+ return;
+ }
+
+ expand_end_case (ffestw_select_texpr (block));
+ pop_momentary ();
+ clear_momentary (); /* ~~~handle character and character*1 */
+#else
+#error
+#endif
+}
+
+/* Iterative DO statement. */
+
+void
+ffeste_R819A (ffestw block, ffelab label UNUSED, ffebld var,
+ ffebld start, ffelexToken start_token,
+ ffebld end, ffelexToken end_token,
+ ffebld incr, ffelexToken incr_token)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ if ((ffebld_op (incr) == FFEBLD_opCONTER)
+ && (ffebld_constant_is_zero (ffebld_conter (incr))))
+ {
+ ffebad_start (FFEBAD_DO_STEP_ZERO);
+ ffebad_here (0, ffelex_token_where_line (incr_token),
+ ffelex_token_where_column (incr_token));
+ ffebad_string ("Iterative DO loop");
+ ffebad_finish ();
+ /* Don't bother replacing it with 1 yet. */
+ }
+
+ if (label == NULL)
+ fputs ("+ DO_iterative_nonlabeled (", dmpout);
+ else
+ fprintf (dmpout, "+ DO_iterative_labeled %lu (", ffelab_value (label));
+ ffebld_dump (var);
+ fputc ('=', dmpout);
+ ffebld_dump (start);
+ fputc (',', dmpout);
+ ffebld_dump (end);
+ fputc (',', dmpout);
+ ffebld_dump (incr);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ /* Start the DO loop. */
+
+ ffeste_begin_iterdo_ (block, NULL, NULL, NULL,
+ var,
+ start, start_token,
+ end, end_token,
+ incr, incr_token,
+ "Iterative DO loop");
+
+ ffecom_pop_calltemps ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R819B -- DO WHILE statement
+
+ ffeste_R819B(construct_name,label_token,expr,expr_token);
+
+ Make sure statement is valid here; implement. */
+
+void
+ffeste_R819B (ffestw block, ffelab label UNUSED, ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ if (label == NULL)
+ fputs ("+ DO_WHILE_nonlabeled (", dmpout);
+ else
+ fprintf (dmpout, "+ DO_WHILE_labeled %lu (", ffelab_value (label));
+ ffebld_dump (expr);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ ffestw_set_do_hook (block, expand_start_loop (1));
+ ffestw_set_do_tvar (block, 0); /* Means DO WHILE vs. iter DO. */
+ if (expr != NULL)
+ expand_exit_loop_if_false (0, ffecom_truth_value (ffecom_expr (expr)));
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R825 -- END DO statement
+
+ ffeste_R825(name_token);
+
+ Make sure ffeste_kind_ identifies a DO block. If not
+ NULL, make sure name_token gives the correct name. Do whatever
+ is specific to seeing END DO with a DO-target label definition on it,
+ where the END DO is really treated as a CONTINUE (i.e. generate th
+ same code you would for CONTINUE). ffeste_do handles the actual
+ generation of end-loop code. */
+
+void
+ffeste_R825 ()
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ END_DO_sugar\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ emit_nop ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R834 -- CYCLE statement
+
+ ffeste_R834(name_token);
+
+ Handle a CYCLE within a loop. */
+
+void
+ffeste_R834 (ffestw block)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "+ CYCLE block #%lu\n", ffestw_blocknum (block));
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ expand_continue_loop (ffestw_do_hook (block));
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R835 -- EXIT statement
+
+ ffeste_R835(name_token);
+
+ Handle a EXIT within a loop. */
+
+void
+ffeste_R835 (ffestw block)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "+ EXIT block #%lu\n", ffestw_blocknum (block));
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ expand_exit_loop (ffestw_do_hook (block));
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R836 -- GOTO statement
+
+ ffeste_R836(label);
+
+ Make sure label_token identifies a valid label for a GOTO. Update
+ that label's info to indicate it is the target of a GOTO. */
+
+void
+ffeste_R836 (ffelab label)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "+ GOTO %lu\n", ffelab_value (label));
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree glabel;
+
+ ffeste_emit_line_note_ ();
+ glabel = ffecom_lookup_label (label);
+ if ((glabel != NULL_TREE)
+ && (TREE_CODE (glabel) != ERROR_MARK))
+ {
+ TREE_USED (glabel) = 1;
+ expand_goto (glabel);
+ clear_momentary ();
+ }
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R837 -- Computed GOTO statement
+
+ ffeste_R837(labels,count,expr);
+
+ Make sure label_list identifies valid labels for a GOTO. Update
+ each label's info to indicate it is the target of a GOTO. */
+
+void
+ffeste_R837 (ffelab *labels, int count, ffebld expr)
+{
+ int i;
+
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ CGOTO (", dmpout);
+ for (i = 0; i < count; ++i)
+ {
+ if (i != 0)
+ fputc (',', dmpout);
+ fprintf (dmpout, "%" ffelabValue_f "u", ffelab_value (labels[i]));
+ }
+ fputs ("),", dmpout);
+ ffebld_dump (expr);
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree texpr;
+ tree value;
+ tree tlabel;
+ int pushok;
+ tree duplicate;
+
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ texpr = ffecom_expr (expr);
+ expand_start_case (0, texpr, TREE_TYPE (texpr), "computed GOTO statement");
+ push_momentary (); /* In case of lots of labels, keep clearing
+ them out. */
+ for (i = 0; i < count; ++i)
+ {
+ value = build_int_2 (i + 1, 0);
+ tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+ pushok = pushcase (value, convert, tlabel, &duplicate);
+ assert (pushok == 0);
+ tlabel = ffecom_lookup_label (labels[i]);
+ if ((tlabel == NULL_TREE)
+ || (TREE_CODE (tlabel) == ERROR_MARK))
+ continue;
+ TREE_USED (tlabel) = 1;
+ expand_goto (tlabel);
+ clear_momentary ();
+ }
+ pop_momentary ();
+ expand_end_case (texpr);
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R838 -- ASSIGN statement
+
+ ffeste_R838(label_token,target_variable,target_token);
+
+ Make sure label_token identifies a valid label for an assignment. Update
+ that label's info to indicate it is the source of an assignment. Update
+ target_variable's info to indicate it is the target the assignment of that
+ label. */
+
+void
+ffeste_R838 (ffelab label, ffebld target)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "+ ASSIGN %lu TO ", ffelab_value (label));
+ ffebld_dump (target);
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree expr_tree;
+ tree label_tree;
+ tree target_tree;
+
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ label_tree = ffecom_lookup_label (label);
+ if ((label_tree != NULL_TREE)
+ && (TREE_CODE (label_tree) != ERROR_MARK))
+ {
+ label_tree = ffecom_1 (ADDR_EXPR,
+ build_pointer_type (void_type_node),
+ label_tree);
+ TREE_CONSTANT (label_tree) = 1;
+ target_tree = ffecom_expr_assign_w (target);
+ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (target_tree)))
+ < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (label_tree))))
+ error ("ASSIGN to variable that is too small");
+ label_tree = convert (TREE_TYPE (target_tree), label_tree);
+ expr_tree = ffecom_modify (void_type_node,
+ target_tree,
+ label_tree);
+ expand_expr_stmt (expr_tree);
+ clear_momentary ();
+ }
+
+ ffecom_pop_calltemps ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R839 -- Assigned GOTO statement
+
+ ffeste_R839(target,target_token,label_list);
+
+ Make sure label_list identifies valid labels for a GOTO. Update
+ each label's info to indicate it is the target of a GOTO. */
+
+void
+ffeste_R839 (ffebld target)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ AGOTO ", dmpout);
+ ffebld_dump (target);
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree t;
+
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ t = ffecom_expr_assign (target);
+ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
+ < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
+ error ("ASSIGNed GOTO target variable is too small");
+ expand_computed_goto (convert (TREE_TYPE (null_pointer_node), t));
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R840 -- Arithmetic IF statement
+
+ ffeste_R840(expr,expr_token,neg,zero,pos);
+
+ Make sure the labels are valid; implement. */
+
+void
+ffeste_R840 (ffebld expr, ffelab neg, ffelab zero, ffelab pos)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ IF_arithmetic (", dmpout);
+ ffebld_dump (expr);
+ fprintf (dmpout, ") %" ffelabValue_f "u,%" ffelabValue_f "u,%" ffelabValue_f "u\n",
+ ffelab_value (neg), ffelab_value (zero), ffelab_value (pos));
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree gneg = ffecom_lookup_label (neg);
+ tree gzero = ffecom_lookup_label (zero);
+ tree gpos = ffecom_lookup_label (pos);
+ tree texpr;
+
+ if ((gneg == NULL_TREE) || (gzero == NULL_TREE) || (gpos == NULL_TREE))
+ return;
+ if ((TREE_CODE (gneg) == ERROR_MARK)
+ || (TREE_CODE (gzero) == ERROR_MARK)
+ || (TREE_CODE (gpos) == ERROR_MARK))
+ return;
+
+ ffecom_push_calltemps ();
+
+ if (neg == zero)
+ if (neg == pos)
+ expand_goto (gzero);
+ else
+ { /* IF (expr.LE.0) THEN GOTO neg/zero ELSE
+ GOTO pos. */
+ texpr = ffecom_expr (expr);
+ texpr = ffecom_2 (LE_EXPR, integer_type_node,
+ texpr,
+ convert (TREE_TYPE (texpr),
+ integer_zero_node));
+ expand_start_cond (ffecom_truth_value (texpr), 0);
+ expand_goto (gzero);
+ expand_start_else ();
+ expand_goto (gpos);
+ expand_end_cond ();
+ }
+ else if (neg == pos)
+ { /* IF (expr.NE.0) THEN GOTO neg/pos ELSE GOTO
+ zero. */
+ texpr = ffecom_expr (expr);
+ texpr = ffecom_2 (NE_EXPR, integer_type_node,
+ texpr,
+ convert (TREE_TYPE (texpr),
+ integer_zero_node));
+ expand_start_cond (ffecom_truth_value (texpr), 0);
+ expand_goto (gneg);
+ expand_start_else ();
+ expand_goto (gzero);
+ expand_end_cond ();
+ }
+ else if (zero == pos)
+ { /* IF (expr.GE.0) THEN GOTO zero/pos ELSE
+ GOTO neg. */
+ texpr = ffecom_expr (expr);
+ texpr = ffecom_2 (GE_EXPR, integer_type_node,
+ texpr,
+ convert (TREE_TYPE (texpr),
+ integer_zero_node));
+ expand_start_cond (ffecom_truth_value (texpr), 0);
+ expand_goto (gzero);
+ expand_start_else ();
+ expand_goto (gneg);
+ expand_end_cond ();
+ }
+ else
+ { /* Use a SAVE_EXPR in combo with:
+ IF (expr.LT.0) THEN GOTO neg
+ ELSEIF (expr.GT.0) THEN GOTO pos
+ ELSE GOTO zero. */
+ tree expr_saved = ffecom_save_tree (ffecom_expr (expr));
+
+ texpr = ffecom_2 (LT_EXPR, integer_type_node,
+ expr_saved,
+ convert (TREE_TYPE (expr_saved),
+ integer_zero_node));
+ expand_start_cond (ffecom_truth_value (texpr), 0);
+ expand_goto (gneg);
+ texpr = ffecom_2 (GT_EXPR, integer_type_node,
+ expr_saved,
+ convert (TREE_TYPE (expr_saved),
+ integer_zero_node));
+ expand_start_elseif (ffecom_truth_value (texpr));
+ expand_goto (gpos);
+ expand_start_else ();
+ expand_goto (gzero);
+ expand_end_cond ();
+ }
+ ffeste_emit_line_note_ ();
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R841 -- CONTINUE statement
+
+ ffeste_R841(); */
+
+void
+ffeste_R841 ()
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ CONTINUE\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_emit_line_note_ ();
+ emit_nop ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R842 -- STOP statement
+
+ ffeste_R842(expr); */
+
+void
+ffeste_R842 (ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ if (expr == NULL)
+ {
+ fputs ("+ STOP\n", dmpout);
+ }
+ else
+ {
+ fputs ("+ STOP_coded ", dmpout);
+ ffebld_dump (expr);
+ fputc ('\n', dmpout);
+ }
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree callit;
+ ffelexToken msg;
+
+ ffeste_emit_line_note_ ();
+ if ((expr == NULL)
+ || (ffeinfo_basictype (ffebld_info (expr))
+ == FFEINFO_basictypeANY))
+ {
+ msg = ffelex_token_new_character ("", ffelex_token_where_line
+ (ffesta_tokens[0]), ffelex_token_where_column
+ (ffesta_tokens[0]));
+ expr = ffebld_new_conter (ffebld_constant_new_characterdefault
+ (msg));
+ ffelex_token_kill (msg);
+ ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
+ FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
+ FFEINFO_whereCONSTANT, 0));
+ }
+ else if (ffeinfo_basictype (ffebld_info (expr))
+ == FFEINFO_basictypeINTEGER)
+ {
+ char num[50];
+
+ assert (ffebld_op (expr) == FFEBLD_opCONTER);
+ assert (ffeinfo_kindtype (ffebld_info (expr))
+ == FFEINFO_kindtypeINTEGERDEFAULT);
+ sprintf (num, "%" ffetargetIntegerDefault_f "d",
+ ffebld_constant_integer1 (ffebld_conter (expr)));
+ msg = ffelex_token_new_character (num, ffelex_token_where_line
+ (ffesta_tokens[0]), ffelex_token_where_column
+ (ffesta_tokens[0]));
+ expr = ffebld_new_conter (ffebld_constant_new_characterdefault
+ (msg));
+ ffelex_token_kill (msg);
+ ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
+ FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
+ FFEINFO_whereCONSTANT, 0));
+ }
+ else
+ {
+ assert (ffeinfo_basictype (ffebld_info (expr))
+ == FFEINFO_basictypeCHARACTER);
+ assert (ffebld_op (expr) == FFEBLD_opCONTER);
+ assert (ffeinfo_kindtype (ffebld_info (expr))
+ == FFEINFO_kindtypeCHARACTERDEFAULT);
+ }
+
+ ffecom_push_calltemps ();
+ callit = ffecom_call_gfrt (FFECOM_gfrtSTOP,
+ ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)));
+ ffecom_pop_calltemps ();
+ TREE_SIDE_EFFECTS (callit) = 1;
+ expand_expr_stmt (callit);
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R843 -- PAUSE statement
+
+ ffeste_R843(expr,expr_token);
+
+ Make sure statement is valid here; implement. expr and expr_token are
+ both NULL if there was no expression. */
+
+void
+ffeste_R843 (ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ if (expr == NULL)
+ {
+ fputs ("+ PAUSE\n", dmpout);
+ }
+ else
+ {
+ fputs ("+ PAUSE_coded ", dmpout);
+ ffebld_dump (expr);
+ fputc ('\n', dmpout);
+ }
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree callit;
+ ffelexToken msg;
+
+ ffeste_emit_line_note_ ();
+ if ((expr == NULL)
+ || (ffeinfo_basictype (ffebld_info (expr))
+ == FFEINFO_basictypeANY))
+ {
+ msg = ffelex_token_new_character ("", ffelex_token_where_line
+ (ffesta_tokens[0]), ffelex_token_where_column
+ (ffesta_tokens[0]));
+ expr = ffebld_new_conter (ffebld_constant_new_characterdefault
+ (msg));
+ ffelex_token_kill (msg);
+ ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
+ FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
+ FFEINFO_whereCONSTANT, 0));
+ }
+ else if (ffeinfo_basictype (ffebld_info (expr))
+ == FFEINFO_basictypeINTEGER)
+ {
+ char num[50];
+
+ assert (ffebld_op (expr) == FFEBLD_opCONTER);
+ assert (ffeinfo_kindtype (ffebld_info (expr))
+ == FFEINFO_kindtypeINTEGERDEFAULT);
+ sprintf (num, "%" ffetargetIntegerDefault_f "d",
+ ffebld_constant_integer1 (ffebld_conter (expr)));
+ msg = ffelex_token_new_character (num, ffelex_token_where_line
+ (ffesta_tokens[0]), ffelex_token_where_column
+ (ffesta_tokens[0]));
+ expr = ffebld_new_conter (ffebld_constant_new_characterdefault
+ (msg));
+ ffelex_token_kill (msg);
+ ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
+ FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
+ FFEINFO_whereCONSTANT, 0));
+ }
+ else
+ {
+ assert (ffeinfo_basictype (ffebld_info (expr))
+ == FFEINFO_basictypeCHARACTER);
+ assert (ffebld_op (expr) == FFEBLD_opCONTER);
+ assert (ffeinfo_kindtype (ffebld_info (expr))
+ == FFEINFO_kindtypeCHARACTERDEFAULT);
+ }
+
+ ffecom_push_calltemps ();
+ callit = ffecom_call_gfrt (FFECOM_gfrtPAUSE,
+ ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)));
+ ffecom_pop_calltemps ();
+ TREE_SIDE_EFFECTS (callit) = 1;
+ expand_expr_stmt (callit);
+ clear_momentary ();
+ }
+#if 0 /* Old approach for phantom g77 run-time
+ library. */
+ {
+ tree callit;
+
+ ffeste_emit_line_note_ ();
+ if (expr == NULL)
+ callit = ffecom_call_gfrt (FFECOM_gfrtPAUSENIL, NULL_TREE);
+ else if (ffeinfo_basictype (ffebld_info (expr))
+ == FFEINFO_basictypeINTEGER)
+ {
+ ffecom_push_calltemps ();
+ callit = ffecom_call_gfrt (FFECOM_gfrtPAUSEINT,
+ ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)));
+ ffecom_pop_calltemps ();
+ }
+ else
+ {
+ if (ffeinfo_basictype (ffebld_info (expr))
+ != FFEINFO_basictypeCHARACTER)
+ break;
+ ffecom_push_calltemps ();
+ callit = ffecom_call_gfrt (FFECOM_gfrtPAUSECHAR,
+ ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)));
+ ffecom_pop_calltemps ();
+ }
+ TREE_SIDE_EFFECTS (callit) = 1;
+ expand_expr_stmt (callit);
+ clear_momentary ();
+ }
+#endif
+#else
+#error
+#endif
+}
+
+/* ffeste_R904 -- OPEN statement
+
+ ffeste_R904();
+
+ Make sure an OPEN is valid in the current context, and implement it. */
+
+void
+ffeste_R904 (ffestpOpenStmt *info)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ OPEN (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->open_spec[FFESTP_openixUNIT]);
+ ffeste_subr_file_ ("ACCESS", &info->open_spec[FFESTP_openixACCESS]);
+ ffeste_subr_file_ ("ACTION", &info->open_spec[FFESTP_openixACTION]);
+ ffeste_subr_file_ ("ASSOCIATEVARIABLE", &info->open_spec[FFESTP_openixASSOCIATEVARIABLE]);
+ ffeste_subr_file_ ("BLANK", &info->open_spec[FFESTP_openixBLANK]);
+ ffeste_subr_file_ ("BLOCKSIZE", &info->open_spec[FFESTP_openixBLOCKSIZE]);
+ ffeste_subr_file_ ("BUFFERCOUNT", &info->open_spec[FFESTP_openixBUFFERCOUNT]);
+ ffeste_subr_file_ ("CARRIAGECONTROL", &info->open_spec[FFESTP_openixCARRIAGECONTROL]);
+ ffeste_subr_file_ ("DEFAULTFILE", &info->open_spec[FFESTP_openixDEFAULTFILE]);
+ ffeste_subr_file_ ("DELIM", &info->open_spec[FFESTP_openixDELIM]);
+ ffeste_subr_file_ ("DISPOSE", &info->open_spec[FFESTP_openixDISPOSE]);
+ ffeste_subr_file_ ("ERR", &info->open_spec[FFESTP_openixERR]);
+ ffeste_subr_file_ ("EXTENDSIZE", &info->open_spec[FFESTP_openixEXTENDSIZE]);
+ ffeste_subr_file_ ("FILE", &info->open_spec[FFESTP_openixFILE]);
+ ffeste_subr_file_ ("FORM", &info->open_spec[FFESTP_openixFORM]);
+ ffeste_subr_file_ ("INITIALSIZE", &info->open_spec[FFESTP_openixINITIALSIZE]);
+ ffeste_subr_file_ ("IOSTAT", &info->open_spec[FFESTP_openixIOSTAT]);
+ ffeste_subr_file_ ("KEY", &info->open_spec[FFESTP_openixKEY]);
+ ffeste_subr_file_ ("MAXREC", &info->open_spec[FFESTP_openixMAXREC]);
+ ffeste_subr_file_ ("NOSPANBLOCKS", &info->open_spec[FFESTP_openixNOSPANBLOCKS]);
+ ffeste_subr_file_ ("ORGANIZATION", &info->open_spec[FFESTP_openixORGANIZATION]);
+ ffeste_subr_file_ ("PAD", &info->open_spec[FFESTP_openixPAD]);
+ ffeste_subr_file_ ("POSITION", &info->open_spec[FFESTP_openixPOSITION]);
+ ffeste_subr_file_ ("READONLY", &info->open_spec[FFESTP_openixREADONLY]);
+ ffeste_subr_file_ ("RECL", &info->open_spec[FFESTP_openixRECL]);
+ ffeste_subr_file_ ("RECORDTYPE", &info->open_spec[FFESTP_openixRECORDTYPE]);
+ ffeste_subr_file_ ("SHARED", &info->open_spec[FFESTP_openixSHARED]);
+ ffeste_subr_file_ ("STATUS", &info->open_spec[FFESTP_openixSTATUS]);
+ ffeste_subr_file_ ("USEROPEN", &info->open_spec[FFESTP_openixUSEROPEN]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree args;
+ bool iostat;
+ bool errl;
+
+#define specified(something) (info->open_spec[something].kw_or_val_present)
+
+ ffeste_emit_line_note_ ();
+
+ iostat = specified (FFESTP_openixIOSTAT);
+ errl = specified (FFESTP_openixERR);
+
+ ffecom_push_calltemps ();
+
+ args = ffeste_io_olist_ (errl || iostat,
+ info->open_spec[FFESTP_openixUNIT].u.expr,
+ &info->open_spec[FFESTP_openixFILE],
+ &info->open_spec[FFESTP_openixSTATUS],
+ &info->open_spec[FFESTP_openixACCESS],
+ &info->open_spec[FFESTP_openixFORM],
+ &info->open_spec[FFESTP_openixRECL],
+ &info->open_spec[FFESTP_openixBLANK]);
+
+ if (errl)
+ {
+ ffeste_io_err_
+ = ffeste_io_abort_
+ = ffecom_lookup_label
+ (info->open_spec[FFESTP_openixERR].u.label);
+ ffeste_io_abort_is_temp_ = FALSE;
+ }
+ else
+ {
+ ffeste_io_err_ = NULL_TREE;
+
+ if ((ffeste_io_abort_is_temp_ = iostat))
+ ffeste_io_abort_ = ffecom_temp_label ();
+ else
+ ffeste_io_abort_ = NULL_TREE;
+ }
+
+ if (iostat)
+ { /* IOSTAT= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = ffecom_expr
+ (info->open_spec[FFESTP_openixIOSTAT].u.expr);
+ }
+ else if (ffeste_io_abort_ != NULL_TREE)
+ { /* no IOSTAT= but ERR= */
+ ffeste_io_iostat_is_temp_ = TRUE;
+ ffeste_io_iostat_
+ = ffecom_push_tempvar (ffecom_integer_type_node,
+ FFETARGET_charactersizeNONE, -1, FALSE);
+ }
+ else
+ { /* no IOSTAT=, or ERR= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = NULL_TREE;
+ }
+
+ /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFOPEN, args),
+ !ffeste_io_abort_is_temp_);
+
+ /* If we've got a temp label, generate its code here. */
+
+ if (ffeste_io_abort_is_temp_)
+ {
+ DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
+ emit_nop ();
+ expand_label (ffeste_io_abort_);
+
+ assert (ffeste_io_err_ == NULL_TREE);
+ }
+
+ /* If we've got a temp iostat, pop the temp. */
+
+ if (ffeste_io_iostat_is_temp_)
+ ffecom_pop_tempvar (ffeste_io_iostat_);
+
+ ffecom_pop_calltemps ();
+
+#undef specified
+ }
+
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R907 -- CLOSE statement
+
+ ffeste_R907();
+
+ Make sure a CLOSE is valid in the current context, and implement it. */
+
+void
+ffeste_R907 (ffestpCloseStmt *info)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ CLOSE (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->close_spec[FFESTP_closeixUNIT]);
+ ffeste_subr_file_ ("ERR", &info->close_spec[FFESTP_closeixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->close_spec[FFESTP_closeixIOSTAT]);
+ ffeste_subr_file_ ("STATUS", &info->close_spec[FFESTP_closeixSTATUS]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree args;
+ bool iostat;
+ bool errl;
+
+#define specified(something) (info->close_spec[something].kw_or_val_present)
+
+ ffeste_emit_line_note_ ();
+
+ iostat = specified (FFESTP_closeixIOSTAT);
+ errl = specified (FFESTP_closeixERR);
+
+ ffecom_push_calltemps ();
+
+ args = ffeste_io_cllist_ (errl || iostat,
+ info->close_spec[FFESTP_closeixUNIT].u.expr,
+ &info->close_spec[FFESTP_closeixSTATUS]);
+
+ if (errl)
+ {
+ ffeste_io_err_
+ = ffeste_io_abort_
+ = ffecom_lookup_label
+ (info->close_spec[FFESTP_closeixERR].u.label);
+ ffeste_io_abort_is_temp_ = FALSE;
+ }
+ else
+ {
+ ffeste_io_err_ = NULL_TREE;
+
+ if ((ffeste_io_abort_is_temp_ = iostat))
+ ffeste_io_abort_ = ffecom_temp_label ();
+ else
+ ffeste_io_abort_ = NULL_TREE;
+ }
+
+ if (iostat)
+ { /* IOSTAT= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = ffecom_expr
+ (info->close_spec[FFESTP_closeixIOSTAT].u.expr);
+ }
+ else if (ffeste_io_abort_ != NULL_TREE)
+ { /* no IOSTAT= but ERR= */
+ ffeste_io_iostat_is_temp_ = TRUE;
+ ffeste_io_iostat_
+ = ffecom_push_tempvar (ffecom_integer_type_node,
+ FFETARGET_charactersizeNONE, -1, FALSE);
+ }
+ else
+ { /* no IOSTAT=, or ERR= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = NULL_TREE;
+ }
+
+ /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFCLOS, args),
+ !ffeste_io_abort_is_temp_);
+
+ /* If we've got a temp label, generate its code here. */
+
+ if (ffeste_io_abort_is_temp_)
+ {
+ DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
+ emit_nop ();
+ expand_label (ffeste_io_abort_);
+
+ assert (ffeste_io_err_ == NULL_TREE);
+ }
+
+ /* If we've got a temp iostat, pop the temp. */
+
+ if (ffeste_io_iostat_is_temp_)
+ ffecom_pop_tempvar (ffeste_io_iostat_);
+
+ ffecom_pop_calltemps ();
+
+#undef specified
+ }
+
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R909_start -- READ(...) statement list begin
+
+ ffeste_R909_start(FALSE);
+
+ Verify that READ is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_R909_start (ffestpReadStmt *info, bool only_format UNUSED,
+ ffestvUnit unit, ffestvFormat format, bool rec,
+ bool key UNUSED)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ switch (format)
+ {
+ case FFESTV_formatNONE:
+ if (rec)
+ fputs ("+ READ_ufdac", dmpout);
+ else if (key)
+ fputs ("+ READ_ufidx", dmpout);
+ else
+ fputs ("+ READ_ufseq", dmpout);
+ break;
+
+ case FFESTV_formatLABEL:
+ case FFESTV_formatCHAREXPR:
+ case FFESTV_formatINTEXPR:
+ if (rec)
+ fputs ("+ READ_fmdac", dmpout);
+ else if (key)
+ fputs ("+ READ_fmidx", dmpout);
+ else if (unit == FFESTV_unitCHAREXPR)
+ fputs ("+ READ_fmint", dmpout);
+ else
+ fputs ("+ READ_fmseq", dmpout);
+ break;
+
+ case FFESTV_formatASTERISK:
+ if (unit == FFESTV_unitCHAREXPR)
+ fputs ("+ READ_lsint", dmpout);
+ else
+ fputs ("+ READ_lsseq", dmpout);
+ break;
+
+ case FFESTV_formatNAMELIST:
+ fputs ("+ READ_nlseq", dmpout);
+ break;
+
+ default:
+ assert ("Unexpected kind of format item in R909 READ" == NULL);
+ }
+
+ if (only_format)
+ {
+ fputc (' ', dmpout);
+ ffeste_subr_file_ ("FORMAT", &info->read_spec[FFESTP_readixFORMAT]);
+ fputc (' ', dmpout);
+
+ return;
+ }
+
+ fputs (" (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->read_spec[FFESTP_readixUNIT]);
+ ffeste_subr_file_ ("FORMAT", &info->read_spec[FFESTP_readixFORMAT]);
+ ffeste_subr_file_ ("ADVANCE", &info->read_spec[FFESTP_readixADVANCE]);
+ ffeste_subr_file_ ("EOR", &info->read_spec[FFESTP_readixEOR]);
+ ffeste_subr_file_ ("ERR", &info->read_spec[FFESTP_readixERR]);
+ ffeste_subr_file_ ("END", &info->read_spec[FFESTP_readixEND]);
+ ffeste_subr_file_ ("IOSTAT", &info->read_spec[FFESTP_readixIOSTAT]);
+ ffeste_subr_file_ ("KEYEQ", &info->read_spec[FFESTP_readixKEYEQ]);
+ ffeste_subr_file_ ("KEYGE", &info->read_spec[FFESTP_readixKEYGE]);
+ ffeste_subr_file_ ("KEYGT", &info->read_spec[FFESTP_readixKEYGT]);
+ ffeste_subr_file_ ("KEYID", &info->read_spec[FFESTP_readixKEYID]);
+ ffeste_subr_file_ ("NULLS", &info->read_spec[FFESTP_readixNULLS]);
+ ffeste_subr_file_ ("REC", &info->read_spec[FFESTP_readixREC]);
+ ffeste_subr_file_ ("SIZE", &info->read_spec[FFESTP_readixSIZE]);
+ fputs (") ", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+
+#define specified(something) (info->read_spec[something].kw_or_val_present)
+
+ ffeste_emit_line_note_ ();
+
+ /* Do the real work. */
+
+ {
+ ffecomGfrt start;
+ ffecomGfrt end;
+ tree cilist;
+ bool iostat;
+ bool errl;
+ bool endl;
+
+ /* First determine the start, per-item, and end run-time functions to
+ call. The per-item function is picked by choosing an ffeste functio
+ to call to handle a given item; it knows how to generate a call to the
+ appropriate run-time function, and is called an "io driver". It
+ handles the implied-DO construct, for example. */
+
+ switch (format)
+ {
+ case FFESTV_formatNONE: /* no FMT= */
+ ffeste_io_driver_ = ffeste_io_douio_;
+ if (rec)
+ start = FFECOM_gfrtSRDUE, end = FFECOM_gfrtERDUE;
+#if 0
+ else if (key)
+ start = FFECOM_gfrtSRIUE, end = FFECOM_gfrtERIUE;
+#endif
+ else
+ start = FFECOM_gfrtSRSUE, end = FFECOM_gfrtERSUE;
+ break;
+
+ case FFESTV_formatLABEL: /* FMT=10 */
+ case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
+ case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
+ ffeste_io_driver_ = ffeste_io_dofio_;
+ if (rec)
+ start = FFECOM_gfrtSRDFE, end = FFECOM_gfrtERDFE;
+#if 0
+ else if (key)
+ start = FFECOM_gfrtSRIFE, end = FFECOM_gfrtERIFE;
+#endif
+ else if (unit == FFESTV_unitCHAREXPR)
+ start = FFECOM_gfrtSRSFI, end = FFECOM_gfrtERSFI;
+ else
+ start = FFECOM_gfrtSRSFE, end = FFECOM_gfrtERSFE;
+ break;
+
+ case FFESTV_formatASTERISK: /* FMT=* */
+ ffeste_io_driver_ = ffeste_io_dolio_;
+ if (unit == FFESTV_unitCHAREXPR)
+ start = FFECOM_gfrtSRSLI, end = FFECOM_gfrtERSLI;
+ else
+ start = FFECOM_gfrtSRSLE, end = FFECOM_gfrtERSLE;
+ break;
+
+ case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
+ /FOO/] */
+ ffeste_io_driver_ = NULL; /* No start or driver function. */
+ start = FFECOM_gfrtSRSNE, end = FFECOM_gfrt;
+ break;
+
+ default:
+ assert ("Weird stuff" == NULL);
+ start = FFECOM_gfrt, end = FFECOM_gfrt;
+ break;
+ }
+ ffeste_io_endgfrt_ = end;
+
+ iostat = specified (FFESTP_readixIOSTAT);
+ errl = specified (FFESTP_readixERR);
+ endl = specified (FFESTP_readixEND);
+
+ ffecom_push_calltemps ();
+
+ if (unit == FFESTV_unitCHAREXPR)
+ {
+ cilist = ffeste_io_icilist_ (errl || iostat,
+ info->read_spec[FFESTP_readixUNIT].u.expr,
+ endl || iostat, format,
+ &info->read_spec[FFESTP_readixFORMAT]);
+ }
+ else
+ {
+ cilist = ffeste_io_cilist_ (errl || iostat, unit,
+ info->read_spec[FFESTP_readixUNIT].u.expr,
+ 5, endl || iostat, format,
+ &info->read_spec[FFESTP_readixFORMAT],
+ rec,
+ info->read_spec[FFESTP_readixREC].u.expr);
+ }
+
+ if (errl)
+ { /* ERR= */
+ ffeste_io_err_
+ = ffecom_lookup_label
+ (info->read_spec[FFESTP_readixERR].u.label);
+
+ if (endl)
+ { /* ERR= END= */
+ ffeste_io_end_
+ = ffecom_lookup_label
+ (info->read_spec[FFESTP_readixEND].u.label);
+ ffeste_io_abort_is_temp_ = TRUE;
+ ffeste_io_abort_ = ffecom_temp_label ();
+ }
+ else
+ { /* ERR= but no END= */
+ ffeste_io_end_ = NULL_TREE;
+ if ((ffeste_io_abort_is_temp_ = iostat))
+ ffeste_io_abort_ = ffecom_temp_label ();
+ else
+ ffeste_io_abort_ = ffeste_io_err_;
+ }
+ }
+ else
+ { /* no ERR= */
+ ffeste_io_err_ = NULL_TREE;
+ if (endl)
+ { /* END= but no ERR= */
+ ffeste_io_end_
+ = ffecom_lookup_label
+ (info->read_spec[FFESTP_readixEND].u.label);
+ if ((ffeste_io_abort_is_temp_ = iostat))
+ ffeste_io_abort_ = ffecom_temp_label ();
+ else
+ ffeste_io_abort_ = ffeste_io_end_;
+ }
+ else
+ { /* no ERR= or END= */
+ ffeste_io_end_ = NULL_TREE;
+ if ((ffeste_io_abort_is_temp_ = iostat))
+ ffeste_io_abort_ = ffecom_temp_label ();
+ else
+ ffeste_io_abort_ = NULL_TREE;
+ }
+ }
+
+ if (iostat)
+ { /* IOSTAT= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = ffecom_expr
+ (info->read_spec[FFESTP_readixIOSTAT].u.expr);
+ }
+ else if (ffeste_io_abort_ != NULL_TREE)
+ { /* no IOSTAT= but ERR= or END= or both */
+ ffeste_io_iostat_is_temp_ = TRUE;
+ ffeste_io_iostat_
+ = ffecom_push_tempvar (ffecom_integer_type_node,
+ FFETARGET_charactersizeNONE, -1, FALSE);
+ }
+ else
+ { /* no IOSTAT=, ERR=, or END= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = NULL_TREE;
+ }
+
+ /* If there is no end function, then there are no item functions (i.e.
+ it's a NAMELIST), and vice versa by the way. In this situation, don't
+ generate the "if (iostat != 0) goto label;" if the label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ ffeste_io_call_ (ffecom_call_gfrt (start, cilist),
+ !ffeste_io_abort_is_temp_ || (end != FFECOM_gfrt));
+ }
+
+#undef specified
+
+ push_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R909_item -- READ statement i/o item
+
+ ffeste_R909_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_R909_item (ffebld expr, ffelexToken expr_token)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ if (expr == NULL)
+ return;
+ while (ffebld_op (expr) == FFEBLD_opPAREN)
+ expr = ffebld_left (expr); /* "READ *,(A)" -- really a bug in the user's
+ code, but I've been told lots of code does
+ this (blech)! */
+ if (ffebld_op (expr) == FFEBLD_opANY)
+ return;
+ if (ffebld_op (expr) == FFEBLD_opIMPDO)
+ ffeste_io_impdo_ (expr, expr_token);
+ else
+ ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE);
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R909_finish -- READ statement list complete
+
+ ffeste_R909_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_R909_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+
+ /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ {
+ if (ffeste_io_endgfrt_ != FFECOM_gfrt)
+ ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE),
+ !ffeste_io_abort_is_temp_);
+
+ clear_momentary ();
+ pop_momentary ();
+
+ /* If we've got a temp label, generate its code here and have it fan out
+ to the END= or ERR= label as appropriate. */
+
+ if (ffeste_io_abort_is_temp_)
+ {
+ DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
+ emit_nop ();
+ expand_label (ffeste_io_abort_);
+
+ /* if (iostat<0) goto end_label; */
+
+ if ((ffeste_io_end_ != NULL_TREE)
+ && (TREE_CODE (ffeste_io_end_) != ERROR_MARK))
+ {
+ expand_start_cond (ffecom_truth_value
+ (ffecom_2 (LT_EXPR, integer_type_node,
+ ffeste_io_iostat_,
+ ffecom_integer_zero_node)),
+ 0);
+ expand_goto (ffeste_io_end_);
+ expand_end_cond ();
+ }
+
+ /* if (iostat>0) goto err_label; */
+
+ if ((ffeste_io_err_ != NULL_TREE)
+ && (TREE_CODE (ffeste_io_err_) != ERROR_MARK))
+ {
+ expand_start_cond (ffecom_truth_value
+ (ffecom_2 (GT_EXPR, integer_type_node,
+ ffeste_io_iostat_,
+ ffecom_integer_zero_node)),
+ 0);
+ expand_goto (ffeste_io_err_);
+ expand_end_cond ();
+ }
+
+ }
+
+ /* If we've got a temp iostat, pop the temp. */
+
+ if (ffeste_io_iostat_is_temp_)
+ ffecom_pop_tempvar (ffeste_io_iostat_);
+
+ ffecom_pop_calltemps ();
+
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R910_start -- WRITE(...) statement list begin
+
+ ffeste_R910_start();
+
+ Verify that WRITE is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_R910_start (ffestpWriteStmt *info, ffestvUnit unit,
+ ffestvFormat format, bool rec)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ switch (format)
+ {
+ case FFESTV_formatNONE:
+ if (rec)
+ fputs ("+ WRITE_ufdac (", dmpout);
+ else
+ fputs ("+ WRITE_ufseq_or_idx (", dmpout);
+ break;
+
+ case FFESTV_formatLABEL:
+ case FFESTV_formatCHAREXPR:
+ case FFESTV_formatINTEXPR:
+ if (rec)
+ fputs ("+ WRITE_fmdac (", dmpout);
+ else if (unit == FFESTV_unitCHAREXPR)
+ fputs ("+ WRITE_fmint (", dmpout);
+ else
+ fputs ("+ WRITE_fmseq_or_idx (", dmpout);
+ break;
+
+ case FFESTV_formatASTERISK:
+ if (unit == FFESTV_unitCHAREXPR)
+ fputs ("+ WRITE_lsint (", dmpout);
+ else
+ fputs ("+ WRITE_lsseq (", dmpout);
+ break;
+
+ case FFESTV_formatNAMELIST:
+ fputs ("+ WRITE_nlseq (", dmpout);
+ break;
+
+ default:
+ assert ("Unexpected kind of format item in R910 WRITE" == NULL);
+ }
+
+ ffeste_subr_file_ ("UNIT", &info->write_spec[FFESTP_writeixUNIT]);
+ ffeste_subr_file_ ("FORMAT", &info->write_spec[FFESTP_writeixFORMAT]);
+ ffeste_subr_file_ ("ADVANCE", &info->write_spec[FFESTP_writeixADVANCE]);
+ ffeste_subr_file_ ("EOR", &info->write_spec[FFESTP_writeixEOR]);
+ ffeste_subr_file_ ("ERR", &info->write_spec[FFESTP_writeixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->write_spec[FFESTP_writeixIOSTAT]);
+ ffeste_subr_file_ ("REC", &info->write_spec[FFESTP_writeixREC]);
+ fputs (") ", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+
+#define specified(something) (info->write_spec[something].kw_or_val_present)
+
+ ffeste_emit_line_note_ ();
+
+ /* Do the real work. */
+
+ {
+ ffecomGfrt start;
+ ffecomGfrt end;
+ tree cilist;
+ bool iostat;
+ bool errl;
+
+ /* First determine the start, per-item, and end run-time functions to
+ call. The per-item function is picked by choosing an ffeste functio
+ to call to handle a given item; it knows how to generate a call to the
+ appropriate run-time function, and is called an "io driver". It
+ handles the implied-DO construct, for example. */
+
+ switch (format)
+ {
+ case FFESTV_formatNONE: /* no FMT= */
+ ffeste_io_driver_ = ffeste_io_douio_;
+ if (rec)
+ start = FFECOM_gfrtSWDUE, end = FFECOM_gfrtEWDUE;
+ else
+ start = FFECOM_gfrtSWSUE, end = FFECOM_gfrtEWSUE;
+ break;
+
+ case FFESTV_formatLABEL: /* FMT=10 */
+ case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
+ case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
+ ffeste_io_driver_ = ffeste_io_dofio_;
+ if (rec)
+ start = FFECOM_gfrtSWDFE, end = FFECOM_gfrtEWDFE;
+ else if (unit == FFESTV_unitCHAREXPR)
+ start = FFECOM_gfrtSWSFI, end = FFECOM_gfrtEWSFI;
+ else
+ start = FFECOM_gfrtSWSFE, end = FFECOM_gfrtEWSFE;
+ break;
+
+ case FFESTV_formatASTERISK: /* FMT=* */
+ ffeste_io_driver_ = ffeste_io_dolio_;
+ if (unit == FFESTV_unitCHAREXPR)
+ start = FFECOM_gfrtSWSLI, end = FFECOM_gfrtEWSLI;
+ else
+ start = FFECOM_gfrtSWSLE, end = FFECOM_gfrtEWSLE;
+ break;
+
+ case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
+ /FOO/] */
+ ffeste_io_driver_ = NULL; /* No start or driver function. */
+ start = FFECOM_gfrtSWSNE, end = FFECOM_gfrt;
+ break;
+
+ default:
+ assert ("Weird stuff" == NULL);
+ start = FFECOM_gfrt, end = FFECOM_gfrt;
+ break;
+ }
+ ffeste_io_endgfrt_ = end;
+
+ iostat = specified (FFESTP_writeixIOSTAT);
+ errl = specified (FFESTP_writeixERR);
+
+ ffecom_push_calltemps ();
+
+ if (unit == FFESTV_unitCHAREXPR)
+ {
+ cilist = ffeste_io_icilist_ (errl || iostat,
+ info->write_spec[FFESTP_writeixUNIT].u.expr,
+ FALSE, format,
+ &info->write_spec[FFESTP_writeixFORMAT]);
+ }
+ else
+ {
+ cilist = ffeste_io_cilist_ (errl || iostat, unit,
+ info->write_spec[FFESTP_writeixUNIT].u.expr,
+ 6, FALSE, format,
+ &info->write_spec[FFESTP_writeixFORMAT],
+ rec,
+ info->write_spec[FFESTP_writeixREC].u.expr);
+ }
+
+ ffeste_io_end_ = NULL_TREE;
+
+ if (errl)
+ { /* ERR= */
+ ffeste_io_err_
+ = ffeste_io_abort_
+ = ffecom_lookup_label
+ (info->write_spec[FFESTP_writeixERR].u.label);
+ ffeste_io_abort_is_temp_ = FALSE;
+ }
+ else
+ { /* no ERR= */
+ ffeste_io_err_ = NULL_TREE;
+
+ if ((ffeste_io_abort_is_temp_ = iostat))
+ ffeste_io_abort_ = ffecom_temp_label ();
+ else
+ ffeste_io_abort_ = NULL_TREE;
+ }
+
+ if (iostat)
+ { /* IOSTAT= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = ffecom_expr
+ (info->write_spec[FFESTP_writeixIOSTAT].u.expr);
+ }
+ else if (ffeste_io_abort_ != NULL_TREE)
+ { /* no IOSTAT= but ERR= */
+ ffeste_io_iostat_is_temp_ = TRUE;
+ ffeste_io_iostat_
+ = ffecom_push_tempvar (ffecom_integer_type_node,
+ FFETARGET_charactersizeNONE, -1, FALSE);
+ }
+ else
+ { /* no IOSTAT=, or ERR= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = NULL_TREE;
+ }
+
+ /* If there is no end function, then there are no item functions (i.e.
+ it's a NAMELIST), and vice versa by the way. In this situation, don't
+ generate the "if (iostat != 0) goto label;" if the label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ ffeste_io_call_ (ffecom_call_gfrt (start, cilist),
+ !ffeste_io_abort_is_temp_ || (end != FFECOM_gfrt));
+ }
+
+#undef specified
+
+ push_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R910_item -- WRITE statement i/o item
+
+ ffeste_R910_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_R910_item (ffebld expr, ffelexToken expr_token)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ if (expr == NULL)
+ return;
+ if (ffebld_op (expr) == FFEBLD_opANY)
+ return;
+ if (ffebld_op (expr) == FFEBLD_opIMPDO)
+ ffeste_io_impdo_ (expr, expr_token);
+ else
+ ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE);
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R910_finish -- WRITE statement list complete
+
+ ffeste_R910_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_R910_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+
+ /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ {
+ if (ffeste_io_endgfrt_ != FFECOM_gfrt)
+ ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE),
+ !ffeste_io_abort_is_temp_);
+
+ clear_momentary ();
+ pop_momentary ();
+
+ /* If we've got a temp label, generate its code here. */
+
+ if (ffeste_io_abort_is_temp_)
+ {
+ DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
+ emit_nop ();
+ expand_label (ffeste_io_abort_);
+
+ assert (ffeste_io_err_ == NULL_TREE);
+ }
+
+ /* If we've got a temp iostat, pop the temp. */
+
+ if (ffeste_io_iostat_is_temp_)
+ ffecom_pop_tempvar (ffeste_io_iostat_);
+
+ ffecom_pop_calltemps ();
+
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R911_start -- PRINT statement list begin
+
+ ffeste_R911_start();
+
+ Verify that PRINT is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_R911_start (ffestpPrintStmt *info, ffestvFormat format)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ switch (format)
+ {
+ case FFESTV_formatLABEL:
+ case FFESTV_formatCHAREXPR:
+ case FFESTV_formatINTEXPR:
+ fputs ("+ PRINT_fm ", dmpout);
+ break;
+
+ case FFESTV_formatASTERISK:
+ fputs ("+ PRINT_ls ", dmpout);
+ break;
+
+ case FFESTV_formatNAMELIST:
+ fputs ("+ PRINT_nl ", dmpout);
+ break;
+
+ default:
+ assert ("Unexpected kind of format item in R911 PRINT" == NULL);
+ }
+ ffeste_subr_file_ ("FORMAT", &info->print_spec[FFESTP_printixFORMAT]);
+ fputc (' ', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+
+ ffeste_emit_line_note_ ();
+
+ /* Do the real work. */
+
+ {
+ ffecomGfrt start;
+ ffecomGfrt end;
+ tree cilist;
+
+ /* First determine the start, per-item, and end run-time functions to
+ call. The per-item function is picked by choosing an ffeste functio
+ to call to handle a given item; it knows how to generate a call to the
+ appropriate run-time function, and is called an "io driver". It
+ handles the implied-DO construct, for example. */
+
+ switch (format)
+ {
+ case FFESTV_formatLABEL: /* FMT=10 */
+ case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
+ case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
+ ffeste_io_driver_ = ffeste_io_dofio_;
+ start = FFECOM_gfrtSWSFE, end = FFECOM_gfrtEWSFE;
+ break;
+
+ case FFESTV_formatASTERISK: /* FMT=* */
+ ffeste_io_driver_ = ffeste_io_dolio_;
+ start = FFECOM_gfrtSWSLE, end = FFECOM_gfrtEWSLE;
+ break;
+
+ case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
+ /FOO/] */
+ ffeste_io_driver_ = NULL; /* No start or driver function. */
+ start = FFECOM_gfrtSWSNE, end = FFECOM_gfrt;
+ break;
+
+ default:
+ assert ("Weird stuff" == NULL);
+ start = FFECOM_gfrt, end = FFECOM_gfrt;
+ break;
+ }
+ ffeste_io_endgfrt_ = end;
+
+ ffecom_push_calltemps ();
+
+ cilist = ffeste_io_cilist_ (FALSE, FFESTV_unitNONE, NULL, 6, FALSE, format,
+ &info->print_spec[FFESTP_printixFORMAT], FALSE, NULL);
+
+ ffeste_io_end_ = NULL_TREE;
+ ffeste_io_err_ = NULL_TREE;
+ ffeste_io_abort_ = NULL_TREE;
+ ffeste_io_abort_is_temp_ = FALSE;
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = NULL_TREE;
+
+ /* If there is no end function, then there are no item functions (i.e.
+ it's a NAMELIST), and vice versa by the way. In this situation, don't
+ generate the "if (iostat != 0) goto label;" if the label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ ffeste_io_call_ (ffecom_call_gfrt (start, cilist),
+ !ffeste_io_abort_is_temp_ || (end != FFECOM_gfrt));
+ }
+
+ push_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R911_item -- PRINT statement i/o item
+
+ ffeste_R911_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_R911_item (ffebld expr, ffelexToken expr_token)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ if (expr == NULL)
+ return;
+ if (ffebld_op (expr) == FFEBLD_opANY)
+ return;
+ if (ffebld_op (expr) == FFEBLD_opIMPDO)
+ ffeste_io_impdo_ (expr, expr_token);
+ else
+ ffeste_io_call_ ((*ffeste_io_driver_) (expr), FALSE);
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R911_finish -- PRINT statement list complete
+
+ ffeste_R911_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_R911_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ if (ffeste_io_endgfrt_ != FFECOM_gfrt)
+ ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE),
+ FALSE);
+
+ ffecom_pop_calltemps ();
+
+ clear_momentary ();
+ pop_momentary ();
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R919 -- BACKSPACE statement
+
+ ffeste_R919();
+
+ Make sure a BACKSPACE is valid in the current context, and implement it. */
+
+void
+ffeste_R919 (ffestpBeruStmt *info)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ BACKSPACE (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
+ ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_subr_beru_ (info, FFECOM_gfrtFBACK);
+#else
+#error
+#endif
+}
+
+/* ffeste_R920 -- ENDFILE statement
+
+ ffeste_R920();
+
+ Make sure a ENDFILE is valid in the current context, and implement it. */
+
+void
+ffeste_R920 (ffestpBeruStmt *info)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ ENDFILE (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
+ ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_subr_beru_ (info, FFECOM_gfrtFEND);
+#else
+#error
+#endif
+}
+
+/* ffeste_R921 -- REWIND statement
+
+ ffeste_R921();
+
+ Make sure a REWIND is valid in the current context, and implement it. */
+
+void
+ffeste_R921 (ffestpBeruStmt *info)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ REWIND (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
+ ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ ffeste_subr_beru_ (info, FFECOM_gfrtFREW);
+#else
+#error
+#endif
+}
+
+/* ffeste_R923A -- INQUIRE statement (non-IOLENGTH version)
+
+ ffeste_R923A(bool by_file);
+
+ Make sure an INQUIRE is valid in the current context, and implement it. */
+
+void
+ffeste_R923A (ffestpInquireStmt *info, bool by_file UNUSED)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ if (by_file)
+ {
+ fputs ("+ INQUIRE_file (", dmpout);
+ ffeste_subr_file_ ("FILE", &info->inquire_spec[FFESTP_inquireixFILE]);
+ }
+ else
+ {
+ fputs ("+ INQUIRE_unit (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->inquire_spec[FFESTP_inquireixUNIT]);
+ }
+ ffeste_subr_file_ ("ACCESS", &info->inquire_spec[FFESTP_inquireixACCESS]);
+ ffeste_subr_file_ ("ACTION", &info->inquire_spec[FFESTP_inquireixACTION]);
+ ffeste_subr_file_ ("BLANK", &info->inquire_spec[FFESTP_inquireixBLANK]);
+ ffeste_subr_file_ ("CARRIAGECONTROL", &info->inquire_spec[FFESTP_inquireixCARRIAGECONTROL]);
+ ffeste_subr_file_ ("DEFAULTFILE", &info->inquire_spec[FFESTP_inquireixDEFAULTFILE]);
+ ffeste_subr_file_ ("DELIM", &info->inquire_spec[FFESTP_inquireixDELIM]);
+ ffeste_subr_file_ ("DIRECT", &info->inquire_spec[FFESTP_inquireixDIRECT]);
+ ffeste_subr_file_ ("ERR", &info->inquire_spec[FFESTP_inquireixERR]);
+ ffeste_subr_file_ ("EXIST", &info->inquire_spec[FFESTP_inquireixEXIST]);
+ ffeste_subr_file_ ("FORM", &info->inquire_spec[FFESTP_inquireixFORM]);
+ ffeste_subr_file_ ("FORMATTED", &info->inquire_spec[FFESTP_inquireixFORMATTED]);
+ ffeste_subr_file_ ("IOSTAT", &info->inquire_spec[FFESTP_inquireixIOSTAT]);
+ ffeste_subr_file_ ("KEYED", &info->inquire_spec[FFESTP_inquireixKEYED]);
+ ffeste_subr_file_ ("NAME", &info->inquire_spec[FFESTP_inquireixNAME]);
+ ffeste_subr_file_ ("NAMED", &info->inquire_spec[FFESTP_inquireixNAMED]);
+ ffeste_subr_file_ ("NEXTREC", &info->inquire_spec[FFESTP_inquireixNEXTREC]);
+ ffeste_subr_file_ ("NUMBER", &info->inquire_spec[FFESTP_inquireixNUMBER]);
+ ffeste_subr_file_ ("OPENED", &info->inquire_spec[FFESTP_inquireixOPENED]);
+ ffeste_subr_file_ ("ORGANIZATION", &info->inquire_spec[FFESTP_inquireixORGANIZATION]);
+ ffeste_subr_file_ ("PAD", &info->inquire_spec[FFESTP_inquireixPAD]);
+ ffeste_subr_file_ ("POSITION", &info->inquire_spec[FFESTP_inquireixPOSITION]);
+ ffeste_subr_file_ ("READ", &info->inquire_spec[FFESTP_inquireixREAD]);
+ ffeste_subr_file_ ("READWRITE", &info->inquire_spec[FFESTP_inquireixREADWRITE]);
+ ffeste_subr_file_ ("RECL", &info->inquire_spec[FFESTP_inquireixRECL]);
+ ffeste_subr_file_ ("RECORDTYPE", &info->inquire_spec[FFESTP_inquireixRECORDTYPE]);
+ ffeste_subr_file_ ("SEQUENTIAL", &info->inquire_spec[FFESTP_inquireixSEQUENTIAL]);
+ ffeste_subr_file_ ("UNFORMATTED", &info->inquire_spec[FFESTP_inquireixUNFORMATTED]);
+ ffeste_subr_file_ ("WRITE", &info->inquire_spec[FFESTP_inquireixWRITE]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree args;
+ bool iostat;
+ bool errl;
+
+#define specified(something) (info->inquire_spec[something].kw_or_val_present)
+
+ ffeste_emit_line_note_ ();
+
+ iostat = specified (FFESTP_inquireixIOSTAT);
+ errl = specified (FFESTP_inquireixERR);
+
+ ffecom_push_calltemps ();
+
+ args = ffeste_io_inlist_ (errl || iostat,
+ &info->inquire_spec[FFESTP_inquireixUNIT],
+ &info->inquire_spec[FFESTP_inquireixFILE],
+ &info->inquire_spec[FFESTP_inquireixEXIST],
+ &info->inquire_spec[FFESTP_inquireixOPENED],
+ &info->inquire_spec[FFESTP_inquireixNUMBER],
+ &info->inquire_spec[FFESTP_inquireixNAMED],
+ &info->inquire_spec[FFESTP_inquireixNAME],
+ &info->inquire_spec[FFESTP_inquireixACCESS],
+ &info->inquire_spec[FFESTP_inquireixSEQUENTIAL],
+ &info->inquire_spec[FFESTP_inquireixDIRECT],
+ &info->inquire_spec[FFESTP_inquireixFORM],
+ &info->inquire_spec[FFESTP_inquireixFORMATTED],
+ &info->inquire_spec[FFESTP_inquireixUNFORMATTED],
+ &info->inquire_spec[FFESTP_inquireixRECL],
+ &info->inquire_spec[FFESTP_inquireixNEXTREC],
+ &info->inquire_spec[FFESTP_inquireixBLANK]);
+
+ if (errl)
+ {
+ ffeste_io_err_
+ = ffeste_io_abort_
+ = ffecom_lookup_label
+ (info->inquire_spec[FFESTP_inquireixERR].u.label);
+ ffeste_io_abort_is_temp_ = FALSE;
+ }
+ else
+ {
+ ffeste_io_err_ = NULL_TREE;
+
+ if ((ffeste_io_abort_is_temp_ = iostat))
+ ffeste_io_abort_ = ffecom_temp_label ();
+ else
+ ffeste_io_abort_ = NULL_TREE;
+ }
+
+ if (iostat)
+ { /* IOSTAT= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = ffecom_expr
+ (info->inquire_spec[FFESTP_inquireixIOSTAT].u.expr);
+ }
+ else if (ffeste_io_abort_ != NULL_TREE)
+ { /* no IOSTAT= but ERR= */
+ ffeste_io_iostat_is_temp_ = TRUE;
+ ffeste_io_iostat_
+ = ffecom_push_tempvar (ffecom_integer_type_node,
+ FFETARGET_charactersizeNONE, -1, FALSE);
+ }
+ else
+ { /* no IOSTAT=, or ERR= */
+ ffeste_io_iostat_is_temp_ = FALSE;
+ ffeste_io_iostat_ = NULL_TREE;
+ }
+
+ /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
+ label, since we're gonna fall through to there anyway. */
+
+ ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFINQU, args),
+ !ffeste_io_abort_is_temp_);
+
+ /* If we've got a temp label, generate its code here. */
+
+ if (ffeste_io_abort_is_temp_)
+ {
+ DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
+ emit_nop ();
+ expand_label (ffeste_io_abort_);
+
+ assert (ffeste_io_err_ == NULL_TREE);
+ }
+
+ /* If we've got a temp iostat, pop the temp. */
+
+ if (ffeste_io_iostat_is_temp_)
+ ffecom_pop_tempvar (ffeste_io_iostat_);
+
+ ffecom_pop_calltemps ();
+
+#undef specified
+ }
+
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R923B_start -- INQUIRE(IOLENGTH=expr) statement list begin
+
+ ffeste_R923B_start();
+
+ Verify that INQUIRE is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_R923B_start (ffestpInquireStmt *info UNUSED)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ INQUIRE (", dmpout);
+ ffeste_subr_file_ ("IOLENGTH", &info->inquire_spec[FFESTP_inquireixIOLENGTH]);
+ fputs (") ", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ assert ("INQUIRE(IOLENGTH=<var>) not implemented yet! ~~~" == NULL);
+ ffeste_emit_line_note_ ();
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R923B_item -- INQUIRE statement i/o item
+
+ ffeste_R923B_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_R923B_item (ffebld expr UNUSED)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R923B_finish -- INQUIRE statement list complete
+
+ ffeste_R923B_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_R923B_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ clear_momentary ();
+#else
+#error
+#endif
+}
+
+/* ffeste_R1001 -- FORMAT statement
+
+ ffeste_R1001(format_list); */
+
+void
+ffeste_R1001 (ffests s)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "$ FORMAT %.*s\n", (int) ffests_length (s), ffests_text (s));
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree t;
+ tree ttype;
+ tree maxindex;
+ tree var;
+
+ assert (ffeste_label_formatdef_ != NULL);
+
+ ffeste_emit_line_note_ ();
+
+ t = build_string (ffests_length (s), ffests_text (s));
+
+ TREE_TYPE (t)
+ = build_type_variant (build_array_type
+ (char_type_node,
+ build_range_type (integer_type_node,
+ integer_one_node,
+ build_int_2 (ffests_length (s),
+ 0))),
+ 1, 0);
+ TREE_CONSTANT (t) = 1;
+ TREE_STATIC (t) = 1;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ var = ffecom_lookup_label (ffeste_label_formatdef_);
+ if ((var != NULL_TREE)
+ && (TREE_CODE (var) == VAR_DECL))
+ {
+ DECL_INITIAL (var) = t;
+ maxindex = build_int_2 (ffests_length (s) - 1, 0);
+ ttype = TREE_TYPE (var);
+ TYPE_DOMAIN (ttype) = build_range_type (integer_type_node,
+ integer_zero_node,
+ maxindex);
+ if (!TREE_TYPE (maxindex))
+ TREE_TYPE (maxindex) = TYPE_DOMAIN (ttype);
+ layout_type (ttype);
+ rest_of_decl_compilation (var, NULL, 1, 0);
+ expand_decl (var);
+ expand_decl_init (var);
+ }
+
+ resume_temporary_allocation ();
+ pop_obstacks ();
+
+ ffeste_label_formatdef_ = NULL;
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R1103 -- End a PROGRAM
+
+ ffeste_R1103(); */
+
+void
+ffeste_R1103 ()
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ END_PROGRAM\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_R1112 -- End a BLOCK DATA
+
+ ffeste_R1112(TRUE); */
+
+void
+ffeste_R1112 ()
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("* END_BLOCK_DATA\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_R1212 -- CALL statement
+
+ ffeste_R1212(expr,expr_token);
+
+ Make sure statement is valid here; implement. */
+
+void
+ffeste_R1212 (ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ CALL ", dmpout);
+ ffebld_dump (expr);
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ ffebld args = ffebld_right (expr);
+ ffebld arg;
+ ffebld labels = NULL; /* First in list of LABTERs. */
+ ffebld prevlabels = NULL;
+ ffebld prevargs = NULL;
+
+ ffeste_emit_line_note_ ();
+
+ /* Here we split the list at ffebld_right(expr) into two lists: one at
+ ffebld_right(expr) consisting of all items that are not LABTERs, the
+ other at labels consisting of all items that are LABTERs. Then, if
+ the latter list is NULL, we have an ordinary call, else we have a call
+ with alternate returns. */
+
+ for (args = ffebld_right (expr); args != NULL; args = ffebld_trail (args))
+ {
+ if (((arg = ffebld_head (args)) == NULL)
+ || (ffebld_op (arg) != FFEBLD_opLABTER))
+ {
+ if (prevargs == NULL)
+ {
+ prevargs = args;
+ ffebld_set_right (expr, args);
+ }
+ else
+ {
+ ffebld_set_trail (prevargs, args);
+ prevargs = args;
+ }
+ }
+ else
+ {
+ if (prevlabels == NULL)
+ {
+ prevlabels = labels = args;
+ }
+ else
+ {
+ ffebld_set_trail (prevlabels, args);
+ prevlabels = args;
+ }
+ }
+ }
+ if (prevlabels == NULL)
+ labels = NULL;
+ else
+ ffebld_set_trail (prevlabels, NULL);
+ if (prevargs == NULL)
+ ffebld_set_right (expr, NULL);
+ else
+ ffebld_set_trail (prevargs, NULL);
+
+ if (labels == NULL)
+ expand_expr_stmt (ffecom_expr (expr));
+ else
+ {
+ tree texpr;
+ tree value;
+ tree tlabel;
+ int caseno;
+ int pushok;
+ tree duplicate;
+
+ texpr = ffecom_expr (expr);
+ expand_start_case (0, texpr, TREE_TYPE (texpr), "CALL statement");
+ push_momentary (); /* In case of many labels, keep 'em cleared
+ out. */
+ for (caseno = 1;
+ labels != NULL;
+ ++caseno, labels = ffebld_trail (labels))
+ {
+ value = build_int_2 (caseno, 0);
+ tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+ pushok = pushcase (value, convert, tlabel, &duplicate);
+ assert (pushok == 0);
+ tlabel
+ = ffecom_lookup_label (ffebld_labter (ffebld_head (labels)));
+ if ((tlabel == NULL_TREE)
+ || (TREE_CODE (tlabel) == ERROR_MARK))
+ continue;
+ TREE_USED (tlabel) = 1;
+ expand_goto (tlabel);
+ clear_momentary ();
+ }
+
+ pop_momentary ();
+ expand_end_case (texpr);
+ }
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R1221 -- End a FUNCTION
+
+ ffeste_R1221(TRUE); */
+
+void
+ffeste_R1221 ()
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ END_FUNCTION\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_R1225 -- End a SUBROUTINE
+
+ ffeste_R1225(TRUE); */
+
+void
+ffeste_R1225 ()
+{
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "+ END_SUBROUTINE\n");
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_R1226 -- ENTRY statement
+
+ ffeste_R1226(entryname,arglist,ending_token);
+
+ Make sure we're in a SUBROUTINE or FUNCTION, register arguments for the
+ entry point name, and so on. */
+
+void
+ffeste_R1226 (ffesymbol entry)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fprintf (dmpout, "+ ENTRY %s", ffesymbol_text (entry));
+ if (ffesymbol_dummyargs (entry) != NULL)
+ {
+ ffebld argh;
+
+ fputc ('(', dmpout);
+ for (argh = ffesymbol_dummyargs (entry);
+ argh != NULL;
+ argh = ffebld_trail (argh))
+ {
+ assert (ffebld_head (argh) != NULL);
+ switch (ffebld_op (ffebld_head (argh)))
+ {
+ case FFEBLD_opSYMTER:
+ fputs (ffesymbol_text (ffebld_symter (ffebld_head (argh))),
+ dmpout);
+ break;
+
+ case FFEBLD_opSTAR:
+ fputc ('*', dmpout);
+ break;
+
+ default:
+ fputc ('?', dmpout);
+ ffebld_dump (ffebld_head (argh));
+ fputc ('?', dmpout);
+ break;
+ }
+ if (ffebld_trail (argh) != NULL)
+ fputc (',', dmpout);
+ }
+ fputc (')', dmpout);
+ }
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree label = ffesymbol_hook (entry).length_tree;
+
+ ffeste_emit_line_note_ ();
+
+ DECL_INITIAL (label) = error_mark_node;
+ emit_nop ();
+ expand_label (label);
+
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_R1227 -- RETURN statement
+
+ ffeste_R1227(expr);
+
+ Make sure statement is valid here; implement. expr and expr_token are
+ both NULL if there was no expression. */
+
+void
+ffeste_R1227 (ffestw block UNUSED, ffebld expr)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ if (expr == NULL)
+ {
+ fputs ("+ RETURN\n", dmpout);
+ }
+ else
+ {
+ fputs ("+ RETURN_alternate ", dmpout);
+ ffebld_dump (expr);
+ fputc ('\n', dmpout);
+ }
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+ {
+ tree rtn;
+
+ ffeste_emit_line_note_ ();
+ ffecom_push_calltemps ();
+
+ rtn = ffecom_return_expr (expr);
+
+ if ((rtn == NULL_TREE)
+ || (rtn == error_mark_node))
+ expand_null_return ();
+ else
+ {
+ tree result = DECL_RESULT (current_function_decl);
+
+ if ((result != error_mark_node)
+ && (TREE_TYPE (result) != error_mark_node))
+ expand_return (ffecom_modify (NULL_TREE,
+ result,
+ convert (TREE_TYPE (result),
+ rtn)));
+ else
+ expand_null_return ();
+ }
+
+ ffecom_pop_calltemps ();
+ clear_momentary ();
+ }
+#else
+#error
+#endif
+}
+
+/* ffeste_V018_start -- REWRITE(...) statement list begin
+
+ ffeste_V018_start();
+
+ Verify that REWRITE is valid here, and begin accepting items in the
+ list. */
+
+#if FFESTR_VXT
+void
+ffeste_V018_start (ffestpRewriteStmt *info, ffestvFormat format)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ switch (format)
+ {
+ case FFESTV_formatNONE:
+ fputs ("+ REWRITE_uf (", dmpout);
+ break;
+
+ case FFESTV_formatLABEL:
+ case FFESTV_formatCHAREXPR:
+ case FFESTV_formatINTEXPR:
+ fputs ("+ REWRITE_fm (", dmpout);
+ break;
+
+ default:
+ assert ("Unexpected kind of format item in V018 REWRITE" == NULL);
+ }
+ ffeste_subr_file_ ("UNIT", &info->rewrite_spec[FFESTP_rewriteixUNIT]);
+ ffeste_subr_file_ ("FMT", &info->rewrite_spec[FFESTP_rewriteixFMT]);
+ ffeste_subr_file_ ("ERR", &info->rewrite_spec[FFESTP_rewriteixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->rewrite_spec[FFESTP_rewriteixIOSTAT]);
+ fputs (") ", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V018_item -- REWRITE statement i/o item
+
+ ffeste_V018_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_V018_item (ffebld expr)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V018_finish -- REWRITE statement list complete
+
+ ffeste_V018_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_V018_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V019_start -- ACCEPT statement list begin
+
+ ffeste_V019_start();
+
+ Verify that ACCEPT is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_V019_start (ffestpAcceptStmt *info, ffestvFormat format)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ switch (format)
+ {
+ case FFESTV_formatLABEL:
+ case FFESTV_formatCHAREXPR:
+ case FFESTV_formatINTEXPR:
+ fputs ("+ ACCEPT_fm ", dmpout);
+ break;
+
+ case FFESTV_formatASTERISK:
+ fputs ("+ ACCEPT_ls ", dmpout);
+ break;
+
+ case FFESTV_formatNAMELIST:
+ fputs ("+ ACCEPT_nl ", dmpout);
+ break;
+
+ default:
+ assert ("Unexpected kind of format item in V019 ACCEPT" == NULL);
+ }
+ ffeste_subr_file_ ("FORMAT", &info->accept_spec[FFESTP_acceptixFORMAT]);
+ fputc (' ', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V019_item -- ACCEPT statement i/o item
+
+ ffeste_V019_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_V019_item (ffebld expr)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V019_finish -- ACCEPT statement list complete
+
+ ffeste_V019_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_V019_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+#endif
+/* ffeste_V020_start -- TYPE statement list begin
+
+ ffeste_V020_start();
+
+ Verify that TYPE is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_V020_start (ffestpTypeStmt *info UNUSED,
+ ffestvFormat format UNUSED)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ switch (format)
+ {
+ case FFESTV_formatLABEL:
+ case FFESTV_formatCHAREXPR:
+ case FFESTV_formatINTEXPR:
+ fputs ("+ TYPE_fm ", dmpout);
+ break;
+
+ case FFESTV_formatASTERISK:
+ fputs ("+ TYPE_ls ", dmpout);
+ break;
+
+ case FFESTV_formatNAMELIST:
+ fputs ("* TYPE_nl ", dmpout);
+ break;
+
+ default:
+ assert ("Unexpected kind of format item in V020 TYPE" == NULL);
+ }
+ ffeste_subr_file_ ("FORMAT", &info->type_spec[FFESTP_typeixFORMAT]);
+ fputc (' ', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V020_item -- TYPE statement i/o item
+
+ ffeste_V020_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_V020_item (ffebld expr UNUSED)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V020_finish -- TYPE statement list complete
+
+ ffeste_V020_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_V020_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V021 -- DELETE statement
+
+ ffeste_V021();
+
+ Make sure a DELETE is valid in the current context, and implement it. */
+
+#if FFESTR_VXT
+void
+ffeste_V021 (ffestpDeleteStmt *info)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ DELETE (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->delete_spec[FFESTP_deleteixUNIT]);
+ ffeste_subr_file_ ("REC", &info->delete_spec[FFESTP_deleteixREC]);
+ ffeste_subr_file_ ("ERR", &info->delete_spec[FFESTP_deleteixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->delete_spec[FFESTP_deleteixIOSTAT]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V022 -- UNLOCK statement
+
+ ffeste_V022();
+
+ Make sure a UNLOCK is valid in the current context, and implement it. */
+
+void
+ffeste_V022 (ffestpBeruStmt *info)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ UNLOCK (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
+ ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V023_start -- ENCODE(...) statement list begin
+
+ ffeste_V023_start();
+
+ Verify that ENCODE is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_V023_start (ffestpVxtcodeStmt *info)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ ENCODE (", dmpout);
+ ffeste_subr_file_ ("C", &info->vxtcode_spec[FFESTP_vxtcodeixC]);
+ ffeste_subr_file_ ("F", &info->vxtcode_spec[FFESTP_vxtcodeixF]);
+ ffeste_subr_file_ ("B", &info->vxtcode_spec[FFESTP_vxtcodeixB]);
+ ffeste_subr_file_ ("ERR", &info->vxtcode_spec[FFESTP_vxtcodeixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->vxtcode_spec[FFESTP_vxtcodeixIOSTAT]);
+ fputs (") ", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V023_item -- ENCODE statement i/o item
+
+ ffeste_V023_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_V023_item (ffebld expr)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V023_finish -- ENCODE statement list complete
+
+ ffeste_V023_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_V023_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V024_start -- DECODE(...) statement list begin
+
+ ffeste_V024_start();
+
+ Verify that DECODE is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_V024_start (ffestpVxtcodeStmt *info)
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ DECODE (", dmpout);
+ ffeste_subr_file_ ("C", &info->vxtcode_spec[FFESTP_vxtcodeixC]);
+ ffeste_subr_file_ ("F", &info->vxtcode_spec[FFESTP_vxtcodeixF]);
+ ffeste_subr_file_ ("B", &info->vxtcode_spec[FFESTP_vxtcodeixB]);
+ ffeste_subr_file_ ("ERR", &info->vxtcode_spec[FFESTP_vxtcodeixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->vxtcode_spec[FFESTP_vxtcodeixIOSTAT]);
+ fputs (") ", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V024_item -- DECODE statement i/o item
+
+ ffeste_V024_item(expr,expr_token);
+
+ Implement output-list expression. */
+
+void
+ffeste_V024_item (ffebld expr)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (expr);
+ fputc (',', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V024_finish -- DECODE statement list complete
+
+ ffeste_V024_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_V024_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V025_start -- DEFINEFILE statement list begin
+
+ ffeste_V025_start();
+
+ Verify that DEFINEFILE is valid here, and begin accepting items in the
+ list. */
+
+void
+ffeste_V025_start ()
+{
+ ffeste_check_start_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ DEFINE_FILE ", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V025_item -- DEFINE FILE statement item
+
+ ffeste_V025_item(u,ut,m,mt,n,nt,asv,asvt);
+
+ Implement item. */
+
+void
+ffeste_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv)
+{
+ ffeste_check_item_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ ffebld_dump (u);
+ fputc ('(', dmpout);
+ ffebld_dump (m);
+ fputc (',', dmpout);
+ ffebld_dump (n);
+ fputs (",U,", dmpout);
+ ffebld_dump (asv);
+ fputs ("),", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V025_finish -- DEFINE FILE statement list complete
+
+ ffeste_V025_finish();
+
+ Just wrap up any local activities. */
+
+void
+ffeste_V025_finish ()
+{
+ ffeste_check_finish_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputc ('\n', dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+/* ffeste_V026 -- FIND statement
+
+ ffeste_V026();
+
+ Make sure a FIND is valid in the current context, and implement it. */
+
+void
+ffeste_V026 (ffestpFindStmt *info)
+{
+ ffeste_check_simple_ ();
+
+#if FFECOM_targetCURRENT == FFECOM_targetFFE
+ fputs ("+ FIND (", dmpout);
+ ffeste_subr_file_ ("UNIT", &info->find_spec[FFESTP_findixUNIT]);
+ ffeste_subr_file_ ("REC", &info->find_spec[FFESTP_findixREC]);
+ ffeste_subr_file_ ("ERR", &info->find_spec[FFESTP_findixERR]);
+ ffeste_subr_file_ ("IOSTAT", &info->find_spec[FFESTP_findixIOSTAT]);
+ fputs (")\n", dmpout);
+#elif FFECOM_targetCURRENT == FFECOM_targetGCC
+#else
+#error
+#endif
+}
+
+#endif