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. */
65 typedef struct gfc_st_parameter_field GTY(())
69 enum ioparam_type param_type;
70 enum iofield_type type;
74 gfc_st_parameter_field;
76 typedef struct gfc_st_parameter GTY(())
85 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
91 static GTY(()) gfc_st_parameter st_parameter[] =
101 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
103 #define IOPARM(param_type, name, mask, type) \
104 { #name, mask, IOPARM_ptype_##param_type, IOPARM_type_##type, NULL, NULL },
105 #include "ioparm.def"
107 { NULL, 0, 0, 0, NULL, NULL }
110 /* Library I/O subroutines */
128 IOCALL_IOLENGTH_DONE,
134 IOCALL_SET_NML_VAL_DIM,
138 static GTY(()) tree iocall[IOCALL_NUM];
140 /* Variable for keeping track of what the last data transfer statement
141 was. Used for deciding which subroutine to call when the data
142 transfer is complete. */
143 static enum { READ, WRITE, IOLENGTH } last_dt;
145 /* The data transfer parameter block that should be shared by all
146 data transfer calls belonging to the same read/write/iolength. */
147 static GTY(()) tree dt_parm;
148 static stmtblock_t *dt_post_end_block;
151 gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
154 gfc_st_parameter_field *p;
157 tree t = make_node (RECORD_TYPE);
159 len = strlen (st_parameter[ptype].name);
160 gcc_assert (len <= sizeof (name) - sizeof ("__st_parameter_"));
161 memcpy (name, "__st_parameter_", sizeof ("__st_parameter_"));
162 memcpy (name + sizeof ("__st_parameter_") - 1, st_parameter[ptype].name,
164 TYPE_NAME (t) = get_identifier (name);
166 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
167 if (p->param_type == ptype)
170 case IOPARM_type_int4:
171 case IOPARM_type_pint4:
172 case IOPARM_type_parray:
173 case IOPARM_type_pchar:
174 case IOPARM_type_pad:
175 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
176 get_identifier (p->name),
179 case IOPARM_type_char1:
180 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
181 get_identifier (p->name),
184 case IOPARM_type_char2:
185 len = strlen (p->name);
186 gcc_assert (len <= sizeof (name) - sizeof ("_len"));
187 memcpy (name, p->name, len);
188 memcpy (name + len, "_len", sizeof ("_len"));
189 p->field_len = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
190 get_identifier (name),
191 gfc_charlen_type_node);
192 if (p->type == IOPARM_type_char2)
193 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
194 get_identifier (p->name),
197 case IOPARM_type_common:
199 = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
200 get_identifier (p->name),
201 st_parameter[IOPARM_ptype_common].type);
203 case IOPARM_type_num:
208 st_parameter[ptype].type = t;
211 /* Create function decls for IO library functions. */
214 gfc_build_io_library_fndecls (void)
216 tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
217 tree parm_type, dt_parm_type;
218 tree gfc_c_int_type_node;
219 HOST_WIDE_INT pad_size;
220 enum ioparam_type ptype;
222 types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
223 types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
224 types[IOPARM_type_parray] = pchar_type_node;
225 types[IOPARM_type_pchar] = pchar_type_node;
226 pad_size = 16 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (pchar_type_node));
227 pad_size += 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (integer_type_node));
228 pad_idx = build_index_type (build_int_cst (NULL_TREE, pad_size));
229 types[IOPARM_type_pad] = build_array_type (char_type_node, pad_idx);
231 /* pad actually contains pointers and integers so it needs to have an
232 alignment that is at least as large as the needed alignment for those
233 types. See the st_parameter_dt structure in libgfortran/io/io.h for
234 what really goes into this space. */
235 TYPE_ALIGN (types[IOPARM_type_pad]) = MAX (TYPE_ALIGN (pchar_type_node),
236 TYPE_ALIGN (gfc_get_int_type (gfc_max_integer_kind)));
238 gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind);
240 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
241 gfc_build_st_parameter (ptype, types);
243 /* Define the transfer functions. */
245 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
247 iocall[IOCALL_X_INTEGER] =
248 gfc_build_library_function_decl (get_identifier
249 (PREFIX("transfer_integer")),
250 void_type_node, 3, dt_parm_type,
251 pvoid_type_node, gfc_int4_type_node);
253 iocall[IOCALL_X_LOGICAL] =
254 gfc_build_library_function_decl (get_identifier
255 (PREFIX("transfer_logical")),
256 void_type_node, 3, dt_parm_type,
257 pvoid_type_node, gfc_int4_type_node);
259 iocall[IOCALL_X_CHARACTER] =
260 gfc_build_library_function_decl (get_identifier
261 (PREFIX("transfer_character")),
262 void_type_node, 3, dt_parm_type,
263 pvoid_type_node, gfc_int4_type_node);
265 iocall[IOCALL_X_REAL] =
266 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
267 void_type_node, 3, dt_parm_type,
268 pvoid_type_node, gfc_int4_type_node);
270 iocall[IOCALL_X_COMPLEX] =
271 gfc_build_library_function_decl (get_identifier
272 (PREFIX("transfer_complex")),
273 void_type_node, 3, dt_parm_type,
274 pvoid_type_node, gfc_int4_type_node);
276 iocall[IOCALL_X_ARRAY] =
277 gfc_build_library_function_decl (get_identifier
278 (PREFIX("transfer_array")),
279 void_type_node, 4, dt_parm_type,
280 pvoid_type_node, gfc_c_int_type_node,
281 gfc_charlen_type_node);
283 /* Library entry points */
285 iocall[IOCALL_READ] =
286 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
287 void_type_node, 1, dt_parm_type);
289 iocall[IOCALL_WRITE] =
290 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
291 void_type_node, 1, dt_parm_type);
293 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_open].type);
294 iocall[IOCALL_OPEN] =
295 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
296 void_type_node, 1, parm_type);
299 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_close].type);
300 iocall[IOCALL_CLOSE] =
301 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
302 void_type_node, 1, parm_type);
304 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_inquire].type);
305 iocall[IOCALL_INQUIRE] =
306 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
307 gfc_int4_type_node, 1, parm_type);
309 iocall[IOCALL_IOLENGTH] =
310 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
311 void_type_node, 1, dt_parm_type);
313 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_filepos].type);
314 iocall[IOCALL_REWIND] =
315 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
316 gfc_int4_type_node, 1, parm_type);
318 iocall[IOCALL_BACKSPACE] =
319 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
320 gfc_int4_type_node, 1, parm_type);
322 iocall[IOCALL_ENDFILE] =
323 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
324 gfc_int4_type_node, 1, parm_type);
326 iocall[IOCALL_FLUSH] =
327 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
328 gfc_int4_type_node, 1, parm_type);
330 /* Library helpers */
332 iocall[IOCALL_READ_DONE] =
333 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
334 gfc_int4_type_node, 1, dt_parm_type);
336 iocall[IOCALL_WRITE_DONE] =
337 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
338 gfc_int4_type_node, 1, dt_parm_type);
340 iocall[IOCALL_IOLENGTH_DONE] =
341 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
342 gfc_int4_type_node, 1, dt_parm_type);
345 iocall[IOCALL_SET_NML_VAL] =
346 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var")),
347 void_type_node, 6, dt_parm_type,
348 pvoid_type_node, pvoid_type_node,
349 gfc_int4_type_node, gfc_charlen_type_node,
352 iocall[IOCALL_SET_NML_VAL_DIM] =
353 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_dim")),
354 void_type_node, 5, dt_parm_type,
355 gfc_int4_type_node, gfc_int4_type_node,
356 gfc_int4_type_node, gfc_int4_type_node);
360 /* Generate code to store an integer constant into the
361 st_parameter_XXX structure. */
364 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
368 gfc_st_parameter_field *p = &st_parameter_field[type];
370 if (p->param_type == IOPARM_ptype_common)
371 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
372 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
373 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
375 gfc_add_modify_expr (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
380 /* Generate code to store a non-string I/O parameter into the
381 st_parameter_XXX structure. This is a pass by value. */
384 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
389 gfc_st_parameter_field *p = &st_parameter_field[type];
391 gfc_init_se (&se, NULL);
392 gfc_conv_expr_type (&se, e, TREE_TYPE (p->field));
393 gfc_add_block_to_block (block, &se.pre);
395 if (p->param_type == IOPARM_ptype_common)
396 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
397 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
398 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
400 gfc_add_modify_expr (block, tmp, se.expr);
405 /* Generate code to store a non-string I/O parameter into the
406 st_parameter_XXX structure. This is pass by reference. */
409 set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
410 tree var, enum iofield type, gfc_expr *e)
414 gfc_st_parameter_field *p = &st_parameter_field[type];
416 gcc_assert (e->ts.type == BT_INTEGER || e->ts.type == BT_LOGICAL);
417 gfc_init_se (&se, NULL);
418 gfc_conv_expr_lhs (&se, e);
420 gfc_add_block_to_block (block, &se.pre);
422 if (TYPE_MODE (TREE_TYPE (se.expr))
423 == TYPE_MODE (TREE_TYPE (TREE_TYPE (p->field))))
424 addr = convert (TREE_TYPE (p->field),
425 build_fold_addr_expr (se.expr));
428 /* The type used by the library has different size
429 from the type of the variable supplied by the user.
430 Need to use a temporary. */
432 = gfc_create_var (TREE_TYPE (TREE_TYPE (p->field)),
433 st_parameter_field[type].name);
434 addr = build_fold_addr_expr (tmpvar);
435 tmp = convert (TREE_TYPE (se.expr), tmpvar);
436 gfc_add_modify_expr (postblock, se.expr, tmp);
439 if (p->param_type == IOPARM_ptype_common)
440 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
441 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
442 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
444 gfc_add_modify_expr (block, tmp, addr);
448 /* Given an array expr, find its address and length to get a string. If the
449 array is full, the string's address is the address of array's first element
450 and the length is the size of the whole array. If it is an element, the
451 string's address is the element's address and the length is the rest size of
456 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
465 sym = e->symtree->n.sym;
466 rank = sym->as->rank - 1;
468 if (e->ref->u.ar.type == AR_FULL)
470 se->expr = gfc_get_symbol_decl (sym);
471 se->expr = gfc_conv_array_data (se->expr);
475 gfc_conv_expr (se, e);
478 array = sym->backend_decl;
479 type = TREE_TYPE (array);
481 if (GFC_ARRAY_TYPE_P (type))
482 size = GFC_TYPE_ARRAY_SIZE (type);
485 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
486 size = gfc_conv_array_stride (array, rank);
487 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
488 gfc_conv_array_ubound (array, rank),
489 gfc_conv_array_lbound (array, rank));
490 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
492 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
497 /* If it is an element, we need the its address and size of the rest. */
498 if (e->ref->u.ar.type == AR_ELEMENT)
500 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
501 TREE_OPERAND (se->expr, 1));
502 se->expr = build_fold_addr_expr (se->expr);
505 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
506 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
508 se->string_length = fold_convert (gfc_charlen_type_node, size);
512 /* Generate code to store a string and its length into the
513 st_parameter_XXX structure. */
516 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
517 enum iofield type, gfc_expr * e)
523 gfc_st_parameter_field *p = &st_parameter_field[type];
525 gfc_init_se (&se, NULL);
527 if (p->param_type == IOPARM_ptype_common)
528 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
529 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
530 io = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
532 len = build3 (COMPONENT_REF, TREE_TYPE (p->field_len), var, p->field_len,
535 /* Integer variable assigned a format label. */
536 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
540 gfc_conv_label_variable (&se, e);
541 tmp = GFC_DECL_STRING_LEN (se.expr);
542 tmp = fold_build2 (LT_EXPR, boolean_type_node,
543 tmp, build_int_cst (TREE_TYPE (tmp), 0));
545 asprintf(&msg, "Label assigned to variable '%s' is not a format label",
547 gfc_trans_runtime_check (tmp, msg, &se.pre, &e->where);
550 gfc_add_modify_expr (&se.pre, io,
551 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
552 gfc_add_modify_expr (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
556 /* General character. */
557 if (e->ts.type == BT_CHARACTER && e->rank == 0)
558 gfc_conv_expr (&se, e);
559 /* Array assigned Hollerith constant or character array. */
560 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
561 gfc_convert_array_to_string (&se, e);
565 gfc_conv_string_parameter (&se);
566 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
567 gfc_add_modify_expr (&se.pre, len, se.string_length);
570 gfc_add_block_to_block (block, &se.pre);
571 gfc_add_block_to_block (postblock, &se.post);
576 /* Generate code to store the character (array) and the character length
577 for an internal unit. */
580 set_internal_unit (stmtblock_t * block, tree var, gfc_expr * e)
587 gfc_st_parameter_field *p;
590 gfc_init_se (&se, NULL);
592 p = &st_parameter_field[IOPARM_dt_internal_unit];
594 io = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
596 len = build3 (COMPONENT_REF, TREE_TYPE (p->field_len), var, p->field_len,
598 p = &st_parameter_field[IOPARM_dt_internal_unit_desc];
599 desc = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
602 gcc_assert (e->ts.type == BT_CHARACTER);
604 /* Character scalars. */
607 gfc_conv_expr (&se, e);
608 gfc_conv_string_parameter (&se);
610 se.expr = fold_convert (pchar_type_node, integer_zero_node);
613 /* Character array. */
614 else if (e->rank > 0)
616 se.ss = gfc_walk_expr (e);
618 /* Return the data pointer and rank from the descriptor. */
619 gfc_conv_expr_descriptor (&se, e, se.ss);
620 tmp = gfc_conv_descriptor_data_get (se.expr);
621 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
626 /* The cast is needed for character substrings and the descriptor
628 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
629 gfc_add_modify_expr (&se.pre, len, se.string_length);
630 gfc_add_modify_expr (&se.pre, desc, se.expr);
632 gfc_add_block_to_block (block, &se.pre);
636 /* Add a case to a IO-result switch. */
639 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
644 return; /* No label, no case */
646 value = build_int_cst (NULL_TREE, label_value);
648 /* Make a backend label for this case. */
649 tmp = gfc_build_label_decl (NULL_TREE);
651 /* And the case itself. */
652 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
653 gfc_add_expr_to_block (body, tmp);
655 /* Jump to the label. */
656 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
657 gfc_add_expr_to_block (body, tmp);
661 /* Generate a switch statement that branches to the correct I/O
662 result label. The last statement of an I/O call stores the
663 result into a variable because there is often cleanup that
664 must be done before the switch, so a temporary would have to
665 be created anyway. */
668 io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
669 gfc_st_label * end_label, gfc_st_label * eor_label)
673 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
675 /* If no labels are specified, ignore the result instead
676 of building an empty switch. */
677 if (err_label == NULL
679 && eor_label == NULL)
682 /* Build a switch statement. */
683 gfc_start_block (&body);
685 /* The label values here must be the same as the values
686 in the library_return enum in the runtime library */
687 add_case (1, err_label, &body);
688 add_case (2, end_label, &body);
689 add_case (3, eor_label, &body);
691 tmp = gfc_finish_block (&body);
693 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
694 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
695 rc = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
697 rc = build2 (BIT_AND_EXPR, TREE_TYPE (rc), rc,
698 build_int_cst (TREE_TYPE (rc), IOPARM_common_libreturn_mask));
700 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
702 gfc_add_expr_to_block (block, tmp);
706 /* Store the current file and line number to variables so that if a
707 library call goes awry, we can tell the user where the problem is. */
710 set_error_locus (stmtblock_t * block, tree var, locus * where)
713 tree str, locus_file;
715 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
717 locus_file = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
718 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
719 locus_file = build3 (COMPONENT_REF, TREE_TYPE (p->field), locus_file,
720 p->field, NULL_TREE);
722 str = gfc_build_cstring_const (f->filename);
724 str = gfc_build_addr_expr (pchar_type_node, str);
725 gfc_add_modify_expr (block, locus_file, str);
727 #ifdef USE_MAPPED_LOCATION
728 line = LOCATION_LINE (where->lb->location);
730 line = where->lb->linenum;
732 set_parameter_const (block, var, IOPARM_common_line, line);
736 /* Translate an OPEN statement. */
739 gfc_trans_open (gfc_code * code)
741 stmtblock_t block, post_block;
744 unsigned int mask = 0;
746 gfc_start_block (&block);
747 gfc_init_block (&post_block);
749 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
751 set_error_locus (&block, var, &code->loc);
755 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
757 set_parameter_const (&block, var, IOPARM_common_unit, 0);
760 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
763 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
767 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
771 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
774 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl);
777 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
781 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
785 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
789 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
793 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
796 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
800 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
804 mask |= IOPARM_common_err;
807 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
810 set_parameter_const (&block, var, IOPARM_common_flags, mask);
812 tmp = build_fold_addr_expr (var);
813 tmp = gfc_chainon_list (NULL_TREE, tmp);
814 tmp = build_function_call_expr (iocall[IOCALL_OPEN], tmp);
815 gfc_add_expr_to_block (&block, tmp);
817 gfc_add_block_to_block (&block, &post_block);
819 io_result (&block, var, p->err, NULL, NULL);
821 return gfc_finish_block (&block);
825 /* Translate a CLOSE statement. */
828 gfc_trans_close (gfc_code * code)
830 stmtblock_t block, post_block;
833 unsigned int mask = 0;
835 gfc_start_block (&block);
836 gfc_init_block (&post_block);
838 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
840 set_error_locus (&block, var, &code->loc);
844 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
846 set_parameter_const (&block, var, IOPARM_common_unit, 0);
849 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
853 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
857 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
861 mask |= IOPARM_common_err;
863 set_parameter_const (&block, var, IOPARM_common_flags, mask);
865 tmp = build_fold_addr_expr (var);
866 tmp = gfc_chainon_list (NULL_TREE, tmp);
867 tmp = build_function_call_expr (iocall[IOCALL_CLOSE], tmp);
868 gfc_add_expr_to_block (&block, tmp);
870 gfc_add_block_to_block (&block, &post_block);
872 io_result (&block, var, p->err, NULL, NULL);
874 return gfc_finish_block (&block);
878 /* Common subroutine for building a file positioning statement. */
881 build_filepos (tree function, gfc_code * code)
883 stmtblock_t block, post_block;
886 unsigned int mask = 0;
888 p = code->ext.filepos;
890 gfc_start_block (&block);
891 gfc_init_block (&post_block);
893 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
896 set_error_locus (&block, var, &code->loc);
899 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
901 set_parameter_const (&block, var, IOPARM_common_unit, 0);
904 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
908 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
912 mask |= IOPARM_common_err;
914 set_parameter_const (&block, var, IOPARM_common_flags, mask);
916 tmp = build_fold_addr_expr (var);
917 tmp = gfc_chainon_list (NULL_TREE, tmp);
918 tmp = build_function_call_expr (function, tmp);
919 gfc_add_expr_to_block (&block, tmp);
921 gfc_add_block_to_block (&block, &post_block);
923 io_result (&block, var, p->err, NULL, NULL);
925 return gfc_finish_block (&block);
929 /* Translate a BACKSPACE statement. */
932 gfc_trans_backspace (gfc_code * code)
934 return build_filepos (iocall[IOCALL_BACKSPACE], code);
938 /* Translate an ENDFILE statement. */
941 gfc_trans_endfile (gfc_code * code)
943 return build_filepos (iocall[IOCALL_ENDFILE], code);
947 /* Translate a REWIND statement. */
950 gfc_trans_rewind (gfc_code * code)
952 return build_filepos (iocall[IOCALL_REWIND], code);
956 /* Translate a FLUSH statement. */
959 gfc_trans_flush (gfc_code * code)
961 return build_filepos (iocall[IOCALL_FLUSH], code);
965 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
968 gfc_trans_inquire (gfc_code * code)
970 stmtblock_t block, post_block;
973 unsigned int mask = 0;
975 gfc_start_block (&block);
976 gfc_init_block (&post_block);
978 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
981 set_error_locus (&block, var, &code->loc);
982 p = code->ext.inquire;
985 if (p->unit && p->file)
986 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers.", &code->loc);
989 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
991 set_parameter_const (&block, var, IOPARM_common_unit, 0);
994 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
998 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1002 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1006 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1010 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1014 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1018 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1022 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1026 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1030 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1034 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1038 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1042 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1046 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1050 mask |= set_parameter_ref (&block, &post_block, var,
1051 IOPARM_inquire_recl_out, p->recl);
1054 mask |= set_parameter_ref (&block, &post_block, var,
1055 IOPARM_inquire_nextrec, p->nextrec);
1058 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1062 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1066 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1070 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1074 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1078 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1082 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1086 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1090 mask |= IOPARM_common_err;
1093 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1096 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1098 tmp = build_fold_addr_expr (var);
1099 tmp = gfc_chainon_list (NULL_TREE, tmp);
1100 tmp = build_function_call_expr (iocall[IOCALL_INQUIRE], tmp);
1101 gfc_add_expr_to_block (&block, tmp);
1103 gfc_add_block_to_block (&block, &post_block);
1105 io_result (&block, var, p->err, NULL, NULL);
1107 return gfc_finish_block (&block);
1111 gfc_new_nml_name_expr (const char * name)
1113 gfc_expr * nml_name;
1115 nml_name = gfc_get_expr();
1116 nml_name->ref = NULL;
1117 nml_name->expr_type = EXPR_CONSTANT;
1118 nml_name->ts.kind = gfc_default_character_kind;
1119 nml_name->ts.type = BT_CHARACTER;
1120 nml_name->value.character.length = strlen(name);
1121 nml_name->value.character.string = gfc_getmem (strlen (name) + 1);
1122 strcpy (nml_name->value.character.string, name);
1127 /* nml_full_name builds up the fully qualified name of a
1128 derived type component. */
1131 nml_full_name (const char* var_name, const char* cmp_name)
1133 int full_name_length;
1136 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1137 full_name = (char*)gfc_getmem (full_name_length + 1);
1138 strcpy (full_name, var_name);
1139 full_name = strcat (full_name, "%");
1140 full_name = strcat (full_name, cmp_name);
1144 /* nml_get_addr_expr builds an address expression from the
1145 gfc_symbol or gfc_component backend_decl's. An offset is
1146 provided so that the address of an element of an array of
1147 derived types is returned. This is used in the runtime to
1148 determine that span of the derived type. */
1151 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1154 tree decl = NULL_TREE;
1158 int dummy_arg_flagged;
1162 sym->attr.referenced = 1;
1163 decl = gfc_get_symbol_decl (sym);
1166 decl = c->backend_decl;
1168 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1169 || TREE_CODE (decl) == VAR_DECL
1170 || TREE_CODE (decl) == PARM_DECL)
1171 || TREE_CODE (decl) == COMPONENT_REF));
1175 /* Build indirect reference, if dummy argument. */
1177 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1179 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref (tmp) : tmp;
1181 /* If an array, set flag and use indirect ref. if built. */
1183 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1184 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1189 /* Treat the component of a derived type, using base_addr for
1190 the derived type. */
1192 if (TREE_CODE (decl) == FIELD_DECL)
1193 tmp = build3 (COMPONENT_REF, TREE_TYPE (tmp),
1194 base_addr, tmp, NULL_TREE);
1196 /* If we have a derived type component, a reference to the first
1197 element of the array is built. This is done so that base_addr,
1198 used in the build of the component reference, always points to
1202 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node);
1204 /* Now build the address expression. */
1206 tmp = build_fold_addr_expr (tmp);
1208 /* If scalar dummy, resolve indirect reference now. */
1210 if (dummy_arg_flagged && !array_flagged)
1211 tmp = build_fold_indirect_ref (tmp);
1213 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1218 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1219 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1220 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1222 #define NML_FIRST_ARG(a) args = gfc_chainon_list (NULL_TREE, a)
1223 #define NML_ADD_ARG(a) args = gfc_chainon_list (args, a)
1224 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1227 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1228 gfc_symbol * sym, gfc_component * c,
1231 gfc_typespec * ts = NULL;
1232 gfc_array_spec * as = NULL;
1233 tree addr_expr = NULL;
1244 gcc_assert (sym || c);
1246 /* Build the namelist object name. */
1248 string = gfc_build_cstring_const (var_name);
1249 string = gfc_build_addr_expr (pchar_type_node, string);
1251 /* Build ts, as and data address using symbol or component. */
1253 ts = (sym) ? &sym->ts : &c->ts;
1254 as = (sym) ? sym->as : c->as;
1256 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1263 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1264 dtype = gfc_get_dtype (dt);
1268 itype = GFC_DTYPE_UNKNOWN;
1274 itype = GFC_DTYPE_INTEGER;
1277 itype = GFC_DTYPE_LOGICAL;
1280 itype = GFC_DTYPE_REAL;
1283 itype = GFC_DTYPE_COMPLEX;
1286 itype = GFC_DTYPE_DERIVED;
1289 itype = GFC_DTYPE_CHARACTER;
1295 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1298 /* Build up the arguments for the transfer call.
1299 The call for the scalar part transfers:
1300 (address, name, type, kind or string_length, dtype) */
1302 dt_parm_addr = build_fold_addr_expr (dt_parm);
1303 NML_FIRST_ARG (dt_parm_addr);
1304 NML_ADD_ARG (addr_expr);
1305 NML_ADD_ARG (string);
1306 NML_ADD_ARG (IARG (ts->kind));
1308 if (ts->type == BT_CHARACTER)
1309 NML_ADD_ARG (ts->cl->backend_decl);
1311 NML_ADD_ARG (convert (gfc_charlen_type_node, integer_zero_node));
1313 NML_ADD_ARG (dtype);
1314 tmp = build_function_call_expr (iocall[IOCALL_SET_NML_VAL], args);
1315 gfc_add_expr_to_block (block, tmp);
1317 /* If the object is an array, transfer rank times:
1318 (null pointer, name, stride, lbound, ubound) */
1320 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1322 NML_FIRST_ARG (dt_parm_addr);
1323 NML_ADD_ARG (IARG (n_dim));
1324 NML_ADD_ARG (GFC_TYPE_ARRAY_STRIDE (dt, n_dim));
1325 NML_ADD_ARG (GFC_TYPE_ARRAY_LBOUND (dt, n_dim));
1326 NML_ADD_ARG (GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1327 tmp = build_function_call_expr (iocall[IOCALL_SET_NML_VAL_DIM], args);
1328 gfc_add_expr_to_block (block, tmp);
1331 if (ts->type == BT_DERIVED)
1335 /* Provide the RECORD_TYPE to build component references. */
1337 tree expr = build_fold_indirect_ref (addr_expr);
1339 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1341 char *full_name = nml_full_name (var_name, cmp->name);
1342 transfer_namelist_element (block,
1345 gfc_free (full_name);
1352 #undef NML_FIRST_ARG
1354 /* Create a data transfer statement. Not all of the fields are valid
1355 for both reading and writing, but improper use has been filtered
1359 build_dt (tree function, gfc_code * code)
1361 stmtblock_t block, post_block, post_end_block;
1366 unsigned int mask = 0;
1368 gfc_start_block (&block);
1369 gfc_init_block (&post_block);
1370 gfc_init_block (&post_end_block);
1372 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1374 set_error_locus (&block, var, &code->loc);
1376 if (last_dt == IOLENGTH)
1380 inq = code->ext.inquire;
1382 /* First check that preconditions are met. */
1383 gcc_assert (inq != NULL);
1384 gcc_assert (inq->iolength != NULL);
1386 /* Connect to the iolength variable. */
1387 mask |= set_parameter_ref (&block, &post_end_block, var,
1388 IOPARM_dt_iolength, inq->iolength);
1394 gcc_assert (dt != NULL);
1397 if (dt && dt->io_unit)
1399 if (dt->io_unit->ts.type == BT_CHARACTER)
1401 mask |= set_internal_unit (&block, var, dt->io_unit);
1402 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1405 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1408 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1413 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1416 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1419 if (dt->format_expr)
1420 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1423 if (dt->format_label)
1425 if (dt->format_label == &format_asterisk)
1426 mask |= IOPARM_dt_list_format;
1428 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1429 dt->format_label->format);
1433 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1437 mask |= set_parameter_ref (&block, &post_end_block, var,
1438 IOPARM_common_iostat, dt->iostat);
1441 mask |= set_parameter_ref (&block, &post_end_block, var,
1442 IOPARM_dt_size, dt->size);
1445 mask |= IOPARM_common_err;
1448 mask |= IOPARM_common_eor;
1451 mask |= IOPARM_common_end;
1455 if (dt->format_expr || dt->format_label)
1456 gfc_internal_error ("build_dt: format with namelist");
1458 nmlname = gfc_new_nml_name_expr (dt->namelist->name);
1460 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1463 if (last_dt == READ)
1464 mask |= IOPARM_dt_namelist_read_mode;
1466 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1470 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1471 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1475 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1478 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1480 tmp = build_fold_addr_expr (var);
1481 tmp = gfc_chainon_list (NULL_TREE, tmp);
1482 tmp = build_function_call_expr (function, tmp);
1483 gfc_add_expr_to_block (&block, tmp);
1485 gfc_add_block_to_block (&block, &post_block);
1488 dt_post_end_block = &post_end_block;
1490 gfc_add_expr_to_block (&block, gfc_trans_code (code->block->next));
1493 dt_post_end_block = NULL;
1495 return gfc_finish_block (&block);
1499 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1500 this as a third sort of data transfer statement, except that
1501 lengths are summed instead of actually transferring any data. */
1504 gfc_trans_iolength (gfc_code * code)
1507 return build_dt (iocall[IOCALL_IOLENGTH], code);
1511 /* Translate a READ statement. */
1514 gfc_trans_read (gfc_code * code)
1517 return build_dt (iocall[IOCALL_READ], code);
1521 /* Translate a WRITE statement */
1524 gfc_trans_write (gfc_code * code)
1527 return build_dt (iocall[IOCALL_WRITE], code);
1531 /* Finish a data transfer statement. */
1534 gfc_trans_dt_end (gfc_code * code)
1539 gfc_init_block (&block);
1544 function = iocall[IOCALL_READ_DONE];
1548 function = iocall[IOCALL_WRITE_DONE];
1552 function = iocall[IOCALL_IOLENGTH_DONE];
1559 tmp = build_fold_addr_expr (dt_parm);
1560 tmp = gfc_chainon_list (NULL_TREE, tmp);
1561 tmp = build_function_call_expr (function, tmp);
1562 gfc_add_expr_to_block (&block, tmp);
1563 gfc_add_block_to_block (&block, dt_post_end_block);
1564 gfc_init_block (dt_post_end_block);
1566 if (last_dt != IOLENGTH)
1568 gcc_assert (code->ext.dt != NULL);
1569 io_result (&block, dt_parm, code->ext.dt->err,
1570 code->ext.dt->end, code->ext.dt->eor);
1573 return gfc_finish_block (&block);
1577 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr);
1579 /* Given an array field in a derived type variable, generate the code
1580 for the loop that iterates over array elements, and the code that
1581 accesses those array elements. Use transfer_expr to generate code
1582 for transferring that element. Because elements may also be
1583 derived types, transfer_expr and transfer_array_component are mutually
1587 transfer_array_component (tree expr, gfc_component * cm)
1597 gfc_start_block (&block);
1598 gfc_init_se (&se, NULL);
1600 /* Create and initialize Scalarization Status. Unlike in
1601 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1602 care of this task, because we don't have a gfc_expr at hand.
1603 Build one manually, as in gfc_trans_subarray_assign. */
1606 ss->type = GFC_SS_COMPONENT;
1608 ss->shape = gfc_get_shape (cm->as->rank);
1609 ss->next = gfc_ss_terminator;
1610 ss->data.info.dimen = cm->as->rank;
1611 ss->data.info.descriptor = expr;
1612 ss->data.info.data = gfc_conv_array_data (expr);
1613 ss->data.info.offset = gfc_conv_array_offset (expr);
1614 for (n = 0; n < cm->as->rank; n++)
1616 ss->data.info.dim[n] = n;
1617 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1618 ss->data.info.stride[n] = gfc_index_one_node;
1620 mpz_init (ss->shape[n]);
1621 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1622 cm->as->lower[n]->value.integer);
1623 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1626 /* Once we got ss, we use scalarizer to create the loop. */
1628 gfc_init_loopinfo (&loop);
1629 gfc_add_ss_to_loop (&loop, ss);
1630 gfc_conv_ss_startstride (&loop);
1631 gfc_conv_loop_setup (&loop);
1632 gfc_mark_ss_chain_used (ss, 1);
1633 gfc_start_scalarized_body (&loop, &body);
1635 gfc_copy_loopinfo_to_se (&se, &loop);
1638 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1640 gfc_conv_tmp_array_ref (&se);
1642 /* Now se.expr contains an element of the array. Take the address and pass
1643 it to the IO routines. */
1644 tmp = build_fold_addr_expr (se.expr);
1645 transfer_expr (&se, &cm->ts, tmp);
1647 /* We are done now with the loop body. Wrap up the scalarizer and
1650 gfc_add_block_to_block (&body, &se.pre);
1651 gfc_add_block_to_block (&body, &se.post);
1653 gfc_trans_scalarizing_loops (&loop, &body);
1655 gfc_add_block_to_block (&block, &loop.pre);
1656 gfc_add_block_to_block (&block, &loop.post);
1658 for (n = 0; n < cm->as->rank; n++)
1659 mpz_clear (ss->shape[n]);
1660 gfc_free (ss->shape);
1662 gfc_cleanup_loop (&loop);
1664 return gfc_finish_block (&block);
1667 /* Generate the call for a scalar transfer node. */
1670 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1672 tree args, tmp, function, arg2, field, expr;
1683 arg2 = build_int_cst (NULL_TREE, kind);
1684 function = iocall[IOCALL_X_INTEGER];
1688 arg2 = build_int_cst (NULL_TREE, kind);
1689 function = iocall[IOCALL_X_REAL];
1693 arg2 = build_int_cst (NULL_TREE, kind);
1694 function = iocall[IOCALL_X_COMPLEX];
1698 arg2 = build_int_cst (NULL_TREE, kind);
1699 function = iocall[IOCALL_X_LOGICAL];
1703 if (se->string_length)
1704 arg2 = se->string_length;
1707 tmp = build_fold_indirect_ref (addr_expr);
1708 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
1709 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
1711 function = iocall[IOCALL_X_CHARACTER];
1715 /* Recurse into the elements of the derived type. */
1716 expr = gfc_evaluate_now (addr_expr, &se->pre);
1717 expr = build_fold_indirect_ref (expr);
1719 for (c = ts->derived->components; c; c = c->next)
1721 field = c->backend_decl;
1722 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
1724 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), expr, field,
1729 tmp = transfer_array_component (tmp, c);
1730 gfc_add_expr_to_block (&se->pre, tmp);
1735 tmp = build_fold_addr_expr (tmp);
1736 transfer_expr (se, &c->ts, tmp);
1742 internal_error ("Bad IO basetype (%d)", ts->type);
1745 tmp = build_fold_addr_expr (dt_parm);
1746 args = gfc_chainon_list (NULL_TREE, tmp);
1747 args = gfc_chainon_list (args, addr_expr);
1748 args = gfc_chainon_list (args, arg2);
1750 tmp = build_function_call_expr (function, args);
1751 gfc_add_expr_to_block (&se->pre, tmp);
1752 gfc_add_block_to_block (&se->pre, &se->post);
1757 /* Generate a call to pass an array descriptor to the IO library. The
1758 array should be of one of the intrinsic types. */
1761 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1763 tree args, tmp, charlen_arg, kind_arg;
1765 if (ts->type == BT_CHARACTER)
1766 charlen_arg = se->string_length;
1768 charlen_arg = build_int_cstu (NULL_TREE, 0);
1770 kind_arg = build_int_cst (NULL_TREE, ts->kind);
1772 tmp = build_fold_addr_expr (dt_parm);
1773 args = gfc_chainon_list (NULL_TREE, tmp);
1774 args = gfc_chainon_list (args, addr_expr);
1775 args = gfc_chainon_list (args, kind_arg);
1776 args = gfc_chainon_list (args, charlen_arg);
1777 tmp = build_function_call_expr (iocall[IOCALL_X_ARRAY], args);
1778 gfc_add_expr_to_block (&se->pre, tmp);
1779 gfc_add_block_to_block (&se->pre, &se->post);
1783 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1786 gfc_trans_transfer (gfc_code * code)
1788 stmtblock_t block, body;
1796 gfc_start_block (&block);
1797 gfc_init_block (&body);
1800 ss = gfc_walk_expr (expr);
1803 gfc_init_se (&se, NULL);
1805 if (ss == gfc_ss_terminator)
1807 /* Transfer a scalar value. */
1808 gfc_conv_expr_reference (&se, expr);
1809 transfer_expr (&se, &expr->ts, se.expr);
1813 /* Transfer an array. If it is an array of an intrinsic
1814 type, pass the descriptor to the library. Otherwise
1815 scalarize the transfer. */
1818 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
1820 gcc_assert (ref->type == REF_ARRAY);
1823 if (expr->ts.type != BT_DERIVED && ref && ref->next == NULL)
1825 /* Get the descriptor. */
1826 gfc_conv_expr_descriptor (&se, expr, ss);
1827 tmp = build_fold_addr_expr (se.expr);
1828 transfer_array_desc (&se, &expr->ts, tmp);
1829 goto finish_block_label;
1832 /* Initialize the scalarizer. */
1833 gfc_init_loopinfo (&loop);
1834 gfc_add_ss_to_loop (&loop, ss);
1836 /* Initialize the loop. */
1837 gfc_conv_ss_startstride (&loop);
1838 gfc_conv_loop_setup (&loop);
1840 /* The main loop body. */
1841 gfc_mark_ss_chain_used (ss, 1);
1842 gfc_start_scalarized_body (&loop, &body);
1844 gfc_copy_loopinfo_to_se (&se, &loop);
1847 gfc_conv_expr_reference (&se, expr);
1848 transfer_expr (&se, &expr->ts, se.expr);
1853 gfc_add_block_to_block (&body, &se.pre);
1854 gfc_add_block_to_block (&body, &se.post);
1857 tmp = gfc_finish_block (&body);
1860 gcc_assert (se.ss == gfc_ss_terminator);
1861 gfc_trans_scalarizing_loops (&loop, &body);
1863 gfc_add_block_to_block (&loop.pre, &loop.post);
1864 tmp = gfc_finish_block (&loop.pre);
1865 gfc_cleanup_loop (&loop);
1868 gfc_add_expr_to_block (&block, tmp);
1870 return gfc_finish_block (&block);
1873 #include "gt-fortran-trans-io.h"