1 /* IO Code translation/library interface
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software
4 Contributed by Paul Brook
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "coretypes.h"
28 #include "tree-gimple.h"
34 #include "trans-stmt.h"
35 #include "trans-array.h"
36 #include "trans-types.h"
37 #include "trans-const.h"
39 /* Members of the ioparm structure. */
67 typedef struct gfc_st_parameter_field GTY(())
71 enum ioparam_type param_type;
72 enum iofield_type type;
76 gfc_st_parameter_field;
78 typedef struct gfc_st_parameter GTY(())
87 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
93 static GTY(()) gfc_st_parameter st_parameter[] =
103 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
105 #define IOPARM(param_type, name, mask, type) \
106 { #name, mask, IOPARM_ptype_##param_type, IOPARM_type_##type, NULL, NULL },
107 #include "ioparm.def"
109 { NULL, 0, 0, 0, NULL, NULL }
112 /* Library I/O subroutines */
130 IOCALL_IOLENGTH_DONE,
136 IOCALL_SET_NML_VAL_DIM,
140 static GTY(()) tree iocall[IOCALL_NUM];
142 /* Variable for keeping track of what the last data transfer statement
143 was. Used for deciding which subroutine to call when the data
144 transfer is complete. */
145 static enum { READ, WRITE, IOLENGTH } last_dt;
147 /* The data transfer parameter block that should be shared by all
148 data transfer calls belonging to the same read/write/iolength. */
149 static GTY(()) tree dt_parm;
150 static stmtblock_t *dt_post_end_block;
153 gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
156 gfc_st_parameter_field *p;
159 tree t = make_node (RECORD_TYPE);
161 len = strlen (st_parameter[ptype].name);
162 gcc_assert (len <= sizeof (name) - sizeof ("__st_parameter_"));
163 memcpy (name, "__st_parameter_", sizeof ("__st_parameter_"));
164 memcpy (name + sizeof ("__st_parameter_") - 1, st_parameter[ptype].name,
166 TYPE_NAME (t) = get_identifier (name);
168 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
169 if (p->param_type == ptype)
172 case IOPARM_type_int4:
173 case IOPARM_type_intio:
174 case IOPARM_type_pint4:
175 case IOPARM_type_pintio:
176 case IOPARM_type_parray:
177 case IOPARM_type_pchar:
178 case IOPARM_type_pad:
179 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
180 get_identifier (p->name),
183 case IOPARM_type_char1:
184 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
185 get_identifier (p->name),
188 case IOPARM_type_char2:
189 len = strlen (p->name);
190 gcc_assert (len <= sizeof (name) - sizeof ("_len"));
191 memcpy (name, p->name, len);
192 memcpy (name + len, "_len", sizeof ("_len"));
193 p->field_len = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
194 get_identifier (name),
195 gfc_charlen_type_node);
196 if (p->type == IOPARM_type_char2)
197 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
198 get_identifier (p->name),
201 case IOPARM_type_common:
203 = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
204 get_identifier (p->name),
205 st_parameter[IOPARM_ptype_common].type);
207 case IOPARM_type_num:
212 st_parameter[ptype].type = t;
215 /* Create function decls for IO library functions. */
218 gfc_build_io_library_fndecls (void)
220 tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
221 tree gfc_intio_type_node;
222 tree parm_type, dt_parm_type;
223 tree gfc_c_int_type_node;
224 HOST_WIDE_INT pad_size;
225 enum ioparam_type ptype;
227 types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
228 types[IOPARM_type_intio] = gfc_intio_type_node
229 = gfc_get_int_type (gfc_intio_kind);
230 types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
231 types[IOPARM_type_pintio]
232 = build_pointer_type (gfc_intio_type_node);
233 types[IOPARM_type_parray] = pchar_type_node;
234 types[IOPARM_type_pchar] = pchar_type_node;
235 pad_size = 16 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (pchar_type_node));
236 pad_size += 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (integer_type_node));
237 pad_idx = build_index_type (build_int_cst (NULL_TREE, pad_size));
238 types[IOPARM_type_pad] = build_array_type (char_type_node, pad_idx);
240 /* pad actually contains pointers and integers so it needs to have an
241 alignment that is at least as large as the needed alignment for those
242 types. See the st_parameter_dt structure in libgfortran/io/io.h for
243 what really goes into this space. */
244 TYPE_ALIGN (types[IOPARM_type_pad]) = MAX (TYPE_ALIGN (pchar_type_node),
245 TYPE_ALIGN (gfc_get_int_type (gfc_max_integer_kind)));
247 gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind);
249 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
250 gfc_build_st_parameter (ptype, types);
252 /* Define the transfer functions. */
254 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
256 iocall[IOCALL_X_INTEGER] =
257 gfc_build_library_function_decl (get_identifier
258 (PREFIX("transfer_integer")),
259 void_type_node, 3, dt_parm_type,
260 pvoid_type_node, gfc_int4_type_node);
262 iocall[IOCALL_X_LOGICAL] =
263 gfc_build_library_function_decl (get_identifier
264 (PREFIX("transfer_logical")),
265 void_type_node, 3, dt_parm_type,
266 pvoid_type_node, gfc_int4_type_node);
268 iocall[IOCALL_X_CHARACTER] =
269 gfc_build_library_function_decl (get_identifier
270 (PREFIX("transfer_character")),
271 void_type_node, 3, dt_parm_type,
272 pvoid_type_node, gfc_int4_type_node);
274 iocall[IOCALL_X_REAL] =
275 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
276 void_type_node, 3, dt_parm_type,
277 pvoid_type_node, gfc_int4_type_node);
279 iocall[IOCALL_X_COMPLEX] =
280 gfc_build_library_function_decl (get_identifier
281 (PREFIX("transfer_complex")),
282 void_type_node, 3, dt_parm_type,
283 pvoid_type_node, gfc_int4_type_node);
285 iocall[IOCALL_X_ARRAY] =
286 gfc_build_library_function_decl (get_identifier
287 (PREFIX("transfer_array")),
288 void_type_node, 4, dt_parm_type,
289 pvoid_type_node, gfc_c_int_type_node,
290 gfc_charlen_type_node);
292 /* Library entry points */
294 iocall[IOCALL_READ] =
295 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
296 void_type_node, 1, dt_parm_type);
298 iocall[IOCALL_WRITE] =
299 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
300 void_type_node, 1, dt_parm_type);
302 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_open].type);
303 iocall[IOCALL_OPEN] =
304 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
305 void_type_node, 1, parm_type);
308 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_close].type);
309 iocall[IOCALL_CLOSE] =
310 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
311 void_type_node, 1, parm_type);
313 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_inquire].type);
314 iocall[IOCALL_INQUIRE] =
315 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
316 gfc_int4_type_node, 1, parm_type);
318 iocall[IOCALL_IOLENGTH] =
319 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
320 void_type_node, 1, dt_parm_type);
322 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_filepos].type);
323 iocall[IOCALL_REWIND] =
324 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
325 gfc_int4_type_node, 1, parm_type);
327 iocall[IOCALL_BACKSPACE] =
328 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
329 gfc_int4_type_node, 1, parm_type);
331 iocall[IOCALL_ENDFILE] =
332 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
333 gfc_int4_type_node, 1, parm_type);
335 iocall[IOCALL_FLUSH] =
336 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
337 gfc_int4_type_node, 1, parm_type);
339 /* Library helpers */
341 iocall[IOCALL_READ_DONE] =
342 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
343 gfc_int4_type_node, 1, dt_parm_type);
345 iocall[IOCALL_WRITE_DONE] =
346 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
347 gfc_int4_type_node, 1, dt_parm_type);
349 iocall[IOCALL_IOLENGTH_DONE] =
350 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
351 gfc_int4_type_node, 1, dt_parm_type);
354 iocall[IOCALL_SET_NML_VAL] =
355 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var")),
356 void_type_node, 6, dt_parm_type,
357 pvoid_type_node, pvoid_type_node,
358 gfc_int4_type_node, gfc_charlen_type_node,
361 iocall[IOCALL_SET_NML_VAL_DIM] =
362 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_dim")),
363 void_type_node, 5, dt_parm_type,
364 gfc_int4_type_node, gfc_int4_type_node,
365 gfc_int4_type_node, gfc_int4_type_node);
369 /* Generate code to store an integer constant into the
370 st_parameter_XXX structure. */
373 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
377 gfc_st_parameter_field *p = &st_parameter_field[type];
379 if (p->param_type == IOPARM_ptype_common)
380 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
381 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
382 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
384 gfc_add_modify_expr (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
389 /* Generate code to store a non-string I/O parameter into the
390 st_parameter_XXX structure. This is a pass by value. */
393 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
398 gfc_st_parameter_field *p = &st_parameter_field[type];
400 gfc_init_se (&se, NULL);
401 gfc_conv_expr_type (&se, e, TREE_TYPE (p->field));
402 gfc_add_block_to_block (block, &se.pre);
404 if (p->param_type == IOPARM_ptype_common)
405 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
406 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
407 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
409 gfc_add_modify_expr (block, tmp, se.expr);
414 /* Generate code to store a non-string I/O parameter into the
415 st_parameter_XXX structure. This is pass by reference. */
418 set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
419 tree var, enum iofield type, gfc_expr *e)
423 gfc_st_parameter_field *p = &st_parameter_field[type];
425 gcc_assert (e->ts.type == BT_INTEGER || e->ts.type == BT_LOGICAL);
426 gfc_init_se (&se, NULL);
427 gfc_conv_expr_lhs (&se, e);
429 gfc_add_block_to_block (block, &se.pre);
431 if (TYPE_MODE (TREE_TYPE (se.expr))
432 == TYPE_MODE (TREE_TYPE (TREE_TYPE (p->field))))
433 addr = convert (TREE_TYPE (p->field),
434 build_fold_addr_expr (se.expr));
437 /* The type used by the library has different size
438 from the type of the variable supplied by the user.
439 Need to use a temporary. */
441 = gfc_create_var (TREE_TYPE (TREE_TYPE (p->field)),
442 st_parameter_field[type].name);
443 addr = build_fold_addr_expr (tmpvar);
444 tmp = convert (TREE_TYPE (se.expr), tmpvar);
445 gfc_add_modify_expr (postblock, se.expr, tmp);
448 if (p->param_type == IOPARM_ptype_common)
449 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
450 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
451 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
453 gfc_add_modify_expr (block, tmp, addr);
457 /* Given an array expr, find its address and length to get a string. If the
458 array is full, the string's address is the address of array's first element
459 and the length is the size of the whole array. If it is an element, the
460 string's address is the element's address and the length is the rest size of
465 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
474 sym = e->symtree->n.sym;
475 rank = sym->as->rank - 1;
477 if (e->ref->u.ar.type == AR_FULL)
479 se->expr = gfc_get_symbol_decl (sym);
480 se->expr = gfc_conv_array_data (se->expr);
484 gfc_conv_expr (se, e);
487 array = sym->backend_decl;
488 type = TREE_TYPE (array);
490 if (GFC_ARRAY_TYPE_P (type))
491 size = GFC_TYPE_ARRAY_SIZE (type);
494 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
495 size = gfc_conv_array_stride (array, rank);
496 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
497 gfc_conv_array_ubound (array, rank),
498 gfc_conv_array_lbound (array, rank));
499 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
501 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
506 /* If it is an element, we need the its address and size of the rest. */
507 if (e->ref->u.ar.type == AR_ELEMENT)
509 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
510 TREE_OPERAND (se->expr, 1));
511 se->expr = build_fold_addr_expr (se->expr);
514 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
515 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
517 se->string_length = fold_convert (gfc_charlen_type_node, size);
521 /* Generate code to store a string and its length into the
522 st_parameter_XXX structure. */
525 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
526 enum iofield type, gfc_expr * e)
532 gfc_st_parameter_field *p = &st_parameter_field[type];
534 gfc_init_se (&se, NULL);
536 if (p->param_type == IOPARM_ptype_common)
537 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
538 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
539 io = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
541 len = build3 (COMPONENT_REF, TREE_TYPE (p->field_len), var, p->field_len,
544 /* Integer variable assigned a format label. */
545 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
549 gfc_conv_label_variable (&se, e);
550 tmp = GFC_DECL_STRING_LEN (se.expr);
551 tmp = fold_build2 (LT_EXPR, boolean_type_node,
552 tmp, build_int_cst (TREE_TYPE (tmp), 0));
554 asprintf(&msg, "Label assigned to variable '%s' is not a format label",
556 gfc_trans_runtime_check (tmp, msg, &se.pre, &e->where);
559 gfc_add_modify_expr (&se.pre, io,
560 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
561 gfc_add_modify_expr (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
565 /* General character. */
566 if (e->ts.type == BT_CHARACTER && e->rank == 0)
567 gfc_conv_expr (&se, e);
568 /* Array assigned Hollerith constant or character array. */
569 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
570 gfc_convert_array_to_string (&se, e);
574 gfc_conv_string_parameter (&se);
575 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
576 gfc_add_modify_expr (&se.pre, len, se.string_length);
579 gfc_add_block_to_block (block, &se.pre);
580 gfc_add_block_to_block (postblock, &se.post);
585 /* Generate code to store the character (array) and the character length
586 for an internal unit. */
589 set_internal_unit (stmtblock_t * block, stmtblock_t * post_block,
590 tree var, gfc_expr * e)
597 gfc_st_parameter_field *p;
600 gfc_init_se (&se, NULL);
602 p = &st_parameter_field[IOPARM_dt_internal_unit];
604 io = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
606 len = build3 (COMPONENT_REF, TREE_TYPE (p->field_len), var, p->field_len,
608 p = &st_parameter_field[IOPARM_dt_internal_unit_desc];
609 desc = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
612 gcc_assert (e->ts.type == BT_CHARACTER);
614 /* Character scalars. */
617 gfc_conv_expr (&se, e);
618 gfc_conv_string_parameter (&se);
620 se.expr = build_int_cst (pchar_type_node, 0);
623 /* Character array. */
624 else if (e->rank > 0)
626 se.ss = gfc_walk_expr (e);
628 if (is_aliased_array (e))
630 /* Use a temporary for components of arrays of derived types
631 or substring array references. */
632 gfc_conv_aliased_arg (&se, e, 0,
633 last_dt == READ ? INTENT_IN : INTENT_OUT);
634 tmp = build_fold_indirect_ref (se.expr);
635 se.expr = gfc_build_addr_expr (pchar_type_node, tmp);
636 tmp = gfc_conv_descriptor_data_get (tmp);
640 /* Return the data pointer and rank from the descriptor. */
641 gfc_conv_expr_descriptor (&se, e, se.ss);
642 tmp = gfc_conv_descriptor_data_get (se.expr);
643 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
649 /* The cast is needed for character substrings and the descriptor
651 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
652 gfc_add_modify_expr (&se.pre, len,
653 fold_convert (TREE_TYPE (len), se.string_length));
654 gfc_add_modify_expr (&se.pre, desc, se.expr);
656 gfc_add_block_to_block (block, &se.pre);
657 gfc_add_block_to_block (post_block, &se.post);
661 /* Add a case to a IO-result switch. */
664 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
669 return; /* No label, no case */
671 value = build_int_cst (NULL_TREE, label_value);
673 /* Make a backend label for this case. */
674 tmp = gfc_build_label_decl (NULL_TREE);
676 /* And the case itself. */
677 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
678 gfc_add_expr_to_block (body, tmp);
680 /* Jump to the label. */
681 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
682 gfc_add_expr_to_block (body, tmp);
686 /* Generate a switch statement that branches to the correct I/O
687 result label. The last statement of an I/O call stores the
688 result into a variable because there is often cleanup that
689 must be done before the switch, so a temporary would have to
690 be created anyway. */
693 io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
694 gfc_st_label * end_label, gfc_st_label * eor_label)
698 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
700 /* If no labels are specified, ignore the result instead
701 of building an empty switch. */
702 if (err_label == NULL
704 && eor_label == NULL)
707 /* Build a switch statement. */
708 gfc_start_block (&body);
710 /* The label values here must be the same as the values
711 in the library_return enum in the runtime library */
712 add_case (1, err_label, &body);
713 add_case (2, end_label, &body);
714 add_case (3, eor_label, &body);
716 tmp = gfc_finish_block (&body);
718 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
719 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
720 rc = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
722 rc = build2 (BIT_AND_EXPR, TREE_TYPE (rc), rc,
723 build_int_cst (TREE_TYPE (rc), IOPARM_common_libreturn_mask));
725 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
727 gfc_add_expr_to_block (block, tmp);
731 /* Store the current file and line number to variables so that if a
732 library call goes awry, we can tell the user where the problem is. */
735 set_error_locus (stmtblock_t * block, tree var, locus * where)
738 tree str, locus_file;
740 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
742 locus_file = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
743 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
744 locus_file = build3 (COMPONENT_REF, TREE_TYPE (p->field), locus_file,
745 p->field, NULL_TREE);
747 str = gfc_build_cstring_const (f->filename);
749 str = gfc_build_addr_expr (pchar_type_node, str);
750 gfc_add_modify_expr (block, locus_file, str);
752 #ifdef USE_MAPPED_LOCATION
753 line = LOCATION_LINE (where->lb->location);
755 line = where->lb->linenum;
757 set_parameter_const (block, var, IOPARM_common_line, line);
761 /* Translate an OPEN statement. */
764 gfc_trans_open (gfc_code * code)
766 stmtblock_t block, post_block;
769 unsigned int mask = 0;
771 gfc_start_block (&block);
772 gfc_init_block (&post_block);
774 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
776 set_error_locus (&block, var, &code->loc);
780 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
782 set_parameter_const (&block, var, IOPARM_common_unit, 0);
785 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
788 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
792 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
796 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
799 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl);
802 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
806 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
810 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
814 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
818 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
821 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
825 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
829 mask |= IOPARM_common_err;
832 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
835 set_parameter_const (&block, var, IOPARM_common_flags, mask);
837 tmp = build_fold_addr_expr (var);
838 tmp = build_call_expr (iocall[IOCALL_OPEN], 1, tmp);
839 gfc_add_expr_to_block (&block, tmp);
841 gfc_add_block_to_block (&block, &post_block);
843 io_result (&block, var, p->err, NULL, NULL);
845 return gfc_finish_block (&block);
849 /* Translate a CLOSE statement. */
852 gfc_trans_close (gfc_code * code)
854 stmtblock_t block, post_block;
857 unsigned int mask = 0;
859 gfc_start_block (&block);
860 gfc_init_block (&post_block);
862 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
864 set_error_locus (&block, var, &code->loc);
868 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
870 set_parameter_const (&block, var, IOPARM_common_unit, 0);
873 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
877 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
881 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
885 mask |= IOPARM_common_err;
887 set_parameter_const (&block, var, IOPARM_common_flags, mask);
889 tmp = build_fold_addr_expr (var);
890 tmp = build_call_expr (iocall[IOCALL_CLOSE], 1, tmp);
891 gfc_add_expr_to_block (&block, tmp);
893 gfc_add_block_to_block (&block, &post_block);
895 io_result (&block, var, p->err, NULL, NULL);
897 return gfc_finish_block (&block);
901 /* Common subroutine for building a file positioning statement. */
904 build_filepos (tree function, gfc_code * code)
906 stmtblock_t block, post_block;
909 unsigned int mask = 0;
911 p = code->ext.filepos;
913 gfc_start_block (&block);
914 gfc_init_block (&post_block);
916 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
919 set_error_locus (&block, var, &code->loc);
922 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
924 set_parameter_const (&block, var, IOPARM_common_unit, 0);
927 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
931 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
935 mask |= IOPARM_common_err;
937 set_parameter_const (&block, var, IOPARM_common_flags, mask);
939 tmp = build_fold_addr_expr (var);
940 tmp = build_call_expr (function, 1, tmp);
941 gfc_add_expr_to_block (&block, tmp);
943 gfc_add_block_to_block (&block, &post_block);
945 io_result (&block, var, p->err, NULL, NULL);
947 return gfc_finish_block (&block);
951 /* Translate a BACKSPACE statement. */
954 gfc_trans_backspace (gfc_code * code)
956 return build_filepos (iocall[IOCALL_BACKSPACE], code);
960 /* Translate an ENDFILE statement. */
963 gfc_trans_endfile (gfc_code * code)
965 return build_filepos (iocall[IOCALL_ENDFILE], code);
969 /* Translate a REWIND statement. */
972 gfc_trans_rewind (gfc_code * code)
974 return build_filepos (iocall[IOCALL_REWIND], code);
978 /* Translate a FLUSH statement. */
981 gfc_trans_flush (gfc_code * code)
983 return build_filepos (iocall[IOCALL_FLUSH], code);
987 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
990 gfc_trans_inquire (gfc_code * code)
992 stmtblock_t block, post_block;
995 unsigned int mask = 0;
997 gfc_start_block (&block);
998 gfc_init_block (&post_block);
1000 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
1003 set_error_locus (&block, var, &code->loc);
1004 p = code->ext.inquire;
1007 if (p->unit && p->file)
1008 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers", &code->loc);
1011 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1013 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1016 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
1020 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1024 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1028 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1032 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1036 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1040 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1044 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1048 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1052 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1056 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1060 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1064 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1068 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1072 mask |= set_parameter_ref (&block, &post_block, var,
1073 IOPARM_inquire_recl_out, p->recl);
1076 mask |= set_parameter_ref (&block, &post_block, var,
1077 IOPARM_inquire_nextrec, p->nextrec);
1080 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1084 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1088 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1092 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1096 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1100 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1104 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1108 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1112 mask |= IOPARM_common_err;
1115 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1119 mask |= set_parameter_ref (&block, &post_block, var,
1120 IOPARM_inquire_strm_pos_out, p->strm_pos);
1122 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1124 tmp = build_fold_addr_expr (var);
1125 tmp = build_call_expr (iocall[IOCALL_INQUIRE], 1, tmp);
1126 gfc_add_expr_to_block (&block, tmp);
1128 gfc_add_block_to_block (&block, &post_block);
1130 io_result (&block, var, p->err, NULL, NULL);
1132 return gfc_finish_block (&block);
1136 gfc_new_nml_name_expr (const char * name)
1138 gfc_expr * nml_name;
1140 nml_name = gfc_get_expr();
1141 nml_name->ref = NULL;
1142 nml_name->expr_type = EXPR_CONSTANT;
1143 nml_name->ts.kind = gfc_default_character_kind;
1144 nml_name->ts.type = BT_CHARACTER;
1145 nml_name->value.character.length = strlen(name);
1146 nml_name->value.character.string = gfc_getmem (strlen (name) + 1);
1147 strcpy (nml_name->value.character.string, name);
1152 /* nml_full_name builds up the fully qualified name of a
1153 derived type component. */
1156 nml_full_name (const char* var_name, const char* cmp_name)
1158 int full_name_length;
1161 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1162 full_name = (char*)gfc_getmem (full_name_length + 1);
1163 strcpy (full_name, var_name);
1164 full_name = strcat (full_name, "%");
1165 full_name = strcat (full_name, cmp_name);
1169 /* nml_get_addr_expr builds an address expression from the
1170 gfc_symbol or gfc_component backend_decl's. An offset is
1171 provided so that the address of an element of an array of
1172 derived types is returned. This is used in the runtime to
1173 determine that span of the derived type. */
1176 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1179 tree decl = NULL_TREE;
1183 int dummy_arg_flagged;
1187 sym->attr.referenced = 1;
1188 decl = gfc_get_symbol_decl (sym);
1191 decl = c->backend_decl;
1193 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1194 || TREE_CODE (decl) == VAR_DECL
1195 || TREE_CODE (decl) == PARM_DECL)
1196 || TREE_CODE (decl) == COMPONENT_REF));
1200 /* Build indirect reference, if dummy argument. */
1202 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1204 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref (tmp) : tmp;
1206 /* If an array, set flag and use indirect ref. if built. */
1208 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1209 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1214 /* Treat the component of a derived type, using base_addr for
1215 the derived type. */
1217 if (TREE_CODE (decl) == FIELD_DECL)
1218 tmp = build3 (COMPONENT_REF, TREE_TYPE (tmp),
1219 base_addr, tmp, NULL_TREE);
1221 /* If we have a derived type component, a reference to the first
1222 element of the array is built. This is done so that base_addr,
1223 used in the build of the component reference, always points to
1227 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node);
1229 /* Now build the address expression. */
1231 tmp = build_fold_addr_expr (tmp);
1233 /* If scalar dummy, resolve indirect reference now. */
1235 if (dummy_arg_flagged && !array_flagged)
1236 tmp = build_fold_indirect_ref (tmp);
1238 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1243 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1244 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1245 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1247 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1250 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1251 gfc_symbol * sym, gfc_component * c,
1254 gfc_typespec * ts = NULL;
1255 gfc_array_spec * as = NULL;
1256 tree addr_expr = NULL;
1266 gcc_assert (sym || c);
1268 /* Build the namelist object name. */
1270 string = gfc_build_cstring_const (var_name);
1271 string = gfc_build_addr_expr (pchar_type_node, string);
1273 /* Build ts, as and data address using symbol or component. */
1275 ts = (sym) ? &sym->ts : &c->ts;
1276 as = (sym) ? sym->as : c->as;
1278 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1285 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1286 dtype = gfc_get_dtype (dt);
1290 itype = GFC_DTYPE_UNKNOWN;
1296 itype = GFC_DTYPE_INTEGER;
1299 itype = GFC_DTYPE_LOGICAL;
1302 itype = GFC_DTYPE_REAL;
1305 itype = GFC_DTYPE_COMPLEX;
1308 itype = GFC_DTYPE_DERIVED;
1311 itype = GFC_DTYPE_CHARACTER;
1317 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1320 /* Build up the arguments for the transfer call.
1321 The call for the scalar part transfers:
1322 (address, name, type, kind or string_length, dtype) */
1324 dt_parm_addr = build_fold_addr_expr (dt_parm);
1326 if (ts->type == BT_CHARACTER)
1327 tmp = ts->cl->backend_decl;
1329 tmp = build_int_cst (gfc_charlen_type_node, 0);
1330 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL], 6,
1331 dt_parm_addr, addr_expr, string,
1332 IARG (ts->kind), tmp, dtype);
1333 gfc_add_expr_to_block (block, tmp);
1335 /* If the object is an array, transfer rank times:
1336 (null pointer, name, stride, lbound, ubound) */
1338 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1340 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL_DIM], 5,
1343 GFC_TYPE_ARRAY_STRIDE (dt, n_dim),
1344 GFC_TYPE_ARRAY_LBOUND (dt, n_dim),
1345 GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1346 gfc_add_expr_to_block (block, tmp);
1349 if (ts->type == BT_DERIVED)
1353 /* Provide the RECORD_TYPE to build component references. */
1355 tree expr = build_fold_indirect_ref (addr_expr);
1357 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1359 char *full_name = nml_full_name (var_name, cmp->name);
1360 transfer_namelist_element (block,
1363 gfc_free (full_name);
1370 /* Create a data transfer statement. Not all of the fields are valid
1371 for both reading and writing, but improper use has been filtered
1375 build_dt (tree function, gfc_code * code)
1377 stmtblock_t block, post_block, post_end_block, post_iu_block;
1382 unsigned int mask = 0;
1384 gfc_start_block (&block);
1385 gfc_init_block (&post_block);
1386 gfc_init_block (&post_end_block);
1387 gfc_init_block (&post_iu_block);
1389 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1391 set_error_locus (&block, var, &code->loc);
1393 if (last_dt == IOLENGTH)
1397 inq = code->ext.inquire;
1399 /* First check that preconditions are met. */
1400 gcc_assert (inq != NULL);
1401 gcc_assert (inq->iolength != NULL);
1403 /* Connect to the iolength variable. */
1404 mask |= set_parameter_ref (&block, &post_end_block, var,
1405 IOPARM_dt_iolength, inq->iolength);
1411 gcc_assert (dt != NULL);
1414 if (dt && dt->io_unit)
1416 if (dt->io_unit->ts.type == BT_CHARACTER)
1418 mask |= set_internal_unit (&block, &post_iu_block,
1420 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1423 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1426 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1431 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1434 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1437 if (dt->format_expr)
1438 mask |= set_string (&block, &post_end_block, var, IOPARM_dt_format,
1441 if (dt->format_label)
1443 if (dt->format_label == &format_asterisk)
1444 mask |= IOPARM_dt_list_format;
1446 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1447 dt->format_label->format);
1451 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1455 mask |= set_parameter_ref (&block, &post_end_block, var,
1456 IOPARM_common_iostat, dt->iostat);
1459 mask |= set_parameter_ref (&block, &post_end_block, var,
1460 IOPARM_dt_size, dt->size);
1463 mask |= IOPARM_common_err;
1466 mask |= IOPARM_common_eor;
1469 mask |= IOPARM_common_end;
1473 if (dt->format_expr || dt->format_label)
1474 gfc_internal_error ("build_dt: format with namelist");
1476 nmlname = gfc_new_nml_name_expr (dt->namelist->name);
1478 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1481 if (last_dt == READ)
1482 mask |= IOPARM_dt_namelist_read_mode;
1484 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1488 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1489 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1493 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1496 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1498 tmp = build_fold_addr_expr (var);
1499 tmp = build_call_expr (function, 1, tmp);
1500 gfc_add_expr_to_block (&block, tmp);
1502 gfc_add_block_to_block (&block, &post_block);
1505 dt_post_end_block = &post_end_block;
1507 gfc_add_expr_to_block (&block, gfc_trans_code (code->block->next));
1509 gfc_add_block_to_block (&block, &post_iu_block);
1512 dt_post_end_block = NULL;
1514 return gfc_finish_block (&block);
1518 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1519 this as a third sort of data transfer statement, except that
1520 lengths are summed instead of actually transferring any data. */
1523 gfc_trans_iolength (gfc_code * code)
1526 return build_dt (iocall[IOCALL_IOLENGTH], code);
1530 /* Translate a READ statement. */
1533 gfc_trans_read (gfc_code * code)
1536 return build_dt (iocall[IOCALL_READ], code);
1540 /* Translate a WRITE statement */
1543 gfc_trans_write (gfc_code * code)
1546 return build_dt (iocall[IOCALL_WRITE], code);
1550 /* Finish a data transfer statement. */
1553 gfc_trans_dt_end (gfc_code * code)
1558 gfc_init_block (&block);
1563 function = iocall[IOCALL_READ_DONE];
1567 function = iocall[IOCALL_WRITE_DONE];
1571 function = iocall[IOCALL_IOLENGTH_DONE];
1578 tmp = build_fold_addr_expr (dt_parm);
1579 tmp = build_call_expr (function, 1, tmp);
1580 gfc_add_expr_to_block (&block, tmp);
1581 gfc_add_block_to_block (&block, dt_post_end_block);
1582 gfc_init_block (dt_post_end_block);
1584 if (last_dt != IOLENGTH)
1586 gcc_assert (code->ext.dt != NULL);
1587 io_result (&block, dt_parm, code->ext.dt->err,
1588 code->ext.dt->end, code->ext.dt->eor);
1591 return gfc_finish_block (&block);
1595 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr);
1597 /* Given an array field in a derived type variable, generate the code
1598 for the loop that iterates over array elements, and the code that
1599 accesses those array elements. Use transfer_expr to generate code
1600 for transferring that element. Because elements may also be
1601 derived types, transfer_expr and transfer_array_component are mutually
1605 transfer_array_component (tree expr, gfc_component * cm)
1615 gfc_start_block (&block);
1616 gfc_init_se (&se, NULL);
1618 /* Create and initialize Scalarization Status. Unlike in
1619 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1620 care of this task, because we don't have a gfc_expr at hand.
1621 Build one manually, as in gfc_trans_subarray_assign. */
1624 ss->type = GFC_SS_COMPONENT;
1626 ss->shape = gfc_get_shape (cm->as->rank);
1627 ss->next = gfc_ss_terminator;
1628 ss->data.info.dimen = cm->as->rank;
1629 ss->data.info.descriptor = expr;
1630 ss->data.info.data = gfc_conv_array_data (expr);
1631 ss->data.info.offset = gfc_conv_array_offset (expr);
1632 for (n = 0; n < cm->as->rank; n++)
1634 ss->data.info.dim[n] = n;
1635 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1636 ss->data.info.stride[n] = gfc_index_one_node;
1638 mpz_init (ss->shape[n]);
1639 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1640 cm->as->lower[n]->value.integer);
1641 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1644 /* Once we got ss, we use scalarizer to create the loop. */
1646 gfc_init_loopinfo (&loop);
1647 gfc_add_ss_to_loop (&loop, ss);
1648 gfc_conv_ss_startstride (&loop);
1649 gfc_conv_loop_setup (&loop);
1650 gfc_mark_ss_chain_used (ss, 1);
1651 gfc_start_scalarized_body (&loop, &body);
1653 gfc_copy_loopinfo_to_se (&se, &loop);
1656 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1658 gfc_conv_tmp_array_ref (&se);
1660 /* Now se.expr contains an element of the array. Take the address and pass
1661 it to the IO routines. */
1662 tmp = build_fold_addr_expr (se.expr);
1663 transfer_expr (&se, &cm->ts, tmp);
1665 /* We are done now with the loop body. Wrap up the scalarizer and
1668 gfc_add_block_to_block (&body, &se.pre);
1669 gfc_add_block_to_block (&body, &se.post);
1671 gfc_trans_scalarizing_loops (&loop, &body);
1673 gfc_add_block_to_block (&block, &loop.pre);
1674 gfc_add_block_to_block (&block, &loop.post);
1676 for (n = 0; n < cm->as->rank; n++)
1677 mpz_clear (ss->shape[n]);
1678 gfc_free (ss->shape);
1680 gfc_cleanup_loop (&loop);
1682 return gfc_finish_block (&block);
1685 /* Generate the call for a scalar transfer node. */
1688 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1690 tree tmp, function, arg2, field, expr;
1701 arg2 = build_int_cst (NULL_TREE, kind);
1702 function = iocall[IOCALL_X_INTEGER];
1706 arg2 = build_int_cst (NULL_TREE, kind);
1707 function = iocall[IOCALL_X_REAL];
1711 arg2 = build_int_cst (NULL_TREE, kind);
1712 function = iocall[IOCALL_X_COMPLEX];
1716 arg2 = build_int_cst (NULL_TREE, kind);
1717 function = iocall[IOCALL_X_LOGICAL];
1722 if (se->string_length)
1723 arg2 = se->string_length;
1726 tmp = build_fold_indirect_ref (addr_expr);
1727 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
1728 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
1730 function = iocall[IOCALL_X_CHARACTER];
1734 /* Recurse into the elements of the derived type. */
1735 expr = gfc_evaluate_now (addr_expr, &se->pre);
1736 expr = build_fold_indirect_ref (expr);
1738 for (c = ts->derived->components; c; c = c->next)
1740 field = c->backend_decl;
1741 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
1743 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), expr, field,
1748 tmp = transfer_array_component (tmp, c);
1749 gfc_add_expr_to_block (&se->pre, tmp);
1754 tmp = build_fold_addr_expr (tmp);
1755 transfer_expr (se, &c->ts, tmp);
1761 internal_error ("Bad IO basetype (%d)", ts->type);
1764 tmp = build_fold_addr_expr (dt_parm);
1765 tmp = build_call_expr (function, 3, tmp, addr_expr, arg2);
1766 gfc_add_expr_to_block (&se->pre, tmp);
1767 gfc_add_block_to_block (&se->pre, &se->post);
1772 /* Generate a call to pass an array descriptor to the IO library. The
1773 array should be of one of the intrinsic types. */
1776 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1778 tree tmp, charlen_arg, kind_arg;
1780 if (ts->type == BT_CHARACTER)
1781 charlen_arg = se->string_length;
1783 charlen_arg = build_int_cst (NULL_TREE, 0);
1785 kind_arg = build_int_cst (NULL_TREE, ts->kind);
1787 tmp = build_fold_addr_expr (dt_parm);
1788 tmp = build_call_expr (iocall[IOCALL_X_ARRAY], 4,
1789 tmp, addr_expr, kind_arg, charlen_arg);
1790 gfc_add_expr_to_block (&se->pre, tmp);
1791 gfc_add_block_to_block (&se->pre, &se->post);
1795 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1798 gfc_trans_transfer (gfc_code * code)
1800 stmtblock_t block, body;
1808 gfc_start_block (&block);
1809 gfc_init_block (&body);
1812 ss = gfc_walk_expr (expr);
1815 gfc_init_se (&se, NULL);
1817 if (ss == gfc_ss_terminator)
1819 /* Transfer a scalar value. */
1820 gfc_conv_expr_reference (&se, expr);
1821 transfer_expr (&se, &expr->ts, se.expr);
1825 /* Transfer an array. If it is an array of an intrinsic
1826 type, pass the descriptor to the library. Otherwise
1827 scalarize the transfer. */
1830 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
1832 gcc_assert (ref->type == REF_ARRAY);
1835 if (expr->ts.type != BT_DERIVED && ref && ref->next == NULL)
1837 /* Get the descriptor. */
1838 gfc_conv_expr_descriptor (&se, expr, ss);
1839 tmp = build_fold_addr_expr (se.expr);
1840 transfer_array_desc (&se, &expr->ts, tmp);
1841 goto finish_block_label;
1844 /* Initialize the scalarizer. */
1845 gfc_init_loopinfo (&loop);
1846 gfc_add_ss_to_loop (&loop, ss);
1848 /* Initialize the loop. */
1849 gfc_conv_ss_startstride (&loop);
1850 gfc_conv_loop_setup (&loop);
1852 /* The main loop body. */
1853 gfc_mark_ss_chain_used (ss, 1);
1854 gfc_start_scalarized_body (&loop, &body);
1856 gfc_copy_loopinfo_to_se (&se, &loop);
1859 gfc_conv_expr_reference (&se, expr);
1860 transfer_expr (&se, &expr->ts, se.expr);
1865 gfc_add_block_to_block (&body, &se.pre);
1866 gfc_add_block_to_block (&body, &se.post);
1869 tmp = gfc_finish_block (&body);
1872 gcc_assert (se.ss == gfc_ss_terminator);
1873 gfc_trans_scalarizing_loops (&loop, &body);
1875 gfc_add_block_to_block (&loop.pre, &loop.post);
1876 tmp = gfc_finish_block (&loop.pre);
1877 gfc_cleanup_loop (&loop);
1880 gfc_add_expr_to_block (&block, tmp);
1882 return gfc_finish_block (&block);
1885 #include "gt-fortran-trans-io.h"