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"
35 #include "trans-stmt.h"
36 #include "trans-array.h"
37 #include "trans-types.h"
38 #include "trans-const.h"
41 /* Members of the ioparm structure. */
43 static GTY(()) tree ioparm_unit
;
44 static GTY(()) tree ioparm_err
;
45 static GTY(()) tree ioparm_end
;
46 static GTY(()) tree ioparm_eor
;
47 static GTY(()) tree ioparm_list_format
;
48 static GTY(()) tree ioparm_library_return
;
49 static GTY(()) tree ioparm_iostat
;
50 static GTY(()) tree ioparm_exist
;
51 static GTY(()) tree ioparm_opened
;
52 static GTY(()) tree ioparm_number
;
53 static GTY(()) tree ioparm_named
;
54 static GTY(()) tree ioparm_rec
;
55 static GTY(()) tree ioparm_nextrec
;
56 static GTY(()) tree ioparm_size
;
57 static GTY(()) tree ioparm_recl_in
;
58 static GTY(()) tree ioparm_recl_out
;
59 static GTY(()) tree ioparm_iolength
;
60 static GTY(()) tree ioparm_file
;
61 static GTY(()) tree ioparm_file_len
;
62 static GTY(()) tree ioparm_status
;
63 static GTY(()) tree ioparm_status_len
;
64 static GTY(()) tree ioparm_access
;
65 static GTY(()) tree ioparm_access_len
;
66 static GTY(()) tree ioparm_form
;
67 static GTY(()) tree ioparm_form_len
;
68 static GTY(()) tree ioparm_blank
;
69 static GTY(()) tree ioparm_blank_len
;
70 static GTY(()) tree ioparm_position
;
71 static GTY(()) tree ioparm_position_len
;
72 static GTY(()) tree ioparm_action
;
73 static GTY(()) tree ioparm_action_len
;
74 static GTY(()) tree ioparm_delim
;
75 static GTY(()) tree ioparm_delim_len
;
76 static GTY(()) tree ioparm_pad
;
77 static GTY(()) tree ioparm_pad_len
;
78 static GTY(()) tree ioparm_format
;
79 static GTY(()) tree ioparm_format_len
;
80 static GTY(()) tree ioparm_advance
;
81 static GTY(()) tree ioparm_advance_len
;
82 static GTY(()) tree ioparm_name
;
83 static GTY(()) tree ioparm_name_len
;
84 static GTY(()) tree ioparm_internal_unit
;
85 static GTY(()) tree ioparm_internal_unit_len
;
86 static GTY(()) tree ioparm_sequential
;
87 static GTY(()) tree ioparm_sequential_len
;
88 static GTY(()) tree ioparm_direct
;
89 static GTY(()) tree ioparm_direct_len
;
90 static GTY(()) tree ioparm_formatted
;
91 static GTY(()) tree ioparm_formatted_len
;
92 static GTY(()) tree ioparm_unformatted
;
93 static GTY(()) tree ioparm_unformatted_len
;
94 static GTY(()) tree ioparm_read
;
95 static GTY(()) tree ioparm_read_len
;
96 static GTY(()) tree ioparm_write
;
97 static GTY(()) tree ioparm_write_len
;
98 static GTY(()) tree ioparm_readwrite
;
99 static GTY(()) tree ioparm_readwrite_len
;
100 static GTY(()) tree ioparm_namelist_name
;
101 static GTY(()) tree ioparm_namelist_name_len
;
102 static GTY(()) tree ioparm_namelist_read_mode
;
104 /* The global I/O variables */
106 static GTY(()) tree ioparm_var
;
107 static GTY(()) tree locus_file
;
108 static GTY(()) tree locus_line
;
111 /* Library I/O subroutines */
113 static GTY(()) tree iocall_read
;
114 static GTY(()) tree iocall_read_done
;
115 static GTY(()) tree iocall_write
;
116 static GTY(()) tree iocall_write_done
;
117 static GTY(()) tree iocall_x_integer
;
118 static GTY(()) tree iocall_x_logical
;
119 static GTY(()) tree iocall_x_character
;
120 static GTY(()) tree iocall_x_real
;
121 static GTY(()) tree iocall_x_complex
;
122 static GTY(()) tree iocall_open
;
123 static GTY(()) tree iocall_close
;
124 static GTY(()) tree iocall_inquire
;
125 static GTY(()) tree iocall_iolength
;
126 static GTY(()) tree iocall_iolength_done
;
127 static GTY(()) tree iocall_rewind
;
128 static GTY(()) tree iocall_backspace
;
129 static GTY(()) tree iocall_endfile
;
130 static GTY(()) tree iocall_set_nml_val_int
;
131 static GTY(()) tree iocall_set_nml_val_float
;
132 static GTY(()) tree iocall_set_nml_val_char
;
133 static GTY(()) tree iocall_set_nml_val_complex
;
134 static GTY(()) tree iocall_set_nml_val_log
;
136 /* Variable for keeping track of what the last data transfer statement
137 was. Used for deciding which subroutine to call when the data
138 transfer is complete. */
139 static enum { READ
, WRITE
, IOLENGTH
} last_dt
;
141 #define ADD_FIELD(name, type) \
142 ioparm_ ## name = gfc_add_field_to_struct \
143 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
144 get_identifier (stringize(name)), type)
146 #define ADD_STRING(name) \
147 ioparm_ ## name = gfc_add_field_to_struct \
148 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
149 get_identifier (stringize(name)), pchar_type_node); \
150 ioparm_ ## name ## _len = gfc_add_field_to_struct \
151 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
152 get_identifier (stringize(name) "_len"), gfc_int4_type_node)
155 /* Create function decls for IO library functions. */
158 gfc_build_io_library_fndecls (void)
160 tree gfc_int4_type_node
;
161 tree gfc_pint4_type_node
;
164 gfc_int4_type_node
= gfc_get_int_type (4);
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 gfc_charlen_type_node
);
336 iocall_set_nml_val_complex
=
337 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_complex")),
339 pvoid_type_node
, pvoid_type_node
,
340 gfc_int4_type_node
,gfc_int4_type_node
);
341 iocall_set_nml_val_log
=
342 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_log")),
344 pvoid_type_node
, pvoid_type_node
,
345 gfc_int4_type_node
,gfc_int4_type_node
);
350 /* Generate code to store an non-string I/O parameter into the
351 ioparm structure. This is a pass by value. */
354 set_parameter_value (stmtblock_t
* block
, tree var
, gfc_expr
* e
)
359 gfc_init_se (&se
, NULL
);
360 gfc_conv_expr_type (&se
, e
, TREE_TYPE (var
));
361 gfc_add_block_to_block (block
, &se
.pre
);
363 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (var
), ioparm_var
, var
, NULL_TREE
);
364 gfc_add_modify_expr (block
, tmp
, se
.expr
);
368 /* Generate code to store an non-string I/O parameter into the
369 ioparm structure. This is pass by reference. */
372 set_parameter_ref (stmtblock_t
* block
, tree var
, gfc_expr
* e
)
377 gfc_init_se (&se
, NULL
);
380 gfc_conv_expr_type (&se
, e
, TREE_TYPE (var
));
381 gfc_add_block_to_block (block
, &se
.pre
);
383 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (var
), ioparm_var
, var
, NULL_TREE
);
384 gfc_add_modify_expr (block
, tmp
, se
.expr
);
388 /* Generate code to store a string and its length into the
392 set_string (stmtblock_t
* block
, stmtblock_t
* postblock
, tree var
,
393 tree var_len
, gfc_expr
* e
)
401 gfc_init_se (&se
, NULL
);
402 gfc_conv_expr (&se
, e
);
404 io
= build3 (COMPONENT_REF
, TREE_TYPE (var
), ioparm_var
, var
, NULL_TREE
);
405 len
= build3 (COMPONENT_REF
, TREE_TYPE (var_len
), ioparm_var
, var_len
,
408 /* Integer variable assigned a format label. */
409 if (e
->ts
.type
== BT_INTEGER
&& e
->symtree
->n
.sym
->attr
.assign
== 1)
412 gfc_build_cstring_const ("Assigned label is not a format label");
413 tmp
= GFC_DECL_STRING_LEN (se
.expr
);
414 tmp
= build2 (LE_EXPR
, boolean_type_node
,
415 tmp
, convert (TREE_TYPE (tmp
), integer_minus_one_node
));
416 gfc_trans_runtime_check (tmp
, msg
, &se
.pre
);
417 gfc_add_modify_expr (&se
.pre
, io
, GFC_DECL_ASSIGN_ADDR (se
.expr
));
418 gfc_add_modify_expr (&se
.pre
, len
, GFC_DECL_STRING_LEN (se
.expr
));
422 gfc_conv_string_parameter (&se
);
423 gfc_add_modify_expr (&se
.pre
, io
, fold_convert (TREE_TYPE (io
), se
.expr
));
424 gfc_add_modify_expr (&se
.pre
, len
, se
.string_length
);
427 gfc_add_block_to_block (block
, &se
.pre
);
428 gfc_add_block_to_block (postblock
, &se
.post
);
433 /* Set a member of the ioparm structure to one. */
435 set_flag (stmtblock_t
*block
, tree var
)
437 tree tmp
, type
= TREE_TYPE (var
);
439 tmp
= build3 (COMPONENT_REF
, type
, ioparm_var
, var
, NULL_TREE
);
440 gfc_add_modify_expr (block
, tmp
, convert (type
, integer_one_node
));
444 /* Add a case to a IO-result switch. */
447 add_case (int label_value
, gfc_st_label
* label
, stmtblock_t
* body
)
452 return; /* No label, no case */
454 value
= build_int_cst (NULL_TREE
, label_value
);
456 /* Make a backend label for this case. */
457 tmp
= build_decl (LABEL_DECL
, NULL_TREE
, NULL_TREE
);
458 DECL_CONTEXT (tmp
) = current_function_decl
;
460 /* And the case itself. */
461 tmp
= build3_v (CASE_LABEL_EXPR
, value
, NULL_TREE
, tmp
);
462 gfc_add_expr_to_block (body
, tmp
);
464 /* Jump to the label. */
465 tmp
= build1_v (GOTO_EXPR
, gfc_get_label_decl (label
));
466 gfc_add_expr_to_block (body
, tmp
);
470 /* Generate a switch statement that branches to the correct I/O
471 result label. The last statement of an I/O call stores the
472 result into a variable because there is often cleanup that
473 must be done before the switch, so a temporary would have to
474 be created anyway. */
477 io_result (stmtblock_t
* block
, gfc_st_label
* err_label
,
478 gfc_st_label
* end_label
, gfc_st_label
* eor_label
)
483 /* If no labels are specified, ignore the result instead
484 of building an empty switch. */
485 if (err_label
== NULL
487 && eor_label
== NULL
)
490 /* Build a switch statement. */
491 gfc_start_block (&body
);
493 /* The label values here must be the same as the values
494 in the library_return enum in the runtime library */
495 add_case (1, err_label
, &body
);
496 add_case (2, end_label
, &body
);
497 add_case (3, eor_label
, &body
);
499 tmp
= gfc_finish_block (&body
);
501 rc
= build3 (COMPONENT_REF
, TREE_TYPE (ioparm_library_return
), ioparm_var
,
502 ioparm_library_return
, NULL_TREE
);
504 tmp
= build3_v (SWITCH_EXPR
, rc
, tmp
, NULL_TREE
);
506 gfc_add_expr_to_block (block
, tmp
);
510 /* Store the current file and line number to variables so that if a
511 library call goes awry, we can tell the user where the problem is. */
514 set_error_locus (stmtblock_t
* block
, locus
* where
)
521 tmp
= gfc_build_cstring_const (f
->filename
);
523 tmp
= gfc_build_addr_expr (pchar_type_node
, tmp
);
524 gfc_add_modify_expr (block
, locus_file
, tmp
);
526 #ifdef USE_MAPPED_LOCATION
527 line
= LOCATION_LINE (where
->lb
->location
);
529 line
= where
->lb
->linenum
;
531 gfc_add_modify_expr (block
, locus_line
, build_int_cst (NULL_TREE
, line
));
535 /* Translate an OPEN statement. */
538 gfc_trans_open (gfc_code
* code
)
540 stmtblock_t block
, post_block
;
544 gfc_init_block (&block
);
545 gfc_init_block (&post_block
);
547 set_error_locus (&block
, &code
->loc
);
551 set_parameter_value (&block
, ioparm_unit
, p
->unit
);
554 set_string (&block
, &post_block
, ioparm_file
, ioparm_file_len
, p
->file
);
557 set_string (&block
, &post_block
, ioparm_status
,
558 ioparm_status_len
, p
->status
);
561 set_string (&block
, &post_block
, ioparm_access
,
562 ioparm_access_len
, p
->access
);
565 set_string (&block
, &post_block
, ioparm_form
, ioparm_form_len
, p
->form
);
568 set_parameter_value (&block
, ioparm_recl_in
, p
->recl
);
571 set_string (&block
, &post_block
, ioparm_blank
, ioparm_blank_len
,
575 set_string (&block
, &post_block
, ioparm_position
,
576 ioparm_position_len
, p
->position
);
579 set_string (&block
, &post_block
, ioparm_action
,
580 ioparm_action_len
, p
->action
);
583 set_string (&block
, &post_block
, ioparm_delim
, ioparm_delim_len
,
587 set_string (&block
, &post_block
, ioparm_pad
, ioparm_pad_len
, p
->pad
);
590 set_parameter_ref (&block
, ioparm_iostat
, p
->iostat
);
593 set_flag (&block
, ioparm_err
);
595 tmp
= gfc_build_function_call (iocall_open
, NULL_TREE
);
596 gfc_add_expr_to_block (&block
, tmp
);
598 gfc_add_block_to_block (&block
, &post_block
);
600 io_result (&block
, p
->err
, NULL
, NULL
);
602 return gfc_finish_block (&block
);
606 /* Translate a CLOSE statement. */
609 gfc_trans_close (gfc_code
* code
)
611 stmtblock_t block
, post_block
;
615 gfc_init_block (&block
);
616 gfc_init_block (&post_block
);
618 set_error_locus (&block
, &code
->loc
);
622 set_parameter_value (&block
, ioparm_unit
, p
->unit
);
625 set_string (&block
, &post_block
, ioparm_status
,
626 ioparm_status_len
, p
->status
);
629 set_parameter_ref (&block
, ioparm_iostat
, p
->iostat
);
632 set_flag (&block
, ioparm_err
);
634 tmp
= gfc_build_function_call (iocall_close
, NULL_TREE
);
635 gfc_add_expr_to_block (&block
, tmp
);
637 gfc_add_block_to_block (&block
, &post_block
);
639 io_result (&block
, p
->err
, NULL
, NULL
);
641 return gfc_finish_block (&block
);
645 /* Common subroutine for building a file positioning statement. */
648 build_filepos (tree function
, gfc_code
* code
)
654 p
= code
->ext
.filepos
;
656 gfc_init_block (&block
);
658 set_error_locus (&block
, &code
->loc
);
661 set_parameter_value (&block
, ioparm_unit
, p
->unit
);
664 set_parameter_ref (&block
, ioparm_iostat
, p
->iostat
);
667 set_flag (&block
, ioparm_err
);
669 tmp
= gfc_build_function_call (function
, NULL
);
670 gfc_add_expr_to_block (&block
, tmp
);
672 io_result (&block
, p
->err
, NULL
, NULL
);
674 return gfc_finish_block (&block
);
678 /* Translate a BACKSPACE statement. */
681 gfc_trans_backspace (gfc_code
* code
)
684 return build_filepos (iocall_backspace
, code
);
688 /* Translate an ENDFILE statement. */
691 gfc_trans_endfile (gfc_code
* code
)
694 return build_filepos (iocall_endfile
, code
);
698 /* Translate a REWIND statement. */
701 gfc_trans_rewind (gfc_code
* code
)
704 return build_filepos (iocall_rewind
, code
);
708 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
711 gfc_trans_inquire (gfc_code
* code
)
713 stmtblock_t block
, post_block
;
717 gfc_init_block (&block
);
718 gfc_init_block (&post_block
);
720 set_error_locus (&block
, &code
->loc
);
721 p
= code
->ext
.inquire
;
724 set_parameter_value (&block
, ioparm_unit
, p
->unit
);
727 set_string (&block
, &post_block
, ioparm_file
, ioparm_file_len
, p
->file
);
730 set_parameter_ref (&block
, ioparm_iostat
, p
->iostat
);
733 set_parameter_ref (&block
, ioparm_exist
, p
->exist
);
736 set_parameter_ref (&block
, ioparm_opened
, p
->opened
);
739 set_parameter_ref (&block
, ioparm_number
, p
->number
);
742 set_parameter_ref (&block
, ioparm_named
, p
->named
);
745 set_string (&block
, &post_block
, ioparm_name
, ioparm_name_len
, p
->name
);
748 set_string (&block
, &post_block
, ioparm_access
,
749 ioparm_access_len
, p
->access
);
752 set_string (&block
, &post_block
, ioparm_sequential
,
753 ioparm_sequential_len
, p
->sequential
);
756 set_string (&block
, &post_block
, ioparm_direct
,
757 ioparm_direct_len
, p
->direct
);
760 set_string (&block
, &post_block
, ioparm_form
, ioparm_form_len
, p
->form
);
763 set_string (&block
, &post_block
, ioparm_formatted
,
764 ioparm_formatted_len
, p
->formatted
);
767 set_string (&block
, &post_block
, ioparm_unformatted
,
768 ioparm_unformatted_len
, p
->unformatted
);
771 set_parameter_ref (&block
, ioparm_recl_out
, p
->recl
);
774 set_parameter_ref (&block
, ioparm_nextrec
, p
->nextrec
);
777 set_string (&block
, &post_block
, ioparm_blank
, ioparm_blank_len
,
781 set_string (&block
, &post_block
, ioparm_position
,
782 ioparm_position_len
, p
->position
);
785 set_string (&block
, &post_block
, ioparm_action
,
786 ioparm_action_len
, p
->action
);
789 set_string (&block
, &post_block
, ioparm_read
, ioparm_read_len
, p
->read
);
792 set_string (&block
, &post_block
, ioparm_write
,
793 ioparm_write_len
, p
->write
);
796 set_string (&block
, &post_block
, ioparm_readwrite
,
797 ioparm_readwrite_len
, p
->readwrite
);
800 set_string (&block
, &post_block
, ioparm_delim
, ioparm_delim_len
,
804 set_flag (&block
, ioparm_err
);
806 tmp
= gfc_build_function_call (iocall_inquire
, NULL
);
807 gfc_add_expr_to_block (&block
, tmp
);
809 gfc_add_block_to_block (&block
, &post_block
);
811 io_result (&block
, p
->err
, NULL
, NULL
);
813 return gfc_finish_block (&block
);
818 gfc_new_nml_name_expr (char * name
)
821 nml_name
= gfc_get_expr();
822 nml_name
->ref
= NULL
;
823 nml_name
->expr_type
= EXPR_CONSTANT
;
824 nml_name
->ts
.kind
= gfc_default_character_kind
;
825 nml_name
->ts
.type
= BT_CHARACTER
;
826 nml_name
->value
.character
.length
= strlen(name
);
827 nml_name
->value
.character
.string
= name
;
833 get_new_var_expr(gfc_symbol
* sym
)
837 nml_var
= gfc_get_expr();
838 nml_var
->expr_type
= EXPR_VARIABLE
;
839 nml_var
->ts
= sym
->ts
;
841 nml_var
->rank
= sym
->as
->rank
;
842 nml_var
->symtree
= (gfc_symtree
*)gfc_getmem (sizeof (gfc_symtree
));
843 nml_var
->symtree
->n
.sym
= sym
;
844 nml_var
->where
= sym
->declared_at
;
845 sym
->attr
.referenced
= 1;
850 /* For a scalar variable STRING whose address is ADDR_EXPR, generate a
851 call to iocall_set_nml_val. For derived type variable, recursively
852 generate calls to iocall_set_nml_val for each leaf field. The leafs
853 have no names -- their STRING field is null, and are interpreted by
854 the run-time library as having only the value, as in the example:
858 Note that the first output field appears after the name of the
859 variable, not of the field name. This causes a little complication
863 transfer_namelist_element (stmtblock_t
* block
, gfc_typespec
* ts
, tree addr_expr
,
864 tree string
, tree string_length
)
866 tree tmp
, args
, arg2
;
869 gcc_assert (POINTER_TYPE_P (TREE_TYPE (addr_expr
)));
871 if (ts
->type
== BT_DERIVED
)
874 expr
= gfc_build_indirect_ref (addr_expr
);
876 for (c
= ts
->derived
->components
; c
; c
= c
->next
)
878 tree field
= c
->backend_decl
;
879 gcc_assert (field
&& TREE_CODE (field
) == FIELD_DECL
);
880 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
),
881 expr
, field
, NULL_TREE
);
884 gfc_todo_error ("NAMELIST IO of array in derived type");
886 tmp
= gfc_build_addr_expr (NULL
, tmp
);
887 transfer_namelist_element (block
, &c
->ts
, tmp
, string
, string_length
);
889 /* The first output field bears the name of the topmost
890 derived type variable. All other fields are anonymous
891 and appear with nulls in their string and string_length
892 fields. After the first use, we set string and
893 string_length to null. */
894 string
= null_pointer_node
;
895 string_length
= integer_zero_node
;
901 args
= gfc_chainon_list (NULL_TREE
, addr_expr
);
902 args
= gfc_chainon_list (args
, string
);
903 args
= gfc_chainon_list (args
, string_length
);
904 arg2
= build_int_cst (gfc_array_index_type
, ts
->kind
);
905 args
= gfc_chainon_list (args
,arg2
);
910 tmp
= gfc_build_function_call (iocall_set_nml_val_int
, args
);
914 expr
= gfc_build_indirect_ref (addr_expr
);
915 gcc_assert (TREE_CODE (TREE_TYPE (expr
)) == ARRAY_TYPE
);
916 args
= gfc_chainon_list (args
,
917 TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (expr
))));
918 tmp
= gfc_build_function_call (iocall_set_nml_val_char
, args
);
922 tmp
= gfc_build_function_call (iocall_set_nml_val_float
, args
);
926 tmp
= gfc_build_function_call (iocall_set_nml_val_log
, args
);
930 tmp
= gfc_build_function_call (iocall_set_nml_val_complex
, args
);
934 internal_error ("Bad namelist IO basetype (%d)", ts
->type
);
937 gfc_add_expr_to_block (block
, tmp
);
940 /* Create a data transfer statement. Not all of the fields are valid
941 for both reading and writing, but improper use has been filtered
945 build_dt (tree
* function
, gfc_code
* code
)
947 stmtblock_t block
, post_block
;
950 gfc_expr
*nmlname
, *nmlvar
;
954 gfc_init_block (&block
);
955 gfc_init_block (&post_block
);
957 set_error_locus (&block
, &code
->loc
);
960 gcc_assert (dt
!= NULL
);
964 if (dt
->io_unit
->ts
.type
== BT_CHARACTER
)
966 set_string (&block
, &post_block
, ioparm_internal_unit
,
967 ioparm_internal_unit_len
, dt
->io_unit
);
970 set_parameter_value (&block
, ioparm_unit
, dt
->io_unit
);
974 set_parameter_value (&block
, ioparm_rec
, dt
->rec
);
977 set_string (&block
, &post_block
, ioparm_advance
, ioparm_advance_len
,
981 set_string (&block
, &post_block
, ioparm_format
, ioparm_format_len
,
984 if (dt
->format_label
)
986 if (dt
->format_label
== &format_asterisk
)
987 set_flag (&block
, ioparm_list_format
);
989 set_string (&block
, &post_block
, ioparm_format
,
990 ioparm_format_len
, dt
->format_label
->format
);
994 set_parameter_ref (&block
, ioparm_iostat
, dt
->iostat
);
997 set_parameter_ref (&block
, ioparm_size
, dt
->size
);
1000 set_flag (&block
, ioparm_err
);
1003 set_flag(&block
, ioparm_eor
);
1006 set_flag(&block
, ioparm_end
);
1010 if (dt
->format_expr
|| dt
->format_label
)
1011 fatal_error("A format cannot be specified with a namelist");
1013 nmlname
= gfc_new_nml_name_expr(dt
->namelist
->name
);
1015 set_string (&block
, &post_block
, ioparm_namelist_name
,
1016 ioparm_namelist_name_len
, nmlname
);
1018 if (last_dt
== READ
)
1019 set_flag (&block
, ioparm_namelist_read_mode
);
1021 for (nml
= dt
->namelist
->namelist
; nml
; nml
= nml
->next
)
1023 gfc_init_se (&se
, NULL
);
1024 gfc_init_se (&se2
, NULL
);
1025 nmlvar
= get_new_var_expr (nml
->sym
);
1026 nmlname
= gfc_new_nml_name_expr (nml
->sym
->name
);
1027 gfc_conv_expr_reference (&se2
, nmlname
);
1028 gfc_conv_expr_reference (&se
, nmlvar
);
1029 gfc_evaluate_now (se
.expr
, &se
.pre
);
1031 transfer_namelist_element (&block
, &nml
->sym
->ts
, se
.expr
,
1032 se2
.expr
, se2
.string_length
);
1036 tmp
= gfc_build_function_call (*function
, NULL_TREE
);
1037 gfc_add_expr_to_block (&block
, tmp
);
1039 gfc_add_block_to_block (&block
, &post_block
);
1041 return gfc_finish_block (&block
);
1045 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1046 this as a third sort of data transfer statement, except that
1047 lengths are summed instead of actually transfering any data. */
1050 gfc_trans_iolength (gfc_code
* code
)
1056 gfc_init_block (&block
);
1058 set_error_locus (&block
, &code
->loc
);
1060 inq
= code
->ext
.inquire
;
1062 /* First check that preconditions are met. */
1063 gcc_assert (inq
!= NULL
);
1064 gcc_assert (inq
->iolength
!= NULL
);
1066 /* Connect to the iolength variable. */
1068 set_parameter_ref (&block
, ioparm_iolength
, inq
->iolength
);
1072 dt
= build_dt(&iocall_iolength
, code
);
1074 gfc_add_expr_to_block (&block
, dt
);
1076 return gfc_finish_block (&block
);
1080 /* Translate a READ statement. */
1083 gfc_trans_read (gfc_code
* code
)
1087 return build_dt (&iocall_read
, code
);
1091 /* Translate a WRITE statement */
1094 gfc_trans_write (gfc_code
* code
)
1098 return build_dt (&iocall_write
, code
);
1102 /* Finish a data transfer statement. */
1105 gfc_trans_dt_end (gfc_code
* code
)
1110 gfc_init_block (&block
);
1115 function
= iocall_read_done
;
1119 function
= iocall_write_done
;
1123 function
= iocall_iolength_done
;
1130 tmp
= gfc_build_function_call (function
, NULL
);
1131 gfc_add_expr_to_block (&block
, tmp
);
1133 if (last_dt
!= IOLENGTH
)
1135 gcc_assert (code
->ext
.dt
!= NULL
);
1136 io_result (&block
, code
->ext
.dt
->err
,
1137 code
->ext
.dt
->end
, code
->ext
.dt
->eor
);
1140 return gfc_finish_block (&block
);
1144 transfer_expr (gfc_se
* se
, gfc_typespec
* ts
, tree addr_expr
);
1146 /* Given an array field in a derived type variable, generate the code
1147 for the loop that iterates over array elements, and the code that
1148 accesses those array elements. Use transfer_expr to generate code
1149 for transferring that element. Because elements may also be
1150 derived types, transfer_expr and transfer_array_component are mutually
1154 transfer_array_component (tree expr
, gfc_component
* cm
)
1164 gfc_start_block (&block
);
1165 gfc_init_se (&se
, NULL
);
1167 /* Create and initialize Scalarization Status. Unlike in
1168 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1169 care of this task, because we don't have a gfc_expr at hand.
1170 Build one manually, as in gfc_trans_subarray_assign. */
1173 ss
->type
= GFC_SS_COMPONENT
;
1175 ss
->shape
= gfc_get_shape (cm
->as
->rank
);
1176 ss
->next
= gfc_ss_terminator
;
1177 ss
->data
.info
.dimen
= cm
->as
->rank
;
1178 ss
->data
.info
.descriptor
= expr
;
1179 ss
->data
.info
.data
= gfc_conv_array_data (expr
);
1180 ss
->data
.info
.offset
= gfc_conv_array_offset (expr
);
1181 for (n
= 0; n
< cm
->as
->rank
; n
++)
1183 ss
->data
.info
.dim
[n
] = n
;
1184 ss
->data
.info
.start
[n
] = gfc_conv_array_lbound (expr
, n
);
1185 ss
->data
.info
.stride
[n
] = gfc_index_one_node
;
1187 mpz_init (ss
->shape
[n
]);
1188 mpz_sub (ss
->shape
[n
], cm
->as
->upper
[n
]->value
.integer
,
1189 cm
->as
->lower
[n
]->value
.integer
);
1190 mpz_add_ui (ss
->shape
[n
], ss
->shape
[n
], 1);
1193 /* Once we got ss, we use scalarizer to create the loop. */
1195 gfc_init_loopinfo (&loop
);
1196 gfc_add_ss_to_loop (&loop
, ss
);
1197 gfc_conv_ss_startstride (&loop
);
1198 gfc_conv_loop_setup (&loop
);
1199 gfc_mark_ss_chain_used (ss
, 1);
1200 gfc_start_scalarized_body (&loop
, &body
);
1202 gfc_copy_loopinfo_to_se (&se
, &loop
);
1205 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1207 gfc_conv_tmp_array_ref (&se
);
1209 /* Now se.expr contains an element of the array. Take the address and pass
1210 it to the IO routines. */
1211 tmp
= gfc_build_addr_expr (NULL
, se
.expr
);
1212 transfer_expr (&se
, &cm
->ts
, tmp
);
1214 /* We are done now with the loop body. Wrap up the scalarizer and
1217 gfc_add_block_to_block (&body
, &se
.pre
);
1218 gfc_add_block_to_block (&body
, &se
.post
);
1220 gfc_trans_scalarizing_loops (&loop
, &body
);
1222 gfc_add_block_to_block (&block
, &loop
.pre
);
1223 gfc_add_block_to_block (&block
, &loop
.post
);
1225 for (n
= 0; n
< cm
->as
->rank
; n
++)
1226 mpz_clear (ss
->shape
[n
]);
1227 gfc_free (ss
->shape
);
1229 gfc_cleanup_loop (&loop
);
1231 return gfc_finish_block (&block
);
1234 /* Generate the call for a scalar transfer node. */
1237 transfer_expr (gfc_se
* se
, gfc_typespec
* ts
, tree addr_expr
)
1239 tree args
, tmp
, function
, arg2
, field
, expr
;
1250 arg2
= build_int_cst (NULL_TREE
, kind
);
1251 function
= iocall_x_integer
;
1255 arg2
= build_int_cst (NULL_TREE
, kind
);
1256 function
= iocall_x_real
;
1260 arg2
= build_int_cst (NULL_TREE
, kind
);
1261 function
= iocall_x_complex
;
1265 arg2
= build_int_cst (NULL_TREE
, kind
);
1266 function
= iocall_x_logical
;
1270 if (se
->string_length
)
1271 arg2
= se
->string_length
;
1274 tmp
= gfc_build_indirect_ref (addr_expr
);
1275 gcc_assert (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
);
1276 arg2
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp
)));
1278 function
= iocall_x_character
;
1282 /* Recurse into the elements of the derived type. */
1283 expr
= gfc_evaluate_now (addr_expr
, &se
->pre
);
1284 expr
= gfc_build_indirect_ref (expr
);
1286 for (c
= ts
->derived
->components
; c
; c
= c
->next
)
1288 field
= c
->backend_decl
;
1289 gcc_assert (field
&& TREE_CODE (field
) == FIELD_DECL
);
1291 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), expr
, field
,
1296 tmp
= transfer_array_component (tmp
, c
);
1297 gfc_add_expr_to_block (&se
->pre
, tmp
);
1302 tmp
= gfc_build_addr_expr (NULL
, tmp
);
1303 transfer_expr (se
, &c
->ts
, tmp
);
1309 internal_error ("Bad IO basetype (%d)", ts
->type
);
1312 args
= gfc_chainon_list (NULL_TREE
, addr_expr
);
1313 args
= gfc_chainon_list (args
, arg2
);
1315 tmp
= gfc_build_function_call (function
, args
);
1316 gfc_add_expr_to_block (&se
->pre
, tmp
);
1317 gfc_add_block_to_block (&se
->pre
, &se
->post
);
1322 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1325 gfc_trans_transfer (gfc_code
* code
)
1327 stmtblock_t block
, body
;
1334 gfc_start_block (&block
);
1337 ss
= gfc_walk_expr (expr
);
1339 gfc_init_se (&se
, NULL
);
1341 if (ss
== gfc_ss_terminator
)
1342 gfc_init_block (&body
);
1345 /* Initialize the scalarizer. */
1346 gfc_init_loopinfo (&loop
);
1347 gfc_add_ss_to_loop (&loop
, ss
);
1349 /* Initialize the loop. */
1350 gfc_conv_ss_startstride (&loop
);
1351 gfc_conv_loop_setup (&loop
);
1353 /* The main loop body. */
1354 gfc_mark_ss_chain_used (ss
, 1);
1355 gfc_start_scalarized_body (&loop
, &body
);
1357 gfc_copy_loopinfo_to_se (&se
, &loop
);
1361 gfc_conv_expr_reference (&se
, expr
);
1363 transfer_expr (&se
, &expr
->ts
, se
.expr
);
1365 gfc_add_block_to_block (&body
, &se
.pre
);
1366 gfc_add_block_to_block (&body
, &se
.post
);
1369 tmp
= gfc_finish_block (&body
);
1372 gcc_assert (se
.ss
== gfc_ss_terminator
);
1373 gfc_trans_scalarizing_loops (&loop
, &body
);
1375 gfc_add_block_to_block (&loop
.pre
, &loop
.post
);
1376 tmp
= gfc_finish_block (&loop
.pre
);
1377 gfc_cleanup_loop (&loop
);
1380 gfc_add_expr_to_block (&block
, tmp
);
1382 return gfc_finish_block (&block
);
1385 #include "gt-fortran-trans-io.h"