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_sequential;
85 static GTY(()) tree ioparm_sequential_len;
86 static GTY(()) tree ioparm_direct;
87 static GTY(()) tree ioparm_direct_len;
88 static GTY(()) tree ioparm_formatted;
89 static GTY(()) tree ioparm_formatted_len;
90 static GTY(()) tree ioparm_unformatted;
91 static GTY(()) tree ioparm_unformatted_len;
92 static GTY(()) tree ioparm_read;
93 static GTY(()) tree ioparm_read_len;
94 static GTY(()) tree ioparm_write;
95 static GTY(()) tree ioparm_write_len;
96 static GTY(()) tree ioparm_readwrite;
97 static GTY(()) tree ioparm_readwrite_len;
98 static GTY(()) tree ioparm_namelist_name;
99 static GTY(()) tree ioparm_namelist_name_len;
100 static GTY(()) tree ioparm_namelist_read_mode;
101 static GTY(()) tree ioparm_iomsg;
102 static GTY(()) tree ioparm_iomsg_len;
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_flush;
131 static GTY(()) tree iocall_set_nml_val;
132 static GTY(()) tree iocall_set_nml_val_dim;
134 /* Variable for keeping track of what the last data transfer statement
135 was. Used for deciding which subroutine to call when the data
136 transfer is complete. */
137 static enum { READ, WRITE, IOLENGTH } last_dt;
139 #define ADD_FIELD(name, type) \
140 ioparm_ ## name = gfc_add_field_to_struct \
141 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
142 get_identifier (stringize(name)), type)
144 #define ADD_STRING(name) \
145 ioparm_ ## name = gfc_add_field_to_struct \
146 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
147 get_identifier (stringize(name)), pchar_type_node); \
148 ioparm_ ## name ## _len = gfc_add_field_to_struct \
149 (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
150 get_identifier (stringize(name) "_len"), gfc_charlen_type_node)
153 /* Create function decls for IO library functions. */
156 gfc_build_io_library_fndecls (void)
158 tree gfc_int4_type_node;
159 tree gfc_pint4_type_node;
162 gfc_int4_type_node = gfc_get_int_type (4);
163 gfc_pint4_type_node = build_pointer_type (gfc_int4_type_node);
165 /* Build the st_parameter structure. Information associated with I/O
166 calls are transferred here. This must match the one defined in the
169 ioparm_type = make_node (RECORD_TYPE);
170 TYPE_NAME (ioparm_type) = get_identifier ("_gfc_ioparm");
172 ADD_FIELD (unit, gfc_int4_type_node);
173 ADD_FIELD (err, gfc_int4_type_node);
174 ADD_FIELD (end, gfc_int4_type_node);
175 ADD_FIELD (eor, gfc_int4_type_node);
176 ADD_FIELD (list_format, gfc_int4_type_node);
177 ADD_FIELD (library_return, gfc_int4_type_node);
179 ADD_FIELD (iostat, gfc_pint4_type_node);
180 ADD_FIELD (exist, gfc_pint4_type_node);
181 ADD_FIELD (opened, gfc_pint4_type_node);
182 ADD_FIELD (number, gfc_pint4_type_node);
183 ADD_FIELD (named, gfc_pint4_type_node);
184 ADD_FIELD (rec, gfc_int4_type_node);
185 ADD_FIELD (nextrec, gfc_pint4_type_node);
186 ADD_FIELD (size, gfc_pint4_type_node);
188 ADD_FIELD (recl_in, gfc_int4_type_node);
189 ADD_FIELD (recl_out, gfc_pint4_type_node);
191 ADD_FIELD (iolength, gfc_pint4_type_node);
199 ADD_STRING (position);
204 ADD_STRING (advance);
206 ADD_STRING (internal_unit);
207 ADD_STRING (sequential);
210 ADD_STRING (formatted);
211 ADD_STRING (unformatted);
214 ADD_STRING (readwrite);
216 ADD_STRING (namelist_name);
217 ADD_FIELD (namelist_read_mode, gfc_int4_type_node);
220 gfc_finish_type (ioparm_type);
222 ioparm_var = build_decl (VAR_DECL, get_identifier (PREFIX("ioparm")),
224 DECL_EXTERNAL (ioparm_var) = 1;
225 TREE_PUBLIC (ioparm_var) = 1;
227 locus_line = build_decl (VAR_DECL, get_identifier (PREFIX("line")),
229 DECL_EXTERNAL (locus_line) = 1;
230 TREE_PUBLIC (locus_line) = 1;
232 locus_file = build_decl (VAR_DECL, get_identifier (PREFIX("filename")),
234 DECL_EXTERNAL (locus_file) = 1;
235 TREE_PUBLIC (locus_file) = 1;
237 /* Define the transfer functions. */
240 gfc_build_library_function_decl (get_identifier
241 (PREFIX("transfer_integer")),
242 void_type_node, 2, pvoid_type_node,
246 gfc_build_library_function_decl (get_identifier
247 (PREFIX("transfer_logical")),
248 void_type_node, 2, pvoid_type_node,
252 gfc_build_library_function_decl (get_identifier
253 (PREFIX("transfer_character")),
254 void_type_node, 2, pvoid_type_node,
258 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
260 pvoid_type_node, gfc_int4_type_node);
263 gfc_build_library_function_decl (get_identifier
264 (PREFIX("transfer_complex")),
265 void_type_node, 2, pvoid_type_node,
268 /* Library entry points */
271 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
275 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
278 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
282 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
286 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
287 gfc_int4_type_node, 0);
290 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
294 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
295 gfc_int4_type_node, 0);
298 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
299 gfc_int4_type_node, 0);
302 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
303 gfc_int4_type_node, 0);
306 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
307 gfc_int4_type_node, 0);
309 /* Library helpers */
312 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
313 gfc_int4_type_node, 0);
316 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
317 gfc_int4_type_node, 0);
319 iocall_iolength_done =
320 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
321 gfc_int4_type_node, 0);
325 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var")),
327 pvoid_type_node, pvoid_type_node,
328 gfc_int4_type_node, gfc_charlen_type_node,
331 iocall_set_nml_val_dim =
332 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_dim")),
334 gfc_int4_type_node, gfc_int4_type_node,
335 gfc_int4_type_node, gfc_int4_type_node);
339 /* Generate code to store a non-string I/O parameter into the
340 ioparm structure. This is a pass by value. */
343 set_parameter_value (stmtblock_t * block, tree var, gfc_expr * e)
348 gfc_init_se (&se, NULL);
349 gfc_conv_expr_type (&se, e, TREE_TYPE (var));
350 gfc_add_block_to_block (block, &se.pre);
352 tmp = build3 (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
353 gfc_add_modify_expr (block, tmp, se.expr);
357 /* Generate code to store a non-string I/O parameter into the
358 ioparm structure. This is pass by reference. */
361 set_parameter_ref (stmtblock_t * block, tree var, gfc_expr * e)
366 gfc_init_se (&se, NULL);
369 gfc_conv_expr_type (&se, e, TREE_TYPE (var));
370 gfc_add_block_to_block (block, &se.pre);
372 tmp = build3 (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
373 gfc_add_modify_expr (block, tmp, se.expr);
376 /* Given an array expr, find its address and length to get a string. If the
377 array is full, the string's address is the address of array's first element
378 and the length is the size of the whole array. If it is an element, the
379 string's address is the element's address and the length is the rest size of
384 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
393 sym = e->symtree->n.sym;
394 rank = sym->as->rank - 1;
396 if (e->ref->u.ar.type == AR_FULL)
398 se->expr = gfc_get_symbol_decl (sym);
399 se->expr = gfc_conv_array_data (se->expr);
403 gfc_conv_expr (se, e);
406 array = sym->backend_decl;
407 type = TREE_TYPE (array);
409 if (GFC_ARRAY_TYPE_P (type))
410 size = GFC_TYPE_ARRAY_SIZE (type);
413 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
414 size = gfc_conv_array_stride (array, rank);
415 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
416 gfc_conv_array_ubound (array, rank),
417 gfc_conv_array_lbound (array, rank));
418 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
420 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
425 /* If it is an element, we need the its address and size of the rest. */
426 if (e->ref->u.ar.type == AR_ELEMENT)
428 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
429 TREE_OPERAND (se->expr, 1));
430 se->expr = gfc_build_addr_expr (NULL, se->expr);
433 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
434 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
436 se->string_length = fold_convert (gfc_charlen_type_node, size);
439 /* Generate code to store a string and its length into the
443 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
444 tree var_len, gfc_expr * e)
452 gfc_init_se (&se, NULL);
454 io = build3 (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
455 len = build3 (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len,
458 /* Integer variable assigned a format label. */
459 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
461 gfc_conv_label_variable (&se, e);
463 gfc_build_cstring_const ("Assigned label is not a format label");
464 tmp = GFC_DECL_STRING_LEN (se.expr);
465 tmp = build2 (LE_EXPR, boolean_type_node,
466 tmp, convert (TREE_TYPE (tmp), integer_minus_one_node));
467 gfc_trans_runtime_check (tmp, msg, &se.pre);
468 gfc_add_modify_expr (&se.pre, io,
469 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
470 gfc_add_modify_expr (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
474 /* General character. */
475 if (e->ts.type == BT_CHARACTER && e->rank == 0)
476 gfc_conv_expr (&se, e);
477 /* Array assigned Hollerith constant or character array. */
478 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
479 gfc_convert_array_to_string (&se, e);
483 gfc_conv_string_parameter (&se);
484 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
485 gfc_add_modify_expr (&se.pre, len, se.string_length);
488 gfc_add_block_to_block (block, &se.pre);
489 gfc_add_block_to_block (postblock, &se.post);
493 /* Set a member of the ioparm structure to one. */
495 set_flag (stmtblock_t *block, tree var)
497 tree tmp, type = TREE_TYPE (var);
499 tmp = build3 (COMPONENT_REF, type, ioparm_var, var, NULL_TREE);
500 gfc_add_modify_expr (block, tmp, convert (type, integer_one_node));
504 /* Add a case to a IO-result switch. */
507 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
512 return; /* No label, no case */
514 value = build_int_cst (NULL_TREE, label_value);
516 /* Make a backend label for this case. */
517 tmp = gfc_build_label_decl (NULL_TREE);
519 /* And the case itself. */
520 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
521 gfc_add_expr_to_block (body, tmp);
523 /* Jump to the label. */
524 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
525 gfc_add_expr_to_block (body, tmp);
529 /* Generate a switch statement that branches to the correct I/O
530 result label. The last statement of an I/O call stores the
531 result into a variable because there is often cleanup that
532 must be done before the switch, so a temporary would have to
533 be created anyway. */
536 io_result (stmtblock_t * block, gfc_st_label * err_label,
537 gfc_st_label * end_label, gfc_st_label * eor_label)
542 /* If no labels are specified, ignore the result instead
543 of building an empty switch. */
544 if (err_label == NULL
546 && eor_label == NULL)
549 /* Build a switch statement. */
550 gfc_start_block (&body);
552 /* The label values here must be the same as the values
553 in the library_return enum in the runtime library */
554 add_case (1, err_label, &body);
555 add_case (2, end_label, &body);
556 add_case (3, eor_label, &body);
558 tmp = gfc_finish_block (&body);
560 rc = build3 (COMPONENT_REF, TREE_TYPE (ioparm_library_return), ioparm_var,
561 ioparm_library_return, NULL_TREE);
563 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
565 gfc_add_expr_to_block (block, tmp);
569 /* Store the current file and line number to variables so that if a
570 library call goes awry, we can tell the user where the problem is. */
573 set_error_locus (stmtblock_t * block, locus * where)
580 tmp = gfc_build_cstring_const (f->filename);
582 tmp = gfc_build_addr_expr (pchar_type_node, tmp);
583 gfc_add_modify_expr (block, locus_file, tmp);
585 #ifdef USE_MAPPED_LOCATION
586 line = LOCATION_LINE (where->lb->location);
588 line = where->lb->linenum;
590 gfc_add_modify_expr (block, locus_line, build_int_cst (NULL_TREE, line));
594 /* Translate an OPEN statement. */
597 gfc_trans_open (gfc_code * code)
599 stmtblock_t block, post_block;
603 gfc_init_block (&block);
604 gfc_init_block (&post_block);
606 set_error_locus (&block, &code->loc);
610 set_parameter_value (&block, ioparm_unit, p->unit);
613 set_string (&block, &post_block, ioparm_file, ioparm_file_len, p->file);
616 set_string (&block, &post_block, ioparm_status,
617 ioparm_status_len, p->status);
620 set_string (&block, &post_block, ioparm_access,
621 ioparm_access_len, p->access);
624 set_string (&block, &post_block, ioparm_form, ioparm_form_len, p->form);
627 set_parameter_value (&block, ioparm_recl_in, p->recl);
630 set_string (&block, &post_block, ioparm_blank, ioparm_blank_len,
634 set_string (&block, &post_block, ioparm_position,
635 ioparm_position_len, p->position);
638 set_string (&block, &post_block, ioparm_action,
639 ioparm_action_len, p->action);
642 set_string (&block, &post_block, ioparm_delim, ioparm_delim_len,
646 set_string (&block, &post_block, ioparm_pad, ioparm_pad_len, p->pad);
649 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
653 set_parameter_ref (&block, ioparm_iostat, p->iostat);
656 set_flag (&block, ioparm_err);
658 tmp = gfc_build_function_call (iocall_open, NULL_TREE);
659 gfc_add_expr_to_block (&block, tmp);
661 gfc_add_block_to_block (&block, &post_block);
663 io_result (&block, p->err, NULL, NULL);
665 return gfc_finish_block (&block);
669 /* Translate a CLOSE statement. */
672 gfc_trans_close (gfc_code * code)
674 stmtblock_t block, post_block;
678 gfc_init_block (&block);
679 gfc_init_block (&post_block);
681 set_error_locus (&block, &code->loc);
685 set_parameter_value (&block, ioparm_unit, p->unit);
688 set_string (&block, &post_block, ioparm_status,
689 ioparm_status_len, p->status);
692 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
696 set_parameter_ref (&block, ioparm_iostat, p->iostat);
699 set_flag (&block, ioparm_err);
701 tmp = gfc_build_function_call (iocall_close, NULL_TREE);
702 gfc_add_expr_to_block (&block, tmp);
704 gfc_add_block_to_block (&block, &post_block);
706 io_result (&block, p->err, NULL, NULL);
708 return gfc_finish_block (&block);
712 /* Common subroutine for building a file positioning statement. */
715 build_filepos (tree function, gfc_code * code)
717 stmtblock_t block, post_block;
721 p = code->ext.filepos;
723 gfc_init_block (&block);
724 gfc_init_block (&post_block);
726 set_error_locus (&block, &code->loc);
729 set_parameter_value (&block, ioparm_unit, p->unit);
732 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
736 set_parameter_ref (&block, ioparm_iostat, p->iostat);
739 set_flag (&block, ioparm_err);
741 tmp = gfc_build_function_call (function, NULL);
742 gfc_add_expr_to_block (&block, tmp);
744 gfc_add_block_to_block (&block, &post_block);
746 io_result (&block, p->err, NULL, NULL);
748 return gfc_finish_block (&block);
752 /* Translate a BACKSPACE statement. */
755 gfc_trans_backspace (gfc_code * code)
758 return build_filepos (iocall_backspace, code);
762 /* Translate an ENDFILE statement. */
765 gfc_trans_endfile (gfc_code * code)
768 return build_filepos (iocall_endfile, code);
772 /* Translate a REWIND statement. */
775 gfc_trans_rewind (gfc_code * code)
778 return build_filepos (iocall_rewind, code);
782 /* Translate a FLUSH statement. */
785 gfc_trans_flush (gfc_code * code)
788 return build_filepos (iocall_flush, code);
792 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
795 gfc_trans_inquire (gfc_code * code)
797 stmtblock_t block, post_block;
801 gfc_init_block (&block);
802 gfc_init_block (&post_block);
804 set_error_locus (&block, &code->loc);
805 p = code->ext.inquire;
808 if (p->unit && p->file)
809 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers.", &code->loc);
812 set_parameter_value (&block, ioparm_unit, p->unit);
815 set_string (&block, &post_block, ioparm_file, ioparm_file_len, p->file);
818 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
822 set_parameter_ref (&block, ioparm_iostat, p->iostat);
825 set_parameter_ref (&block, ioparm_exist, p->exist);
828 set_parameter_ref (&block, ioparm_opened, p->opened);
831 set_parameter_ref (&block, ioparm_number, p->number);
834 set_parameter_ref (&block, ioparm_named, p->named);
837 set_string (&block, &post_block, ioparm_name, ioparm_name_len, p->name);
840 set_string (&block, &post_block, ioparm_access,
841 ioparm_access_len, p->access);
844 set_string (&block, &post_block, ioparm_sequential,
845 ioparm_sequential_len, p->sequential);
848 set_string (&block, &post_block, ioparm_direct,
849 ioparm_direct_len, p->direct);
852 set_string (&block, &post_block, ioparm_form, ioparm_form_len, p->form);
855 set_string (&block, &post_block, ioparm_formatted,
856 ioparm_formatted_len, p->formatted);
859 set_string (&block, &post_block, ioparm_unformatted,
860 ioparm_unformatted_len, p->unformatted);
863 set_parameter_ref (&block, ioparm_recl_out, p->recl);
866 set_parameter_ref (&block, ioparm_nextrec, p->nextrec);
869 set_string (&block, &post_block, ioparm_blank, ioparm_blank_len,
873 set_string (&block, &post_block, ioparm_position,
874 ioparm_position_len, p->position);
877 set_string (&block, &post_block, ioparm_action,
878 ioparm_action_len, p->action);
881 set_string (&block, &post_block, ioparm_read, ioparm_read_len, p->read);
884 set_string (&block, &post_block, ioparm_write,
885 ioparm_write_len, p->write);
888 set_string (&block, &post_block, ioparm_readwrite,
889 ioparm_readwrite_len, p->readwrite);
892 set_string (&block, &post_block, ioparm_delim, ioparm_delim_len,
896 set_string (&block, &post_block, ioparm_pad, ioparm_pad_len,
900 set_flag (&block, ioparm_err);
902 tmp = gfc_build_function_call (iocall_inquire, NULL);
903 gfc_add_expr_to_block (&block, tmp);
905 gfc_add_block_to_block (&block, &post_block);
907 io_result (&block, p->err, NULL, NULL);
909 return gfc_finish_block (&block);
913 gfc_new_nml_name_expr (const char * name)
917 nml_name = gfc_get_expr();
918 nml_name->ref = NULL;
919 nml_name->expr_type = EXPR_CONSTANT;
920 nml_name->ts.kind = gfc_default_character_kind;
921 nml_name->ts.type = BT_CHARACTER;
922 nml_name->value.character.length = strlen(name);
923 nml_name->value.character.string = gfc_getmem (strlen (name) + 1);
924 strcpy (nml_name->value.character.string, name);
929 /* nml_full_name builds up the fully qualified name of a
930 derived type component. */
933 nml_full_name (const char* var_name, const char* cmp_name)
935 int full_name_length;
938 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
939 full_name = (char*)gfc_getmem (full_name_length + 1);
940 strcpy (full_name, var_name);
941 full_name = strcat (full_name, "%");
942 full_name = strcat (full_name, cmp_name);
946 /* nml_get_addr_expr builds an address expression from the
947 gfc_symbol or gfc_component backend_decl's. An offset is
948 provided so that the address of an element of an array of
949 derived types is returned. This is used in the runtime to
950 determine that span of the derived type. */
953 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
956 tree decl = NULL_TREE;
960 int dummy_arg_flagged;
964 sym->attr.referenced = 1;
965 decl = gfc_get_symbol_decl (sym);
968 decl = c->backend_decl;
970 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
971 || TREE_CODE (decl) == VAR_DECL
972 || TREE_CODE (decl) == PARM_DECL)
973 || TREE_CODE (decl) == COMPONENT_REF));
977 /* Build indirect reference, if dummy argument. */
979 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
981 itmp = (dummy_arg_flagged) ? gfc_build_indirect_ref (tmp) : tmp;
983 /* If an array, set flag and use indirect ref. if built. */
985 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
986 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
991 /* Treat the component of a derived type, using base_addr for
994 if (TREE_CODE (decl) == FIELD_DECL)
995 tmp = build3 (COMPONENT_REF, TREE_TYPE (tmp),
996 base_addr, tmp, NULL_TREE);
998 /* If we have a derived type component, a reference to the first
999 element of the array is built. This is done so that base_addr,
1000 used in the build of the component reference, always points to
1004 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node);
1006 /* Now build the address expression. */
1008 tmp = gfc_build_addr_expr (NULL, tmp);
1010 /* If scalar dummy, resolve indirect reference now. */
1012 if (dummy_arg_flagged && !array_flagged)
1013 tmp = gfc_build_indirect_ref (tmp);
1015 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1020 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1021 call to iocall_set_nml_val. For derived type variable, recursively
1022 generate calls to iocall_set_nml_val for each component. */
1024 #define NML_FIRST_ARG(a) args = gfc_chainon_list (NULL_TREE, a)
1025 #define NML_ADD_ARG(a) args = gfc_chainon_list (args, a)
1026 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1029 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1030 gfc_symbol * sym, gfc_component * c,
1033 gfc_typespec * ts = NULL;
1034 gfc_array_spec * as = NULL;
1035 tree addr_expr = NULL;
1045 gcc_assert (sym || c);
1047 /* Build the namelist object name. */
1049 string = gfc_build_cstring_const (var_name);
1050 string = gfc_build_addr_expr (pchar_type_node, string);
1052 /* Build ts, as and data address using symbol or component. */
1054 ts = (sym) ? &sym->ts : &c->ts;
1055 as = (sym) ? sym->as : c->as;
1057 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1064 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1065 dtype = gfc_get_dtype (dt);
1069 itype = GFC_DTYPE_UNKNOWN;
1075 itype = GFC_DTYPE_INTEGER;
1078 itype = GFC_DTYPE_LOGICAL;
1081 itype = GFC_DTYPE_REAL;
1084 itype = GFC_DTYPE_COMPLEX;
1087 itype = GFC_DTYPE_DERIVED;
1090 itype = GFC_DTYPE_CHARACTER;
1096 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1099 /* Build up the arguments for the transfer call.
1100 The call for the scalar part transfers:
1101 (address, name, type, kind or string_length, dtype) */
1103 NML_FIRST_ARG (addr_expr);
1104 NML_ADD_ARG (string);
1105 NML_ADD_ARG (IARG (ts->kind));
1107 if (ts->type == BT_CHARACTER)
1108 NML_ADD_ARG (ts->cl->backend_decl);
1110 NML_ADD_ARG (convert (gfc_charlen_type_node, integer_zero_node));
1112 NML_ADD_ARG (dtype);
1113 tmp = gfc_build_function_call (iocall_set_nml_val, args);
1114 gfc_add_expr_to_block (block, tmp);
1116 /* If the object is an array, transfer rank times:
1117 (null pointer, name, stride, lbound, ubound) */
1119 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1121 NML_FIRST_ARG (IARG (n_dim));
1122 NML_ADD_ARG (GFC_TYPE_ARRAY_STRIDE (dt, n_dim));
1123 NML_ADD_ARG (GFC_TYPE_ARRAY_LBOUND (dt, n_dim));
1124 NML_ADD_ARG (GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1125 tmp = gfc_build_function_call (iocall_set_nml_val_dim, args);
1126 gfc_add_expr_to_block (block, tmp);
1129 if (ts->type == BT_DERIVED)
1133 /* Provide the RECORD_TYPE to build component references. */
1135 tree expr = gfc_build_indirect_ref (addr_expr);
1137 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1139 char *full_name = nml_full_name (var_name, cmp->name);
1140 transfer_namelist_element (block,
1143 gfc_free (full_name);
1150 #undef NML_FIRST_ARG
1152 /* Create a data transfer statement. Not all of the fields are valid
1153 for both reading and writing, but improper use has been filtered
1157 build_dt (tree * function, gfc_code * code)
1159 stmtblock_t block, post_block;
1165 gfc_init_block (&block);
1166 gfc_init_block (&post_block);
1168 set_error_locus (&block, &code->loc);
1171 gcc_assert (dt != NULL);
1175 if (dt->io_unit->ts.type == BT_CHARACTER)
1177 set_string (&block, &post_block, ioparm_internal_unit,
1178 ioparm_internal_unit_len, dt->io_unit);
1181 set_parameter_value (&block, ioparm_unit, dt->io_unit);
1185 set_parameter_value (&block, ioparm_rec, dt->rec);
1188 set_string (&block, &post_block, ioparm_advance, ioparm_advance_len,
1191 if (dt->format_expr)
1192 set_string (&block, &post_block, ioparm_format, ioparm_format_len,
1195 if (dt->format_label)
1197 if (dt->format_label == &format_asterisk)
1198 set_flag (&block, ioparm_list_format);
1200 set_string (&block, &post_block, ioparm_format,
1201 ioparm_format_len, dt->format_label->format);
1205 set_string (&block, &post_block, ioparm_iomsg, ioparm_iomsg_len,
1209 set_parameter_ref (&block, ioparm_iostat, dt->iostat);
1212 set_parameter_ref (&block, ioparm_size, dt->size);
1215 set_flag (&block, ioparm_err);
1218 set_flag(&block, ioparm_eor);
1221 set_flag(&block, ioparm_end);
1225 if (dt->format_expr || dt->format_label)
1226 gfc_internal_error ("build_dt: format with namelist");
1228 nmlname = gfc_new_nml_name_expr(dt->namelist->name);
1230 set_string (&block, &post_block, ioparm_namelist_name,
1231 ioparm_namelist_name_len, nmlname);
1233 if (last_dt == READ)
1234 set_flag (&block, ioparm_namelist_read_mode);
1236 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1237 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1241 tmp = gfc_build_function_call (*function, NULL_TREE);
1242 gfc_add_expr_to_block (&block, tmp);
1244 gfc_add_block_to_block (&block, &post_block);
1246 return gfc_finish_block (&block);
1250 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1251 this as a third sort of data transfer statement, except that
1252 lengths are summed instead of actually transferring any data. */
1255 gfc_trans_iolength (gfc_code * code)
1261 gfc_init_block (&block);
1263 set_error_locus (&block, &code->loc);
1265 inq = code->ext.inquire;
1267 /* First check that preconditions are met. */
1268 gcc_assert (inq != NULL);
1269 gcc_assert (inq->iolength != NULL);
1271 /* Connect to the iolength variable. */
1273 set_parameter_ref (&block, ioparm_iolength, inq->iolength);
1277 dt = build_dt(&iocall_iolength, code);
1279 gfc_add_expr_to_block (&block, dt);
1281 return gfc_finish_block (&block);
1285 /* Translate a READ statement. */
1288 gfc_trans_read (gfc_code * code)
1292 return build_dt (&iocall_read, code);
1296 /* Translate a WRITE statement */
1299 gfc_trans_write (gfc_code * code)
1303 return build_dt (&iocall_write, code);
1307 /* Finish a data transfer statement. */
1310 gfc_trans_dt_end (gfc_code * code)
1315 gfc_init_block (&block);
1320 function = iocall_read_done;
1324 function = iocall_write_done;
1328 function = iocall_iolength_done;
1335 tmp = gfc_build_function_call (function, NULL);
1336 gfc_add_expr_to_block (&block, tmp);
1338 if (last_dt != IOLENGTH)
1340 gcc_assert (code->ext.dt != NULL);
1341 io_result (&block, code->ext.dt->err,
1342 code->ext.dt->end, code->ext.dt->eor);
1345 return gfc_finish_block (&block);
1349 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr);
1351 /* Given an array field in a derived type variable, generate the code
1352 for the loop that iterates over array elements, and the code that
1353 accesses those array elements. Use transfer_expr to generate code
1354 for transferring that element. Because elements may also be
1355 derived types, transfer_expr and transfer_array_component are mutually
1359 transfer_array_component (tree expr, gfc_component * cm)
1369 gfc_start_block (&block);
1370 gfc_init_se (&se, NULL);
1372 /* Create and initialize Scalarization Status. Unlike in
1373 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1374 care of this task, because we don't have a gfc_expr at hand.
1375 Build one manually, as in gfc_trans_subarray_assign. */
1378 ss->type = GFC_SS_COMPONENT;
1380 ss->shape = gfc_get_shape (cm->as->rank);
1381 ss->next = gfc_ss_terminator;
1382 ss->data.info.dimen = cm->as->rank;
1383 ss->data.info.descriptor = expr;
1384 ss->data.info.data = gfc_conv_array_data (expr);
1385 ss->data.info.offset = gfc_conv_array_offset (expr);
1386 for (n = 0; n < cm->as->rank; n++)
1388 ss->data.info.dim[n] = n;
1389 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1390 ss->data.info.stride[n] = gfc_index_one_node;
1392 mpz_init (ss->shape[n]);
1393 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1394 cm->as->lower[n]->value.integer);
1395 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1398 /* Once we got ss, we use scalarizer to create the loop. */
1400 gfc_init_loopinfo (&loop);
1401 gfc_add_ss_to_loop (&loop, ss);
1402 gfc_conv_ss_startstride (&loop);
1403 gfc_conv_loop_setup (&loop);
1404 gfc_mark_ss_chain_used (ss, 1);
1405 gfc_start_scalarized_body (&loop, &body);
1407 gfc_copy_loopinfo_to_se (&se, &loop);
1410 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1412 gfc_conv_tmp_array_ref (&se);
1414 /* Now se.expr contains an element of the array. Take the address and pass
1415 it to the IO routines. */
1416 tmp = gfc_build_addr_expr (NULL, se.expr);
1417 transfer_expr (&se, &cm->ts, tmp);
1419 /* We are done now with the loop body. Wrap up the scalarizer and
1422 gfc_add_block_to_block (&body, &se.pre);
1423 gfc_add_block_to_block (&body, &se.post);
1425 gfc_trans_scalarizing_loops (&loop, &body);
1427 gfc_add_block_to_block (&block, &loop.pre);
1428 gfc_add_block_to_block (&block, &loop.post);
1430 for (n = 0; n < cm->as->rank; n++)
1431 mpz_clear (ss->shape[n]);
1432 gfc_free (ss->shape);
1434 gfc_cleanup_loop (&loop);
1436 return gfc_finish_block (&block);
1439 /* Generate the call for a scalar transfer node. */
1442 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1444 tree args, tmp, function, arg2, field, expr;
1455 arg2 = build_int_cst (NULL_TREE, kind);
1456 function = iocall_x_integer;
1460 arg2 = build_int_cst (NULL_TREE, kind);
1461 function = iocall_x_real;
1465 arg2 = build_int_cst (NULL_TREE, kind);
1466 function = iocall_x_complex;
1470 arg2 = build_int_cst (NULL_TREE, kind);
1471 function = iocall_x_logical;
1475 if (se->string_length)
1476 arg2 = se->string_length;
1479 tmp = gfc_build_indirect_ref (addr_expr);
1480 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
1481 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
1483 function = iocall_x_character;
1487 /* Recurse into the elements of the derived type. */
1488 expr = gfc_evaluate_now (addr_expr, &se->pre);
1489 expr = gfc_build_indirect_ref (expr);
1491 for (c = ts->derived->components; c; c = c->next)
1493 field = c->backend_decl;
1494 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
1496 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), expr, field,
1501 tmp = transfer_array_component (tmp, c);
1502 gfc_add_expr_to_block (&se->pre, tmp);
1507 tmp = gfc_build_addr_expr (NULL, tmp);
1508 transfer_expr (se, &c->ts, tmp);
1514 internal_error ("Bad IO basetype (%d)", ts->type);
1517 args = gfc_chainon_list (NULL_TREE, addr_expr);
1518 args = gfc_chainon_list (args, arg2);
1520 tmp = gfc_build_function_call (function, args);
1521 gfc_add_expr_to_block (&se->pre, tmp);
1522 gfc_add_block_to_block (&se->pre, &se->post);
1527 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1530 gfc_trans_transfer (gfc_code * code)
1532 stmtblock_t block, body;
1539 gfc_start_block (&block);
1542 ss = gfc_walk_expr (expr);
1544 gfc_init_se (&se, NULL);
1546 if (ss == gfc_ss_terminator)
1547 gfc_init_block (&body);
1550 /* Initialize the scalarizer. */
1551 gfc_init_loopinfo (&loop);
1552 gfc_add_ss_to_loop (&loop, ss);
1554 /* Initialize the loop. */
1555 gfc_conv_ss_startstride (&loop);
1556 gfc_conv_loop_setup (&loop);
1558 /* The main loop body. */
1559 gfc_mark_ss_chain_used (ss, 1);
1560 gfc_start_scalarized_body (&loop, &body);
1562 gfc_copy_loopinfo_to_se (&se, &loop);
1566 gfc_conv_expr_reference (&se, expr);
1568 transfer_expr (&se, &expr->ts, se.expr);
1570 gfc_add_block_to_block (&body, &se.pre);
1571 gfc_add_block_to_block (&body, &se.post);
1574 tmp = gfc_finish_block (&body);
1577 gcc_assert (se.ss == gfc_ss_terminator);
1578 gfc_trans_scalarizing_loops (&loop, &body);
1580 gfc_add_block_to_block (&loop.pre, &loop.post);
1581 tmp = gfc_finish_block (&loop.pre);
1582 gfc_cleanup_loop (&loop);
1585 gfc_add_expr_to_block (&block, tmp);
1587 return gfc_finish_block (&block);
1590 #include "gt-fortran-trans-io.h"