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 = gfc_chainon_list (NULL_TREE, tmp);
839 tmp = build_function_call_expr (iocall[IOCALL_OPEN], tmp);
840 gfc_add_expr_to_block (&block, tmp);
842 gfc_add_block_to_block (&block, &post_block);
844 io_result (&block, var, p->err, NULL, NULL);
846 return gfc_finish_block (&block);
850 /* Translate a CLOSE statement. */
853 gfc_trans_close (gfc_code * code)
855 stmtblock_t block, post_block;
858 unsigned int mask = 0;
860 gfc_start_block (&block);
861 gfc_init_block (&post_block);
863 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
865 set_error_locus (&block, var, &code->loc);
869 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
871 set_parameter_const (&block, var, IOPARM_common_unit, 0);
874 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
878 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
882 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
886 mask |= IOPARM_common_err;
888 set_parameter_const (&block, var, IOPARM_common_flags, mask);
890 tmp = build_fold_addr_expr (var);
891 tmp = gfc_chainon_list (NULL_TREE, tmp);
892 tmp = build_function_call_expr (iocall[IOCALL_CLOSE], tmp);
893 gfc_add_expr_to_block (&block, tmp);
895 gfc_add_block_to_block (&block, &post_block);
897 io_result (&block, var, p->err, NULL, NULL);
899 return gfc_finish_block (&block);
903 /* Common subroutine for building a file positioning statement. */
906 build_filepos (tree function, gfc_code * code)
908 stmtblock_t block, post_block;
911 unsigned int mask = 0;
913 p = code->ext.filepos;
915 gfc_start_block (&block);
916 gfc_init_block (&post_block);
918 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
921 set_error_locus (&block, var, &code->loc);
924 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
926 set_parameter_const (&block, var, IOPARM_common_unit, 0);
929 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
933 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
937 mask |= IOPARM_common_err;
939 set_parameter_const (&block, var, IOPARM_common_flags, mask);
941 tmp = build_fold_addr_expr (var);
942 tmp = gfc_chainon_list (NULL_TREE, tmp);
943 tmp = build_function_call_expr (function, tmp);
944 gfc_add_expr_to_block (&block, tmp);
946 gfc_add_block_to_block (&block, &post_block);
948 io_result (&block, var, p->err, NULL, NULL);
950 return gfc_finish_block (&block);
954 /* Translate a BACKSPACE statement. */
957 gfc_trans_backspace (gfc_code * code)
959 return build_filepos (iocall[IOCALL_BACKSPACE], code);
963 /* Translate an ENDFILE statement. */
966 gfc_trans_endfile (gfc_code * code)
968 return build_filepos (iocall[IOCALL_ENDFILE], code);
972 /* Translate a REWIND statement. */
975 gfc_trans_rewind (gfc_code * code)
977 return build_filepos (iocall[IOCALL_REWIND], code);
981 /* Translate a FLUSH statement. */
984 gfc_trans_flush (gfc_code * code)
986 return build_filepos (iocall[IOCALL_FLUSH], code);
990 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
993 gfc_trans_inquire (gfc_code * code)
995 stmtblock_t block, post_block;
998 unsigned int mask = 0;
1000 gfc_start_block (&block);
1001 gfc_init_block (&post_block);
1003 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
1006 set_error_locus (&block, var, &code->loc);
1007 p = code->ext.inquire;
1010 if (p->unit && p->file)
1011 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers", &code->loc);
1014 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1016 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1019 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
1023 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1027 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1031 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1035 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1039 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1043 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1047 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1051 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1055 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1059 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1063 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1067 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1071 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1075 mask |= set_parameter_ref (&block, &post_block, var,
1076 IOPARM_inquire_recl_out, p->recl);
1079 mask |= set_parameter_ref (&block, &post_block, var,
1080 IOPARM_inquire_nextrec, p->nextrec);
1083 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1087 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1091 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1095 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1099 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1103 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1107 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1111 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1115 mask |= IOPARM_common_err;
1118 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1122 mask |= set_parameter_ref (&block, &post_block, var,
1123 IOPARM_inquire_strm_pos_out, p->strm_pos);
1125 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1127 tmp = build_fold_addr_expr (var);
1128 tmp = gfc_chainon_list (NULL_TREE, tmp);
1129 tmp = build_function_call_expr (iocall[IOCALL_INQUIRE], tmp);
1130 gfc_add_expr_to_block (&block, tmp);
1132 gfc_add_block_to_block (&block, &post_block);
1134 io_result (&block, var, p->err, NULL, NULL);
1136 return gfc_finish_block (&block);
1140 gfc_new_nml_name_expr (const char * name)
1142 gfc_expr * nml_name;
1144 nml_name = gfc_get_expr();
1145 nml_name->ref = NULL;
1146 nml_name->expr_type = EXPR_CONSTANT;
1147 nml_name->ts.kind = gfc_default_character_kind;
1148 nml_name->ts.type = BT_CHARACTER;
1149 nml_name->value.character.length = strlen(name);
1150 nml_name->value.character.string = gfc_getmem (strlen (name) + 1);
1151 strcpy (nml_name->value.character.string, name);
1156 /* nml_full_name builds up the fully qualified name of a
1157 derived type component. */
1160 nml_full_name (const char* var_name, const char* cmp_name)
1162 int full_name_length;
1165 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1166 full_name = (char*)gfc_getmem (full_name_length + 1);
1167 strcpy (full_name, var_name);
1168 full_name = strcat (full_name, "%");
1169 full_name = strcat (full_name, cmp_name);
1173 /* nml_get_addr_expr builds an address expression from the
1174 gfc_symbol or gfc_component backend_decl's. An offset is
1175 provided so that the address of an element of an array of
1176 derived types is returned. This is used in the runtime to
1177 determine that span of the derived type. */
1180 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1183 tree decl = NULL_TREE;
1187 int dummy_arg_flagged;
1191 sym->attr.referenced = 1;
1192 decl = gfc_get_symbol_decl (sym);
1195 decl = c->backend_decl;
1197 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1198 || TREE_CODE (decl) == VAR_DECL
1199 || TREE_CODE (decl) == PARM_DECL)
1200 || TREE_CODE (decl) == COMPONENT_REF));
1204 /* Build indirect reference, if dummy argument. */
1206 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1208 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref (tmp) : tmp;
1210 /* If an array, set flag and use indirect ref. if built. */
1212 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1213 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1218 /* Treat the component of a derived type, using base_addr for
1219 the derived type. */
1221 if (TREE_CODE (decl) == FIELD_DECL)
1222 tmp = build3 (COMPONENT_REF, TREE_TYPE (tmp),
1223 base_addr, tmp, NULL_TREE);
1225 /* If we have a derived type component, a reference to the first
1226 element of the array is built. This is done so that base_addr,
1227 used in the build of the component reference, always points to
1231 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node);
1233 /* Now build the address expression. */
1235 tmp = build_fold_addr_expr (tmp);
1237 /* If scalar dummy, resolve indirect reference now. */
1239 if (dummy_arg_flagged && !array_flagged)
1240 tmp = build_fold_indirect_ref (tmp);
1242 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1247 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1248 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1249 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1251 #define NML_FIRST_ARG(a) args = gfc_chainon_list (NULL_TREE, a)
1252 #define NML_ADD_ARG(a) args = gfc_chainon_list (args, a)
1253 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1256 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1257 gfc_symbol * sym, gfc_component * c,
1260 gfc_typespec * ts = NULL;
1261 gfc_array_spec * as = NULL;
1262 tree addr_expr = NULL;
1273 gcc_assert (sym || c);
1275 /* Build the namelist object name. */
1277 string = gfc_build_cstring_const (var_name);
1278 string = gfc_build_addr_expr (pchar_type_node, string);
1280 /* Build ts, as and data address using symbol or component. */
1282 ts = (sym) ? &sym->ts : &c->ts;
1283 as = (sym) ? sym->as : c->as;
1285 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1292 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1293 dtype = gfc_get_dtype (dt);
1297 itype = GFC_DTYPE_UNKNOWN;
1303 itype = GFC_DTYPE_INTEGER;
1306 itype = GFC_DTYPE_LOGICAL;
1309 itype = GFC_DTYPE_REAL;
1312 itype = GFC_DTYPE_COMPLEX;
1315 itype = GFC_DTYPE_DERIVED;
1318 itype = GFC_DTYPE_CHARACTER;
1324 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1327 /* Build up the arguments for the transfer call.
1328 The call for the scalar part transfers:
1329 (address, name, type, kind or string_length, dtype) */
1331 dt_parm_addr = build_fold_addr_expr (dt_parm);
1332 NML_FIRST_ARG (dt_parm_addr);
1333 NML_ADD_ARG (addr_expr);
1334 NML_ADD_ARG (string);
1335 NML_ADD_ARG (IARG (ts->kind));
1337 if (ts->type == BT_CHARACTER)
1338 NML_ADD_ARG (ts->cl->backend_decl);
1340 NML_ADD_ARG (build_int_cst (gfc_charlen_type_node, 0));
1342 NML_ADD_ARG (dtype);
1343 tmp = build_function_call_expr (iocall[IOCALL_SET_NML_VAL], args);
1344 gfc_add_expr_to_block (block, tmp);
1346 /* If the object is an array, transfer rank times:
1347 (null pointer, name, stride, lbound, ubound) */
1349 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1351 NML_FIRST_ARG (dt_parm_addr);
1352 NML_ADD_ARG (IARG (n_dim));
1353 NML_ADD_ARG (GFC_TYPE_ARRAY_STRIDE (dt, n_dim));
1354 NML_ADD_ARG (GFC_TYPE_ARRAY_LBOUND (dt, n_dim));
1355 NML_ADD_ARG (GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1356 tmp = build_function_call_expr (iocall[IOCALL_SET_NML_VAL_DIM], args);
1357 gfc_add_expr_to_block (block, tmp);
1360 if (ts->type == BT_DERIVED)
1364 /* Provide the RECORD_TYPE to build component references. */
1366 tree expr = build_fold_indirect_ref (addr_expr);
1368 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1370 char *full_name = nml_full_name (var_name, cmp->name);
1371 transfer_namelist_element (block,
1374 gfc_free (full_name);
1381 #undef NML_FIRST_ARG
1383 /* Create a data transfer statement. Not all of the fields are valid
1384 for both reading and writing, but improper use has been filtered
1388 build_dt (tree function, gfc_code * code)
1390 stmtblock_t block, post_block, post_end_block, post_iu_block;
1395 unsigned int mask = 0;
1397 gfc_start_block (&block);
1398 gfc_init_block (&post_block);
1399 gfc_init_block (&post_end_block);
1400 gfc_init_block (&post_iu_block);
1402 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1404 set_error_locus (&block, var, &code->loc);
1406 if (last_dt == IOLENGTH)
1410 inq = code->ext.inquire;
1412 /* First check that preconditions are met. */
1413 gcc_assert (inq != NULL);
1414 gcc_assert (inq->iolength != NULL);
1416 /* Connect to the iolength variable. */
1417 mask |= set_parameter_ref (&block, &post_end_block, var,
1418 IOPARM_dt_iolength, inq->iolength);
1424 gcc_assert (dt != NULL);
1427 if (dt && dt->io_unit)
1429 if (dt->io_unit->ts.type == BT_CHARACTER)
1431 mask |= set_internal_unit (&block, &post_iu_block,
1433 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1436 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1439 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1444 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1447 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1450 if (dt->format_expr)
1451 mask |= set_string (&block, &post_end_block, var, IOPARM_dt_format,
1454 if (dt->format_label)
1456 if (dt->format_label == &format_asterisk)
1457 mask |= IOPARM_dt_list_format;
1459 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1460 dt->format_label->format);
1464 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1468 mask |= set_parameter_ref (&block, &post_end_block, var,
1469 IOPARM_common_iostat, dt->iostat);
1472 mask |= set_parameter_ref (&block, &post_end_block, var,
1473 IOPARM_dt_size, dt->size);
1476 mask |= IOPARM_common_err;
1479 mask |= IOPARM_common_eor;
1482 mask |= IOPARM_common_end;
1486 if (dt->format_expr || dt->format_label)
1487 gfc_internal_error ("build_dt: format with namelist");
1489 nmlname = gfc_new_nml_name_expr (dt->namelist->name);
1491 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1494 if (last_dt == READ)
1495 mask |= IOPARM_dt_namelist_read_mode;
1497 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1501 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1502 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1506 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1509 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1511 tmp = build_fold_addr_expr (var);
1512 tmp = gfc_chainon_list (NULL_TREE, tmp);
1513 tmp = build_function_call_expr (function, tmp);
1514 gfc_add_expr_to_block (&block, tmp);
1516 gfc_add_block_to_block (&block, &post_block);
1519 dt_post_end_block = &post_end_block;
1521 gfc_add_expr_to_block (&block, gfc_trans_code (code->block->next));
1523 gfc_add_block_to_block (&block, &post_iu_block);
1526 dt_post_end_block = NULL;
1528 return gfc_finish_block (&block);
1532 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1533 this as a third sort of data transfer statement, except that
1534 lengths are summed instead of actually transferring any data. */
1537 gfc_trans_iolength (gfc_code * code)
1540 return build_dt (iocall[IOCALL_IOLENGTH], code);
1544 /* Translate a READ statement. */
1547 gfc_trans_read (gfc_code * code)
1550 return build_dt (iocall[IOCALL_READ], code);
1554 /* Translate a WRITE statement */
1557 gfc_trans_write (gfc_code * code)
1560 return build_dt (iocall[IOCALL_WRITE], code);
1564 /* Finish a data transfer statement. */
1567 gfc_trans_dt_end (gfc_code * code)
1572 gfc_init_block (&block);
1577 function = iocall[IOCALL_READ_DONE];
1581 function = iocall[IOCALL_WRITE_DONE];
1585 function = iocall[IOCALL_IOLENGTH_DONE];
1592 tmp = build_fold_addr_expr (dt_parm);
1593 tmp = gfc_chainon_list (NULL_TREE, tmp);
1594 tmp = build_function_call_expr (function, tmp);
1595 gfc_add_expr_to_block (&block, tmp);
1596 gfc_add_block_to_block (&block, dt_post_end_block);
1597 gfc_init_block (dt_post_end_block);
1599 if (last_dt != IOLENGTH)
1601 gcc_assert (code->ext.dt != NULL);
1602 io_result (&block, dt_parm, code->ext.dt->err,
1603 code->ext.dt->end, code->ext.dt->eor);
1606 return gfc_finish_block (&block);
1610 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr);
1612 /* Given an array field in a derived type variable, generate the code
1613 for the loop that iterates over array elements, and the code that
1614 accesses those array elements. Use transfer_expr to generate code
1615 for transferring that element. Because elements may also be
1616 derived types, transfer_expr and transfer_array_component are mutually
1620 transfer_array_component (tree expr, gfc_component * cm)
1630 gfc_start_block (&block);
1631 gfc_init_se (&se, NULL);
1633 /* Create and initialize Scalarization Status. Unlike in
1634 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1635 care of this task, because we don't have a gfc_expr at hand.
1636 Build one manually, as in gfc_trans_subarray_assign. */
1639 ss->type = GFC_SS_COMPONENT;
1641 ss->shape = gfc_get_shape (cm->as->rank);
1642 ss->next = gfc_ss_terminator;
1643 ss->data.info.dimen = cm->as->rank;
1644 ss->data.info.descriptor = expr;
1645 ss->data.info.data = gfc_conv_array_data (expr);
1646 ss->data.info.offset = gfc_conv_array_offset (expr);
1647 for (n = 0; n < cm->as->rank; n++)
1649 ss->data.info.dim[n] = n;
1650 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1651 ss->data.info.stride[n] = gfc_index_one_node;
1653 mpz_init (ss->shape[n]);
1654 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1655 cm->as->lower[n]->value.integer);
1656 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1659 /* Once we got ss, we use scalarizer to create the loop. */
1661 gfc_init_loopinfo (&loop);
1662 gfc_add_ss_to_loop (&loop, ss);
1663 gfc_conv_ss_startstride (&loop);
1664 gfc_conv_loop_setup (&loop);
1665 gfc_mark_ss_chain_used (ss, 1);
1666 gfc_start_scalarized_body (&loop, &body);
1668 gfc_copy_loopinfo_to_se (&se, &loop);
1671 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1673 gfc_conv_tmp_array_ref (&se);
1675 /* Now se.expr contains an element of the array. Take the address and pass
1676 it to the IO routines. */
1677 tmp = build_fold_addr_expr (se.expr);
1678 transfer_expr (&se, &cm->ts, tmp);
1680 /* We are done now with the loop body. Wrap up the scalarizer and
1683 gfc_add_block_to_block (&body, &se.pre);
1684 gfc_add_block_to_block (&body, &se.post);
1686 gfc_trans_scalarizing_loops (&loop, &body);
1688 gfc_add_block_to_block (&block, &loop.pre);
1689 gfc_add_block_to_block (&block, &loop.post);
1691 for (n = 0; n < cm->as->rank; n++)
1692 mpz_clear (ss->shape[n]);
1693 gfc_free (ss->shape);
1695 gfc_cleanup_loop (&loop);
1697 return gfc_finish_block (&block);
1700 /* Generate the call for a scalar transfer node. */
1703 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1705 tree args, tmp, function, arg2, field, expr;
1716 arg2 = build_int_cst (NULL_TREE, kind);
1717 function = iocall[IOCALL_X_INTEGER];
1721 arg2 = build_int_cst (NULL_TREE, kind);
1722 function = iocall[IOCALL_X_REAL];
1726 arg2 = build_int_cst (NULL_TREE, kind);
1727 function = iocall[IOCALL_X_COMPLEX];
1731 arg2 = build_int_cst (NULL_TREE, kind);
1732 function = iocall[IOCALL_X_LOGICAL];
1737 if (se->string_length)
1738 arg2 = se->string_length;
1741 tmp = build_fold_indirect_ref (addr_expr);
1742 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
1743 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
1745 function = iocall[IOCALL_X_CHARACTER];
1749 /* Recurse into the elements of the derived type. */
1750 expr = gfc_evaluate_now (addr_expr, &se->pre);
1751 expr = build_fold_indirect_ref (expr);
1753 for (c = ts->derived->components; c; c = c->next)
1755 field = c->backend_decl;
1756 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
1758 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), expr, field,
1763 tmp = transfer_array_component (tmp, c);
1764 gfc_add_expr_to_block (&se->pre, tmp);
1769 tmp = build_fold_addr_expr (tmp);
1770 transfer_expr (se, &c->ts, tmp);
1776 internal_error ("Bad IO basetype (%d)", ts->type);
1779 tmp = build_fold_addr_expr (dt_parm);
1780 args = gfc_chainon_list (NULL_TREE, tmp);
1781 args = gfc_chainon_list (args, addr_expr);
1782 args = gfc_chainon_list (args, arg2);
1784 tmp = build_function_call_expr (function, args);
1785 gfc_add_expr_to_block (&se->pre, tmp);
1786 gfc_add_block_to_block (&se->pre, &se->post);
1791 /* Generate a call to pass an array descriptor to the IO library. The
1792 array should be of one of the intrinsic types. */
1795 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1797 tree args, tmp, charlen_arg, kind_arg;
1799 if (ts->type == BT_CHARACTER)
1800 charlen_arg = se->string_length;
1802 charlen_arg = build_int_cst (NULL_TREE, 0);
1804 kind_arg = build_int_cst (NULL_TREE, ts->kind);
1806 tmp = build_fold_addr_expr (dt_parm);
1807 args = gfc_chainon_list (NULL_TREE, tmp);
1808 args = gfc_chainon_list (args, addr_expr);
1809 args = gfc_chainon_list (args, kind_arg);
1810 args = gfc_chainon_list (args, charlen_arg);
1811 tmp = build_function_call_expr (iocall[IOCALL_X_ARRAY], args);
1812 gfc_add_expr_to_block (&se->pre, tmp);
1813 gfc_add_block_to_block (&se->pre, &se->post);
1817 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1820 gfc_trans_transfer (gfc_code * code)
1822 stmtblock_t block, body;
1830 gfc_start_block (&block);
1831 gfc_init_block (&body);
1834 ss = gfc_walk_expr (expr);
1837 gfc_init_se (&se, NULL);
1839 if (ss == gfc_ss_terminator)
1841 /* Transfer a scalar value. */
1842 gfc_conv_expr_reference (&se, expr);
1843 transfer_expr (&se, &expr->ts, se.expr);
1847 /* Transfer an array. If it is an array of an intrinsic
1848 type, pass the descriptor to the library. Otherwise
1849 scalarize the transfer. */
1852 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
1854 gcc_assert (ref->type == REF_ARRAY);
1857 if (expr->ts.type != BT_DERIVED && ref && ref->next == NULL)
1859 /* Get the descriptor. */
1860 gfc_conv_expr_descriptor (&se, expr, ss);
1861 tmp = build_fold_addr_expr (se.expr);
1862 transfer_array_desc (&se, &expr->ts, tmp);
1863 goto finish_block_label;
1866 /* Initialize the scalarizer. */
1867 gfc_init_loopinfo (&loop);
1868 gfc_add_ss_to_loop (&loop, ss);
1870 /* Initialize the loop. */
1871 gfc_conv_ss_startstride (&loop);
1872 gfc_conv_loop_setup (&loop);
1874 /* The main loop body. */
1875 gfc_mark_ss_chain_used (ss, 1);
1876 gfc_start_scalarized_body (&loop, &body);
1878 gfc_copy_loopinfo_to_se (&se, &loop);
1881 gfc_conv_expr_reference (&se, expr);
1882 transfer_expr (&se, &expr->ts, se.expr);
1887 gfc_add_block_to_block (&body, &se.pre);
1888 gfc_add_block_to_block (&body, &se.post);
1891 tmp = gfc_finish_block (&body);
1894 gcc_assert (se.ss == gfc_ss_terminator);
1895 gfc_trans_scalarizing_loops (&loop, &body);
1897 gfc_add_block_to_block (&loop.pre, &loop.post);
1898 tmp = gfc_finish_block (&loop.pre);
1899 gfc_cleanup_loop (&loop);
1902 gfc_add_expr_to_block (&block, tmp);
1904 return gfc_finish_block (&block);
1907 #include "gt-fortran-trans-io.h"