1 /* IO Code translation/library interface
2 Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Paul Brook
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 #include "coretypes.h"
27 #include "tree-gimple.h"
36 #include "trans-stmt.h"
37 #include "trans-array.h"
38 #include "trans-types.h"
39 #include "trans-const.h"
42 static GTY(()) tree gfc_pint4_type_node
;
44 /* Members of the ioparm structure. */
46 static GTY(()) tree ioparm_unit
;
47 static GTY(()) tree ioparm_err
;
48 static GTY(()) tree ioparm_end
;
49 static GTY(()) tree ioparm_eor
;
50 static GTY(()) tree ioparm_list_format
;
51 static GTY(()) tree ioparm_library_return
;
52 static GTY(()) tree ioparm_iostat
;
53 static GTY(()) tree ioparm_exist
;
54 static GTY(()) tree ioparm_opened
;
55 static GTY(()) tree ioparm_number
;
56 static GTY(()) tree ioparm_named
;
57 static GTY(()) tree ioparm_rec
;
58 static GTY(()) tree ioparm_nextrec
;
59 static GTY(()) tree ioparm_size
;
60 static GTY(()) tree ioparm_recl_in
;
61 static GTY(()) tree ioparm_recl_out
;
62 static GTY(()) tree ioparm_iolength
;
63 static GTY(()) tree ioparm_file
;
64 static GTY(()) tree ioparm_file_len
;
65 static GTY(()) tree ioparm_status
;
66 static GTY(()) tree ioparm_status_len
;
67 static GTY(()) tree ioparm_access
;
68 static GTY(()) tree ioparm_access_len
;
69 static GTY(()) tree ioparm_form
;
70 static GTY(()) tree ioparm_form_len
;
71 static GTY(()) tree ioparm_blank
;
72 static GTY(()) tree ioparm_blank_len
;
73 static GTY(()) tree ioparm_position
;
74 static GTY(()) tree ioparm_position_len
;
75 static GTY(()) tree ioparm_action
;
76 static GTY(()) tree ioparm_action_len
;
77 static GTY(()) tree ioparm_delim
;
78 static GTY(()) tree ioparm_delim_len
;
79 static GTY(()) tree ioparm_pad
;
80 static GTY(()) tree ioparm_pad_len
;
81 static GTY(()) tree ioparm_format
;
82 static GTY(()) tree ioparm_format_len
;
83 static GTY(()) tree ioparm_advance
;
84 static GTY(()) tree ioparm_advance_len
;
85 static GTY(()) tree ioparm_name
;
86 static GTY(()) tree ioparm_name_len
;
87 static GTY(()) tree ioparm_internal_unit
;
88 static GTY(()) tree ioparm_internal_unit_len
;
89 static GTY(()) tree ioparm_sequential
;
90 static GTY(()) tree ioparm_sequential_len
;
91 static GTY(()) tree ioparm_direct
;
92 static GTY(()) tree ioparm_direct_len
;
93 static GTY(()) tree ioparm_formatted
;
94 static GTY(()) tree ioparm_formatted_len
;
95 static GTY(()) tree ioparm_unformatted
;
96 static GTY(()) tree ioparm_unformatted_len
;
97 static GTY(()) tree ioparm_read
;
98 static GTY(()) tree ioparm_read_len
;
99 static GTY(()) tree ioparm_write
;
100 static GTY(()) tree ioparm_write_len
;
101 static GTY(()) tree ioparm_readwrite
;
102 static GTY(()) tree ioparm_readwrite_len
;
103 static GTY(()) tree ioparm_namelist_name
;
104 static GTY(()) tree ioparm_namelist_name_len
;
105 static GTY(()) tree ioparm_namelist_read_mode
;
107 /* The global I/O variables */
109 static GTY(()) tree ioparm_var
;
110 static GTY(()) tree locus_file
;
111 static GTY(()) tree locus_line
;
114 /* Library I/O subroutines */
116 static GTY(()) tree iocall_read
;
117 static GTY(()) tree iocall_read_done
;
118 static GTY(()) tree iocall_write
;
119 static GTY(()) tree iocall_write_done
;
120 static GTY(()) tree iocall_x_integer
;
121 static GTY(()) tree iocall_x_logical
;
122 static GTY(()) tree iocall_x_character
;
123 static GTY(()) tree iocall_x_real
;
124 static GTY(()) tree iocall_x_complex
;
125 static GTY(()) tree iocall_open
;
126 static GTY(()) tree iocall_close
;
127 static GTY(()) tree iocall_inquire
;
128 static GTY(()) tree iocall_iolength
;
129 static GTY(()) tree iocall_iolength_done
;
130 static GTY(()) tree iocall_rewind
;
131 static GTY(()) tree iocall_backspace
;
132 static GTY(()) tree iocall_endfile
;
133 static GTY(()) tree iocall_set_nml_val_int
;
134 static GTY(()) tree iocall_set_nml_val_float
;
135 static GTY(()) tree iocall_set_nml_val_char
;
136 static GTY(()) tree iocall_set_nml_val_complex
;
137 static GTY(()) tree iocall_set_nml_val_log
;
139 /* Variable for keeping track of what the last data transfer statement
140 was. Used for deciding which subroutine to call when the data
141 transfer is complete. */
142 static enum { READ
, WRITE
, IOLENGTH
} last_dt
;
144 #define ADD_FIELD(name, type) \
145 ioparm_ ## name = gfc_add_field_to_struct \
146 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
147 get_identifier (stringize(name)), type)
149 #define ADD_STRING(name) \
150 ioparm_ ## name = gfc_add_field_to_struct \
151 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
152 get_identifier (stringize(name)), pchar_type_node); \
153 ioparm_ ## name ## _len = gfc_add_field_to_struct \
154 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
155 get_identifier (stringize(name) "_len"), gfc_int4_type_node)
158 /* Create function decls for IO library functions. */
161 gfc_build_io_library_fndecls (void)
165 gfc_pint4_type_node
= build_pointer_type (gfc_int4_type_node
);
167 /* Build the st_parameter structure. Information associated with I/O
168 calls are transferred here. This must match the one defined in the
171 ioparm_type
= make_node (RECORD_TYPE
);
172 TYPE_NAME (ioparm_type
) = get_identifier ("_gfc_ioparm");
174 ADD_FIELD (unit
, gfc_int4_type_node
);
175 ADD_FIELD (err
, gfc_int4_type_node
);
176 ADD_FIELD (end
, gfc_int4_type_node
);
177 ADD_FIELD (eor
, gfc_int4_type_node
);
178 ADD_FIELD (list_format
, gfc_int4_type_node
);
179 ADD_FIELD (library_return
, gfc_int4_type_node
);
181 ADD_FIELD (iostat
, gfc_pint4_type_node
);
182 ADD_FIELD (exist
, gfc_pint4_type_node
);
183 ADD_FIELD (opened
, gfc_pint4_type_node
);
184 ADD_FIELD (number
, gfc_pint4_type_node
);
185 ADD_FIELD (named
, gfc_pint4_type_node
);
186 ADD_FIELD (rec
, gfc_pint4_type_node
);
187 ADD_FIELD (nextrec
, gfc_pint4_type_node
);
188 ADD_FIELD (size
, gfc_pint4_type_node
);
190 ADD_FIELD (recl_in
, gfc_pint4_type_node
);
191 ADD_FIELD (recl_out
, gfc_pint4_type_node
);
193 ADD_FIELD (iolength
, gfc_pint4_type_node
);
201 ADD_STRING (position
);
206 ADD_STRING (advance
);
208 ADD_STRING (internal_unit
);
209 ADD_STRING (sequential
);
212 ADD_STRING (formatted
);
213 ADD_STRING (unformatted
);
216 ADD_STRING (readwrite
);
218 ADD_STRING (namelist_name
);
219 ADD_FIELD (namelist_read_mode
, gfc_int4_type_node
);
221 gfc_finish_type (ioparm_type
);
223 ioparm_var
= build_decl (VAR_DECL
, get_identifier (PREFIX("ioparm")),
225 DECL_EXTERNAL (ioparm_var
) = 1;
226 TREE_PUBLIC (ioparm_var
) = 1;
228 locus_line
= build_decl (VAR_DECL
, get_identifier (PREFIX("line")),
230 DECL_EXTERNAL (locus_line
) = 1;
231 TREE_PUBLIC (locus_line
) = 1;
233 locus_file
= build_decl (VAR_DECL
, get_identifier (PREFIX("filename")),
235 DECL_EXTERNAL (locus_file
) = 1;
236 TREE_PUBLIC (locus_file
) = 1;
238 /* Define the transfer functions. */
241 gfc_build_library_function_decl (get_identifier
242 (PREFIX("transfer_integer")),
243 void_type_node
, 2, pvoid_type_node
,
247 gfc_build_library_function_decl (get_identifier
248 (PREFIX("transfer_logical")),
249 void_type_node
, 2, pvoid_type_node
,
253 gfc_build_library_function_decl (get_identifier
254 (PREFIX("transfer_character")),
255 void_type_node
, 2, pvoid_type_node
,
259 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
261 pvoid_type_node
, gfc_int4_type_node
);
264 gfc_build_library_function_decl (get_identifier
265 (PREFIX("transfer_complex")),
266 void_type_node
, 2, pvoid_type_node
,
269 /* Library entry points */
272 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
276 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
279 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
283 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
287 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
288 gfc_int4_type_node
, 0);
291 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
295 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
296 gfc_int4_type_node
, 0);
299 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
300 gfc_int4_type_node
, 0);
303 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
304 gfc_int4_type_node
, 0);
305 /* Library helpers */
308 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
309 gfc_int4_type_node
, 0);
312 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
313 gfc_int4_type_node
, 0);
315 iocall_iolength_done
=
316 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
317 gfc_int4_type_node
, 0);
319 iocall_set_nml_val_int
=
320 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_int")),
322 pvoid_type_node
, pvoid_type_node
,
323 gfc_int4_type_node
,gfc_int4_type_node
);
325 iocall_set_nml_val_float
=
326 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_float")),
328 pvoid_type_node
, pvoid_type_node
,
329 gfc_int4_type_node
,gfc_int4_type_node
);
330 iocall_set_nml_val_char
=
331 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_char")),
333 pvoid_type_node
, pvoid_type_node
,
334 gfc_int4_type_node
,gfc_int4_type_node
);
335 iocall_set_nml_val_complex
=
336 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_complex")),
338 pvoid_type_node
, pvoid_type_node
,
339 gfc_int4_type_node
,gfc_int4_type_node
);
340 iocall_set_nml_val_log
=
341 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_log")),
343 pvoid_type_node
, pvoid_type_node
,
344 gfc_int4_type_node
,gfc_int4_type_node
);
349 /* Generate code to store an non-string I/O parameter into the
350 ioparm structure. This is a pass by value. */
353 set_parameter_value (stmtblock_t
* block
, tree var
, gfc_expr
* e
)
358 gfc_init_se (&se
, NULL
);
359 gfc_conv_expr_type (&se
, e
, TREE_TYPE (var
));
360 gfc_add_block_to_block (block
, &se
.pre
);
362 tmp
= build (COMPONENT_REF
, TREE_TYPE (var
), ioparm_var
, var
, NULL_TREE
);
363 gfc_add_modify_expr (block
, tmp
, se
.expr
);
367 /* Generate code to store an non-string I/O parameter into the
368 ioparm structure. This is pass by reference. */
371 set_parameter_ref (stmtblock_t
* block
, tree var
, gfc_expr
* e
)
376 gfc_init_se (&se
, NULL
);
379 gfc_conv_expr_type (&se
, e
, TREE_TYPE (var
));
380 gfc_add_block_to_block (block
, &se
.pre
);
382 tmp
= build (COMPONENT_REF
, TREE_TYPE (var
), ioparm_var
, var
, NULL_TREE
);
383 gfc_add_modify_expr (block
, tmp
, se
.expr
);
387 /* Generate code to store a string and its length into the
391 set_string (stmtblock_t
* block
, stmtblock_t
* postblock
, tree var
,
392 tree var_len
, gfc_expr
* e
)
400 gfc_init_se (&se
, NULL
);
401 gfc_conv_expr (&se
, e
);
403 io
= build (COMPONENT_REF
, TREE_TYPE (var
), ioparm_var
, var
, NULL_TREE
);
404 len
= build (COMPONENT_REF
, TREE_TYPE (var_len
), ioparm_var
, var_len
,
407 /* Integer variable assigned a format label. */
408 if (e
->ts
.type
== BT_INTEGER
&& e
->symtree
->n
.sym
->attr
.assign
== 1)
411 gfc_build_string_const (37, "Assigned label is not a format label");
412 tmp
= GFC_DECL_STRING_LEN (se
.expr
);
413 tmp
= build (LE_EXPR
, boolean_type_node
, tmp
, integer_minus_one_node
);
414 gfc_trans_runtime_check (tmp
, msg
, &se
.pre
);
415 gfc_add_modify_expr (&se
.pre
, io
, GFC_DECL_ASSIGN_ADDR (se
.expr
));
416 gfc_add_modify_expr (&se
.pre
, len
, GFC_DECL_STRING_LEN (se
.expr
));
420 gfc_conv_string_parameter (&se
);
421 gfc_add_modify_expr (&se
.pre
, io
, se
.expr
);
422 gfc_add_modify_expr (&se
.pre
, len
, se
.string_length
);
425 gfc_add_block_to_block (block
, &se
.pre
);
426 gfc_add_block_to_block (postblock
, &se
.post
);
431 /* Set a member of the ioparm structure to one. */
433 set_flag (stmtblock_t
*block
, tree var
)
437 tmp
= build (COMPONENT_REF
, TREE_TYPE(var
), ioparm_var
, var
, NULL_TREE
);
438 gfc_add_modify_expr (block
, tmp
, integer_one_node
);
442 /* Add a case to a IO-result switch. */
445 add_case (int label_value
, gfc_st_label
* label
, stmtblock_t
* body
)
450 return; /* No label, no case */
452 value
= build_int_2 (label_value
, 0);
454 /* Make a backend label for this case. */
455 tmp
= build_decl (LABEL_DECL
, NULL_TREE
, NULL_TREE
);
456 DECL_CONTEXT (tmp
) = current_function_decl
;
458 /* And the case itself. */
459 tmp
= build_v (CASE_LABEL_EXPR
, value
, NULL_TREE
, tmp
);
460 gfc_add_expr_to_block (body
, tmp
);
462 /* Jump to the label. */
463 tmp
= build1_v (GOTO_EXPR
, gfc_get_label_decl (label
));
464 gfc_add_expr_to_block (body
, tmp
);
468 /* Generate a switch statement that branches to the correct I/O
469 result label. The last statement of an I/O call stores the
470 result into a variable because there is often cleanup that
471 must be done before the switch, so a temporary would have to
472 be created anyway. */
475 io_result (stmtblock_t
* block
, gfc_st_label
* err_label
,
476 gfc_st_label
* end_label
, gfc_st_label
* eor_label
)
481 /* If no labels are specified, ignore the result instead
482 of building an empty switch. */
483 if (err_label
== NULL
485 && eor_label
== NULL
)
488 /* Build a switch statement. */
489 gfc_start_block (&body
);
491 /* The label values here must be the same as the values
492 in the library_return enum in the runtime library */
493 add_case (1, err_label
, &body
);
494 add_case (2, end_label
, &body
);
495 add_case (3, eor_label
, &body
);
497 tmp
= gfc_finish_block (&body
);
499 rc
= build (COMPONENT_REF
, TREE_TYPE (ioparm_library_return
), ioparm_var
,
500 ioparm_library_return
, NULL_TREE
);
502 tmp
= build_v (SWITCH_EXPR
, rc
, tmp
, NULL_TREE
);
504 gfc_add_expr_to_block (block
, tmp
);
508 /* Store the current file and line number to variables so that if a
509 library call goes awry, we can tell the user where the problem is. */
512 set_error_locus (stmtblock_t
* block
, locus
* where
)
519 tmp
= gfc_build_string_const (strlen (f
->filename
) + 1, f
->filename
);
521 tmp
= gfc_build_addr_expr (pchar_type_node
, tmp
);
522 gfc_add_modify_expr (block
, locus_file
, tmp
);
524 line
= where
->lb
->linenum
;
525 gfc_add_modify_expr (block
, locus_line
, build_int_2 (line
, 0));
529 /* Translate an OPEN statement. */
532 gfc_trans_open (gfc_code
* code
)
534 stmtblock_t block
, post_block
;
538 gfc_init_block (&block
);
539 gfc_init_block (&post_block
);
541 set_error_locus (&block
, &code
->loc
);
545 set_parameter_value (&block
, ioparm_unit
, p
->unit
);
548 set_string (&block
, &post_block
, ioparm_file
, ioparm_file_len
, p
->file
);
551 set_string (&block
, &post_block
, ioparm_status
,
552 ioparm_status_len
, p
->status
);
555 set_string (&block
, &post_block
, ioparm_access
,
556 ioparm_access_len
, p
->access
);
559 set_string (&block
, &post_block
, ioparm_form
, ioparm_form_len
, p
->form
);
562 set_parameter_value (&block
, ioparm_recl_in
, p
->recl
);
565 set_string (&block
, &post_block
, ioparm_blank
, ioparm_blank_len
,
569 set_string (&block
, &post_block
, ioparm_position
,
570 ioparm_position_len
, p
->position
);
573 set_string (&block
, &post_block
, ioparm_action
,
574 ioparm_action_len
, p
->action
);
577 set_string (&block
, &post_block
, ioparm_delim
, ioparm_delim_len
,
581 set_string (&block
, &post_block
, ioparm_pad
, ioparm_pad_len
, p
->pad
);
584 set_parameter_ref (&block
, ioparm_iostat
, p
->iostat
);
587 set_flag (&block
, ioparm_err
);
589 tmp
= gfc_build_function_call (iocall_open
, NULL_TREE
);
590 gfc_add_expr_to_block (&block
, tmp
);
592 gfc_add_block_to_block (&block
, &post_block
);
594 io_result (&block
, p
->err
, NULL
, NULL
);
596 return gfc_finish_block (&block
);
600 /* Translate a CLOSE statement. */
603 gfc_trans_close (gfc_code
* code
)
605 stmtblock_t block
, post_block
;
609 gfc_init_block (&block
);
610 gfc_init_block (&post_block
);
612 set_error_locus (&block
, &code
->loc
);
616 set_parameter_value (&block
, ioparm_unit
, p
->unit
);
619 set_string (&block
, &post_block
, ioparm_status
,
620 ioparm_status_len
, p
->status
);
623 set_parameter_ref (&block
, ioparm_iostat
, p
->iostat
);
626 set_flag (&block
, ioparm_err
);
628 tmp
= gfc_build_function_call (iocall_close
, NULL_TREE
);
629 gfc_add_expr_to_block (&block
, tmp
);
631 gfc_add_block_to_block (&block
, &post_block
);
633 io_result (&block
, p
->err
, NULL
, NULL
);
635 return gfc_finish_block (&block
);
639 /* Common subroutine for building a file positioning statement. */
642 build_filepos (tree function
, gfc_code
* code
)
648 p
= code
->ext
.filepos
;
650 gfc_init_block (&block
);
652 set_error_locus (&block
, &code
->loc
);
655 set_parameter_value (&block
, ioparm_unit
, p
->unit
);
658 set_parameter_ref (&block
, ioparm_iostat
, p
->iostat
);
661 set_flag (&block
, ioparm_err
);
663 tmp
= gfc_build_function_call (function
, NULL
);
664 gfc_add_expr_to_block (&block
, tmp
);
666 io_result (&block
, p
->err
, NULL
, NULL
);
668 return gfc_finish_block (&block
);
672 /* Translate a BACKSPACE statement. */
675 gfc_trans_backspace (gfc_code
* code
)
678 return build_filepos (iocall_backspace
, code
);
682 /* Translate an ENDFILE statement. */
685 gfc_trans_endfile (gfc_code
* code
)
688 return build_filepos (iocall_endfile
, code
);
692 /* Translate a REWIND statement. */
695 gfc_trans_rewind (gfc_code
* code
)
698 return build_filepos (iocall_rewind
, code
);
702 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
705 gfc_trans_inquire (gfc_code
* code
)
707 stmtblock_t block
, post_block
;
711 gfc_init_block (&block
);
712 gfc_init_block (&post_block
);
714 set_error_locus (&block
, &code
->loc
);
715 p
= code
->ext
.inquire
;
718 set_parameter_value (&block
, ioparm_unit
, p
->unit
);
721 set_string (&block
, &post_block
, ioparm_file
, ioparm_file_len
, p
->file
);
724 set_parameter_ref (&block
, ioparm_iostat
, p
->iostat
);
727 set_parameter_ref (&block
, ioparm_exist
, p
->exist
);
730 set_parameter_ref (&block
, ioparm_opened
, p
->opened
);
733 set_parameter_ref (&block
, ioparm_number
, p
->number
);
736 set_parameter_ref (&block
, ioparm_named
, p
->named
);
739 set_string (&block
, &post_block
, ioparm_name
, ioparm_name_len
, p
->name
);
742 set_string (&block
, &post_block
, ioparm_access
,
743 ioparm_access_len
, p
->access
);
746 set_string (&block
, &post_block
, ioparm_sequential
,
747 ioparm_sequential_len
, p
->sequential
);
750 set_string (&block
, &post_block
, ioparm_direct
,
751 ioparm_direct_len
, p
->direct
);
754 set_string (&block
, &post_block
, ioparm_form
, ioparm_form_len
, p
->form
);
757 set_string (&block
, &post_block
, ioparm_formatted
,
758 ioparm_formatted_len
, p
->formatted
);
761 set_string (&block
, &post_block
, ioparm_unformatted
,
762 ioparm_unformatted_len
, p
->unformatted
);
765 set_parameter_ref (&block
, ioparm_recl_out
, p
->recl
);
768 set_parameter_ref (&block
, ioparm_nextrec
, p
->nextrec
);
771 set_string (&block
, &post_block
, ioparm_blank
, ioparm_blank_len
,
775 set_string (&block
, &post_block
, ioparm_position
,
776 ioparm_position_len
, p
->position
);
779 set_string (&block
, &post_block
, ioparm_action
,
780 ioparm_action_len
, p
->action
);
783 set_string (&block
, &post_block
, ioparm_read
, ioparm_read_len
, p
->read
);
786 set_string (&block
, &post_block
, ioparm_write
,
787 ioparm_write_len
, p
->write
);
790 set_string (&block
, &post_block
, ioparm_readwrite
,
791 ioparm_readwrite_len
, p
->readwrite
);
794 set_string (&block
, &post_block
, ioparm_delim
, ioparm_delim_len
,
798 set_flag (&block
, ioparm_err
);
800 tmp
= gfc_build_function_call (iocall_inquire
, NULL
);
801 gfc_add_expr_to_block (&block
, tmp
);
803 gfc_add_block_to_block (&block
, &post_block
);
805 io_result (&block
, p
->err
, NULL
, NULL
);
807 return gfc_finish_block (&block
);
812 gfc_new_nml_name_expr (char * name
)
815 nml_name
= gfc_get_expr();
816 nml_name
->ref
= NULL
;
817 nml_name
->expr_type
= EXPR_CONSTANT
;
818 nml_name
->ts
.kind
= gfc_default_character_kind ();
819 nml_name
->ts
.type
= BT_CHARACTER
;
820 nml_name
->value
.character
.length
= strlen(name
);
821 nml_name
->value
.character
.string
= name
;
827 get_new_var_expr(gfc_symbol
* sym
)
831 nml_var
= gfc_get_expr();
832 nml_var
->expr_type
= EXPR_VARIABLE
;
833 nml_var
->ts
= sym
->ts
;
835 nml_var
->rank
= sym
->as
->rank
;
836 nml_var
->symtree
= (gfc_symtree
*)gfc_getmem (sizeof (gfc_symtree
));
837 nml_var
->symtree
->n
.sym
= sym
;
838 nml_var
->where
= sym
->declared_at
;
839 sym
->attr
.referenced
= 1;
845 /* Create a data transfer statement. Not all of the fields are valid
846 for both reading and writing, but improper use has been filtered
850 build_dt (tree
* function
, gfc_code
* code
)
852 stmtblock_t block
, post_block
;
854 tree tmp
, args
, arg2
;
855 gfc_expr
*nmlname
, *nmlvar
;
856 gfc_namelist
*nml
, *nml_tail
;
858 int ts_kind
, ts_type
, name_len
;
860 gfc_init_block (&block
);
861 gfc_init_block (&post_block
);
863 set_error_locus (&block
, &code
->loc
);
870 if (dt
->io_unit
->ts
.type
== BT_CHARACTER
)
872 set_string (&block
, &post_block
, ioparm_internal_unit
,
873 ioparm_internal_unit_len
, dt
->io_unit
);
876 set_parameter_value (&block
, ioparm_unit
, dt
->io_unit
);
880 set_parameter_value (&block
, ioparm_rec
, dt
->rec
);
883 set_string (&block
, &post_block
, ioparm_advance
, ioparm_advance_len
,
887 set_string (&block
, &post_block
, ioparm_format
, ioparm_format_len
,
890 if (dt
->format_label
)
892 if (dt
->format_label
== &format_asterisk
)
893 set_flag (&block
, ioparm_list_format
);
895 set_string (&block
, &post_block
, ioparm_format
,
896 ioparm_format_len
, dt
->format_label
->format
);
900 set_parameter_ref (&block
, ioparm_iostat
, dt
->iostat
);
903 set_parameter_ref (&block
, ioparm_size
, dt
->size
);
906 set_flag (&block
, ioparm_err
);
909 set_flag(&block
, ioparm_eor
);
912 set_flag(&block
, ioparm_end
);
916 if (dt
->format_expr
|| dt
->format_label
)
917 fatal_error("A format cannot be specified with a namelist");
919 nmlname
= gfc_new_nml_name_expr(dt
->namelist
->name
);
921 set_string (&block
, &post_block
, ioparm_namelist_name
,
922 ioparm_namelist_name_len
, nmlname
);
925 set_flag (&block
, ioparm_namelist_read_mode
);
927 nml
= dt
->namelist
->namelist
;
928 nml_tail
= dt
->namelist
->namelist_tail
;
932 gfc_init_se (&se
, NULL
);
933 gfc_init_se (&se2
, NULL
);
934 nmlvar
= get_new_var_expr(nml
->sym
);
935 nmlname
= gfc_new_nml_name_expr(nml
->sym
->name
);
936 name_len
= strlen(nml
->sym
->name
);
937 ts_kind
= nml
->sym
->ts
.kind
;
938 ts_type
= nml
->sym
->ts
.type
;
940 gfc_conv_expr_reference (&se2
, nmlname
);
941 gfc_conv_expr_reference (&se
, nmlvar
);
942 args
= gfc_chainon_list (NULL_TREE
, se
.expr
);
943 args
= gfc_chainon_list (args
, se2
.expr
);
944 args
= gfc_chainon_list (args
, se2
.string_length
);
945 arg2
= build_int_2 (ts_kind
, 0);
946 args
= gfc_chainon_list (args
,arg2
);
950 tmp
= gfc_build_function_call (iocall_set_nml_val_int
, args
);
953 tmp
= gfc_build_function_call (iocall_set_nml_val_char
, args
);
956 tmp
= gfc_build_function_call (iocall_set_nml_val_float
, args
);
959 tmp
= gfc_build_function_call (iocall_set_nml_val_log
, args
);
962 tmp
= gfc_build_function_call (iocall_set_nml_val_complex
, args
);
965 internal_error ("Bad namelist IO basetype (%d)", ts_type
);
968 gfc_add_expr_to_block (&block
, tmp
);
974 tmp
= gfc_build_function_call (*function
, NULL_TREE
);
975 gfc_add_expr_to_block (&block
, tmp
);
977 gfc_add_block_to_block (&block
, &post_block
);
979 return gfc_finish_block (&block
);
983 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
984 this as a third sort of data transfer statement, except that
985 lengths are summed instead of actually transfering any data. */
988 gfc_trans_iolength (gfc_code
* code
)
994 gfc_init_block (&block
);
996 set_error_locus (&block
, &code
->loc
);
998 inq
= code
->ext
.inquire
;
1000 /* First check that preconditions are met. */
1001 assert(inq
!= NULL
);
1002 assert(inq
->iolength
!= NULL
);
1004 /* Connect to the iolength variable. */
1006 set_parameter_ref (&block
, ioparm_iolength
, inq
->iolength
);
1010 dt
= build_dt(&iocall_iolength
, code
);
1012 gfc_add_expr_to_block (&block
, dt
);
1014 return gfc_finish_block (&block
);
1018 /* Translate a READ statement. */
1021 gfc_trans_read (gfc_code
* code
)
1025 return build_dt (&iocall_read
, code
);
1029 /* Translate a WRITE statement */
1032 gfc_trans_write (gfc_code
* code
)
1036 return build_dt (&iocall_write
, code
);
1040 /* Finish a data transfer statement. */
1043 gfc_trans_dt_end (gfc_code
* code
)
1048 gfc_init_block (&block
);
1053 function
= iocall_read_done
;
1057 function
= iocall_write_done
;
1061 function
= iocall_iolength_done
;
1068 tmp
= gfc_build_function_call (function
, NULL
);
1069 gfc_add_expr_to_block (&block
, tmp
);
1071 if (last_dt
!= IOLENGTH
)
1073 assert(code
->ext
.dt
!= NULL
);
1074 io_result (&block
, code
->ext
.dt
->err
,
1075 code
->ext
.dt
->end
, code
->ext
.dt
->eor
);
1078 return gfc_finish_block (&block
);
1082 /* Generate the call for a scalar transfer node. */
1085 transfer_expr (gfc_se
* se
, gfc_typespec
* ts
, tree addr_expr
)
1087 tree args
, tmp
, function
, arg2
, field
, expr
;
1098 arg2
= build_int_2 (kind
, 0);
1099 function
= iocall_x_integer
;
1103 arg2
= build_int_2 (kind
, 0);
1104 function
= iocall_x_real
;
1108 arg2
= build_int_2 (kind
, 0);
1109 function
= iocall_x_complex
;
1113 arg2
= build_int_2 (kind
, 0);
1114 function
= iocall_x_logical
;
1118 arg2
= se
->string_length
;
1119 function
= iocall_x_character
;
1123 expr
= gfc_evaluate_now (addr_expr
, &se
->pre
);
1124 expr
= gfc_build_indirect_ref (expr
);
1126 for (c
= ts
->derived
->components
; c
; c
= c
->next
)
1128 field
= c
->backend_decl
;
1129 assert (field
&& TREE_CODE (field
) == FIELD_DECL
);
1131 tmp
= build (COMPONENT_REF
, TREE_TYPE (field
), expr
, field
,
1134 if (c
->ts
.type
== BT_CHARACTER
)
1136 assert (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
);
1138 TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp
)));
1140 transfer_expr (se
, &c
->ts
, gfc_build_addr_expr (NULL
, tmp
));
1145 internal_error ("Bad IO basetype (%d)", ts
->type
);
1148 args
= gfc_chainon_list (NULL_TREE
, addr_expr
);
1149 args
= gfc_chainon_list (args
, arg2
);
1151 tmp
= gfc_build_function_call (function
, args
);
1152 gfc_add_expr_to_block (&se
->pre
, tmp
);
1153 gfc_add_block_to_block (&se
->pre
, &se
->post
);
1158 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1161 gfc_trans_transfer (gfc_code
* code
)
1163 stmtblock_t block
, body
;
1170 gfc_start_block (&block
);
1173 ss
= gfc_walk_expr (expr
);
1175 gfc_init_se (&se
, NULL
);
1177 if (ss
== gfc_ss_terminator
)
1178 gfc_init_block (&body
);
1181 /* Initialize the scalarizer. */
1182 gfc_init_loopinfo (&loop
);
1183 gfc_add_ss_to_loop (&loop
, ss
);
1185 /* Initialize the loop. */
1186 gfc_conv_ss_startstride (&loop
);
1187 gfc_conv_loop_setup (&loop
);
1189 /* The main loop body. */
1190 gfc_mark_ss_chain_used (ss
, 1);
1191 gfc_start_scalarized_body (&loop
, &body
);
1193 gfc_copy_loopinfo_to_se (&se
, &loop
);
1197 gfc_conv_expr_reference (&se
, expr
);
1199 transfer_expr (&se
, &expr
->ts
, se
.expr
);
1201 gfc_add_block_to_block (&body
, &se
.pre
);
1202 gfc_add_block_to_block (&body
, &se
.post
);
1205 tmp
= gfc_finish_block (&body
);
1208 assert (se
.ss
== gfc_ss_terminator
);
1209 gfc_trans_scalarizing_loops (&loop
, &body
);
1211 gfc_add_block_to_block (&loop
.pre
, &loop
.post
);
1212 tmp
= gfc_finish_block (&loop
.pre
);
1213 gfc_cleanup_loop (&loop
);
1216 gfc_add_expr_to_block (&block
, tmp
);
1218 return gfc_finish_block (&block
);;
1221 #include "gt-fortran-trans-io.h"