2009-04-21 Taras Glek <tglek@mozilla.com>
[official-gcc.git] / gcc / fortran / trans-io.c
blobb8ff5f36f53fd4fa2682a7c45579f7c237e27aca
1 /* IO Code translation/library interface
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
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 3, or (at your option) any later
11 version.
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
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "ggc.h"
29 #include "toplev.h"
30 #include "real.h"
31 #include "gfortran.h"
32 #include "trans.h"
33 #include "trans-stmt.h"
34 #include "trans-array.h"
35 #include "trans-types.h"
36 #include "trans-const.h"
38 /* Members of the ioparm structure. */
40 enum ioparam_type
42 IOPARM_ptype_common,
43 IOPARM_ptype_open,
44 IOPARM_ptype_close,
45 IOPARM_ptype_filepos,
46 IOPARM_ptype_inquire,
47 IOPARM_ptype_dt,
48 IOPARM_ptype_wait,
49 IOPARM_ptype_num
52 enum iofield_type
54 IOPARM_type_int4,
55 IOPARM_type_intio,
56 IOPARM_type_pint4,
57 IOPARM_type_pintio,
58 IOPARM_type_pchar,
59 IOPARM_type_parray,
60 IOPARM_type_pad,
61 IOPARM_type_char1,
62 IOPARM_type_char2,
63 IOPARM_type_common,
64 IOPARM_type_num
67 typedef struct GTY(()) gfc_st_parameter_field {
68 const char *name;
69 unsigned int mask;
70 enum ioparam_type param_type;
71 enum iofield_type type;
72 tree field;
73 tree field_len;
75 gfc_st_parameter_field;
77 typedef struct GTY(()) gfc_st_parameter {
78 const char *name;
79 tree type;
81 gfc_st_parameter;
83 enum iofield
85 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
86 #include "ioparm.def"
87 #undef IOPARM
88 IOPARM_field_num
91 static GTY(()) gfc_st_parameter st_parameter[] =
93 { "common", NULL },
94 { "open", NULL },
95 { "close", NULL },
96 { "filepos", NULL },
97 { "inquire", NULL },
98 { "dt", NULL },
99 { "wait", NULL }
102 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
104 #define IOPARM(param_type, name, mask, type) \
105 { #name, mask, IOPARM_ptype_##param_type, IOPARM_type_##type, NULL, NULL },
106 #include "ioparm.def"
107 #undef IOPARM
108 { NULL, 0, 0, 0, NULL, NULL }
111 /* Library I/O subroutines */
113 enum iocall
115 IOCALL_READ,
116 IOCALL_READ_DONE,
117 IOCALL_WRITE,
118 IOCALL_WRITE_DONE,
119 IOCALL_X_INTEGER,
120 IOCALL_X_LOGICAL,
121 IOCALL_X_CHARACTER,
122 IOCALL_X_CHARACTER_WIDE,
123 IOCALL_X_REAL,
124 IOCALL_X_COMPLEX,
125 IOCALL_X_ARRAY,
126 IOCALL_OPEN,
127 IOCALL_CLOSE,
128 IOCALL_INQUIRE,
129 IOCALL_IOLENGTH,
130 IOCALL_IOLENGTH_DONE,
131 IOCALL_REWIND,
132 IOCALL_BACKSPACE,
133 IOCALL_ENDFILE,
134 IOCALL_FLUSH,
135 IOCALL_SET_NML_VAL,
136 IOCALL_SET_NML_VAL_DIM,
137 IOCALL_WAIT,
138 IOCALL_NUM
141 static GTY(()) tree iocall[IOCALL_NUM];
143 /* Variable for keeping track of what the last data transfer statement
144 was. Used for deciding which subroutine to call when the data
145 transfer is complete. */
146 static enum { READ, WRITE, IOLENGTH } last_dt;
148 /* The data transfer parameter block that should be shared by all
149 data transfer calls belonging to the same read/write/iolength. */
150 static GTY(()) tree dt_parm;
151 static stmtblock_t *dt_post_end_block;
153 static void
154 gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
156 enum iofield type;
157 gfc_st_parameter_field *p;
158 char name[64];
159 size_t len;
160 tree t = make_node (RECORD_TYPE);
162 len = strlen (st_parameter[ptype].name);
163 gcc_assert (len <= sizeof (name) - sizeof ("__st_parameter_"));
164 memcpy (name, "__st_parameter_", sizeof ("__st_parameter_"));
165 memcpy (name + sizeof ("__st_parameter_") - 1, st_parameter[ptype].name,
166 len + 1);
167 TYPE_NAME (t) = get_identifier (name);
169 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
170 if (p->param_type == ptype)
171 switch (p->type)
173 case IOPARM_type_int4:
174 case IOPARM_type_intio:
175 case IOPARM_type_pint4:
176 case IOPARM_type_pintio:
177 case IOPARM_type_parray:
178 case IOPARM_type_pchar:
179 case IOPARM_type_pad:
180 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
181 get_identifier (p->name),
182 types[p->type]);
183 break;
184 case IOPARM_type_char1:
185 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
186 get_identifier (p->name),
187 pchar_type_node);
188 /* FALLTHROUGH */
189 case IOPARM_type_char2:
190 len = strlen (p->name);
191 gcc_assert (len <= sizeof (name) - sizeof ("_len"));
192 memcpy (name, p->name, len);
193 memcpy (name + len, "_len", sizeof ("_len"));
194 p->field_len = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
195 get_identifier (name),
196 gfc_charlen_type_node);
197 if (p->type == IOPARM_type_char2)
198 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
199 get_identifier (p->name),
200 pchar_type_node);
201 break;
202 case IOPARM_type_common:
203 p->field
204 = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
205 get_identifier (p->name),
206 st_parameter[IOPARM_ptype_common].type);
207 break;
208 case IOPARM_type_num:
209 gcc_unreachable ();
212 gfc_finish_type (t);
213 st_parameter[ptype].type = t;
217 /* Build code to test an error condition and call generate_error if needed.
218 Note: This builds calls to generate_error in the runtime library function.
219 The function generate_error is dependent on certain parameters in the
220 st_parameter_common flags to be set. (See libgfortran/runtime/error.c)
221 Therefore, the code to set these flags must be generated before
222 this function is used. */
224 void
225 gfc_trans_io_runtime_check (tree cond, tree var, int error_code,
226 const char * msgid, stmtblock_t * pblock)
228 stmtblock_t block;
229 tree body;
230 tree tmp;
231 tree arg1, arg2, arg3;
232 char *message;
234 if (integer_zerop (cond))
235 return;
237 /* The code to generate the error. */
238 gfc_start_block (&block);
240 arg1 = gfc_build_addr_expr (NULL_TREE, var);
242 arg2 = build_int_cst (integer_type_node, error_code),
244 asprintf (&message, "%s", _(msgid));
245 arg3 = gfc_build_addr_expr (pchar_type_node,
246 gfc_build_localized_cstring_const (message));
247 gfc_free(message);
249 tmp = build_call_expr (gfor_fndecl_generate_error, 3, arg1, arg2, arg3);
251 gfc_add_expr_to_block (&block, tmp);
253 body = gfc_finish_block (&block);
255 if (integer_onep (cond))
257 gfc_add_expr_to_block (pblock, body);
259 else
261 /* Tell the compiler that this isn't likely. */
262 cond = fold_convert (long_integer_type_node, cond);
263 tmp = build_int_cst (long_integer_type_node, 0);
264 cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
265 cond = fold_convert (boolean_type_node, cond);
267 tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ());
268 gfc_add_expr_to_block (pblock, tmp);
273 /* Create function decls for IO library functions. */
275 void
276 gfc_build_io_library_fndecls (void)
278 tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
279 tree gfc_intio_type_node;
280 tree parm_type, dt_parm_type;
281 HOST_WIDE_INT pad_size;
282 enum ioparam_type ptype;
284 types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
285 types[IOPARM_type_intio] = gfc_intio_type_node
286 = gfc_get_int_type (gfc_intio_kind);
287 types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
288 types[IOPARM_type_pintio]
289 = build_pointer_type (gfc_intio_type_node);
290 types[IOPARM_type_parray] = pchar_type_node;
291 types[IOPARM_type_pchar] = pchar_type_node;
292 pad_size = 16 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (pchar_type_node));
293 pad_size += 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (integer_type_node));
294 pad_idx = build_index_type (build_int_cst (NULL_TREE, pad_size - 1));
295 types[IOPARM_type_pad] = build_array_type (char_type_node, pad_idx);
297 /* pad actually contains pointers and integers so it needs to have an
298 alignment that is at least as large as the needed alignment for those
299 types. See the st_parameter_dt structure in libgfortran/io/io.h for
300 what really goes into this space. */
301 TYPE_ALIGN (types[IOPARM_type_pad]) = MAX (TYPE_ALIGN (pchar_type_node),
302 TYPE_ALIGN (gfc_get_int_type (gfc_intio_kind)));
304 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
305 gfc_build_st_parameter (ptype, types);
307 /* Define the transfer functions. */
309 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
311 iocall[IOCALL_X_INTEGER] =
312 gfc_build_library_function_decl (get_identifier
313 (PREFIX("transfer_integer")),
314 void_type_node, 3, dt_parm_type,
315 pvoid_type_node, gfc_int4_type_node);
317 iocall[IOCALL_X_LOGICAL] =
318 gfc_build_library_function_decl (get_identifier
319 (PREFIX("transfer_logical")),
320 void_type_node, 3, dt_parm_type,
321 pvoid_type_node, gfc_int4_type_node);
323 iocall[IOCALL_X_CHARACTER] =
324 gfc_build_library_function_decl (get_identifier
325 (PREFIX("transfer_character")),
326 void_type_node, 3, dt_parm_type,
327 pvoid_type_node, gfc_int4_type_node);
329 iocall[IOCALL_X_CHARACTER_WIDE] =
330 gfc_build_library_function_decl (get_identifier
331 (PREFIX("transfer_character_wide")),
332 void_type_node, 4, dt_parm_type,
333 pvoid_type_node, gfc_charlen_type_node,
334 gfc_int4_type_node);
336 iocall[IOCALL_X_REAL] =
337 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
338 void_type_node, 3, dt_parm_type,
339 pvoid_type_node, gfc_int4_type_node);
341 iocall[IOCALL_X_COMPLEX] =
342 gfc_build_library_function_decl (get_identifier
343 (PREFIX("transfer_complex")),
344 void_type_node, 3, dt_parm_type,
345 pvoid_type_node, gfc_int4_type_node);
347 iocall[IOCALL_X_ARRAY] =
348 gfc_build_library_function_decl (get_identifier
349 (PREFIX("transfer_array")),
350 void_type_node, 4, dt_parm_type,
351 pvoid_type_node, integer_type_node,
352 gfc_charlen_type_node);
354 /* Library entry points */
356 iocall[IOCALL_READ] =
357 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
358 void_type_node, 1, dt_parm_type);
360 iocall[IOCALL_WRITE] =
361 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
362 void_type_node, 1, dt_parm_type);
364 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_open].type);
365 iocall[IOCALL_OPEN] =
366 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
367 void_type_node, 1, parm_type);
370 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_close].type);
371 iocall[IOCALL_CLOSE] =
372 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
373 void_type_node, 1, parm_type);
375 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_inquire].type);
376 iocall[IOCALL_INQUIRE] =
377 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
378 gfc_int4_type_node, 1, parm_type);
380 iocall[IOCALL_IOLENGTH] =
381 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
382 void_type_node, 1, dt_parm_type);
384 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_wait].type);
385 iocall[IOCALL_WAIT] =
386 gfc_build_library_function_decl (get_identifier (PREFIX("st_wait")),
387 gfc_int4_type_node, 1, parm_type);
389 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_filepos].type);
390 iocall[IOCALL_REWIND] =
391 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
392 gfc_int4_type_node, 1, parm_type);
394 iocall[IOCALL_BACKSPACE] =
395 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
396 gfc_int4_type_node, 1, parm_type);
398 iocall[IOCALL_ENDFILE] =
399 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
400 gfc_int4_type_node, 1, parm_type);
402 iocall[IOCALL_FLUSH] =
403 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
404 gfc_int4_type_node, 1, parm_type);
406 /* Library helpers */
408 iocall[IOCALL_READ_DONE] =
409 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
410 gfc_int4_type_node, 1, dt_parm_type);
412 iocall[IOCALL_WRITE_DONE] =
413 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
414 gfc_int4_type_node, 1, dt_parm_type);
416 iocall[IOCALL_IOLENGTH_DONE] =
417 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
418 gfc_int4_type_node, 1, dt_parm_type);
421 iocall[IOCALL_SET_NML_VAL] =
422 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var")),
423 void_type_node, 6, dt_parm_type,
424 pvoid_type_node, pvoid_type_node,
425 gfc_int4_type_node, gfc_charlen_type_node,
426 gfc_int4_type_node);
428 iocall[IOCALL_SET_NML_VAL_DIM] =
429 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_dim")),
430 void_type_node, 5, dt_parm_type,
431 gfc_int4_type_node, gfc_array_index_type,
432 gfc_array_index_type, gfc_array_index_type);
436 /* Generate code to store an integer constant into the
437 st_parameter_XXX structure. */
439 static unsigned int
440 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
441 unsigned int val)
443 tree tmp;
444 gfc_st_parameter_field *p = &st_parameter_field[type];
446 if (p->param_type == IOPARM_ptype_common)
447 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
448 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
449 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
450 NULL_TREE);
451 gfc_add_modify (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
452 return p->mask;
456 /* Generate code to store a non-string I/O parameter into the
457 st_parameter_XXX structure. This is a pass by value. */
459 static unsigned int
460 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
461 gfc_expr *e)
463 gfc_se se;
464 tree tmp;
465 gfc_st_parameter_field *p = &st_parameter_field[type];
466 tree dest_type = TREE_TYPE (p->field);
468 gfc_init_se (&se, NULL);
469 gfc_conv_expr_val (&se, e);
471 /* If we're storing a UNIT number, we need to check it first. */
472 if (type == IOPARM_common_unit && e->ts.kind != 4)
474 tree cond, max;
475 int i;
477 /* Don't evaluate the UNIT number multiple times. */
478 se.expr = gfc_evaluate_now (se.expr, &se.pre);
480 /* UNIT numbers should be nonnegative. */
481 cond = fold_build2 (LT_EXPR, boolean_type_node, se.expr,
482 build_int_cst (TREE_TYPE (se.expr),0));
483 gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
484 "Negative unit number in I/O statement",
485 &se.pre);
487 /* UNIT numbers should be less than the max. */
488 i = gfc_validate_kind (BT_INTEGER, 4, false);
489 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
490 cond = fold_build2 (GT_EXPR, boolean_type_node, se.expr,
491 fold_convert (TREE_TYPE (se.expr), max));
492 gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
493 "Unit number in I/O statement too large",
494 &se.pre);
498 se.expr = convert (dest_type, se.expr);
499 gfc_add_block_to_block (block, &se.pre);
501 if (p->param_type == IOPARM_ptype_common)
502 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
503 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
505 tmp = fold_build3 (COMPONENT_REF, dest_type, var, p->field, NULL_TREE);
506 gfc_add_modify (block, tmp, se.expr);
507 return p->mask;
511 /* Generate code to store a non-string I/O parameter into the
512 st_parameter_XXX structure. This is pass by reference. */
514 static unsigned int
515 set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
516 tree var, enum iofield type, gfc_expr *e)
518 gfc_se se;
519 tree tmp, addr;
520 gfc_st_parameter_field *p = &st_parameter_field[type];
522 gcc_assert (e->ts.type == BT_INTEGER || e->ts.type == BT_LOGICAL);
523 gfc_init_se (&se, NULL);
524 gfc_conv_expr_lhs (&se, e);
526 gfc_add_block_to_block (block, &se.pre);
528 if (TYPE_MODE (TREE_TYPE (se.expr))
529 == TYPE_MODE (TREE_TYPE (TREE_TYPE (p->field))))
531 addr = convert (TREE_TYPE (p->field), gfc_build_addr_expr (NULL_TREE, se.expr));
533 /* If this is for the iostat variable initialize the
534 user variable to LIBERROR_OK which is zero. */
535 if (type == IOPARM_common_iostat)
536 gfc_add_modify (block, se.expr,
537 build_int_cst (TREE_TYPE (se.expr), LIBERROR_OK));
539 else
541 /* The type used by the library has different size
542 from the type of the variable supplied by the user.
543 Need to use a temporary. */
544 tree tmpvar = gfc_create_var (TREE_TYPE (TREE_TYPE (p->field)),
545 st_parameter_field[type].name);
547 /* If this is for the iostat variable, initialize the
548 user variable to LIBERROR_OK which is zero. */
549 if (type == IOPARM_common_iostat)
550 gfc_add_modify (block, tmpvar,
551 build_int_cst (TREE_TYPE (tmpvar), LIBERROR_OK));
553 addr = gfc_build_addr_expr (NULL_TREE, tmpvar);
554 /* After the I/O operation, we set the variable from the temporary. */
555 tmp = convert (TREE_TYPE (se.expr), tmpvar);
556 gfc_add_modify (postblock, se.expr, tmp);
559 if (p->param_type == IOPARM_ptype_common)
560 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
561 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
562 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
563 var, p->field, NULL_TREE);
564 gfc_add_modify (block, tmp, addr);
565 return p->mask;
568 /* Given an array expr, find its address and length to get a string. If the
569 array is full, the string's address is the address of array's first element
570 and the length is the size of the whole array. If it is an element, the
571 string's address is the element's address and the length is the rest size of
572 the array.
575 static void
576 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
578 tree tmp;
579 tree array;
580 tree type;
581 tree size;
582 int rank;
583 gfc_symbol *sym;
585 sym = e->symtree->n.sym;
586 rank = sym->as->rank - 1;
588 if (e->ref->u.ar.type == AR_FULL)
590 se->expr = gfc_get_symbol_decl (sym);
591 se->expr = gfc_conv_array_data (se->expr);
593 else
595 gfc_conv_expr (se, e);
598 array = sym->backend_decl;
599 type = TREE_TYPE (array);
601 if (GFC_ARRAY_TYPE_P (type))
602 size = GFC_TYPE_ARRAY_SIZE (type);
603 else
605 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
606 size = gfc_conv_array_stride (array, rank);
607 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
608 gfc_conv_array_ubound (array, rank),
609 gfc_conv_array_lbound (array, rank));
610 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
611 gfc_index_one_node);
612 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
615 gcc_assert (size);
617 /* If it is an element, we need the its address and size of the rest. */
618 if (e->ref->u.ar.type == AR_ELEMENT)
620 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
621 TREE_OPERAND (se->expr, 1));
622 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
625 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
626 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
627 fold_convert (gfc_array_index_type, tmp));
629 se->string_length = fold_convert (gfc_charlen_type_node, size);
633 /* Generate code to store a string and its length into the
634 st_parameter_XXX structure. */
636 static unsigned int
637 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
638 enum iofield type, gfc_expr * e)
640 gfc_se se;
641 tree tmp;
642 tree io;
643 tree len;
644 gfc_st_parameter_field *p = &st_parameter_field[type];
646 gfc_init_se (&se, NULL);
648 if (p->param_type == IOPARM_ptype_common)
649 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
650 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
651 io = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
652 var, p->field, NULL_TREE);
653 len = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field_len),
654 var, p->field_len, NULL_TREE);
656 /* Integer variable assigned a format label. */
657 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
659 char * msg;
660 tree cond;
662 gfc_conv_label_variable (&se, e);
663 tmp = GFC_DECL_STRING_LEN (se.expr);
664 cond = fold_build2 (LT_EXPR, boolean_type_node,
665 tmp, build_int_cst (TREE_TYPE (tmp), 0));
667 asprintf(&msg, "Label assigned to variable '%s' (%%ld) is not a format "
668 "label", e->symtree->name);
669 gfc_trans_runtime_check (true, false, cond, &se.pre, &e->where, msg,
670 fold_convert (long_integer_type_node, tmp));
671 gfc_free (msg);
673 gfc_add_modify (&se.pre, io,
674 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
675 gfc_add_modify (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
677 else
679 /* General character. */
680 if (e->ts.type == BT_CHARACTER && e->rank == 0)
681 gfc_conv_expr (&se, e);
682 /* Array assigned Hollerith constant or character array. */
683 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
684 gfc_convert_array_to_string (&se, e);
685 else
686 gcc_unreachable ();
688 gfc_conv_string_parameter (&se);
689 gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
690 gfc_add_modify (&se.pre, len, se.string_length);
693 gfc_add_block_to_block (block, &se.pre);
694 gfc_add_block_to_block (postblock, &se.post);
695 return p->mask;
699 /* Generate code to store the character (array) and the character length
700 for an internal unit. */
702 static unsigned int
703 set_internal_unit (stmtblock_t * block, stmtblock_t * post_block,
704 tree var, gfc_expr * e)
706 gfc_se se;
707 tree io;
708 tree len;
709 tree desc;
710 tree tmp;
711 gfc_st_parameter_field *p;
712 unsigned int mask;
714 gfc_init_se (&se, NULL);
716 p = &st_parameter_field[IOPARM_dt_internal_unit];
717 mask = p->mask;
718 io = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
719 var, p->field, NULL_TREE);
720 len = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field_len),
721 var, p->field_len, NULL_TREE);
722 p = &st_parameter_field[IOPARM_dt_internal_unit_desc];
723 desc = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
724 var, p->field, NULL_TREE);
726 gcc_assert (e->ts.type == BT_CHARACTER);
728 /* Character scalars. */
729 if (e->rank == 0)
731 gfc_conv_expr (&se, e);
732 gfc_conv_string_parameter (&se);
733 tmp = se.expr;
734 se.expr = build_int_cst (pchar_type_node, 0);
737 /* Character array. */
738 else if (e->rank > 0)
740 se.ss = gfc_walk_expr (e);
742 if (is_subref_array (e))
744 /* Use a temporary for components of arrays of derived types
745 or substring array references. */
746 gfc_conv_subref_array_arg (&se, e, 0,
747 last_dt == READ ? INTENT_IN : INTENT_OUT);
748 tmp = build_fold_indirect_ref (se.expr);
749 se.expr = gfc_build_addr_expr (pchar_type_node, tmp);
750 tmp = gfc_conv_descriptor_data_get (tmp);
752 else
754 /* Return the data pointer and rank from the descriptor. */
755 gfc_conv_expr_descriptor (&se, e, se.ss);
756 tmp = gfc_conv_descriptor_data_get (se.expr);
757 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
760 else
761 gcc_unreachable ();
763 /* The cast is needed for character substrings and the descriptor
764 data. */
765 gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
766 gfc_add_modify (&se.pre, len,
767 fold_convert (TREE_TYPE (len), se.string_length));
768 gfc_add_modify (&se.pre, desc, se.expr);
770 gfc_add_block_to_block (block, &se.pre);
771 gfc_add_block_to_block (post_block, &se.post);
772 return mask;
775 /* Add a case to a IO-result switch. */
777 static void
778 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
780 tree tmp, value;
782 if (label == NULL)
783 return; /* No label, no case */
785 value = build_int_cst (NULL_TREE, label_value);
787 /* Make a backend label for this case. */
788 tmp = gfc_build_label_decl (NULL_TREE);
790 /* And the case itself. */
791 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
792 gfc_add_expr_to_block (body, tmp);
794 /* Jump to the label. */
795 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
796 gfc_add_expr_to_block (body, tmp);
800 /* Generate a switch statement that branches to the correct I/O
801 result label. The last statement of an I/O call stores the
802 result into a variable because there is often cleanup that
803 must be done before the switch, so a temporary would have to
804 be created anyway. */
806 static void
807 io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
808 gfc_st_label * end_label, gfc_st_label * eor_label)
810 stmtblock_t body;
811 tree tmp, rc;
812 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
814 /* If no labels are specified, ignore the result instead
815 of building an empty switch. */
816 if (err_label == NULL
817 && end_label == NULL
818 && eor_label == NULL)
819 return;
821 /* Build a switch statement. */
822 gfc_start_block (&body);
824 /* The label values here must be the same as the values
825 in the library_return enum in the runtime library */
826 add_case (1, err_label, &body);
827 add_case (2, end_label, &body);
828 add_case (3, eor_label, &body);
830 tmp = gfc_finish_block (&body);
832 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
833 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
834 rc = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
835 var, p->field, NULL_TREE);
836 rc = fold_build2 (BIT_AND_EXPR, TREE_TYPE (rc),
837 rc, build_int_cst (TREE_TYPE (rc),
838 IOPARM_common_libreturn_mask));
840 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
842 gfc_add_expr_to_block (block, tmp);
846 /* Store the current file and line number to variables so that if a
847 library call goes awry, we can tell the user where the problem is. */
849 static void
850 set_error_locus (stmtblock_t * block, tree var, locus * where)
852 gfc_file *f;
853 tree str, locus_file;
854 int line;
855 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
857 locus_file = fold_build3 (COMPONENT_REF,
858 st_parameter[IOPARM_ptype_common].type,
859 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
860 locus_file = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
861 locus_file, p->field, NULL_TREE);
862 f = where->lb->file;
863 str = gfc_build_cstring_const (f->filename);
865 str = gfc_build_addr_expr (pchar_type_node, str);
866 gfc_add_modify (block, locus_file, str);
868 line = LOCATION_LINE (where->lb->location);
869 set_parameter_const (block, var, IOPARM_common_line, line);
873 /* Translate an OPEN statement. */
875 tree
876 gfc_trans_open (gfc_code * code)
878 stmtblock_t block, post_block;
879 gfc_open *p;
880 tree tmp, var;
881 unsigned int mask = 0;
883 gfc_start_block (&block);
884 gfc_init_block (&post_block);
886 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
888 set_error_locus (&block, var, &code->loc);
889 p = code->ext.open;
891 if (p->iomsg)
892 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
893 p->iomsg);
895 if (p->iostat)
896 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
897 p->iostat);
899 if (p->err)
900 mask |= IOPARM_common_err;
902 if (p->file)
903 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
905 if (p->status)
906 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
907 p->status);
909 if (p->access)
910 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
911 p->access);
913 if (p->form)
914 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
916 if (p->recl)
917 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl);
919 if (p->blank)
920 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
921 p->blank);
923 if (p->position)
924 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
925 p->position);
927 if (p->action)
928 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
929 p->action);
931 if (p->delim)
932 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
933 p->delim);
935 if (p->pad)
936 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
938 if (p->decimal)
939 mask |= set_string (&block, &post_block, var, IOPARM_open_decimal,
940 p->decimal);
942 if (p->encoding)
943 mask |= set_string (&block, &post_block, var, IOPARM_open_encoding,
944 p->encoding);
946 if (p->round)
947 mask |= set_string (&block, &post_block, var, IOPARM_open_round, p->round);
949 if (p->sign)
950 mask |= set_string (&block, &post_block, var, IOPARM_open_sign, p->sign);
952 if (p->asynchronous)
953 mask |= set_string (&block, &post_block, var, IOPARM_open_asynchronous,
954 p->asynchronous);
956 if (p->convert)
957 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
958 p->convert);
960 set_parameter_const (&block, var, IOPARM_common_flags, mask);
962 if (p->unit)
963 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
964 else
965 set_parameter_const (&block, var, IOPARM_common_unit, 0);
967 tmp = gfc_build_addr_expr (NULL_TREE, var);
968 tmp = build_call_expr (iocall[IOCALL_OPEN], 1, tmp);
969 gfc_add_expr_to_block (&block, tmp);
971 gfc_add_block_to_block (&block, &post_block);
973 io_result (&block, var, p->err, NULL, NULL);
975 return gfc_finish_block (&block);
979 /* Translate a CLOSE statement. */
981 tree
982 gfc_trans_close (gfc_code * code)
984 stmtblock_t block, post_block;
985 gfc_close *p;
986 tree tmp, var;
987 unsigned int mask = 0;
989 gfc_start_block (&block);
990 gfc_init_block (&post_block);
992 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
994 set_error_locus (&block, var, &code->loc);
995 p = code->ext.close;
997 if (p->iomsg)
998 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
999 p->iomsg);
1001 if (p->iostat)
1002 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1003 p->iostat);
1005 if (p->err)
1006 mask |= IOPARM_common_err;
1008 if (p->status)
1009 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
1010 p->status);
1012 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1014 if (p->unit)
1015 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1016 else
1017 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1019 tmp = gfc_build_addr_expr (NULL_TREE, var);
1020 tmp = build_call_expr (iocall[IOCALL_CLOSE], 1, tmp);
1021 gfc_add_expr_to_block (&block, tmp);
1023 gfc_add_block_to_block (&block, &post_block);
1025 io_result (&block, var, p->err, NULL, NULL);
1027 return gfc_finish_block (&block);
1031 /* Common subroutine for building a file positioning statement. */
1033 static tree
1034 build_filepos (tree function, gfc_code * code)
1036 stmtblock_t block, post_block;
1037 gfc_filepos *p;
1038 tree tmp, var;
1039 unsigned int mask = 0;
1041 p = code->ext.filepos;
1043 gfc_start_block (&block);
1044 gfc_init_block (&post_block);
1046 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
1047 "filepos_parm");
1049 set_error_locus (&block, var, &code->loc);
1051 if (p->iomsg)
1052 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1053 p->iomsg);
1055 if (p->iostat)
1056 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1057 p->iostat);
1059 if (p->err)
1060 mask |= IOPARM_common_err;
1062 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1064 if (p->unit)
1065 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1066 else
1067 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1069 tmp = gfc_build_addr_expr (NULL_TREE, var);
1070 tmp = build_call_expr (function, 1, tmp);
1071 gfc_add_expr_to_block (&block, tmp);
1073 gfc_add_block_to_block (&block, &post_block);
1075 io_result (&block, var, p->err, NULL, NULL);
1077 return gfc_finish_block (&block);
1081 /* Translate a BACKSPACE statement. */
1083 tree
1084 gfc_trans_backspace (gfc_code * code)
1086 return build_filepos (iocall[IOCALL_BACKSPACE], code);
1090 /* Translate an ENDFILE statement. */
1092 tree
1093 gfc_trans_endfile (gfc_code * code)
1095 return build_filepos (iocall[IOCALL_ENDFILE], code);
1099 /* Translate a REWIND statement. */
1101 tree
1102 gfc_trans_rewind (gfc_code * code)
1104 return build_filepos (iocall[IOCALL_REWIND], code);
1108 /* Translate a FLUSH statement. */
1110 tree
1111 gfc_trans_flush (gfc_code * code)
1113 return build_filepos (iocall[IOCALL_FLUSH], code);
1117 /* Create a dummy iostat variable to catch any error due to bad unit. */
1119 static gfc_expr *
1120 create_dummy_iostat (void)
1122 gfc_symtree *st;
1123 gfc_expr *e;
1125 gfc_get_ha_sym_tree ("@iostat", &st);
1126 st->n.sym->ts.type = BT_INTEGER;
1127 st->n.sym->ts.kind = gfc_default_integer_kind;
1128 gfc_set_sym_referenced (st->n.sym);
1129 gfc_commit_symbol (st->n.sym);
1130 st->n.sym->backend_decl
1131 = gfc_create_var (gfc_get_int_type (st->n.sym->ts.kind),
1132 st->n.sym->name);
1134 e = gfc_get_expr ();
1135 e->expr_type = EXPR_VARIABLE;
1136 e->symtree = st;
1137 e->ts.type = BT_INTEGER;
1138 e->ts.kind = st->n.sym->ts.kind;
1140 return e;
1144 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
1146 tree
1147 gfc_trans_inquire (gfc_code * code)
1149 stmtblock_t block, post_block;
1150 gfc_inquire *p;
1151 tree tmp, var;
1152 unsigned int mask = 0, mask2 = 0;
1154 gfc_start_block (&block);
1155 gfc_init_block (&post_block);
1157 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
1158 "inquire_parm");
1160 set_error_locus (&block, var, &code->loc);
1161 p = code->ext.inquire;
1163 if (p->iomsg)
1164 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1165 p->iomsg);
1167 if (p->iostat)
1168 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1169 p->iostat);
1171 if (p->err)
1172 mask |= IOPARM_common_err;
1174 /* Sanity check. */
1175 if (p->unit && p->file)
1176 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers", &code->loc);
1178 if (p->file)
1179 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
1180 p->file);
1182 if (p->exist)
1184 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1185 p->exist);
1187 if (p->unit && !p->iostat)
1189 p->iostat = create_dummy_iostat ();
1190 mask |= set_parameter_ref (&block, &post_block, var,
1191 IOPARM_common_iostat, p->iostat);
1195 if (p->opened)
1196 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1197 p->opened);
1199 if (p->number)
1200 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1201 p->number);
1203 if (p->named)
1204 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1205 p->named);
1207 if (p->name)
1208 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1209 p->name);
1211 if (p->access)
1212 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1213 p->access);
1215 if (p->sequential)
1216 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1217 p->sequential);
1219 if (p->direct)
1220 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1221 p->direct);
1223 if (p->form)
1224 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1225 p->form);
1227 if (p->formatted)
1228 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1229 p->formatted);
1231 if (p->unformatted)
1232 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1233 p->unformatted);
1235 if (p->recl)
1236 mask |= set_parameter_ref (&block, &post_block, var,
1237 IOPARM_inquire_recl_out, p->recl);
1239 if (p->nextrec)
1240 mask |= set_parameter_ref (&block, &post_block, var,
1241 IOPARM_inquire_nextrec, p->nextrec);
1243 if (p->blank)
1244 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1245 p->blank);
1247 if (p->delim)
1248 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1249 p->delim);
1251 if (p->position)
1252 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1253 p->position);
1255 if (p->action)
1256 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1257 p->action);
1259 if (p->read)
1260 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1261 p->read);
1263 if (p->write)
1264 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1265 p->write);
1267 if (p->readwrite)
1268 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1269 p->readwrite);
1271 if (p->pad)
1272 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1273 p->pad);
1275 if (p->convert)
1276 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1277 p->convert);
1279 if (p->strm_pos)
1280 mask |= set_parameter_ref (&block, &post_block, var,
1281 IOPARM_inquire_strm_pos_out, p->strm_pos);
1283 /* The second series of flags. */
1284 if (p->asynchronous)
1285 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_asynchronous,
1286 p->asynchronous);
1288 if (p->decimal)
1289 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_decimal,
1290 p->decimal);
1292 if (p->encoding)
1293 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_encoding,
1294 p->encoding);
1296 if (p->round)
1297 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_round,
1298 p->round);
1300 if (p->sign)
1301 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_sign,
1302 p->sign);
1304 if (p->pending)
1305 mask2 |= set_parameter_ref (&block, &post_block, var,
1306 IOPARM_inquire_pending, p->pending);
1308 if (p->size)
1309 mask2 |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_size,
1310 p->size);
1312 if (p->id)
1313 mask2 |= set_parameter_ref (&block, &post_block,var, IOPARM_inquire_id,
1314 p->id);
1316 if (mask2)
1317 mask |= set_parameter_const (&block, var, IOPARM_inquire_flags2, mask2);
1319 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1321 if (p->unit)
1322 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1323 else
1324 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1326 tmp = gfc_build_addr_expr (NULL_TREE, var);
1327 tmp = build_call_expr (iocall[IOCALL_INQUIRE], 1, tmp);
1328 gfc_add_expr_to_block (&block, tmp);
1330 gfc_add_block_to_block (&block, &post_block);
1332 io_result (&block, var, p->err, NULL, NULL);
1334 return gfc_finish_block (&block);
1338 tree
1339 gfc_trans_wait (gfc_code * code)
1341 stmtblock_t block, post_block;
1342 gfc_wait *p;
1343 tree tmp, var;
1344 unsigned int mask = 0;
1346 gfc_start_block (&block);
1347 gfc_init_block (&post_block);
1349 var = gfc_create_var (st_parameter[IOPARM_ptype_wait].type,
1350 "wait_parm");
1352 set_error_locus (&block, var, &code->loc);
1353 p = code->ext.wait;
1355 /* Set parameters here. */
1356 if (p->iomsg)
1357 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1358 p->iomsg);
1360 if (p->iostat)
1361 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1362 p->iostat);
1364 if (p->err)
1365 mask |= IOPARM_common_err;
1367 if (p->id)
1368 mask |= set_parameter_value (&block, var, IOPARM_wait_id, p->id);
1370 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1372 if (p->unit)
1373 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1375 tmp = gfc_build_addr_expr (NULL_TREE, var);
1376 tmp = build_call_expr (iocall[IOCALL_WAIT], 1, tmp);
1377 gfc_add_expr_to_block (&block, tmp);
1379 gfc_add_block_to_block (&block, &post_block);
1381 io_result (&block, var, p->err, NULL, NULL);
1383 return gfc_finish_block (&block);
1387 static gfc_expr *
1388 gfc_new_nml_name_expr (const char * name)
1390 gfc_expr * nml_name;
1392 nml_name = gfc_get_expr();
1393 nml_name->ref = NULL;
1394 nml_name->expr_type = EXPR_CONSTANT;
1395 nml_name->ts.kind = gfc_default_character_kind;
1396 nml_name->ts.type = BT_CHARACTER;
1397 nml_name->value.character.length = strlen(name);
1398 nml_name->value.character.string = gfc_char_to_widechar (name);
1400 return nml_name;
1403 /* nml_full_name builds up the fully qualified name of a
1404 derived type component. */
1406 static char*
1407 nml_full_name (const char* var_name, const char* cmp_name)
1409 int full_name_length;
1410 char * full_name;
1412 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1413 full_name = (char*)gfc_getmem (full_name_length + 1);
1414 strcpy (full_name, var_name);
1415 full_name = strcat (full_name, "%");
1416 full_name = strcat (full_name, cmp_name);
1417 return full_name;
1420 /* nml_get_addr_expr builds an address expression from the
1421 gfc_symbol or gfc_component backend_decl's. An offset is
1422 provided so that the address of an element of an array of
1423 derived types is returned. This is used in the runtime to
1424 determine that span of the derived type. */
1426 static tree
1427 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1428 tree base_addr)
1430 tree decl = NULL_TREE;
1431 tree tmp;
1432 tree itmp;
1433 int array_flagged;
1434 int dummy_arg_flagged;
1436 if (sym)
1438 sym->attr.referenced = 1;
1439 decl = gfc_get_symbol_decl (sym);
1441 /* If this is the enclosing function declaration, use
1442 the fake result instead. */
1443 if (decl == current_function_decl)
1444 decl = gfc_get_fake_result_decl (sym, 0);
1445 else if (decl == DECL_CONTEXT (current_function_decl))
1446 decl = gfc_get_fake_result_decl (sym, 1);
1448 else
1449 decl = c->backend_decl;
1451 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1452 || TREE_CODE (decl) == VAR_DECL
1453 || TREE_CODE (decl) == PARM_DECL)
1454 || TREE_CODE (decl) == COMPONENT_REF));
1456 tmp = decl;
1458 /* Build indirect reference, if dummy argument. */
1460 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1462 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref (tmp) : tmp;
1464 /* If an array, set flag and use indirect ref. if built. */
1466 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1467 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1469 if (array_flagged)
1470 tmp = itmp;
1472 /* Treat the component of a derived type, using base_addr for
1473 the derived type. */
1475 if (TREE_CODE (decl) == FIELD_DECL)
1476 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
1477 base_addr, tmp, NULL_TREE);
1479 /* If we have a derived type component, a reference to the first
1480 element of the array is built. This is done so that base_addr,
1481 used in the build of the component reference, always points to
1482 a RECORD_TYPE. */
1484 if (array_flagged)
1485 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node, NULL);
1487 /* Now build the address expression. */
1489 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1491 /* If scalar dummy, resolve indirect reference now. */
1493 if (dummy_arg_flagged && !array_flagged)
1494 tmp = build_fold_indirect_ref (tmp);
1496 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1498 return tmp;
1501 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1502 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1503 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1505 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1507 static void
1508 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1509 gfc_symbol * sym, gfc_component * c,
1510 tree base_addr)
1512 gfc_typespec * ts = NULL;
1513 gfc_array_spec * as = NULL;
1514 tree addr_expr = NULL;
1515 tree dt = NULL;
1516 tree string;
1517 tree tmp;
1518 tree dtype;
1519 tree dt_parm_addr;
1520 int n_dim;
1521 int itype;
1522 int rank = 0;
1524 gcc_assert (sym || c);
1526 /* Build the namelist object name. */
1528 string = gfc_build_cstring_const (var_name);
1529 string = gfc_build_addr_expr (pchar_type_node, string);
1531 /* Build ts, as and data address using symbol or component. */
1533 ts = (sym) ? &sym->ts : &c->ts;
1534 as = (sym) ? sym->as : c->as;
1536 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1538 if (as)
1539 rank = as->rank;
1541 if (rank)
1543 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1544 dtype = gfc_get_dtype (dt);
1546 else
1548 itype = GFC_DTYPE_UNKNOWN;
1550 switch (ts->type)
1553 case BT_INTEGER:
1554 itype = GFC_DTYPE_INTEGER;
1555 break;
1556 case BT_LOGICAL:
1557 itype = GFC_DTYPE_LOGICAL;
1558 break;
1559 case BT_REAL:
1560 itype = GFC_DTYPE_REAL;
1561 break;
1562 case BT_COMPLEX:
1563 itype = GFC_DTYPE_COMPLEX;
1564 break;
1565 case BT_DERIVED:
1566 itype = GFC_DTYPE_DERIVED;
1567 break;
1568 case BT_CHARACTER:
1569 itype = GFC_DTYPE_CHARACTER;
1570 break;
1571 default:
1572 gcc_unreachable ();
1575 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1578 /* Build up the arguments for the transfer call.
1579 The call for the scalar part transfers:
1580 (address, name, type, kind or string_length, dtype) */
1582 dt_parm_addr = gfc_build_addr_expr (NULL_TREE, dt_parm);
1584 if (ts->type == BT_CHARACTER)
1585 tmp = ts->cl->backend_decl;
1586 else
1587 tmp = build_int_cst (gfc_charlen_type_node, 0);
1588 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL], 6,
1589 dt_parm_addr, addr_expr, string,
1590 IARG (ts->kind), tmp, dtype);
1591 gfc_add_expr_to_block (block, tmp);
1593 /* If the object is an array, transfer rank times:
1594 (null pointer, name, stride, lbound, ubound) */
1596 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1598 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL_DIM], 5,
1599 dt_parm_addr,
1600 IARG (n_dim),
1601 GFC_TYPE_ARRAY_STRIDE (dt, n_dim),
1602 GFC_TYPE_ARRAY_LBOUND (dt, n_dim),
1603 GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1604 gfc_add_expr_to_block (block, tmp);
1607 if (ts->type == BT_DERIVED)
1609 gfc_component *cmp;
1611 /* Provide the RECORD_TYPE to build component references. */
1613 tree expr = build_fold_indirect_ref (addr_expr);
1615 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1617 char *full_name = nml_full_name (var_name, cmp->name);
1618 transfer_namelist_element (block,
1619 full_name,
1620 NULL, cmp, expr);
1621 gfc_free (full_name);
1626 #undef IARG
1628 /* Create a data transfer statement. Not all of the fields are valid
1629 for both reading and writing, but improper use has been filtered
1630 out by now. */
1632 static tree
1633 build_dt (tree function, gfc_code * code)
1635 stmtblock_t block, post_block, post_end_block, post_iu_block;
1636 gfc_dt *dt;
1637 tree tmp, var;
1638 gfc_expr *nmlname;
1639 gfc_namelist *nml;
1640 unsigned int mask = 0;
1642 gfc_start_block (&block);
1643 gfc_init_block (&post_block);
1644 gfc_init_block (&post_end_block);
1645 gfc_init_block (&post_iu_block);
1647 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1649 set_error_locus (&block, var, &code->loc);
1651 if (last_dt == IOLENGTH)
1653 gfc_inquire *inq;
1655 inq = code->ext.inquire;
1657 /* First check that preconditions are met. */
1658 gcc_assert (inq != NULL);
1659 gcc_assert (inq->iolength != NULL);
1661 /* Connect to the iolength variable. */
1662 mask |= set_parameter_ref (&block, &post_end_block, var,
1663 IOPARM_dt_iolength, inq->iolength);
1664 dt = NULL;
1666 else
1668 dt = code->ext.dt;
1669 gcc_assert (dt != NULL);
1672 if (dt && dt->io_unit)
1674 if (dt->io_unit->ts.type == BT_CHARACTER)
1676 mask |= set_internal_unit (&block, &post_iu_block,
1677 var, dt->io_unit);
1678 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1681 else
1682 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1684 if (dt)
1686 if (dt->iomsg)
1687 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1688 dt->iomsg);
1690 if (dt->iostat)
1691 mask |= set_parameter_ref (&block, &post_end_block, var,
1692 IOPARM_common_iostat, dt->iostat);
1694 if (dt->err)
1695 mask |= IOPARM_common_err;
1697 if (dt->eor)
1698 mask |= IOPARM_common_eor;
1700 if (dt->end)
1701 mask |= IOPARM_common_end;
1703 if (dt->id)
1704 mask |= set_parameter_ref (&block, &post_end_block, var,
1705 IOPARM_dt_id, dt->id);
1707 if (dt->pos)
1708 mask |= set_parameter_value (&block, var, IOPARM_dt_pos, dt->pos);
1710 if (dt->asynchronous)
1711 mask |= set_string (&block, &post_block, var, IOPARM_dt_asynchronous,
1712 dt->asynchronous);
1714 if (dt->blank)
1715 mask |= set_string (&block, &post_block, var, IOPARM_dt_blank,
1716 dt->blank);
1718 if (dt->decimal)
1719 mask |= set_string (&block, &post_block, var, IOPARM_dt_decimal,
1720 dt->decimal);
1722 if (dt->delim)
1723 mask |= set_string (&block, &post_block, var, IOPARM_dt_delim,
1724 dt->delim);
1726 if (dt->pad)
1727 mask |= set_string (&block, &post_block, var, IOPARM_dt_pad,
1728 dt->pad);
1730 if (dt->round)
1731 mask |= set_string (&block, &post_block, var, IOPARM_dt_round,
1732 dt->round);
1734 if (dt->sign)
1735 mask |= set_string (&block, &post_block, var, IOPARM_dt_sign,
1736 dt->sign);
1738 if (dt->rec)
1739 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1741 if (dt->advance)
1742 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1743 dt->advance);
1745 if (dt->format_expr)
1746 mask |= set_string (&block, &post_end_block, var, IOPARM_dt_format,
1747 dt->format_expr);
1749 if (dt->format_label)
1751 if (dt->format_label == &format_asterisk)
1752 mask |= IOPARM_dt_list_format;
1753 else
1754 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1755 dt->format_label->format);
1758 if (dt->size)
1759 mask |= set_parameter_ref (&block, &post_end_block, var,
1760 IOPARM_dt_size, dt->size);
1762 if (dt->namelist)
1764 if (dt->format_expr || dt->format_label)
1765 gfc_internal_error ("build_dt: format with namelist");
1767 nmlname = gfc_new_nml_name_expr (dt->namelist->name);
1769 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1770 nmlname);
1772 if (last_dt == READ)
1773 mask |= IOPARM_dt_namelist_read_mode;
1775 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1777 dt_parm = var;
1779 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1780 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1781 NULL, NULL);
1783 else
1784 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1786 if (dt->io_unit && dt->io_unit->ts.type == BT_INTEGER)
1787 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1789 else
1790 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1792 tmp = gfc_build_addr_expr (NULL_TREE, var);
1793 tmp = build_call_expr (function, 1, tmp);
1794 gfc_add_expr_to_block (&block, tmp);
1796 gfc_add_block_to_block (&block, &post_block);
1798 dt_parm = var;
1799 dt_post_end_block = &post_end_block;
1801 gfc_add_expr_to_block (&block, gfc_trans_code (code->block->next));
1803 gfc_add_block_to_block (&block, &post_iu_block);
1805 dt_parm = NULL;
1806 dt_post_end_block = NULL;
1808 return gfc_finish_block (&block);
1812 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1813 this as a third sort of data transfer statement, except that
1814 lengths are summed instead of actually transferring any data. */
1816 tree
1817 gfc_trans_iolength (gfc_code * code)
1819 last_dt = IOLENGTH;
1820 return build_dt (iocall[IOCALL_IOLENGTH], code);
1824 /* Translate a READ statement. */
1826 tree
1827 gfc_trans_read (gfc_code * code)
1829 last_dt = READ;
1830 return build_dt (iocall[IOCALL_READ], code);
1834 /* Translate a WRITE statement */
1836 tree
1837 gfc_trans_write (gfc_code * code)
1839 last_dt = WRITE;
1840 return build_dt (iocall[IOCALL_WRITE], code);
1844 /* Finish a data transfer statement. */
1846 tree
1847 gfc_trans_dt_end (gfc_code * code)
1849 tree function, tmp;
1850 stmtblock_t block;
1852 gfc_init_block (&block);
1854 switch (last_dt)
1856 case READ:
1857 function = iocall[IOCALL_READ_DONE];
1858 break;
1860 case WRITE:
1861 function = iocall[IOCALL_WRITE_DONE];
1862 break;
1864 case IOLENGTH:
1865 function = iocall[IOCALL_IOLENGTH_DONE];
1866 break;
1868 default:
1869 gcc_unreachable ();
1872 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
1873 tmp = build_call_expr (function, 1, tmp);
1874 gfc_add_expr_to_block (&block, tmp);
1875 gfc_add_block_to_block (&block, dt_post_end_block);
1876 gfc_init_block (dt_post_end_block);
1878 if (last_dt != IOLENGTH)
1880 gcc_assert (code->ext.dt != NULL);
1881 io_result (&block, dt_parm, code->ext.dt->err,
1882 code->ext.dt->end, code->ext.dt->eor);
1885 return gfc_finish_block (&block);
1888 static void
1889 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code);
1891 /* Given an array field in a derived type variable, generate the code
1892 for the loop that iterates over array elements, and the code that
1893 accesses those array elements. Use transfer_expr to generate code
1894 for transferring that element. Because elements may also be
1895 derived types, transfer_expr and transfer_array_component are mutually
1896 recursive. */
1898 static tree
1899 transfer_array_component (tree expr, gfc_component * cm, locus * where)
1901 tree tmp;
1902 stmtblock_t body;
1903 stmtblock_t block;
1904 gfc_loopinfo loop;
1905 int n;
1906 gfc_ss *ss;
1907 gfc_se se;
1909 gfc_start_block (&block);
1910 gfc_init_se (&se, NULL);
1912 /* Create and initialize Scalarization Status. Unlike in
1913 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1914 care of this task, because we don't have a gfc_expr at hand.
1915 Build one manually, as in gfc_trans_subarray_assign. */
1917 ss = gfc_get_ss ();
1918 ss->type = GFC_SS_COMPONENT;
1919 ss->expr = NULL;
1920 ss->shape = gfc_get_shape (cm->as->rank);
1921 ss->next = gfc_ss_terminator;
1922 ss->data.info.dimen = cm->as->rank;
1923 ss->data.info.descriptor = expr;
1924 ss->data.info.data = gfc_conv_array_data (expr);
1925 ss->data.info.offset = gfc_conv_array_offset (expr);
1926 for (n = 0; n < cm->as->rank; n++)
1928 ss->data.info.dim[n] = n;
1929 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1930 ss->data.info.stride[n] = gfc_index_one_node;
1932 mpz_init (ss->shape[n]);
1933 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1934 cm->as->lower[n]->value.integer);
1935 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1938 /* Once we got ss, we use scalarizer to create the loop. */
1940 gfc_init_loopinfo (&loop);
1941 gfc_add_ss_to_loop (&loop, ss);
1942 gfc_conv_ss_startstride (&loop);
1943 gfc_conv_loop_setup (&loop, where);
1944 gfc_mark_ss_chain_used (ss, 1);
1945 gfc_start_scalarized_body (&loop, &body);
1947 gfc_copy_loopinfo_to_se (&se, &loop);
1948 se.ss = ss;
1950 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1951 se.expr = expr;
1952 gfc_conv_tmp_array_ref (&se);
1954 /* Now se.expr contains an element of the array. Take the address and pass
1955 it to the IO routines. */
1956 tmp = gfc_build_addr_expr (NULL_TREE, se.expr);
1957 transfer_expr (&se, &cm->ts, tmp, NULL);
1959 /* We are done now with the loop body. Wrap up the scalarizer and
1960 return. */
1962 gfc_add_block_to_block (&body, &se.pre);
1963 gfc_add_block_to_block (&body, &se.post);
1965 gfc_trans_scalarizing_loops (&loop, &body);
1967 gfc_add_block_to_block (&block, &loop.pre);
1968 gfc_add_block_to_block (&block, &loop.post);
1970 for (n = 0; n < cm->as->rank; n++)
1971 mpz_clear (ss->shape[n]);
1972 gfc_free (ss->shape);
1974 gfc_cleanup_loop (&loop);
1976 return gfc_finish_block (&block);
1979 /* Generate the call for a scalar transfer node. */
1981 static void
1982 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
1984 tree tmp, function, arg2, arg3, field, expr;
1985 gfc_component *c;
1986 int kind;
1988 /* It is possible to get a C_NULL_PTR or C_NULL_FUNPTR expression here if
1989 the user says something like: print *, 'c_null_ptr: ', c_null_ptr
1990 We need to translate the expression to a constant if it's either
1991 C_NULL_PTR or C_NULL_FUNPTR. We could also get a user variable of
1992 type C_PTR or C_FUNPTR, in which case the ts->type may no longer be
1993 BT_DERIVED (could have been changed by gfc_conv_expr). */
1994 if ((ts->type == BT_DERIVED && ts->is_iso_c == 1 && ts->derived != NULL)
1995 || (ts->derived != NULL && ts->derived->ts.is_iso_c == 1))
1997 /* C_PTR and C_FUNPTR have private components which means they can not
1998 be printed. However, if -std=gnu and not -pedantic, allow
1999 the component to be printed to help debugging. */
2000 if (gfc_notification_std (GFC_STD_GNU) != SILENT)
2002 gfc_error_now ("Derived type '%s' at %L has PRIVATE components",
2003 ts->derived->name, code != NULL ? &(code->loc) :
2004 &gfc_current_locus);
2005 return;
2008 ts->type = ts->derived->ts.type;
2009 ts->kind = ts->derived->ts.kind;
2010 ts->f90_type = ts->derived->ts.f90_type;
2013 kind = ts->kind;
2014 function = NULL;
2015 arg2 = NULL;
2016 arg3 = NULL;
2018 switch (ts->type)
2020 case BT_INTEGER:
2021 arg2 = build_int_cst (NULL_TREE, kind);
2022 function = iocall[IOCALL_X_INTEGER];
2023 break;
2025 case BT_REAL:
2026 arg2 = build_int_cst (NULL_TREE, kind);
2027 function = iocall[IOCALL_X_REAL];
2028 break;
2030 case BT_COMPLEX:
2031 arg2 = build_int_cst (NULL_TREE, kind);
2032 function = iocall[IOCALL_X_COMPLEX];
2033 break;
2035 case BT_LOGICAL:
2036 arg2 = build_int_cst (NULL_TREE, kind);
2037 function = iocall[IOCALL_X_LOGICAL];
2038 break;
2040 case BT_CHARACTER:
2041 if (kind == 4)
2043 if (se->string_length)
2044 arg2 = se->string_length;
2045 else
2047 tmp = build_fold_indirect_ref (addr_expr);
2048 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
2049 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
2050 arg2 = fold_convert (gfc_charlen_type_node, arg2);
2052 arg3 = build_int_cst (NULL_TREE, kind);
2053 function = iocall[IOCALL_X_CHARACTER_WIDE];
2054 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2055 tmp = build_call_expr (function, 4, tmp, addr_expr, arg2, arg3);
2056 gfc_add_expr_to_block (&se->pre, tmp);
2057 gfc_add_block_to_block (&se->pre, &se->post);
2058 return;
2060 /* Fall through. */
2061 case BT_HOLLERITH:
2062 if (se->string_length)
2063 arg2 = se->string_length;
2064 else
2066 tmp = build_fold_indirect_ref (addr_expr);
2067 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
2068 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
2070 function = iocall[IOCALL_X_CHARACTER];
2071 break;
2073 case BT_DERIVED:
2074 /* Recurse into the elements of the derived type. */
2075 expr = gfc_evaluate_now (addr_expr, &se->pre);
2076 expr = build_fold_indirect_ref (expr);
2078 for (c = ts->derived->components; c; c = c->next)
2080 field = c->backend_decl;
2081 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2083 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
2084 expr, field, NULL_TREE);
2086 if (c->attr.dimension)
2088 tmp = transfer_array_component (tmp, c, & code->loc);
2089 gfc_add_expr_to_block (&se->pre, tmp);
2091 else
2093 if (!c->attr.pointer)
2094 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
2095 transfer_expr (se, &c->ts, tmp, code);
2098 return;
2100 default:
2101 internal_error ("Bad IO basetype (%d)", ts->type);
2104 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2105 tmp = build_call_expr (function, 3, tmp, addr_expr, arg2);
2106 gfc_add_expr_to_block (&se->pre, tmp);
2107 gfc_add_block_to_block (&se->pre, &se->post);
2112 /* Generate a call to pass an array descriptor to the IO library. The
2113 array should be of one of the intrinsic types. */
2115 static void
2116 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
2118 tree tmp, charlen_arg, kind_arg;
2120 if (ts->type == BT_CHARACTER)
2121 charlen_arg = se->string_length;
2122 else
2123 charlen_arg = build_int_cst (NULL_TREE, 0);
2125 kind_arg = build_int_cst (NULL_TREE, ts->kind);
2127 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2128 tmp = build_call_expr (iocall[IOCALL_X_ARRAY], 4,
2129 tmp, addr_expr, kind_arg, charlen_arg);
2130 gfc_add_expr_to_block (&se->pre, tmp);
2131 gfc_add_block_to_block (&se->pre, &se->post);
2135 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
2137 tree
2138 gfc_trans_transfer (gfc_code * code)
2140 stmtblock_t block, body;
2141 gfc_loopinfo loop;
2142 gfc_expr *expr;
2143 gfc_ref *ref;
2144 gfc_ss *ss;
2145 gfc_se se;
2146 tree tmp;
2147 int n;
2149 gfc_start_block (&block);
2150 gfc_init_block (&body);
2152 expr = code->expr;
2153 ss = gfc_walk_expr (expr);
2155 ref = NULL;
2156 gfc_init_se (&se, NULL);
2158 if (ss == gfc_ss_terminator)
2160 /* Transfer a scalar value. */
2161 gfc_conv_expr_reference (&se, expr);
2162 transfer_expr (&se, &expr->ts, se.expr, code);
2164 else
2166 /* Transfer an array. If it is an array of an intrinsic
2167 type, pass the descriptor to the library. Otherwise
2168 scalarize the transfer. */
2169 if (expr->ref)
2171 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
2172 ref = ref->next);
2173 gcc_assert (ref->type == REF_ARRAY);
2176 if (expr->ts.type != BT_DERIVED
2177 && ref && ref->next == NULL
2178 && !is_subref_array (expr))
2180 bool seen_vector = false;
2182 if (ref && ref->u.ar.type == AR_SECTION)
2184 for (n = 0; n < ref->u.ar.dimen; n++)
2185 if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
2186 seen_vector = true;
2189 if (seen_vector && last_dt == READ)
2191 /* Create a temp, read to that and copy it back. */
2192 gfc_conv_subref_array_arg (&se, expr, 0, INTENT_OUT);
2193 tmp = se.expr;
2195 else
2197 /* Get the descriptor. */
2198 gfc_conv_expr_descriptor (&se, expr, ss);
2199 tmp = gfc_build_addr_expr (NULL_TREE, se.expr);
2202 transfer_array_desc (&se, &expr->ts, tmp);
2203 goto finish_block_label;
2206 /* Initialize the scalarizer. */
2207 gfc_init_loopinfo (&loop);
2208 gfc_add_ss_to_loop (&loop, ss);
2210 /* Initialize the loop. */
2211 gfc_conv_ss_startstride (&loop);
2212 gfc_conv_loop_setup (&loop, &code->expr->where);
2214 /* The main loop body. */
2215 gfc_mark_ss_chain_used (ss, 1);
2216 gfc_start_scalarized_body (&loop, &body);
2218 gfc_copy_loopinfo_to_se (&se, &loop);
2219 se.ss = ss;
2221 gfc_conv_expr_reference (&se, expr);
2222 transfer_expr (&se, &expr->ts, se.expr, code);
2225 finish_block_label:
2227 gfc_add_block_to_block (&body, &se.pre);
2228 gfc_add_block_to_block (&body, &se.post);
2230 if (se.ss == NULL)
2231 tmp = gfc_finish_block (&body);
2232 else
2234 gcc_assert (se.ss == gfc_ss_terminator);
2235 gfc_trans_scalarizing_loops (&loop, &body);
2237 gfc_add_block_to_block (&loop.pre, &loop.post);
2238 tmp = gfc_finish_block (&loop.pre);
2239 gfc_cleanup_loop (&loop);
2242 gfc_add_expr_to_block (&block, tmp);
2244 return gfc_finish_block (&block);
2247 #include "gt-fortran-trans-io.h"