summaryrefslogtreecommitdiffstats
path: root/gcc/fortran/trans-io.c
diff options
context:
space:
mode:
authorpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-22 00:43:55 +0000
committerpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-22 00:43:55 +0000
commit6799e2f82d0b258f03b184224558ef22e73a0b6f (patch)
treeceecaee98023a95b8e6865056ce0fa2cc4afb927 /gcc/fortran/trans-io.c
parentd4e6d8361ae1fe9af98e8defb7c1be78d8d50e35 (diff)
downloadppe42-gcc-6799e2f82d0b258f03b184224558ef22e73a0b6f.tar.gz
ppe42-gcc-6799e2f82d0b258f03b184224558ef22e73a0b6f.zip
PR fortran/15750
* io.c (gfc_match_inquire): Bugfix for iolength related stuff. (gfc_resolve_inquire): Resolve the iolength tag. Return SUCCESS at end of function if no failure has occured. * resolve.c (resolve_code): Resolve if iolength is encountered. * trans-io.c: (ioparm_iolength, iocall_iolength, iocall_iolength_done): New variables. (last_dt): Add IOLENGTH. (gfc_build_io_library_fndecls ): Set iolength related variables. (gfc_trans_iolength): Implement. (gfc_trans_dt_end): Treat iolength as a third form of data transfer. libgfortran/ PR fortran/15750 * inquire.c (st_inquire): Add comment * io.h (st_parameter): Add iolength. (st_iolength, st_iolength_done): Declare. * transfer.c (iolength_transfer, iolength_transfer_init, st_iolength, st_iolength_done): New functions. testsuite/ * gfortran.fortran-torture/execute/iolength_1.f90: New test. * gfortran.fortran-torture/execute/iolength_3.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83472 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-io.c')
-rw-r--r--gcc/fortran/trans-io.c89
1 files changed, 76 insertions, 13 deletions
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index c0570fc8575..3f4076fc557 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -59,6 +59,7 @@ static GTY(()) tree ioparm_nextrec;
static GTY(()) tree ioparm_size;
static GTY(()) tree ioparm_recl_in;
static GTY(()) tree ioparm_recl_out;
+static GTY(()) tree ioparm_iolength;
static GTY(()) tree ioparm_file;
static GTY(()) tree ioparm_file_len;
static GTY(()) tree ioparm_status;
@@ -124,6 +125,8 @@ static GTY(()) tree iocall_x_complex;
static GTY(()) tree iocall_open;
static GTY(()) tree iocall_close;
static GTY(()) tree iocall_inquire;
+static GTY(()) tree iocall_iolength;
+static GTY(()) tree iocall_iolength_done;
static GTY(()) tree iocall_rewind;
static GTY(()) tree iocall_backspace;
static GTY(()) tree iocall_endfile;
@@ -136,7 +139,7 @@ static GTY(()) tree iocall_set_nml_val_log;
/* Variable for keeping track of what the last data transfer statement
was. Used for deciding which subroutine to call when the data
transfer is complete. */
-static enum { READ, WRITE } last_dt;
+static enum { READ, WRITE, IOLENGTH } last_dt;
#define ADD_FIELD(name, type) \
ioparm_ ## name = gfc_add_field_to_struct \
@@ -187,6 +190,8 @@ gfc_build_io_library_fndecls (void)
ADD_FIELD (recl_in, gfc_pint4_type_node);
ADD_FIELD (recl_out, gfc_pint4_type_node);
+ ADD_FIELD (iolength, gfc_pint4_type_node);
+
ADD_STRING (file);
ADD_STRING (status);
@@ -282,6 +287,10 @@ gfc_build_io_library_fndecls (void)
gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
gfc_int4_type_node, 0);
+ iocall_iolength =
+ gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
+ void_type_node, 0);
+
iocall_rewind =
gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
gfc_int4_type_node, 0);
@@ -302,6 +311,11 @@ gfc_build_io_library_fndecls (void)
iocall_write_done =
gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
gfc_int4_type_node, 0);
+
+ iocall_iolength_done =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
+ gfc_int4_type_node, 0);
+
iocall_set_nml_val_int =
gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_int")),
void_type_node, 4,
@@ -793,16 +807,6 @@ gfc_trans_inquire (gfc_code * code)
}
-/* Translate the IOLENGTH form of an INQUIRE statement. We treat
- this as a third sort of data transfer statement, except that
- lengths are summed instead of actually transfering any data. */
-
-tree
-gfc_trans_iolength (gfc_code * c ATTRIBUTE_UNUSED)
-{
- gfc_todo_error ("IOLENGTH statement");
-}
-
static gfc_expr *
gfc_new_nml_name_expr (char * name)
{
@@ -858,6 +862,8 @@ build_dt (tree * function, gfc_code * code)
set_error_locus (&block, &code->loc);
dt = code->ext.dt;
+ assert (dt != NULL);
+
if (dt->io_unit)
{
if (dt->io_unit->ts.type == BT_CHARACTER)
@@ -973,6 +979,41 @@ build_dt (tree * function, gfc_code * code)
}
+/* Translate the IOLENGTH form of an INQUIRE statement. We treat
+ this as a third sort of data transfer statement, except that
+ lengths are summed instead of actually transfering any data. */
+
+tree
+gfc_trans_iolength (gfc_code * code)
+{
+ stmtblock_t block;
+ gfc_inquire *inq;
+ tree dt;
+
+ gfc_init_block (&block);
+
+ set_error_locus (&block, &code->loc);
+
+ inq = code->ext.inquire;
+
+ /* First check that preconditions are met. */
+ assert(inq != NULL);
+ assert(inq->iolength != NULL);
+
+ /* Connect to the iolength variable. */
+ if (inq->iolength)
+ set_parameter_ref (&block, ioparm_iolength, inq->iolength);
+
+ /* Actual logic. */
+ last_dt = IOLENGTH;
+ dt = build_dt(&iocall_iolength, code);
+
+ gfc_add_expr_to_block (&block, dt);
+
+ return gfc_finish_block (&block);
+}
+
+
/* Translate a READ statement. */
tree
@@ -1005,12 +1046,33 @@ gfc_trans_dt_end (gfc_code * code)
gfc_init_block (&block);
- function = (last_dt == READ) ? iocall_read_done : iocall_write_done;
+ switch (last_dt)
+ {
+ case READ:
+ function = iocall_read_done;
+ break;
+
+ case WRITE:
+ function = iocall_write_done;
+ break;
+
+ case IOLENGTH:
+ function = iocall_iolength_done;
+ break;
+
+ default:
+ abort ();
+ }
tmp = gfc_build_function_call (function, NULL);
gfc_add_expr_to_block (&block, tmp);
- io_result (&block, code->ext.dt->err, code->ext.dt->end, code->ext.dt->eor);
+ if (last_dt != IOLENGTH)
+ {
+ assert(code->ext.dt != NULL);
+ io_result (&block, code->ext.dt->err,
+ code->ext.dt->end, code->ext.dt->eor);
+ }
return gfc_finish_block (&block);
}
@@ -1087,6 +1149,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
tmp = gfc_build_function_call (function, args);
gfc_add_expr_to_block (&se->pre, tmp);
gfc_add_block_to_block (&se->pre, &se->post);
+
}
OpenPOWER on IntegriCloud