diff options
author | pbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-22 00:43:55 +0000 |
---|---|---|
committer | pbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-22 00:43:55 +0000 |
commit | 6799e2f82d0b258f03b184224558ef22e73a0b6f (patch) | |
tree | ceecaee98023a95b8e6865056ce0fa2cc4afb927 /gcc/fortran/trans-io.c | |
parent | d4e6d8361ae1fe9af98e8defb7c1be78d8d50e35 (diff) | |
download | ppe42-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.c | 89 |
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); + } |