1 /* IO Code translation/library interface
2 Copyright (C) 2002, 2003, 2004, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "coretypes.h"
27 #include "tree-gimple.h"
33 #include "trans-stmt.h"
34 #include "trans-array.h"
35 #include "trans-types.h"
36 #include "trans-const.h"
39 /* Members of the ioparm structure. */
41 static GTY(()) tree ioparm_unit;
42 static GTY(()) tree ioparm_err;
43 static GTY(()) tree ioparm_end;
44 static GTY(()) tree ioparm_eor;
45 static GTY(()) tree ioparm_list_format;
46 static GTY(()) tree ioparm_library_return;
47 static GTY(()) tree ioparm_iostat;
48 static GTY(()) tree ioparm_exist;
49 static GTY(()) tree ioparm_opened;
50 static GTY(()) tree ioparm_number;
51 static GTY(()) tree ioparm_named;
52 static GTY(()) tree ioparm_rec;
53 static GTY(()) tree ioparm_nextrec;
54 static GTY(()) tree ioparm_size;
55 static GTY(()) tree ioparm_recl_in;
56 static GTY(()) tree ioparm_recl_out;
57 static GTY(()) tree ioparm_iolength;
58 static GTY(()) tree ioparm_file;
59 static GTY(()) tree ioparm_file_len;
60 static GTY(()) tree ioparm_status;
61 static GTY(()) tree ioparm_status_len;
62 static GTY(()) tree ioparm_access;
63 static GTY(()) tree ioparm_access_len;
64 static GTY(()) tree ioparm_form;
65 static GTY(()) tree ioparm_form_len;
66 static GTY(()) tree ioparm_blank;
67 static GTY(()) tree ioparm_blank_len;
68 static GTY(()) tree ioparm_position;
69 static GTY(()) tree ioparm_position_len;
70 static GTY(()) tree ioparm_action;
71 static GTY(()) tree ioparm_action_len;
72 static GTY(()) tree ioparm_delim;
73 static GTY(()) tree ioparm_delim_len;
74 static GTY(()) tree ioparm_pad;
75 static GTY(()) tree ioparm_pad_len;
76 static GTY(()) tree ioparm_format;
77 static GTY(()) tree ioparm_format_len;
78 static GTY(()) tree ioparm_advance;
79 static GTY(()) tree ioparm_advance_len;
80 static GTY(()) tree ioparm_name;
81 static GTY(()) tree ioparm_name_len;
82 static GTY(()) tree ioparm_internal_unit;
83 static GTY(()) tree ioparm_internal_unit_len;
84 static GTY(()) tree ioparm_internal_unit_desc;
85 static GTY(()) tree ioparm_sequential;
86 static GTY(()) tree ioparm_sequential_len;
87 static GTY(()) tree ioparm_direct;
88 static GTY(()) tree ioparm_direct_len;
89 static GTY(()) tree ioparm_formatted;
90 static GTY(()) tree ioparm_formatted_len;
91 static GTY(()) tree ioparm_unformatted;
92 static GTY(()) tree ioparm_unformatted_len;
93 static GTY(()) tree ioparm_read;
94 static GTY(()) tree ioparm_read_len;
95 static GTY(()) tree ioparm_write;
96 static GTY(()) tree ioparm_write_len;
97 static GTY(()) tree ioparm_readwrite;
98 static GTY(()) tree ioparm_readwrite_len;
99 static GTY(()) tree ioparm_namelist_name;
100 static GTY(()) tree ioparm_namelist_name_len;
101 static GTY(()) tree ioparm_namelist_read_mode;
102 static GTY(()) tree ioparm_iomsg;
103 static GTY(()) tree ioparm_iomsg_len;
105 /* The global I/O variables */
107 static GTY(()) tree ioparm_var;
108 static GTY(()) tree locus_file;
109 static GTY(()) tree locus_line;
112 /* Library I/O subroutines */
114 static GTY(()) tree iocall_read;
115 static GTY(()) tree iocall_read_done;
116 static GTY(()) tree iocall_write;
117 static GTY(()) tree iocall_write_done;
118 static GTY(()) tree iocall_x_integer;
119 static GTY(()) tree iocall_x_logical;
120 static GTY(()) tree iocall_x_character;
121 static GTY(()) tree iocall_x_real;
122 static GTY(()) tree iocall_x_complex;
123 static GTY(()) tree iocall_x_array;
124 static GTY(()) tree iocall_open;
125 static GTY(()) tree iocall_close;
126 static GTY(()) tree iocall_inquire;
127 static GTY(()) tree iocall_iolength;
128 static GTY(()) tree iocall_iolength_done;
129 static GTY(()) tree iocall_rewind;
130 static GTY(()) tree iocall_backspace;
131 static GTY(()) tree iocall_endfile;
132 static GTY(()) tree iocall_flush;
133 static GTY(()) tree iocall_set_nml_val;
134 static GTY(()) tree iocall_set_nml_val_dim;
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_charlen_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;
162 tree gfc_c_int_type_node;
165 gfc_int4_type_node = gfc_get_int_type (4);
166 gfc_pint4_type_node = build_pointer_type (gfc_int4_type_node);
167 gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind);
169 /* Build the st_parameter structure. Information associated with I/O
170 calls are transferred here. This must match the one defined in the
173 ioparm_type = make_node (RECORD_TYPE);
174 TYPE_NAME (ioparm_type) = get_identifier ("_gfc_ioparm");
176 ADD_FIELD (unit, gfc_int4_type_node);
177 ADD_FIELD (err, gfc_int4_type_node);
178 ADD_FIELD (end, gfc_int4_type_node);
179 ADD_FIELD (eor, gfc_int4_type_node);
180 ADD_FIELD (list_format, gfc_int4_type_node);
181 ADD_FIELD (library_return, gfc_int4_type_node);
183 ADD_FIELD (iostat, gfc_pint4_type_node);
184 ADD_FIELD (exist, gfc_pint4_type_node);
185 ADD_FIELD (opened, gfc_pint4_type_node);
186 ADD_FIELD (number, gfc_pint4_type_node);
187 ADD_FIELD (named, gfc_pint4_type_node);
188 ADD_FIELD (rec, gfc_int4_type_node);
189 ADD_FIELD (nextrec, gfc_pint4_type_node);
190 ADD_FIELD (size, gfc_pint4_type_node);
192 ADD_FIELD (recl_in, gfc_int4_type_node);
193 ADD_FIELD (recl_out, gfc_pint4_type_node);
195 ADD_FIELD (iolength, gfc_pint4_type_node);
203 ADD_STRING (position);
208 ADD_STRING (advance);
210 ADD_STRING (internal_unit);
211 ADD_FIELD (internal_unit_desc, pchar_type_node);
212 ADD_STRING (sequential);
215 ADD_STRING (formatted);
216 ADD_STRING (unformatted);
219 ADD_STRING (readwrite);
221 ADD_STRING (namelist_name);
222 ADD_FIELD (namelist_read_mode, gfc_int4_type_node);
225 gfc_finish_type (ioparm_type);
227 ioparm_var = build_decl (VAR_DECL, get_identifier (PREFIX("ioparm")),
229 DECL_EXTERNAL (ioparm_var) = 1;
230 TREE_PUBLIC (ioparm_var) = 1;
232 locus_line = build_decl (VAR_DECL, get_identifier (PREFIX("line")),
234 DECL_EXTERNAL (locus_line) = 1;
235 TREE_PUBLIC (locus_line) = 1;
237 locus_file = build_decl (VAR_DECL, get_identifier (PREFIX("filename")),
239 DECL_EXTERNAL (locus_file) = 1;
240 TREE_PUBLIC (locus_file) = 1;
242 /* Define the transfer functions. */
245 gfc_build_library_function_decl (get_identifier
246 (PREFIX("transfer_integer")),
247 void_type_node, 2, pvoid_type_node,
251 gfc_build_library_function_decl (get_identifier
252 (PREFIX("transfer_logical")),
253 void_type_node, 2, pvoid_type_node,
257 gfc_build_library_function_decl (get_identifier
258 (PREFIX("transfer_character")),
259 void_type_node, 2, pvoid_type_node,
263 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
265 pvoid_type_node, gfc_int4_type_node);
268 gfc_build_library_function_decl (get_identifier
269 (PREFIX("transfer_complex")),
270 void_type_node, 2, pvoid_type_node,
274 gfc_build_library_function_decl (get_identifier
275 (PREFIX("transfer_array")),
276 void_type_node, 3, pvoid_type_node,
278 gfc_charlen_type_node);
280 /* Library entry points */
283 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
287 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
290 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
294 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
298 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
299 gfc_int4_type_node, 0);
302 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
306 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
307 gfc_int4_type_node, 0);
310 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
311 gfc_int4_type_node, 0);
314 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
315 gfc_int4_type_node, 0);
318 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
319 gfc_int4_type_node, 0);
321 /* Library helpers */
324 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
325 gfc_int4_type_node, 0);
328 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
329 gfc_int4_type_node, 0);
331 iocall_iolength_done =
332 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
333 gfc_int4_type_node, 0);
337 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var")),
339 pvoid_type_node, pvoid_type_node,
340 gfc_int4_type_node, gfc_charlen_type_node,
343 iocall_set_nml_val_dim =
344 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_dim")),
346 gfc_int4_type_node, gfc_int4_type_node,
347 gfc_int4_type_node, gfc_int4_type_node);
351 /* Generate code to store a non-string I/O parameter into the
352 ioparm structure. This is a pass by value. */
355 set_parameter_value (stmtblock_t * block, tree var, gfc_expr * e)
360 gfc_init_se (&se, NULL);
361 gfc_conv_expr_type (&se, e, TREE_TYPE (var));
362 gfc_add_block_to_block (block, &se.pre);
364 tmp = build3 (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
365 gfc_add_modify_expr (block, tmp, se.expr);
369 /* Generate code to store a non-string I/O parameter into the
370 ioparm structure. This is pass by reference. */
373 set_parameter_ref (stmtblock_t * block, tree var, gfc_expr * e)
378 gfc_init_se (&se, NULL);
381 gfc_conv_expr_type (&se, e, TREE_TYPE (var));
382 gfc_add_block_to_block (block, &se.pre);
384 tmp = build3 (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
385 gfc_add_modify_expr (block, tmp, se.expr);
388 /* Given an array expr, find its address and length to get a string. If the
389 array is full, the string's address is the address of array's first element
390 and the length is the size of the whole array. If it is an element, the
391 string's address is the element's address and the length is the rest size of
396 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
405 sym = e->symtree->n.sym;
406 rank = sym->as->rank - 1;
408 if (e->ref->u.ar.type == AR_FULL)
410 se->expr = gfc_get_symbol_decl (sym);
411 se->expr = gfc_conv_array_data (se->expr);
415 gfc_conv_expr (se, e);
418 array = sym->backend_decl;
419 type = TREE_TYPE (array);
421 if (GFC_ARRAY_TYPE_P (type))
422 size = GFC_TYPE_ARRAY_SIZE (type);
425 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
426 size = gfc_conv_array_stride (array, rank);
427 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
428 gfc_conv_array_ubound (array, rank),
429 gfc_conv_array_lbound (array, rank));
430 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
432 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
437 /* If it is an element, we need the its address and size of the rest. */
438 if (e->ref->u.ar.type == AR_ELEMENT)
440 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
441 TREE_OPERAND (se->expr, 1));
442 se->expr = gfc_build_addr_expr (NULL, se->expr);
445 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
446 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
448 se->string_length = fold_convert (gfc_charlen_type_node, size);
452 /* Generate code to store a string and its length into the
456 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
457 tree var_len, gfc_expr * e)
465 gfc_init_se (&se, NULL);
467 io = build3 (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
468 len = build3 (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len,
471 /* Integer variable assigned a format label. */
472 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
474 gfc_conv_label_variable (&se, e);
476 gfc_build_cstring_const ("Assigned label is not a format label");
477 tmp = GFC_DECL_STRING_LEN (se.expr);
478 tmp = build2 (LE_EXPR, boolean_type_node,
479 tmp, convert (TREE_TYPE (tmp), integer_minus_one_node));
480 gfc_trans_runtime_check (tmp, msg, &se.pre);
481 gfc_add_modify_expr (&se.pre, io,
482 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
483 gfc_add_modify_expr (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
487 /* General character. */
488 if (e->ts.type == BT_CHARACTER && e->rank == 0)
489 gfc_conv_expr (&se, e);
490 /* Array assigned Hollerith constant or character array. */
491 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
492 gfc_convert_array_to_string (&se, e);
496 gfc_conv_string_parameter (&se);
497 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
498 gfc_add_modify_expr (&se.pre, len, se.string_length);
501 gfc_add_block_to_block (block, &se.pre);
502 gfc_add_block_to_block (postblock, &se.post);
506 /* Generate code to store the character (array) and the character length
507 for an internal unit. */
510 set_internal_unit (stmtblock_t * block, tree iunit, tree iunit_len,
511 tree iunit_desc, gfc_expr * e)
519 gfc_init_se (&se, NULL);
521 io = build3 (COMPONENT_REF, TREE_TYPE (iunit), ioparm_var, iunit, NULL_TREE);
522 len = build3 (COMPONENT_REF, TREE_TYPE (iunit_len), ioparm_var, iunit_len,
524 desc = build3 (COMPONENT_REF, TREE_TYPE (iunit_desc), ioparm_var, iunit_desc,
527 gcc_assert (e->ts.type == BT_CHARACTER);
529 /* Character scalars. */
532 gfc_conv_expr (&se, e);
533 gfc_conv_string_parameter (&se);
535 se.expr = fold_convert (pchar_type_node, integer_zero_node);
538 /* Character array. */
539 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
541 se.ss = gfc_walk_expr (e);
543 /* Return the data pointer and rank from the descriptor. */
544 gfc_conv_expr_descriptor (&se, e, se.ss);
545 tmp = gfc_conv_descriptor_data_get (se.expr);
546 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
551 /* The cast is needed for character substrings and the descriptor
553 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
554 gfc_add_modify_expr (&se.pre, len, se.string_length);
555 gfc_add_modify_expr (&se.pre, desc, se.expr);
557 gfc_add_block_to_block (block, &se.pre);
560 /* Set a member of the ioparm structure to one. */
562 set_flag (stmtblock_t *block, tree var)
564 tree tmp, type = TREE_TYPE (var);
566 tmp = build3 (COMPONENT_REF, type, ioparm_var, var, NULL_TREE);
567 gfc_add_modify_expr (block, tmp, convert (type, integer_one_node));
571 /* Add a case to a IO-result switch. */
574 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
579 return; /* No label, no case */
581 value = build_int_cst (NULL_TREE, label_value);
583 /* Make a backend label for this case. */
584 tmp = gfc_build_label_decl (NULL_TREE);
586 /* And the case itself. */
587 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
588 gfc_add_expr_to_block (body, tmp);
590 /* Jump to the label. */
591 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
592 gfc_add_expr_to_block (body, tmp);
596 /* Generate a switch statement that branches to the correct I/O
597 result label. The last statement of an I/O call stores the
598 result into a variable because there is often cleanup that
599 must be done before the switch, so a temporary would have to
600 be created anyway. */
603 io_result (stmtblock_t * block, gfc_st_label * err_label,
604 gfc_st_label * end_label, gfc_st_label * eor_label)
609 /* If no labels are specified, ignore the result instead
610 of building an empty switch. */
611 if (err_label == NULL
613 && eor_label == NULL)
616 /* Build a switch statement. */
617 gfc_start_block (&body);
619 /* The label values here must be the same as the values
620 in the library_return enum in the runtime library */
621 add_case (1, err_label, &body);
622 add_case (2, end_label, &body);
623 add_case (3, eor_label, &body);
625 tmp = gfc_finish_block (&body);
627 rc = build3 (COMPONENT_REF, TREE_TYPE (ioparm_library_return), ioparm_var,
628 ioparm_library_return, NULL_TREE);
630 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
632 gfc_add_expr_to_block (block, tmp);
636 /* Store the current file and line number to variables so that if a
637 library call goes awry, we can tell the user where the problem is. */
640 set_error_locus (stmtblock_t * block, locus * where)
647 tmp = gfc_build_cstring_const (f->filename);
649 tmp = gfc_build_addr_expr (pchar_type_node, tmp);
650 gfc_add_modify_expr (block, locus_file, tmp);
652 #ifdef USE_MAPPED_LOCATION
653 line = LOCATION_LINE (where->lb->location);
655 line = where->lb->linenum;
657 gfc_add_modify_expr (block, locus_line, build_int_cst (NULL_TREE, line));
661 /* Translate an OPEN statement. */
664 gfc_trans_open (gfc_code * code)
666 stmtblock_t block, post_block;
670 gfc_init_block (&block);
671 gfc_init_block (&post_block);
673 set_error_locus (&block, &code->loc);
677 set_parameter_value (&block, ioparm_unit, p->unit);
680 set_string (&block, &post_block, ioparm_file, ioparm_file_len, p->file);
683 set_string (&block, &post_block, ioparm_status,
684 ioparm_status_len, p->status);
687 set_string (&block, &post_block, ioparm_access,
688 ioparm_access_len, p->access);
691 set_string (&block, &post_block, ioparm_form, ioparm_form_len, p->form);
694 set_parameter_value (&block, ioparm_recl_in, p->recl);
697 set_string (&block, &post_block, ioparm_blank, ioparm_blank_len,
701 set_string (&block, &post_block, ioparm_position,
702 ioparm_position_len, p->position);
705 set_string (&block, &post_block, ioparm_action,
706 ioparm_action_len, p->action);
709 set_string (&block, &post_block, ioparm_delim, ioparm_delim_len,
713 set_string (&block, &post_block, ioparm_pad, ioparm_pad_len, p->pad);
716 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
720 set_parameter_ref (&block, ioparm_iostat, p->iostat);
723 set_flag (&block, ioparm_err);
725 tmp = gfc_build_function_call (iocall_open, NULL_TREE);
726 gfc_add_expr_to_block (&block, tmp);
728 gfc_add_block_to_block (&block, &post_block);
730 io_result (&block, p->err, NULL, NULL);
732 return gfc_finish_block (&block);
736 /* Translate a CLOSE statement. */
739 gfc_trans_close (gfc_code * code)
741 stmtblock_t block, post_block;
745 gfc_init_block (&block);
746 gfc_init_block (&post_block);
748 set_error_locus (&block, &code->loc);
752 set_parameter_value (&block, ioparm_unit, p->unit);
755 set_string (&block, &post_block, ioparm_status,
756 ioparm_status_len, p->status);
759 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
763 set_parameter_ref (&block, ioparm_iostat, p->iostat);
766 set_flag (&block, ioparm_err);
768 tmp = gfc_build_function_call (iocall_close, NULL_TREE);
769 gfc_add_expr_to_block (&block, tmp);
771 gfc_add_block_to_block (&block, &post_block);
773 io_result (&block, p->err, NULL, NULL);
775 return gfc_finish_block (&block);
779 /* Common subroutine for building a file positioning statement. */
782 build_filepos (tree function, gfc_code * code)
784 stmtblock_t block, post_block;
788 p = code->ext.filepos;
790 gfc_init_block (&block);
791 gfc_init_block (&post_block);
793 set_error_locus (&block, &code->loc);
796 set_parameter_value (&block, ioparm_unit, p->unit);
799 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
803 set_parameter_ref (&block, ioparm_iostat, p->iostat);
806 set_flag (&block, ioparm_err);
808 tmp = gfc_build_function_call (function, NULL);
809 gfc_add_expr_to_block (&block, tmp);
811 gfc_add_block_to_block (&block, &post_block);
813 io_result (&block, p->err, NULL, NULL);
815 return gfc_finish_block (&block);
819 /* Translate a BACKSPACE statement. */
822 gfc_trans_backspace (gfc_code * code)
825 return build_filepos (iocall_backspace, code);
829 /* Translate an ENDFILE statement. */
832 gfc_trans_endfile (gfc_code * code)
835 return build_filepos (iocall_endfile, code);
839 /* Translate a REWIND statement. */
842 gfc_trans_rewind (gfc_code * code)
845 return build_filepos (iocall_rewind, code);
849 /* Translate a FLUSH statement. */
852 gfc_trans_flush (gfc_code * code)
855 return build_filepos (iocall_flush, code);
859 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
862 gfc_trans_inquire (gfc_code * code)
864 stmtblock_t block, post_block;
868 gfc_init_block (&block);
869 gfc_init_block (&post_block);
871 set_error_locus (&block, &code->loc);
872 p = code->ext.inquire;
875 if (p->unit && p->file)
876 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers.", &code->loc);
879 set_parameter_value (&block, ioparm_unit, p->unit);
882 set_string (&block, &post_block, ioparm_file, ioparm_file_len, p->file);
885 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
889 set_parameter_ref (&block, ioparm_iostat, p->iostat);
892 set_parameter_ref (&block, ioparm_exist, p->exist);
895 set_parameter_ref (&block, ioparm_opened, p->opened);
898 set_parameter_ref (&block, ioparm_number, p->number);
901 set_parameter_ref (&block, ioparm_named, p->named);
904 set_string (&block, &post_block, ioparm_name, ioparm_name_len, p->name);
907 set_string (&block, &post_block, ioparm_access,
908 ioparm_access_len, p->access);
911 set_string (&block, &post_block, ioparm_sequential,
912 ioparm_sequential_len, p->sequential);
915 set_string (&block, &post_block, ioparm_direct,
916 ioparm_direct_len, p->direct);
919 set_string (&block, &post_block, ioparm_form, ioparm_form_len, p->form);
922 set_string (&block, &post_block, ioparm_formatted,
923 ioparm_formatted_len, p->formatted);
926 set_string (&block, &post_block, ioparm_unformatted,
927 ioparm_unformatted_len, p->unformatted);
930 set_parameter_ref (&block, ioparm_recl_out, p->recl);
933 set_parameter_ref (&block, ioparm_nextrec, p->nextrec);
936 set_string (&block, &post_block, ioparm_blank, ioparm_blank_len,
940 set_string (&block, &post_block, ioparm_position,
941 ioparm_position_len, p->position);
944 set_string (&block, &post_block, ioparm_action,
945 ioparm_action_len, p->action);
948 set_string (&block, &post_block, ioparm_read, ioparm_read_len, p->read);
951 set_string (&block, &post_block, ioparm_write,
952 ioparm_write_len, p->write);
955 set_string (&block, &post_block, ioparm_readwrite,
956 ioparm_readwrite_len, p->readwrite);
959 set_string (&block, &post_block, ioparm_delim, ioparm_delim_len,
963 set_string (&block, &post_block, ioparm_pad, ioparm_pad_len,
967 set_flag (&block, ioparm_err);
969 tmp = gfc_build_function_call (iocall_inquire, NULL);
970 gfc_add_expr_to_block (&block, tmp);
972 gfc_add_block_to_block (&block, &post_block);
974 io_result (&block, p->err, NULL, NULL);
976 return gfc_finish_block (&block);
980 gfc_new_nml_name_expr (const char * name)
984 nml_name = gfc_get_expr();
985 nml_name->ref = NULL;
986 nml_name->expr_type = EXPR_CONSTANT;
987 nml_name->ts.kind = gfc_default_character_kind;
988 nml_name->ts.type = BT_CHARACTER;
989 nml_name->value.character.length = strlen(name);
990 nml_name->value.character.string = gfc_getmem (strlen (name) + 1);
991 strcpy (nml_name->value.character.string, name);
996 /* nml_full_name builds up the fully qualified name of a
997 derived type component. */
1000 nml_full_name (const char* var_name, const char* cmp_name)
1002 int full_name_length;
1005 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1006 full_name = (char*)gfc_getmem (full_name_length + 1);
1007 strcpy (full_name, var_name);
1008 full_name = strcat (full_name, "%");
1009 full_name = strcat (full_name, cmp_name);
1013 /* nml_get_addr_expr builds an address expression from the
1014 gfc_symbol or gfc_component backend_decl's. An offset is
1015 provided so that the address of an element of an array of
1016 derived types is returned. This is used in the runtime to
1017 determine that span of the derived type. */
1020 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1023 tree decl = NULL_TREE;
1027 int dummy_arg_flagged;
1031 sym->attr.referenced = 1;
1032 decl = gfc_get_symbol_decl (sym);
1035 decl = c->backend_decl;
1037 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1038 || TREE_CODE (decl) == VAR_DECL
1039 || TREE_CODE (decl) == PARM_DECL)
1040 || TREE_CODE (decl) == COMPONENT_REF));
1044 /* Build indirect reference, if dummy argument. */
1046 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1048 itmp = (dummy_arg_flagged) ? gfc_build_indirect_ref (tmp) : tmp;
1050 /* If an array, set flag and use indirect ref. if built. */
1052 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1053 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1058 /* Treat the component of a derived type, using base_addr for
1059 the derived type. */
1061 if (TREE_CODE (decl) == FIELD_DECL)
1062 tmp = build3 (COMPONENT_REF, TREE_TYPE (tmp),
1063 base_addr, tmp, NULL_TREE);
1065 /* If we have a derived type component, a reference to the first
1066 element of the array is built. This is done so that base_addr,
1067 used in the build of the component reference, always points to
1071 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node);
1073 /* Now build the address expression. */
1075 tmp = gfc_build_addr_expr (NULL, tmp);
1077 /* If scalar dummy, resolve indirect reference now. */
1079 if (dummy_arg_flagged && !array_flagged)
1080 tmp = gfc_build_indirect_ref (tmp);
1082 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1087 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1088 call to iocall_set_nml_val. For derived type variable, recursively
1089 generate calls to iocall_set_nml_val for each component. */
1091 #define NML_FIRST_ARG(a) args = gfc_chainon_list (NULL_TREE, a)
1092 #define NML_ADD_ARG(a) args = gfc_chainon_list (args, a)
1093 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1096 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1097 gfc_symbol * sym, gfc_component * c,
1100 gfc_typespec * ts = NULL;
1101 gfc_array_spec * as = NULL;
1102 tree addr_expr = NULL;
1112 gcc_assert (sym || c);
1114 /* Build the namelist object name. */
1116 string = gfc_build_cstring_const (var_name);
1117 string = gfc_build_addr_expr (pchar_type_node, string);
1119 /* Build ts, as and data address using symbol or component. */
1121 ts = (sym) ? &sym->ts : &c->ts;
1122 as = (sym) ? sym->as : c->as;
1124 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1131 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1132 dtype = gfc_get_dtype (dt);
1136 itype = GFC_DTYPE_UNKNOWN;
1142 itype = GFC_DTYPE_INTEGER;
1145 itype = GFC_DTYPE_LOGICAL;
1148 itype = GFC_DTYPE_REAL;
1151 itype = GFC_DTYPE_COMPLEX;
1154 itype = GFC_DTYPE_DERIVED;
1157 itype = GFC_DTYPE_CHARACTER;
1163 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1166 /* Build up the arguments for the transfer call.
1167 The call for the scalar part transfers:
1168 (address, name, type, kind or string_length, dtype) */
1170 NML_FIRST_ARG (addr_expr);
1171 NML_ADD_ARG (string);
1172 NML_ADD_ARG (IARG (ts->kind));
1174 if (ts->type == BT_CHARACTER)
1175 NML_ADD_ARG (ts->cl->backend_decl);
1177 NML_ADD_ARG (convert (gfc_charlen_type_node, integer_zero_node));
1179 NML_ADD_ARG (dtype);
1180 tmp = gfc_build_function_call (iocall_set_nml_val, args);
1181 gfc_add_expr_to_block (block, tmp);
1183 /* If the object is an array, transfer rank times:
1184 (null pointer, name, stride, lbound, ubound) */
1186 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1188 NML_FIRST_ARG (IARG (n_dim));
1189 NML_ADD_ARG (GFC_TYPE_ARRAY_STRIDE (dt, n_dim));
1190 NML_ADD_ARG (GFC_TYPE_ARRAY_LBOUND (dt, n_dim));
1191 NML_ADD_ARG (GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1192 tmp = gfc_build_function_call (iocall_set_nml_val_dim, args);
1193 gfc_add_expr_to_block (block, tmp);
1196 if (ts->type == BT_DERIVED)
1200 /* Provide the RECORD_TYPE to build component references. */
1202 tree expr = gfc_build_indirect_ref (addr_expr);
1204 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1206 char *full_name = nml_full_name (var_name, cmp->name);
1207 transfer_namelist_element (block,
1210 gfc_free (full_name);
1217 #undef NML_FIRST_ARG
1219 /* Create a data transfer statement. Not all of the fields are valid
1220 for both reading and writing, but improper use has been filtered
1224 build_dt (tree * function, gfc_code * code)
1226 stmtblock_t block, post_block;
1232 gfc_init_block (&block);
1233 gfc_init_block (&post_block);
1235 set_error_locus (&block, &code->loc);
1238 gcc_assert (dt != NULL);
1242 if (dt->io_unit->ts.type == BT_CHARACTER)
1244 set_internal_unit (&block,
1245 ioparm_internal_unit,
1246 ioparm_internal_unit_len,
1247 ioparm_internal_unit_desc,
1251 set_parameter_value (&block, ioparm_unit, dt->io_unit);
1255 set_parameter_value (&block, ioparm_rec, dt->rec);
1258 set_string (&block, &post_block, ioparm_advance, ioparm_advance_len,
1261 if (dt->format_expr)
1262 set_string (&block, &post_block, ioparm_format, ioparm_format_len,
1265 if (dt->format_label)
1267 if (dt->format_label == &format_asterisk)
1268 set_flag (&block, ioparm_list_format);
1270 set_string (&block, &post_block, ioparm_format,
1271 ioparm_format_len, dt->format_label->format);
1275 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
1279 set_parameter_ref (&block, ioparm_iostat, dt->iostat);
1282 set_parameter_ref (&block, ioparm_size, dt->size);
1285 set_flag (&block, ioparm_err);
1288 set_flag(&block, ioparm_eor);
1291 set_flag(&block, ioparm_end);
1295 if (dt->format_expr || dt->format_label)
1296 gfc_internal_error ("build_dt: format with namelist");
1298 nmlname = gfc_new_nml_name_expr(dt->namelist->name);
1300 set_string (&block, &post_block, ioparm_namelist_name,
1301 ioparm_namelist_name_len, nmlname);
1303 if (last_dt == READ)
1304 set_flag (&block, ioparm_namelist_read_mode);
1306 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1307 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1311 tmp = gfc_build_function_call (*function, NULL_TREE);
1312 gfc_add_expr_to_block (&block, tmp);
1314 gfc_add_block_to_block (&block, &post_block);
1316 return gfc_finish_block (&block);
1320 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1321 this as a third sort of data transfer statement, except that
1322 lengths are summed instead of actually transferring any data. */
1325 gfc_trans_iolength (gfc_code * code)
1331 gfc_init_block (&block);
1333 set_error_locus (&block, &code->loc);
1335 inq = code->ext.inquire;
1337 /* First check that preconditions are met. */
1338 gcc_assert (inq != NULL);
1339 gcc_assert (inq->iolength != NULL);
1341 /* Connect to the iolength variable. */
1343 set_parameter_ref (&block, ioparm_iolength, inq->iolength);
1347 dt = build_dt(&iocall_iolength, code);
1349 gfc_add_expr_to_block (&block, dt);
1351 return gfc_finish_block (&block);
1355 /* Translate a READ statement. */
1358 gfc_trans_read (gfc_code * code)
1362 return build_dt (&iocall_read, code);
1366 /* Translate a WRITE statement */
1369 gfc_trans_write (gfc_code * code)
1373 return build_dt (&iocall_write, code);
1377 /* Finish a data transfer statement. */
1380 gfc_trans_dt_end (gfc_code * code)
1385 gfc_init_block (&block);
1390 function = iocall_read_done;
1394 function = iocall_write_done;
1398 function = iocall_iolength_done;
1405 tmp = gfc_build_function_call (function, NULL);
1406 gfc_add_expr_to_block (&block, tmp);
1408 if (last_dt != IOLENGTH)
1410 gcc_assert (code->ext.dt != NULL);
1411 io_result (&block, code->ext.dt->err,
1412 code->ext.dt->end, code->ext.dt->eor);
1415 return gfc_finish_block (&block);
1419 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr);
1421 /* Given an array field in a derived type variable, generate the code
1422 for the loop that iterates over array elements, and the code that
1423 accesses those array elements. Use transfer_expr to generate code
1424 for transferring that element. Because elements may also be
1425 derived types, transfer_expr and transfer_array_component are mutually
1429 transfer_array_component (tree expr, gfc_component * cm)
1439 gfc_start_block (&block);
1440 gfc_init_se (&se, NULL);
1442 /* Create and initialize Scalarization Status. Unlike in
1443 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1444 care of this task, because we don't have a gfc_expr at hand.
1445 Build one manually, as in gfc_trans_subarray_assign. */
1448 ss->type = GFC_SS_COMPONENT;
1450 ss->shape = gfc_get_shape (cm->as->rank);
1451 ss->next = gfc_ss_terminator;
1452 ss->data.info.dimen = cm->as->rank;
1453 ss->data.info.descriptor = expr;
1454 ss->data.info.data = gfc_conv_array_data (expr);
1455 ss->data.info.offset = gfc_conv_array_offset (expr);
1456 for (n = 0; n < cm->as->rank; n++)
1458 ss->data.info.dim[n] = n;
1459 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1460 ss->data.info.stride[n] = gfc_index_one_node;
1462 mpz_init (ss->shape[n]);
1463 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1464 cm->as->lower[n]->value.integer);
1465 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1468 /* Once we got ss, we use scalarizer to create the loop. */
1470 gfc_init_loopinfo (&loop);
1471 gfc_add_ss_to_loop (&loop, ss);
1472 gfc_conv_ss_startstride (&loop);
1473 gfc_conv_loop_setup (&loop);
1474 gfc_mark_ss_chain_used (ss, 1);
1475 gfc_start_scalarized_body (&loop, &body);
1477 gfc_copy_loopinfo_to_se (&se, &loop);
1480 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1482 gfc_conv_tmp_array_ref (&se);
1484 /* Now se.expr contains an element of the array. Take the address and pass
1485 it to the IO routines. */
1486 tmp = gfc_build_addr_expr (NULL, se.expr);
1487 transfer_expr (&se, &cm->ts, tmp);
1489 /* We are done now with the loop body. Wrap up the scalarizer and
1492 gfc_add_block_to_block (&body, &se.pre);
1493 gfc_add_block_to_block (&body, &se.post);
1495 gfc_trans_scalarizing_loops (&loop, &body);
1497 gfc_add_block_to_block (&block, &loop.pre);
1498 gfc_add_block_to_block (&block, &loop.post);
1500 for (n = 0; n < cm->as->rank; n++)
1501 mpz_clear (ss->shape[n]);
1502 gfc_free (ss->shape);
1504 gfc_cleanup_loop (&loop);
1506 return gfc_finish_block (&block);
1509 /* Generate the call for a scalar transfer node. */
1512 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1514 tree args, tmp, function, arg2, field, expr;
1525 arg2 = build_int_cst (NULL_TREE, kind);
1526 function = iocall_x_integer;
1530 arg2 = build_int_cst (NULL_TREE, kind);
1531 function = iocall_x_real;
1535 arg2 = build_int_cst (NULL_TREE, kind);
1536 function = iocall_x_complex;
1540 arg2 = build_int_cst (NULL_TREE, kind);
1541 function = iocall_x_logical;
1545 if (se->string_length)
1546 arg2 = se->string_length;
1549 tmp = gfc_build_indirect_ref (addr_expr);
1550 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
1551 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
1553 function = iocall_x_character;
1557 /* Recurse into the elements of the derived type. */
1558 expr = gfc_evaluate_now (addr_expr, &se->pre);
1559 expr = gfc_build_indirect_ref (expr);
1561 for (c = ts->derived->components; c; c = c->next)
1563 field = c->backend_decl;
1564 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
1566 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), expr, field,
1571 tmp = transfer_array_component (tmp, c);
1572 gfc_add_expr_to_block (&se->pre, tmp);
1577 tmp = gfc_build_addr_expr (NULL, tmp);
1578 transfer_expr (se, &c->ts, tmp);
1584 internal_error ("Bad IO basetype (%d)", ts->type);
1587 args = gfc_chainon_list (NULL_TREE, addr_expr);
1588 args = gfc_chainon_list (args, arg2);
1590 tmp = gfc_build_function_call (function, args);
1591 gfc_add_expr_to_block (&se->pre, tmp);
1592 gfc_add_block_to_block (&se->pre, &se->post);
1597 /* Generate a call to pass an array descriptor to the IO library. The
1598 array should be of one of the intrinsic types. */
1601 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1603 tree args, tmp, charlen_arg, kind_arg;
1605 if (ts->type == BT_CHARACTER)
1606 charlen_arg = se->string_length;
1608 charlen_arg = build_int_cstu (NULL_TREE, 0);
1610 kind_arg = build_int_cst (NULL_TREE, ts->kind);
1612 args = gfc_chainon_list (NULL_TREE, addr_expr);
1613 args = gfc_chainon_list (args, kind_arg);
1614 args = gfc_chainon_list (args, charlen_arg);
1615 tmp = gfc_build_function_call (iocall_x_array, args);
1616 gfc_add_expr_to_block (&se->pre, tmp);
1617 gfc_add_block_to_block (&se->pre, &se->post);
1621 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1624 gfc_trans_transfer (gfc_code * code)
1626 stmtblock_t block, body;
1633 gfc_start_block (&block);
1634 gfc_init_block (&body);
1637 ss = gfc_walk_expr (expr);
1639 gfc_init_se (&se, NULL);
1641 if (ss == gfc_ss_terminator)
1643 gfc_conv_expr_reference (&se, expr);
1644 transfer_expr (&se, &expr->ts, se.expr);
1646 else if (expr->ts.type == BT_DERIVED)
1648 /* Initialize the scalarizer. */
1649 gfc_init_loopinfo (&loop);
1650 gfc_add_ss_to_loop (&loop, ss);
1652 /* Initialize the loop. */
1653 gfc_conv_ss_startstride (&loop);
1654 gfc_conv_loop_setup (&loop);
1656 /* The main loop body. */
1657 gfc_mark_ss_chain_used (ss, 1);
1658 gfc_start_scalarized_body (&loop, &body);
1660 gfc_copy_loopinfo_to_se (&se, &loop);
1663 gfc_conv_expr_reference (&se, expr);
1664 transfer_expr (&se, &expr->ts, se.expr);
1668 /* Pass the array descriptor to the library. */
1669 gfc_conv_expr_descriptor (&se, expr, ss);
1670 tmp = gfc_build_addr_expr (NULL, se.expr);
1671 transfer_array_desc (&se, &expr->ts, tmp);
1674 gfc_add_block_to_block (&body, &se.pre);
1675 gfc_add_block_to_block (&body, &se.post);
1678 tmp = gfc_finish_block (&body);
1681 gcc_assert (se.ss == gfc_ss_terminator);
1682 gfc_trans_scalarizing_loops (&loop, &body);
1684 gfc_add_block_to_block (&loop.pre, &loop.post);
1685 tmp = gfc_finish_block (&loop.pre);
1686 gfc_cleanup_loop (&loop);
1689 gfc_add_expr_to_block (&block, tmp);
1691 return gfc_finish_block (&block);
1694 #include "gt-fortran-trans-io.h"